diff -ruw linux-3.2.24/arch/Kconfig linux-3.2.24-fbx/arch/Kconfig
--- linux-3.2.24/arch/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/Kconfig	2013-06-13 15:06:37.998519417 +0200
@@ -181,4 +181,28 @@
 config ARCH_HAVE_NMI_SAFE_CMPXCHG
 	bool
 
+config HAVE_ARCH_SECCOMP_FILTER
+	bool
+	help
+	  An arch should select this symbol if it provides all of these things:
+	  - syscall_get_arch()
+	  - syscall_get_arguments()
+	  - syscall_rollback()
+	  - syscall_set_return_value()
+	  - SIGSYS siginfo_t support
+	  - uses __secure_computing_int() or secure_computing()
+	  - secure_computing is called from a ptrace_event()-safe context
+	  - secure_computing return value is checked and a return value of -1
+	    results in the system call being skipped immediately.
+
+config SECCOMP_FILTER
+	def_bool y
+	depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET
+	help
+	  Enable tasks to build secure computing environments defined
+	  in terms of Berkeley Packet Filter programs which implement
+	  task-defined system call filtering polices.
+
+	  See Documentation/prctl/seccomp_filter.txt for details.
+
 source "kernel/gcov/Kconfig"
diff -ruw linux-3.2.24/arch/x86/boot/early_serial_console.c linux-3.2.24-fbx/arch/x86/boot/early_serial_console.c
--- linux-3.2.24/arch/x86/boot/early_serial_console.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/boot/early_serial_console.c	2011-11-04 14:26:06.415888633 +0100
@@ -26,11 +26,17 @@
 	unsigned divisor;
 
 	outb(0x3, port + LCR);	/* 8n1 */
+#ifndef CONFIG_X86_INTEL_CE
 	outb(0, port + IER);	/* no interrupt */
+#endif
 	outb(0, port + FCR);	/* no fifo */
 	outb(0x3, port + MCR);	/* DTR + RTS */
 
+#ifdef CONFIG_X86_INTEL_CE
+	divisor	= 921600 / baud;
+#else
 	divisor	= 115200 / baud;
+#endif
 	c = inb(port + LCR);
 	outb(c | DLAB, port + LCR);
 	outb(divisor & 0xff, port + DLL);
diff -ruw linux-3.2.24/arch/x86/include/asm/bootparam.h linux-3.2.24-fbx/arch/x86/include/asm/bootparam.h
--- linux-3.2.24/arch/x86/include/asm/bootparam.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/include/asm/bootparam.h	2013-06-13 15:06:39.066518904 +0200
@@ -14,6 +14,12 @@
 #define SETUP_E820_EXT			1
 #define SETUP_DTB			2
 
+/*
+ * use a number that likely won't clash with newer extensions.
+ */
+#define SETUP_FBXSERIAL_EXT		0x42000001
+#define SETUP_FBXBOOTINFO		0x42000002
+
 /* extensible setup data list node */
 struct setup_data {
 	__u64 next;
diff -ruw linux-3.2.24/arch/x86/include/asm/string_32.h linux-3.2.24-fbx/arch/x86/include/asm/string_32.h
--- linux-3.2.24/arch/x86/include/asm/string_32.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/include/asm/string_32.h	2011-11-04 14:26:06.447888667 +0100
@@ -178,7 +178,7 @@
 
 #ifndef CONFIG_KMEMCHECK
 
-#if (__GNUC__ >= 4)
+#if (__GNUC__ >= 4 && !defined(CONFIG_X86_INTEL_CE))
 #define memcpy(t, f, n) __builtin_memcpy(t, f, n)
 #else
 #define memcpy(t, f, n)				\
@@ -321,7 +321,7 @@
 	 : __memset_generic((s), (c), (count)))
 
 #define __HAVE_ARCH_MEMSET
-#if (__GNUC__ >= 4)
+#if (__GNUC__ >= 4 && !defined(CONFIG_X86_INTEL_CE))
 #define memset(s, c, count) __builtin_memset(s, c, count)
 #else
 #define memset(s, c, count)						\
diff -ruw linux-3.2.24/arch/x86/include/asm/syscall.h linux-3.2.24-fbx/arch/x86/include/asm/syscall.h
--- linux-3.2.24/arch/x86/include/asm/syscall.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/include/asm/syscall.h	2013-06-13 15:06:39.074518901 +0200
@@ -13,6 +13,7 @@
 #ifndef _ASM_X86_SYSCALL_H
 #define _ASM_X86_SYSCALL_H
 
+#include <linux/audit.h>
 #include <linux/sched.h>
 #include <linux/err.h>
 
@@ -86,6 +87,12 @@
 	memcpy(&regs->bx + i, args, n * sizeof(args[0]));
 }
 
+static inline int syscall_get_arch(struct task_struct *task,
+				   struct pt_regs *regs)
+{
+	return AUDIT_ARCH_I386;
+}
+
 #else	 /* CONFIG_X86_64 */
 
 static inline void syscall_get_arguments(struct task_struct *task,
@@ -210,6 +217,22 @@
 		}
 }
 
+static inline int syscall_get_arch(struct task_struct *task,
+				   struct pt_regs *regs)
+{
+#ifdef CONFIG_IA32_EMULATION
+	/*
+	 * TS_COMPAT is set for 32-bit syscall entries and then
+	 * remains set until we return to user mode.
+	 *
+	 * TIF_IA32 tasks should always have TS_COMPAT set at
+	 * system call time.
+	 */
+	if (task_thread_info(task)->status & TS_COMPAT)
+		return AUDIT_ARCH_I386;
+#endif
+	return AUDIT_ARCH_X86_64;
+}
 #endif	/* CONFIG_X86_32 */
 
 #endif	/* _ASM_X86_SYSCALL_H */
diff -ruw linux-3.2.24/arch/x86/Kconfig linux-3.2.24-fbx/arch/x86/Kconfig
--- linux-3.2.24/arch/x86/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/Kconfig	2013-06-13 16:01:28.479228849 +0200
@@ -75,6 +75,7 @@
 	select HAVE_BPF_JIT if (X86_64 && NET)
 	select CLKEVT_I8253
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select HAVE_ARCH_SECCOMP_FILTER
 
 config INSTRUCTION_DECODER
 	def_bool (KPROBES || PERF_EVENTS)
@@ -390,6 +391,11 @@
 	  This option compiles in support for the CE4100 SOC for settop
 	  boxes and media devices.
 
+config FBX6HD
+	bool "Freebox 6HD support"
+	depends on X86_INTEL_CE
+	select FBXSERIAL
+
 config X86_WANT_INTEL_MID
 	bool "Intel MID platform support"
 	depends on X86_32
diff -ruw linux-3.2.24/arch/x86/kernel/early_printk.c linux-3.2.24-fbx/arch/x86/kernel/early_printk.c
--- linux-3.2.24/arch/x86/kernel/early_printk.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/kernel/early_printk.c	2013-06-13 15:06:39.098518889 +0200
@@ -144,7 +144,9 @@
 	}
 
 	outb(0x3, early_serial_base + LCR);	/* 8n1 */
+#ifndef CONFIG_X86_INTEL_CE
 	outb(0, early_serial_base + IER);	/* no interrupt */
+#endif
 	outb(0, early_serial_base + FCR);	/* no fifo */
 	outb(0x3, early_serial_base + MCR);	/* DTR + RTS */
 
@@ -154,7 +156,11 @@
 			baud = DEFAULT_BAUD;
 	}
 
+#ifdef CONFIG_X86_INTEL_CE
+	divisor = 921600 / baud;
+#else
 	divisor = 115200 / baud;
+#endif
 	c = inb(early_serial_base + LCR);
 	outb(c | DLAB, early_serial_base + LCR);
 	outb(divisor & 0xff, early_serial_base + DLL);
diff -ruw linux-3.2.24/arch/x86/kernel/head32.c linux-3.2.24-fbx/arch/x86/kernel/head32.c
--- linux-3.2.24/arch/x86/kernel/head32.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/kernel/head32.c	2013-06-13 15:06:39.098518889 +0200
@@ -46,6 +46,13 @@
 	}
 #endif
 
+#ifdef CONFIG_FBX6HD
+	/* bootloader does not set subarch correctly, so we can't
+	 * compile generic kernels, though we may be able to detect
+	 * ce4100 at runtime */
+	boot_params.hdr.hardware_subarch = X86_SUBARCH_CE4100;
+#endif
+
 	/* Call the subarch specific early setup function */
 	switch (boot_params.hdr.hardware_subarch) {
 	case X86_SUBARCH_MRST:
diff -ruw linux-3.2.24/arch/x86/kernel/Makefile linux-3.2.24-fbx/arch/x86/kernel/Makefile
--- linux-3.2.24/arch/x86/kernel/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/kernel/Makefile	2013-06-13 15:06:39.078518900 +0200
@@ -73,6 +73,7 @@
 obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_VM86)		+= vm86_32.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+obj-$(CONFIG_ARCH_GEN3)		+= i2c-intelce.o
 
 obj-$(CONFIG_HPET_TIMER) 	+= hpet.o
 obj-$(CONFIG_APB_TIMER)		+= apb_timer.o
@@ -99,6 +100,9 @@
 obj-$(CONFIG_SWIOTLB)			+= pci-swiotlb.o
 obj-$(CONFIG_OF)			+= devicetree.o
 
+obj-$(CONFIG_FBXSERIAL)			+= fbxserial.o
+obj-y					+= fbxbootinfo.o
+
 ###
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
diff -ruw linux-3.2.24/arch/x86/kernel/ptrace.c linux-3.2.24-fbx/arch/x86/kernel/ptrace.c
--- linux-3.2.24/arch/x86/kernel/ptrace.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/kernel/ptrace.c	2013-06-13 15:06:39.106518887 +0200
@@ -1379,7 +1379,11 @@
 		regs->flags |= X86_EFLAGS_TF;
 
 	/* do the secure computing check first */
-	secure_computing(regs->orig_ax);
+	if (secure_computing(regs->orig_ax)) {
+		/* seccomp failures shouldn't expose any additional code. */
+		ret = -1L;
+		goto out;
+	}
 
 	if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
 		ret = -1L;
@@ -1406,6 +1410,7 @@
 #endif
 	}
 
+out:
 	return ret ?: regs->orig_ax;
 }
 
diff -ruw linux-3.2.24/arch/x86/kernel/setup.c linux-3.2.24-fbx/arch/x86/kernel/setup.c
--- linux-3.2.24/arch/x86/kernel/setup.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/kernel/setup.c	2013-06-13 15:06:39.106518887 +0200
@@ -428,6 +428,8 @@
 {
 	struct setup_data *data;
 	u64 pa_data;
+	extern void parse_fbxserial_ext(struct setup_data *d);
+	extern void parse_fbxbootinfo(struct setup_data *d);
 
 	if (boot_params.hdr.version < 0x0209)
 		return;
@@ -452,6 +454,14 @@
 		case SETUP_DTB:
 			add_dtb(pa_data);
 			break;
+#ifdef CONFIG_FBXSERIAL
+		case SETUP_FBXSERIAL_EXT:
+			parse_fbxserial_ext(data);
+			break;
+#endif
+		case SETUP_FBXBOOTINFO:
+			parse_fbxbootinfo(data);
+			break;
 		default:
 			break;
 		}
@@ -920,15 +930,15 @@
 	/* preallocate 4k for mptable mpc */
 	early_reserve_e820_mpc_new();
 
-#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
-	setup_bios_corruption_check();
-#endif
-
 	printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
 			max_pfn_mapped<<PAGE_SHIFT);
 
 	setup_trampolines();
 
+#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
+	setup_bios_corruption_check();
+#endif
+
 	init_gbpages();
 
 	/* max_pfn_mapped is updated here */
diff -ruw linux-3.2.24/arch/x86/kernel/tsc.c linux-3.2.24-fbx/arch/x86/kernel/tsc.c
--- linux-3.2.24/arch/x86/kernel/tsc.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/kernel/tsc.c	2013-06-13 15:52:30.177198391 +0200
@@ -957,7 +957,7 @@
 void __init tsc_init(void)
 {
 	u64 lpj;
-	int cpu;
+	int cpu, ret;
 
 	x86_init.timers.tsc_pre_init();
 
diff -ruw linux-3.2.24/arch/x86/pci/ce4100.c linux-3.2.24-fbx/arch/x86/pci/ce4100.c
--- linux-3.2.24/arch/x86/pci/ce4100.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/pci/ce4100.c	2012-07-27 18:10:44.260135034 +0200
@@ -115,6 +115,16 @@
 	reg_read(reg, value);
 }
 
+static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value)
+{
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
+	/* force interrupt pin value to 0 */
+	*value = reg->sim_reg.value & 0xfff00ff;
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+}
+
 static struct sim_dev_reg bus1_fixups[] = {
 	DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write)
 	DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write)
@@ -144,6 +154,7 @@
 	DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write)
 	DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write)
 	DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write)
+	DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
 	DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
 	DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write)
 	DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write)
@@ -161,8 +172,10 @@
 	DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write)
 	DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write)
 	DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write)
+	DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
 	DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
 	DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write)
+	DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
 };
 
 static void __init init_sim_regs(void)
diff -ruw linux-3.2.24/arch/x86/platform/ce4100/ce4100.c linux-3.2.24-fbx/arch/x86/platform/ce4100/ce4100.c
--- linux-3.2.24/arch/x86/platform/ce4100/ce4100.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/platform/ce4100/ce4100.c	2013-06-13 15:06:39.126518876 +0200
@@ -14,6 +14,8 @@
 #include <linux/module.h>
 #include <linux/serial_reg.h>
 #include <linux/serial_8250.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 
 #include <asm/ce4100.h>
 #include <asm/prom.h>
@@ -21,12 +23,18 @@
 #include <asm/i8259.h>
 #include <asm/io.h>
 #include <asm/io_apic.h>
+#include <asm/emergency-restart.h>
 
 static int ce4100_i8042_detect(void)
 {
 	return 0;
 }
 
+static void ce4100_power_off(void)
+{
+	outb(0x4, 0xcf9);
+}
+
 #ifdef CONFIG_SERIAL_8250
 
 static unsigned int mem_serial_in(struct uart_port *p, int offset)
@@ -92,8 +100,11 @@
 		up->membase =
 			(void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
 		up->membase += up->mapbase & ~PAGE_MASK;
+		up->mapbase += port * 0x100;
+		up->membase += port * 0x100;
 		up->iotype   = UPIO_MEM32;
 		up->regshift = 2;
+		up->irq = 4;
 	}
 #endif
 	up->iobase = 0;
@@ -126,10 +137,72 @@
 }
 #endif
 
+
+#ifdef CONFIG_FBX6HD
+
+#include <linux/crash_zone.h>
+static const struct of_device_id remoti_ids[] __initdata = {
+	{ .compatible = "ti,remoti" },
+	{ /* sentinel */ },
+};
+
+extern int sdv_i2c_fixup_ck505(void);
+
+static int __init fbx6hd_init(void)
+{
+	int ret;
+
+	panic_timeout = 10;
+
+	ret = of_platform_bus_probe(NULL, remoti_ids, NULL);
+	if (ret) {
+		pr_err("failed to probe remoti platform bus\n");
+		return ret;
+	}
+
+	ret = crash_zone_of_init();
+	if (ret)
+		printk(KERN_ERR " failed to register crashzone\n");
+
+	return ret;
+}
+
+arch_initcall(fbx6hd_init);
+
+static char *__init fbx6hd_memory_setup(void)
+{
+	char *who = "fbx-rammap";
+	u64 usable_mem_size;
+
+	/* BIOS does not report correct ram size */
+	usable_mem_size = 1024 << 20;
+
+	/*
+	 * acpi tables are at 0x10000
+	 * uc8051 code is running at 0x40000
+	 */
+	e820_add_region(0x10000, 0x10000, E820_ACPI);
+	e820_add_region(0x20000, 0x40000 - 0x20000, E820_RAM);
+	e820_add_region(0x50000, 0x98000 - 0x50000, E820_RAM);
+	e820_add_region(HIGH_MEMORY, usable_mem_size - HIGH_MEMORY, E820_RAM);
+
+	return who;
+}
+
+static void __init fbx6hd_fixup_ck505(void)
+{
+	sdv_i2c_fixup_ck505();
+}
+#endif
+
 /*
  * CE4100 specific x86_init function overrides and early setup
  * calls.
  */
+#ifdef CONFIG_OF_EARLY_FLATTREE
+extern void *__dtb_start;
+#endif
+
 void __init x86_ce4100_early_setup(void)
 {
 	x86_init.oem.arch_setup = sdv_arch_setup;
@@ -139,8 +212,25 @@
 	x86_init.mpparse.find_smp_config = x86_init_noop;
 	x86_init.pci.init = ce4100_pci_init;
 
+	reboot_type = BOOT_KBD;
+
+#ifdef CONFIG_FBX6HD
+	/* our crappy firmware does not pass a valid e820 map, so
+	 * fixup manually */
+	x86_init.resources.memory_setup = fbx6hd_memory_setup;
+
+	/* early fixup of clock */
+	x86_init.timers.tsc_pre_init = fbx6hd_fixup_ck505;
+#endif
+
+#ifdef CONFIG_OF_EARLY_FLATTREE
+	initial_dtb = __pa(&__dtb_start);
+#endif
+
 #ifdef CONFIG_X86_IO_APIC
 	x86_init.pci.init_irq = sdv_pci_init;
 	x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
 #endif
+
+	pm_power_off = ce4100_power_off;
 }
diff -ruw linux-3.2.24/arch/x86/platform/ce4100/Makefile linux-3.2.24-fbx/arch/x86/platform/ce4100/Makefile
--- linux-3.2.24/arch/x86/platform/ce4100/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/arch/x86/platform/ce4100/Makefile	2011-11-04 14:26:06.531888753 +0100
@@ -1 +1,8 @@
 obj-$(CONFIG_X86_INTEL_CE)	+= ce4100.o
+
+obj-$(CONFIG_FBX6HD)		+= fbx6hd.dtb.o i2c-intelce.o
+
+clean-files := *dtb.S
+
+$(obj)/%.dtb: $(src)/%.dts
+	$(call cmd,dtc)
diff -ruw linux-3.2.24/crypto/algboss.c linux-3.2.24-fbx/crypto/algboss.c
--- linux-3.2.24/crypto/algboss.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/crypto/algboss.c	2013-06-13 15:06:39.150518864 +0200
@@ -219,7 +219,9 @@
 	if (type & CRYPTO_ALG_TESTED)
 		goto skiptest;
 
+#ifdef CONFIG_CRYPTO_BUILTIN_TEST
 	err = alg_test(param->driver, param->alg, type, CRYPTO_ALG_TESTED);
+#endif
 
 skiptest:
 	crypto_alg_tested(param->driver, err);
diff -ruw linux-3.2.24/crypto/Kconfig linux-3.2.24-fbx/crypto/Kconfig
--- linux-3.2.24/crypto/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/crypto/Kconfig	2013-06-13 15:06:39.150518864 +0200
@@ -86,6 +86,10 @@
 	tristate
 	select CRYPTO_ALGAPI2
 
+config CRYPTO_BUILTIN_TEST
+	bool "Include builtin tests"
+	default y
+
 config CRYPTO_MANAGER
 	tristate "Cryptographic algorithm manager"
 	select CRYPTO_MANAGER2
diff -ruw linux-3.2.24/crypto/Makefile linux-3.2.24-fbx/crypto/Makefile
--- linux-3.2.24/crypto/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/crypto/Makefile	2013-06-13 15:06:39.150518864 +0200
@@ -28,7 +28,10 @@
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
 
-cryptomgr-y := algboss.o testmgr.o
+cryptomgr-y := algboss.o
+ifeq ($(CONFIG_CRYPTO_BUILTIN_TEST),y)
+cryptomgr-y += testmgr.o
+endif
 
 obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
 obj-$(CONFIG_CRYPTO_USER) += crypto_user.o
diff -ruw linux-3.2.24/drivers/char/Kconfig linux-3.2.24-fbx/drivers/char/Kconfig
--- linux-3.2.24/drivers/char/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/char/Kconfig	2013-06-13 15:06:39.290518798 +0200
@@ -15,6 +15,15 @@
 	  kind of kernel debugging operations.
 	  When in doubt, say "N".
 
+config DEVPHYSMEM
+	bool "/dev/physmem virtual device support"
+	default n
+	help
+	  Say Y here if you want to support the /dev/physmem device. The
+	  /dev/physmem device allows unprivileged access to physical memory
+	  unused by the kernel.
+	  When in doubt, say "N".
+
 config STALDRV
 	bool "Stallion multiport serial support"
 	depends on SERIAL_NONSTANDARD
diff -ruw linux-3.2.24/drivers/char/mem.c linux-3.2.24-fbx/drivers/char/mem.c
--- linux-3.2.24/drivers/char/mem.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/char/mem.c	2013-06-13 15:06:39.302518792 +0200
@@ -354,6 +354,16 @@
 }
 #endif
 
+#ifdef CONFIG_DEVPHYSMEM
+static int mmap_physmem(struct file * file, struct vm_area_struct * vma)
+{
+	if (vma->vm_pgoff < max_pfn && !capable(CAP_SYS_RAWIO))
+		return -EPERM;
+
+	return mmap_mem(file, vma);
+}
+#endif
+
 #ifdef CONFIG_CRASH_DUMP
 /*
  * Read memory corresponding to the old kernel.
@@ -732,6 +742,13 @@
 	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
 }
 
+#ifdef CONFIG_DEVPHYSMEM
+static int open_physmem(struct inode * inode, struct file * filp)
+{
+	return 0;
+}
+#endif
+
 #define zero_lseek	null_lseek
 #define full_lseek      null_lseek
 #define write_zero	write_null
@@ -807,6 +824,14 @@
 };
 #endif
 
+#ifdef CONFIG_DEVPHYSMEM
+static const struct file_operations physmem_fops = {
+	.mmap		= mmap_physmem,
+	.open		= open_physmem,
+	.get_unmapped_area = get_unmapped_area_mem,
+};
+#endif
+
 static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv,
 			   unsigned long count, loff_t pos)
 {
@@ -867,6 +892,9 @@
 #ifdef CONFIG_CRASH_DUMP
 	[12] = { "oldmem", 0, &oldmem_fops, NULL },
 #endif
+#ifdef CONFIG_DEVPHYSMEM
+	[16] = { "physmem", 0, &physmem_fops, &directly_mappable_cdev_bdi },
+#endif
 };
 
 static int memory_open(struct inode *inode, struct file *filp)
diff -ruw linux-3.2.24/drivers/hid/hid-dr.c linux-3.2.24-fbx/drivers/hid/hid-dr.c
--- linux-3.2.24/drivers/hid/hid-dr.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/hid/hid-dr.c	2012-07-27 18:10:44.668135421 +0200
@@ -236,6 +236,75 @@
 	0xC0                /*  End Collection                  */
 };
 
+/* Size of the original descriptor of the PID 0x0006 joystick */
+#define PID0006_RDESC_ORIG_SIZE	101
+
+/* Fixed report descriptor for PID 0x006 joystick */
+static __u8 pid0006_rdesc_fixed[] = {
+	0x05, 0x01,         /*  Usage Page (Desktop),                   */
+	0x09, 0x04,         /*  Usage (Joystik),                        */
+	0xA1, 0x01,         /*  Collection (Application),               */
+	0xA1, 0x02,         /*      Collection (Logical),               */
+	0x75, 0x08,         /*          Report Size (8),                */
+	0x95, 0x02,         /*          Report Count (2),               */
+	0x15, 0x00,         /*          Logical Minimum (0),            */
+	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),          */
+	0x35, 0x00,         /*          Physical Minimum (0),           */
+	0x46, 0xFF, 0x00,   /*          Physical Maximum (255),         */
+	0x09, 0x30,         /*          Usage (X),                      */
+	0x09, 0x31,         /*          Usage (Y),                      */
+	0x81, 0x02,         /*          Input (Variable),               */
+
+	/* Ignore noisy input */
+	0x75, 0x08,         /*          Report Size (8),                */
+	0x95, 0x01,         /*          Report Count (1),               */
+	0x81, 0x01,         /*          Input (Constant),       */
+
+	0x75, 0x08,         /*          Report Size (8),                */
+	0x95, 0x02,         /*          Report Count (2),               */
+	0x15, 0x00,         /*          Logical Minimum (0),            */
+	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),          */
+	0x35, 0x00,         /*          Physical Minimum (0),           */
+	0x46, 0xFF, 0x00,   /*          Physical Maximum (255),         */
+	0x09, 0x30,         /*          Usage (X),                      */
+	0x09, 0x31,         /*          Usage (Y),                      */
+	0x81, 0x02,         /*          Input (Variable),               */
+
+	0x75, 0x04,         /*          Report Size (4),                */
+	0x95, 0x01,         /*          Report Count (1),               */
+	0x25, 0x07,         /*          Logical Maximum (7),            */
+	0x46, 0x3B, 0x01,   /*          Physical Maximum (315),         */
+	0x65, 0x14,         /*          Unit (Degrees),                 */
+	0x09, 0x39,         /*          Usage (Hat Switch),             */
+	0x81, 0x42,         /*          Input (Variable, Null State),   */
+	0x65, 0x00,         /*          Unit,                           */
+	0x75, 0x01,         /*          Report Size (1),                */
+	0x95, 0x0C,         /*          Report Count (12),              */
+	0x25, 0x01,         /*          Logical Maximum (1),            */
+	0x45, 0x01,         /*          Physical Maximum (1),           */
+	0x05, 0x09,         /*          Usage Page (Button),            */
+	0x19, 0x01,         /*          Usage Minimum (01h),            */
+	0x29, 0x0C,         /*          Usage Maximum (0Ch),            */
+	0x81, 0x02,         /*          Input (Variable),               */
+	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),             */
+	0x75, 0x01,         /*          Report Size (1),                */
+	0x95, 0x08,         /*          Report Count (8),               */
+	0x25, 0x01,         /*          Logical Maximum (1),            */
+	0x45, 0x01,         /*          Physical Maximum (1),           */
+	0x09, 0x01,         /*          Usage (01h),                    */
+	0x81, 0x02,         /*          Input (Variable),               */
+	0xC0,               /*      End Collection,                     */
+	0xA1, 0x02,         /*      Collection (Logical),               */
+	0x75, 0x08,         /*          Report Size (8),                */
+	0x95, 0x07,         /*          Report Count (7),               */
+	0x46, 0xFF, 0x00,   /*          Physical Maximum (255),         */
+	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),          */
+	0x09, 0x02,         /*          Usage (02h),                    */
+	0x91, 0x02,         /*          Output (Variable),              */
+	0xC0,               /*      End Collection,                     */
+	0xC0                /*  End Collection                          */
+};
+
 static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 				unsigned int *rsize)
 {
@@ -246,6 +315,12 @@
 			*rsize = sizeof(pid0011_rdesc_fixed);
 		}
 		break;
+	case 0x0006:
+		if (*rsize == PID0006_RDESC_ORIG_SIZE) {
+			rdesc = pid0006_rdesc_fixed;
+			*rsize = sizeof(pid0006_rdesc_fixed);
+		}
+		break;
 	}
 	return rdesc;
 }
@@ -270,6 +345,7 @@
 
 	switch (hdev->product) {
 	case 0x0006:
+		strcpy(hdev->name, "Freebox Gamepad");
 		ret = drff_init(hdev);
 		if (ret) {
 			dev_err(&hdev->dev, "force feedback init failed\n");
diff -ruw linux-3.2.24/drivers/hwmon/adt7475.c linux-3.2.24-fbx/drivers/hwmon/adt7475.c
--- linux-3.2.24/drivers/hwmon/adt7475.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/hwmon/adt7475.c	2013-06-13 15:06:39.478518708 +0200
@@ -122,7 +122,19 @@
 
 /* Macro to read the registers */
 
-#define adt7475_read(reg) i2c_smbus_read_byte_data(client, (reg))
+static inline s32 __adt7475_read(const struct i2c_client *client, u8 cmd)
+{
+	s32 ret;
+
+	ret = i2c_smbus_read_byte_data(client, cmd);
+	if (ret < 0) {
+		printk("__adt7475_read error: %d\n", ret);
+		return 0;
+	}
+	return ret;
+}
+
+#define adt7475_read(reg) __adt7475_read(client, (reg))
 
 /* Macros to easily index the registers */
 
@@ -276,6 +288,9 @@
 {
 	u16 val;
 
+	if (need_resched())
+		yield();
+
 	val = i2c_smbus_read_byte_data(client, reg);
 	val |= (i2c_smbus_read_byte_data(client, reg + 1) << 8);
 
@@ -828,7 +843,7 @@
 
 	data->range[sattr->index] =
 		adt7475_read(TEMP_TRANGE_REG(sattr->index));
-	data->range[sattr->index] &= ~7;
+	data->range[sattr->index] &= ~0xf;
 	data->range[sattr->index] |= out;
 
 	i2c_smbus_write_byte_data(client, TEMP_TRANGE_REG(sattr->index),
diff -ruw linux-3.2.24/drivers/hwmon/coretemp.c linux-3.2.24-fbx/drivers/hwmon/coretemp.c
--- linux-3.2.24/drivers/hwmon/coretemp.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/hwmon/coretemp.c	2013-06-13 15:52:30.337198314 +0200
@@ -213,14 +213,22 @@
 		usemsr_ee = 0;
 
 		host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
-
-		if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL
-		    && (host_bridge->device == 0xa000	/* NM10 based nettop */
-		    || host_bridge->device == 0xa010))	/* NM10 based netbook */
+		if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL) {
+			switch (host_bridge->device) {
+			/* NM10 based nettop */
+			case 0xa000:
+			case 0xa010:
 			tjmax = 100000;
-		else
+				break;
+			/* CE3100 / CE4100 */
+			case 0x0708:
+				tjmax = 110000;
+				break;
+			default:
 			tjmax = 90000;
-
+				break;
+			}
+		}
 		pci_dev_put(host_bridge);
 	}
 
diff -ruw linux-3.2.24/drivers/hwmon/Kconfig linux-3.2.24-fbx/drivers/hwmon/Kconfig
--- linux-3.2.24/drivers/hwmon/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/hwmon/Kconfig	2013-06-13 15:52:30.333198316 +0200
@@ -1361,6 +1361,10 @@
         help
           Support for the A/D converter on MC13783 PMIC.
 
+config SENSORS_KIRKWOOD_CORETEMP
+	tristate "Kirkwood core temperature censor"
+	depends on ARCH_KIRKWOOD
+
 if ACPI
 
 comment "ACPI drivers"
diff -ruw linux-3.2.24/drivers/hwmon/lm85.c linux-3.2.24-fbx/drivers/hwmon/lm85.c
--- linux-3.2.24/drivers/hwmon/lm85.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/hwmon/lm85.c	2013-06-13 15:06:39.486518705 +0200
@@ -205,11 +205,11 @@
 #define RANGE_FROM_REG(val)	lm85_range_map[(val) & 0x0f]
 
 /* These are the PWM frequency encodings */
-static const int lm85_freq_map[8] = { /* 1 Hz */
-	10, 15, 23, 30, 38, 47, 61, 94
+static const int lm85_freq_map[11] = { /* 1 Hz */
+	10, 15, 23, 30, 38, 47, 61, 94, 94, 94, 94
 };
-static const int adm1027_freq_map[8] = { /* 1 Hz */
-	11, 15, 22, 29, 35, 44, 59, 88
+static const int adm1027_freq_map[11] = { /* 1 Hz */
+	11, 15, 22, 29, 35, 44, 59, 88, 88, 88, 25000
 };
 
 static int FREQ_TO_REG(const int *map, int freq)
@@ -217,7 +217,7 @@
 	int i;
 
 	/* Find the closest match */
-	for (i = 0; i < 7; ++i)
+	for (i = 0; i < 10; ++i)
 		if (freq <= (map[i] + map[i + 1]) / 2)
 			break;
 	return i;
@@ -225,7 +225,7 @@
 
 static int FREQ_FROM_REG(const int *map, u8 reg)
 {
-	return map[reg & 0x07];
+	return map[reg & 0x0f];
 }
 
 /* Since we can't use strings, I'm abusing these numbers
@@ -929,7 +929,7 @@
 		TEMP_FROM_REG(data->zone[nr].limit));
 	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
 		((data->zone[nr].range & 0x0f) << 4)
-		| (data->pwm_freq[nr] & 0x07));
+		| (data->pwm_freq[nr] & 0x0f));
 
 	mutex_unlock(&data->update_lock);
 	return count;
@@ -960,7 +960,7 @@
 		val - min);
 	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
 		((data->zone[nr].range & 0x0f) << 4)
-		| (data->pwm_freq[nr] & 0x07));
+		| (data->pwm_freq[nr] & 0x0f));
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -1146,8 +1146,28 @@
 
 static void lm85_init_client(struct i2c_client *client)
 {
+	struct lm85_data *data = i2c_get_clientdata(client);
 	int value;
 
+	/* workaround for emc2300 (emc6d103s), when auto temp min is
+	 * the default value, pwm can never be controlled manually, so
+	 * change this */
+	if (data->type == emc6d103s) {
+		int nr;
+
+		for (nr = 0; nr < 3; nr++) {
+			data->zone[nr].limit = TEMP_TO_REG(-127000);
+			lm85_write_value(client, LM85_REG_AFAN_LIMIT(nr),
+					 data->zone[nr].limit);
+
+			/* also force high frequency */
+			data->pwm_freq[nr] = 0xa;
+			lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
+					 data->pwm_freq[nr]);
+		}
+	}
+
+
 	/* Start monitoring if needed */
 	value = lm85_read_value(client, LM85_REG_CONFIG);
 	if (!(value & 0x01)) {
@@ -1570,7 +1590,7 @@
 			data->autofan[i].config =
 			    lm85_read_value(client, LM85_REG_AFAN_CONFIG(i));
 			val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i));
-			data->pwm_freq[i] = val & 0x07;
+			data->pwm_freq[i] = val & 0x0f;
 			data->zone[i].range = val >> 4;
 			data->autofan[i].min_pwm =
 			    lm85_read_value(client, LM85_REG_AFAN_MINPWM(i));
diff -ruw linux-3.2.24/drivers/hwmon/Makefile linux-3.2.24-fbx/drivers/hwmon/Makefile
--- linux-3.2.24/drivers/hwmon/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/hwmon/Makefile	2013-06-13 15:52:30.333198316 +0200
@@ -125,6 +125,7 @@
 obj-$(CONFIG_SENSORS_W83L786NG)	+= w83l786ng.o
 obj-$(CONFIG_SENSORS_WM831X)	+= wm831x-hwmon.o
 obj-$(CONFIG_SENSORS_WM8350)	+= wm8350-hwmon.o
+obj-$(CONFIG_SENSORS_KIRKWOOD_CORETEMP)+= kirkwood-coretemp.o
 
 obj-$(CONFIG_PMBUS)		+= pmbus/
 
diff -ruw linux-3.2.24/drivers/i2c/busses/i2c-pxa.c linux-3.2.24-fbx/drivers/i2c/busses/i2c-pxa.c
--- linux-3.2.24/drivers/i2c/busses/i2c-pxa.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/i2c/busses/i2c-pxa.c	2013-06-13 15:06:39.510518693 +0200
@@ -798,6 +798,16 @@
 		if (ret != I2C_RETRY)
 			goto out;
 
+		if (i == 1 &&
+		    (readl(_ISR(i2c)) & ISR_UB) &&
+		    (readl(_IBMR(i2c)) != 3)) {
+			/* last try and bus is still busy, try
+			 * reset */
+			dev_err(&i2c->adap.dev, "%s: unit still busy after "
+				"hw reset\n", __func__);
+			i2c_pxa_reset(i2c);
+		}
+
 		if (i2c_debug)
 			dev_dbg(&adap->dev, "Retrying transmission\n");
 		udelay(100);
@@ -1054,6 +1064,11 @@
 	int ret;
 	int irq;
 
+#ifdef CONFIG_FBX6HD
+	if (dev->id != 2)
+		return -ENODEV;
+#endif
+
 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(dev, 0);
 	if (res == NULL || irq < 0)
diff -ruw linux-3.2.24/drivers/i2c/busses/i2c-pxa-pci.c linux-3.2.24-fbx/drivers/i2c/busses/i2c-pxa-pci.c
--- linux-3.2.24/drivers/i2c/busses/i2c-pxa-pci.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/i2c/busses/i2c-pxa-pci.c	2013-06-13 15:06:39.510518693 +0200
@@ -5,6 +5,7 @@
  */
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/of.h>
@@ -37,6 +38,8 @@
 	res[1].start = dev->irq;
 	res[1].end = dev->irq;
 
+	child = NULL;
+	if (dev->dev.of_node) {
 	for_each_child_of_node(dev->dev.of_node, child) {
 		const void *prop;
 		struct resource r;
@@ -65,6 +68,9 @@
 		ret = -EINVAL;
 		goto out;
 	}
+	}
+
+	pdata.class = I2C_CLASS_HWMON;
 
 	pdev = platform_device_alloc("ce4100-i2c", devnum);
 	if (!pdev) {
@@ -105,10 +111,6 @@
 	if (ret)
 		return ret;
 
-	if (!dev->dev.of_node) {
-		dev_err(&dev->dev, "Missing device tree node.\n");
-		return -EINVAL;
-	}
 	sds = kzalloc(sizeof(*sds), GFP_KERNEL);
 	if (!sds) {
 		ret = -ENOMEM;
diff -ruw linux-3.2.24/drivers/ide/Kconfig linux-3.2.24-fbx/drivers/ide/Kconfig
--- linux-3.2.24/drivers/ide/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/ide/Kconfig	2012-11-30 16:07:16.658641554 +0100
@@ -692,6 +692,11 @@
        depends on BLK_DEV_IDE_AU1XXX
 endchoice
 
+config BLK_DEV_IDE_TANGO2
+	tristate "IDE for Tango2"
+	depends on TANGO2
+	select BLK_DEV_IDEDMA_SFF
+
 config BLK_DEV_IDE_TX4938
 	tristate "TX4938 internal IDE support"
 	depends on SOC_TX4938
diff -ruw linux-3.2.24/drivers/ide/Makefile linux-3.2.24-fbx/drivers/ide/Makefile
--- linux-3.2.24/drivers/ide/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/ide/Makefile	2013-06-13 15:06:39.514518690 +0200
@@ -117,3 +117,4 @@
 obj-$(CONFIG_BLK_DEV_IDE_TX4938)	+= tx4938ide.o
 obj-$(CONFIG_BLK_DEV_IDE_TX4939)	+= tx4939ide.o
 obj-$(CONFIG_BLK_DEV_IDE_AT91)		+= at91_ide.o
+obj-$(CONFIG_BLK_DEV_IDE_TANGO2)	+= tango2ide.o
diff -ruw linux-3.2.24/drivers/input/misc/Kconfig linux-3.2.24-fbx/drivers/input/misc/Kconfig
--- linux-3.2.24/drivers/input/misc/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/input/misc/Kconfig	2013-06-13 15:06:39.722518589 +0200
@@ -544,4 +544,9 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called xen-kbdfront.
 
+config INPUT_SMSC_CAP1066
+	tristate "SMSC CAP1066 capacitive sensor driver"
+	select I2C
+	select INPUT_POLLDEV
+
 endif
diff -ruw linux-3.2.24/drivers/input/misc/Makefile linux-3.2.24-fbx/drivers/input/misc/Makefile
--- linux-3.2.24/drivers/input/misc/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/input/misc/Makefile	2013-06-13 15:06:39.722518589 +0200
@@ -51,3 +51,4 @@
 obj-$(CONFIG_INPUT_WM831X_ON)		+= wm831x-on.o
 obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND)	+= xen-kbdfront.o
 obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
+obj-$(CONFIG_INPUT_SMSC_CAP1066)	+= smsc_cap1066.o
diff -ruw linux-3.2.24/drivers/Kconfig linux-3.2.24-fbx/drivers/Kconfig
--- linux-3.2.24/drivers/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/Kconfig	2013-06-13 15:06:39.162518860 +0200
@@ -4,8 +4,12 @@
 
 source "drivers/connector/Kconfig"
 
+source "drivers/fbxprocfs/Kconfig"
+
 source "drivers/mtd/Kconfig"
 
+source "drivers/fbxmtd/Kconfig"
+
 source "drivers/of/Kconfig"
 
 source "drivers/parport/Kconfig"
@@ -60,6 +64,10 @@
 
 source "drivers/gpio/Kconfig"
 
+source "drivers/fbxgpio/Kconfig"
+
+source "drivers/fbxjtag/Kconfig"
+
 source "drivers/w1/Kconfig"
 
 source "drivers/power/Kconfig"
@@ -68,6 +76,8 @@
 
 source "drivers/thermal/Kconfig"
 
+source "drivers/fbxwatchdog/Kconfig"
+
 source "drivers/watchdog/Kconfig"
 
 source "drivers/ssb/Kconfig"
@@ -96,6 +106,8 @@
 
 source "drivers/leds/Kconfig"
 
+source "drivers/fbxpanel/Kconfig"
+
 source "drivers/accessibility/Kconfig"
 
 source "drivers/infiniband/Kconfig"
diff -ruw linux-3.2.24/drivers/Makefile linux-3.2.24-fbx/drivers/Makefile
--- linux-3.2.24/drivers/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/Makefile	2013-06-13 15:06:39.162518860 +0200
@@ -8,6 +8,8 @@
 # GPIO must come after pinctrl as gpios may need to mux pins etc
 obj-y				+= pinctrl/
 obj-y				+= gpio/
+obj-$(CONFIG_FREEBOX_GPIO)	+= fbxgpio/
+obj-$(CONFIG_FREEBOX_JTAG)	+= fbxjtag/
 obj-$(CONFIG_PCI)		+= pci/
 obj-$(CONFIG_PARISC)		+= parisc/
 obj-$(CONFIG_RAPIDIO)		+= rapidio/
@@ -60,6 +62,9 @@
 obj-$(CONFIG_UIO)		+= uio/
 obj-y				+= cdrom/
 obj-y				+= auxdisplay/
+
+obj-$(CONFIG_FREEBOX_PROCFS)	+= fbxprocfs/
+obj-$(CONFIG_FREEBOX_MTD)	+= fbxmtd/
 obj-$(CONFIG_PCCARD)		+= pcmcia/
 obj-$(CONFIG_DIO)		+= dio/
 obj-$(CONFIG_SBUS)		+= sbus/
@@ -85,6 +90,7 @@
 obj-$(CONFIG_POWER_SUPPLY)	+= power/
 obj-$(CONFIG_HWMON)		+= hwmon/
 obj-$(CONFIG_THERMAL)		+= thermal/
+obj-$(CONFIG_FREEBOX_WATCHDOG)	+= fbxwatchdog/
 obj-$(CONFIG_WATCHDOG)		+= watchdog/
 obj-$(CONFIG_PHONE)		+= telephony/
 obj-$(CONFIG_MD)		+= md/
@@ -100,6 +106,7 @@
 obj-$(CONFIG_MMC)		+= mmc/
 obj-$(CONFIG_MEMSTICK)		+= memstick/
 obj-y				+= leds/
+obj-$(CONFIG_FREEBOX_PANEL)	+= fbxpanel/
 obj-$(CONFIG_INFINIBAND)	+= infiniband/
 obj-$(CONFIG_SGI_SN)		+= sn/
 obj-y				+= firmware/
diff -ruw linux-3.2.24/drivers/media/dvb/dvb-core/dvb_frontend.c linux-3.2.24-fbx/drivers/media/dvb/dvb-core/dvb_frontend.c
--- linux-3.2.24/drivers/media/dvb/dvb-core/dvb_frontend.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/media/dvb/dvb-core/dvb_frontend.c	2013-06-13 15:06:39.882518515 +0200
@@ -695,6 +695,7 @@
 
 	fepriv->exit = DVB_FE_NORMAL_EXIT;
 	mb();
+	wake_up_all(&fepriv->events.wait_queue);
 
 	if (!fepriv->thread)
 		return;
@@ -1950,6 +1951,9 @@
 
 	poll_wait (file, &fepriv->events.wait_queue, wait);
 
+	if (fepriv->exit)
+		return POLLERR | POLLHUP;
+
 	if (fepriv->events.eventw != fepriv->events.eventr)
 		return (POLLIN | POLLRDNORM | POLLPRI);
 
diff -ruw linux-3.2.24/drivers/media/dvb/dvb-usb/dib0700_devices.c linux-3.2.24-fbx/drivers/media/dvb/dvb-usb/dib0700_devices.c
--- linux-3.2.24/drivers/media/dvb/dvb-usb/dib0700_devices.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/media/dvb/dvb-usb/dib0700_devices.c	2013-06-13 15:06:39.886518513 +0200
@@ -2960,6 +2960,7 @@
 /* 75 */{ USB_DEVICE(USB_VID_MEDION,    USB_PID_CREATIX_CTX1921) },
 	{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV340E) },
 	{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV340E_SE) },
+	{ USB_DEVICE(USB_VID_DIBCOM,	USB_PID_DIBCOM_HOOK_DEFAULT_STK7770P) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -3640,6 +3641,35 @@
 			.change_protocol  = dib0700_change_protocol,
 		},
 	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+		.num_adapters = 1,
+		.adapter = {
+			{
+			.num_frontends = 1,
+			.fe = {{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter       = stk70x0p_pid_filter,
+				.pid_filter_ctrl  = stk70x0p_pid_filter_ctrl,
+				.frontend_attach  = stk7770p_frontend_attach,
+				.tuner_attach     = dib7770p_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+			}},
+				.size_of_priv =
+					sizeof(struct dib0700_adapter_state),
+			},
+		},
+
+		.num_device_descs = 1,
+		.devices = {
+			{   "DiBcom STK7770P reference design no IR",
+				{ &dib0700_usb_id_table[78], NULL },
+				{ NULL },
+			},
+		},
+
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
 		.num_adapters = 1,
 		.adapter = {
 			{
diff -ruw linux-3.2.24/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c linux-3.2.24-fbx/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
--- linux-3.2.24/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c	2013-06-13 15:06:39.890518510 +0200
@@ -244,6 +244,10 @@
 		adap->fe_adap[i].fe_sleep = adap->fe_adap[i].fe->ops.sleep;
 		adap->fe_adap[i].fe->ops.sleep = dvb_usb_fe_sleep;
 
+		/* only attach the tuner if the demod is there */
+		if (adap->props.fe[i].tuner_attach != NULL)
+			adap->props.fe[i].tuner_attach(adap);
+
 		if (dvb_register_frontend(&adap->dvb_adap, adap->fe_adap[i].fe)) {
 			err("Frontend %d registration failed.", i);
 			dvb_frontend_detach(adap->fe_adap[i].fe);
@@ -256,10 +260,6 @@
 				return 0;
 		}
 
-		/* only attach the tuner if the demod is there */
-		if (adap->props.fe[i].tuner_attach != NULL)
-			adap->props.fe[i].tuner_attach(adap);
-
 		adap->num_frontends_initialized++;
 	}
 
diff -ruw linux-3.2.24/drivers/media/dvb/dvb-usb/dvb-usb.h linux-3.2.24-fbx/drivers/media/dvb/dvb-usb/dvb-usb.h
--- linux-3.2.24/drivers/media/dvb/dvb-usb/dvb-usb.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/media/dvb/dvb-usb/dvb-usb.h	2013-06-13 15:06:39.890518510 +0200
@@ -295,7 +295,7 @@
 	int generic_bulk_ctrl_endpoint_response;
 
 	int num_device_descs;
-	struct dvb_usb_device_description devices[12];
+	struct dvb_usb_device_description devices[32];
 };
 
 /**
diff -ruw linux-3.2.24/drivers/media/dvb/dvb-usb/dvb-usb-ids.h linux-3.2.24-fbx/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
--- linux-3.2.24/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2013-06-13 15:06:39.890518510 +0200
@@ -95,6 +95,7 @@
 #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_HOOK_DEFAULT_STK7770P		0x0066
 #define USB_PID_DIBCOM_MOD3000_COLD			0x0bb8
 #define USB_PID_DIBCOM_MOD3000_WARM			0x0bb9
 #define USB_PID_DIBCOM_MOD3001_COLD			0x0bc6
diff -ruw linux-3.2.24/drivers/media/dvb/Kconfig linux-3.2.24-fbx/drivers/media/dvb/Kconfig
--- linux-3.2.24/drivers/media/dvb/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/media/dvb/Kconfig	2012-11-30 16:07:17.138641576 +0100
@@ -64,6 +64,10 @@
 	depends on DVB_CORE && PCI && I2C
 source "drivers/media/dvb/dm1105/Kconfig"
 
+comment "Supported Tango2 Adapters"
+	depends on DVB_CORE && ARCH_FBX5_B
+source "drivers/media/dvb/tango2/Kconfig"
+
 comment "Supported FireWire (IEEE 1394) Adapters"
 	depends on DVB_CORE && FIREWIRE
 source "drivers/media/dvb/firewire/Kconfig"
diff -ruw linux-3.2.24/drivers/media/dvb/Makefile linux-3.2.24-fbx/drivers/media/dvb/Makefile
--- linux-3.2.24/drivers/media/dvb/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/media/dvb/Makefile	2012-11-30 16:07:17.138641576 +0100
@@ -16,6 +16,7 @@
 		pt1/		\
 		mantis/		\
 		ngene/		\
-		ddbridge/
+		ddbridge/	\
+		tango2/
 
 obj-$(CONFIG_DVB_FIREDTV)	+= firewire/
diff -ruw linux-3.2.24/drivers/media/rc/keymaps/Makefile linux-3.2.24-fbx/drivers/media/rc/keymaps/Makefile
--- linux-3.2.24/drivers/media/rc/keymaps/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/media/rc/keymaps/Makefile	2013-06-13 15:52:30.397198286 +0200
@@ -71,6 +71,7 @@
 			rc-pv951.o \
 			rc-hauppauge.o \
 			rc-rc6-mce.o \
+			rc-rc6-freebox.o \
 			rc-real-audio-220-32-keys.o \
 			rc-snapstream-firefly.o \
 			rc-streamzap.o \
diff -ruw linux-3.2.24/drivers/media/rc/mceusb.c linux-3.2.24-fbx/drivers/media/rc/mceusb.c
--- linux-3.2.24/drivers/media/rc/mceusb.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/media/rc/mceusb.c	2013-06-13 15:52:30.397198286 +0200
@@ -210,6 +210,7 @@
 	MULTIFUNCTION,
 	TIVO_KIT,
 	MCE_GEN2_NO_TX,
+	MCE_FREEBOX,
 };
 
 struct mceusb_model {
@@ -266,6 +267,11 @@
 		.mce_gen2 = 1,
 		.rc_map = RC_MAP_TIVO,
 	},
+	[MCE_FREEBOX] = {
+		.mce_gen2 = 1,
+		.no_tx = 1,
+		.rc_map = "rc-rc6-freebox",
+	}
 };
 
 static struct usb_device_id mceusb_dev_table[] = {
@@ -360,7 +366,8 @@
 	/* Formosa Industrial Computing AIM IR605/A */
 	{ USB_DEVICE(VENDOR_FORMOSA, 0xe03c) },
 	/* Formosa Industrial Computing */
-	{ USB_DEVICE(VENDOR_FORMOSA, 0xe03e) },
+	{ USB_DEVICE(VENDOR_FORMOSA, 0xe03e),
+	  .driver_info = MCE_FREEBOX },
 	/* Fintek eHome Infrared Transceiver (HP branded) */
 	{ USB_DEVICE(VENDOR_FINTEK, 0x5168) },
 	/* Fintek eHome Infrared Transceiver */
@@ -939,7 +946,7 @@
 
 	/* 2-byte return value commands */
 	case MCE_RSP_EQIRTIMEOUT:
-		ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT);
+		ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT / 1000);
 		break;
 	case MCE_RSP_EQIRNUMPORTS:
 		ir->num_txports = hi;
@@ -1214,7 +1221,7 @@
 	rc->priv = ir;
 	rc->driver_type = RC_DRIVER_IR_RAW;
 	rc->allowed_protos = RC_TYPE_ALL;
-	rc->timeout = MS_TO_NS(100);
+	rc->timeout = MS_TO_NS(50);
 	if (!ir->flags.no_tx) {
 		rc->s_tx_mask = mceusb_set_tx_mask;
 		rc->s_tx_carrier = mceusb_set_tx_carrier;
diff -ruw linux-3.2.24/drivers/misc/Kconfig linux-3.2.24-fbx/drivers/misc/Kconfig
--- linux-3.2.24/drivers/misc/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/misc/Kconfig	2013-06-13 15:06:40.162518380 +0200
@@ -451,6 +451,18 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called vmw_balloon.
 
+config INTELCE_PIC16PMU
+	tristate "PIC16 PMU, LED, hwmon support"
+	select INPUT_POLLDEV
+	select NEW_LEDS
+	select I2C
+	select HWMON
+	select ARCH_REQUIRE_GPIOLIB
+	---help---
+	  Freebox v6 HD PIC16 PMU interface support, enables
+	  control of the on-board LEDs and reports the power status,
+	  reset status and button status.
+
 config ARM_CHARLCD
 	bool "ARM Ltd. Character LCD Driver"
 	depends on PLAT_VERSATILE
@@ -500,6 +512,9 @@
 	  stereo and mono audio, video, microphone and UART data to use
 	  a common connector port.
 
+config CRASHZONE
+	bool "crashzone support"
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
@@ -508,5 +523,7 @@
 source "drivers/misc/lis3lv02d/Kconfig"
 source "drivers/misc/carma/Kconfig"
 source "drivers/misc/altera-stapl/Kconfig"
+source "drivers/misc/remoti/Kconfig"
+source "drivers/misc/hdmi-cec/Kconfig"
 
 endif # MISC_DEVICES
diff -ruw linux-3.2.24/drivers/misc/Makefile linux-3.2.24-fbx/drivers/misc/Makefile
--- linux-3.2.24/drivers/misc/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/misc/Makefile	2013-06-13 15:06:40.162518380 +0200
@@ -23,6 +23,7 @@
 obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
 obj-$(CONFIG_KGDB_TESTS)	+= kgdbts.o
 obj-$(CONFIG_SGI_XP)		+= sgi-xp/
+obj-$(CONFIG_INTELCE_PIC16PMU)	+= pic16-pmu.o
 obj-$(CONFIG_SGI_GRU)		+= sgi-gru/
 obj-$(CONFIG_CS5535_MFGPT)	+= cs5535-mfgpt.o
 obj-$(CONFIG_HP_ILO)		+= hpilo.o
@@ -36,6 +37,7 @@
 obj-$(CONFIG_C2PORT)		+= c2port/
 obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-$(CONFIG_HMC6352)		+= hmc6352.o
+obj-$(CONFIG_CRASHZONE)		+= crash_zone.o
 obj-y				+= eeprom/
 obj-y				+= cb710/
 obj-$(CONFIG_SPEAR13XX_PCIE_GADGET)	+= spear13xx_pcie_gadget.o
@@ -48,3 +50,5 @@
 obj-y				+= carma/
 obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
 obj-$(CONFIG_ALTERA_STAPL)	+=altera-stapl/
+obj-y				+= remoti/
+obj-y				+= hdmi-cec/
diff -ruw linux-3.2.24/drivers/mtd/Kconfig linux-3.2.24-fbx/drivers/mtd/Kconfig
--- linux-3.2.24/drivers/mtd/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/mtd/Kconfig	2013-06-13 15:52:30.417198276 +0200
@@ -23,6 +23,9 @@
 	  WARNING: some of the tests will ERASE entire MTD device which they
 	  test. Do not use these tests unless you really know what you do.
 
+config MTD_ERASE_PRINTK
+	bool "write to kernel log when a block is erased"
+
 config MTD_REDBOOT_PARTS
 	tristate "RedBoot partition table parsing"
 	---help---
@@ -140,6 +143,17 @@
 	---help---
 	  TI AR7 partitioning support
 
+config MTD_FBX6HD_PARTS
+	tristate "Freebox V6 HD partitioning support"
+	help
+	  Freebox V6 HD partitioning support
+
+config MTD_FBX6HD_PARTS_WRITE_ALL
+	bool "make all partitions writeable"
+	depends on MTD_FBX6HD_PARTS
+	help
+	  Freebox V6 HD partitions support
+
 comment "User Modules And Translation Layers"
 
 config MTD_CHAR
diff -ruw linux-3.2.24/drivers/mtd/Makefile linux-3.2.24-fbx/drivers/mtd/Makefile
--- linux-3.2.24/drivers/mtd/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/mtd/Makefile	2013-06-13 15:06:40.198518362 +0200
@@ -11,6 +11,7 @@
 obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
 obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
 obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
+obj-$(CONFIG_MTD_FBX6HD_PARTS)	+= fbx6hd-mtdparts.o
 
 # 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_CHAR)		+= mtdchar.o
diff -ruw linux-3.2.24/drivers/mtd/mtdchar.c linux-3.2.24-fbx/drivers/mtd/mtdchar.c
--- linux-3.2.24/drivers/mtd/mtdchar.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/mtd/mtdchar.c	2013-06-13 15:06:40.210518356 +0200
@@ -221,6 +221,7 @@
 		{
 			struct mtd_oob_ops ops;
 
+			memset(&ops, 0, sizeof (ops));
 			ops.mode = MTD_OPS_RAW;
 			ops.datbuf = kbuf;
 			ops.oobbuf = NULL;
@@ -317,6 +318,7 @@
 		{
 			struct mtd_oob_ops ops;
 
+			memset(&ops, 0, sizeof (ops));
 			ops.mode = MTD_OPS_RAW;
 			ops.datbuf = kbuf;
 			ops.oobbuf = NULL;
@@ -720,6 +722,10 @@
 			erase->callback = mtdchar_erase_callback;
 			erase->priv = (unsigned long)&waitq;
 
+#ifdef CONFIG_MTD_ERASE_PRINTK
+			printk(KERN_DEBUG "mtd: %s: ERASE offset=@%08llx\n",
+			       mtd->name, erase->addr);
+#endif
 			/*
 			  FIXME: Allow INTERRUPTIBLE. Which means
 			  not having the wait_queue head on the stack.
diff -ruw linux-3.2.24/drivers/mtd/mtdcore.c linux-3.2.24-fbx/drivers/mtd/mtdcore.c
--- linux-3.2.24/drivers/mtd/mtdcore.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/mtd/mtdcore.c	2013-06-13 15:06:40.210518356 +0200
@@ -252,6 +252,33 @@
 }
 static DEVICE_ATTR(name, S_IRUGO, mtd_name_show, NULL);
 
+static ssize_t mtd_nand_type_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", mtd->nand_type);
+}
+static DEVICE_ATTR(nand_type, S_IRUGO, mtd_nand_type_show, NULL);
+
+static ssize_t mtd_nand_manufacturer_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", mtd->nand_manufacturer);
+}
+static DEVICE_ATTR(nand_manufacturer, S_IRUGO, mtd_nand_manufacturer_show, NULL);
+
+static ssize_t mtd_nand_onfi_version_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", mtd->onfi_version);
+}
+static DEVICE_ATTR(onfi_version, S_IRUGO, mtd_nand_onfi_version_show, NULL);
+
 static struct attribute *mtd_attrs[] = {
 	&dev_attr_type.attr,
 	&dev_attr_flags.attr,
@@ -262,6 +289,9 @@
 	&dev_attr_oobsize.attr,
 	&dev_attr_numeraseregions.attr,
 	&dev_attr_name.attr,
+	&dev_attr_nand_type.attr,
+	&dev_attr_nand_manufacturer.attr,
+	&dev_attr_onfi_version.attr,
 	NULL,
 };
 
diff -ruw linux-3.2.24/drivers/mtd/mtdpart.c linux-3.2.24-fbx/drivers/mtd/mtdpart.c
--- linux-3.2.24/drivers/mtd/mtdpart.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/mtd/mtdpart.c	2013-06-13 15:06:40.210518356 +0200
@@ -406,6 +406,9 @@
 	slave->mtd.oobsize = master->oobsize;
 	slave->mtd.oobavail = master->oobavail;
 	slave->mtd.subpage_sft = master->subpage_sft;
+	slave->mtd.nand_type = master->nand_type;
+	slave->mtd.nand_manufacturer = master->nand_manufacturer;
+	slave->mtd.onfi_version = master->onfi_version;
 
 	slave->mtd.name = name;
 	slave->mtd.owner = master->owner;
diff -ruw linux-3.2.24/drivers/mtd/nand/Kconfig linux-3.2.24-fbx/drivers/mtd/nand/Kconfig
--- linux-3.2.24/drivers/mtd/nand/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/mtd/nand/Kconfig	2013-06-13 15:06:40.214518353 +0200
@@ -58,6 +58,15 @@
 	  NAND chips (page size 256 byte, erase size 4-8KiB). The IDs
 	  of these chips were reused by later, larger chips.
 
+config MTD_FORCE_BAD_BLOCK_ERASE
+	bool "Force erase on bad blocks (useful for bootloader parts)"
+	depends on MTD_NAND
+	default n
+	help
+	  Enable this option only when you need to force an erase on
+	  blocks being marked as "bad" by Linux (i.e: other ECC/bad block
+	  marker layout).
+
 config MTD_NAND_AUTCPU12
 	tristate "SmartMediaCard on autronix autcpu12 board"
 	depends on ARCH_AUTCPU12
@@ -537,4 +546,9 @@
 	  Enables support for NAND Flash chips on the ST Microelectronics
 	  Flexible Static Memory Controller (FSMC)
 
+config MTD_NAND_DENALI_FBX
+	tristate "NAND Denali controller support"
+	depends on MTD_NAND && PCI
+	default n
+
 endif # MTD_NAND
diff -ruw linux-3.2.24/drivers/mtd/nand/Makefile linux-3.2.24-fbx/drivers/mtd/nand/Makefile
--- linux-3.2.24/drivers/mtd/nand/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/mtd/nand/Makefile	2013-06-13 15:06:40.214518353 +0200
@@ -49,5 +49,6 @@
 obj-$(CONFIG_MTD_NAND_RICOH)		+= r852.o
 obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
+obj-$(CONFIG_MTD_NAND_DENALI_FBX)	+= denali_nand.o
 
 nand-objs := nand_base.o nand_bbt.o
diff -ruw linux-3.2.24/drivers/mtd/nand/nand_base.c linux-3.2.24-fbx/drivers/mtd/nand/nand_base.c
--- linux-3.2.24/drivers/mtd/nand/nand_base.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/mtd/nand/nand_base.c	2013-06-13 15:06:40.218518351 +0200
@@ -2589,6 +2589,7 @@
 
 	while (len) {
 		/* Heck if we have a bad block, we do not erase bad blocks! */
+#ifndef CONFIG_MTD_FORCE_BAD_BLOCK_ERASE
 		if (nand_block_checkbad(mtd, ((loff_t) page) <<
 					chip->page_shift, 0, allowbbt)) {
 			pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
@@ -2596,6 +2597,7 @@
 			instr->state = MTD_ERASE_FAILED;
 			goto erase_exit;
 		}
+#endif
 
 		/*
 		 * Invalidate the page cache, if we erase the block which
@@ -2922,6 +2924,7 @@
 	int i, maf_idx;
 	u8 id_data[8];
 	int ret;
+	char onfi_version[5];
 
 	/* Select the device */
 	chip->select_chip(mtd, 0);
@@ -3163,7 +3166,38 @@
 		nand_manuf_ids[maf_idx].name,
 		chip->onfi_version ? chip->onfi_params.model : type->name);
 
+	mtd->nand_type = kstrdup(type->name, GFP_KERNEL);
+	if (!mtd->nand_type)
+		return ERR_PTR(-ENOMEM);
+
+	mtd->nand_manufacturer = kstrdup(nand_manuf_ids[maf_idx].name,
+						GFP_KERNEL);
+	if (!mtd->nand_manufacturer) {
+		ret = -ENOMEM;
+		goto out_nand_type;
+	}
+
+	snprintf(onfi_version, sizeof(onfi_version), "0");
+
+	if (chip->onfi_version)
+		snprintf(onfi_version, sizeof(onfi_version), "%d.%d",
+					chip->onfi_version / 10,
+					chip->onfi_version % 10);
+
+	mtd->onfi_version = kstrdup(onfi_version, GFP_KERNEL);
+	if (!mtd->onfi_version) {
+		ret = -ENOMEM;
+		goto out_nand_manufacturer;
+	}
+
 	return type;
+
+out_nand_manufacturer:
+	kfree(mtd->nand_manufacturer);
+out_nand_type:
+	kfree(mtd->nand_type);
+
+	return ERR_PTR(ret);
 }
 
 /**
@@ -3183,6 +3217,7 @@
 	int i, busw, nand_maf_id, nand_dev_id;
 	struct nand_chip *chip = mtd->priv;
 	struct nand_flash_dev *type;
+	int err;
 
 	/* Get buswidth to select the correct functions */
 	busw = chip->options & NAND_BUSWIDTH_16;
@@ -3197,7 +3232,8 @@
 		if (!(chip->options & NAND_SCAN_SILENT_NODEV))
 			pr_warn("No NAND device found\n");
 		chip->select_chip(mtd, -1);
-		return PTR_ERR(type);
+		err = PTR_ERR(type);
+		goto out_error;
 	}
 
 	/* Check for a chip array */
@@ -3220,6 +3256,16 @@
 	mtd->size = i * chip->chipsize;
 
 	return 0;
+
+out_error:
+	if (mtd->nand_type)
+		kfree(mtd->nand_type);
+	if (mtd->nand_manufacturer)
+		kfree(mtd->nand_manufacturer);
+	if (mtd->onfi_version)
+		kfree(mtd->onfi_version);
+
+	return err;
 }
 EXPORT_SYMBOL(nand_scan_ident);
 
@@ -3342,9 +3388,13 @@
 		chip->ecc.read_page = nand_read_page_swecc;
 		chip->ecc.read_subpage = nand_read_subpage;
 		chip->ecc.write_page = nand_write_page_swecc;
+		if (!chip->ecc.read_page_raw)
 		chip->ecc.read_page_raw = nand_read_page_raw;
+		if (!chip->ecc.write_page_raw)
 		chip->ecc.write_page_raw = nand_write_page_raw;
+		if (!chip->ecc.read_oob)
 		chip->ecc.read_oob = nand_read_oob_std;
+		if (!chip->ecc.write_oob)
 		chip->ecc.write_oob = nand_write_oob_std;
 		if (!chip->ecc.size)
 			chip->ecc.size = 256;
diff -ruw linux-3.2.24/drivers/net/ethernet/intel/e1000/e1000.h linux-3.2.24-fbx/drivers/net/ethernet/intel/e1000/e1000.h
--- linux-3.2.24/drivers/net/ethernet/intel/e1000/e1000.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/net/ethernet/intel/e1000/e1000.h	2013-06-13 15:06:40.362518284 +0200
@@ -224,6 +224,7 @@
 	u16 link_speed;
 	u16 link_duplex;
 	spinlock_t stats_lock;
+	spinlock_t phy_lock;
 	unsigned int total_tx_bytes;
 	unsigned int total_tx_packets;
 	unsigned int total_rx_bytes;
@@ -311,6 +312,11 @@
 	struct delayed_work fifo_stall_task;
 	struct delayed_work phy_info_task;
 
+#ifdef CONFIG_FBX6HD
+	int last_phy_gpio;
+	bool last_link_active;
+#endif
+
 	struct mutex mutex;
 };
 
diff -ruw linux-3.2.24/drivers/net/ethernet/intel/e1000/e1000_hw.c linux-3.2.24-fbx/drivers/net/ethernet/intel/e1000/e1000_hw.c
--- linux-3.2.24/drivers/net/ethernet/intel/e1000/e1000_hw.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/net/ethernet/intel/e1000/e1000_hw.c	2013-06-13 15:06:40.362518284 +0200
@@ -107,6 +107,7 @@
 };
 
 static DEFINE_SPINLOCK(e1000_eeprom_lock);
+static DEFINE_SPINLOCK(e1000_phy_lock);
 
 /**
  * e1000_set_phy_type - Set the phy type member in the hw struct.
@@ -2830,19 +2831,25 @@
 s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data)
 {
 	u32 ret_val;
+	unsigned long flags;
 
 	e_dbg("e1000_read_phy_reg");
 
+	spin_lock_irqsave(&e1000_phy_lock, flags);
+
 	if ((hw->phy_type == e1000_phy_igp) &&
 	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
 		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
 						 (u16) reg_addr);
-		if (ret_val)
+		if (ret_val) {
+			spin_unlock_irqrestore(&e1000_phy_lock, flags);
 			return ret_val;
 	}
+	}
 
 	ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
 					phy_data);
+	spin_unlock_irqrestore(&e1000_phy_lock, flags);
 
 	return ret_val;
 }
@@ -2965,19 +2972,25 @@
 s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data)
 {
 	u32 ret_val;
+	unsigned long flags;
 
 	e_dbg("e1000_write_phy_reg");
 
+	spin_lock_irqsave(&e1000_phy_lock, flags);
+
 	if ((hw->phy_type == e1000_phy_igp) &&
 	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
 		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
 						 (u16) reg_addr);
-		if (ret_val)
+		if (ret_val) {
+			spin_unlock_irqrestore(&e1000_phy_lock, flags);
 			return ret_val;
 	}
+	}
 
 	ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
 					 phy_data);
+	spin_unlock_irqrestore(&e1000_phy_lock, flags);
 
 	return ret_val;
 }
diff -ruw linux-3.2.24/drivers/net/ethernet/intel/e1000/e1000_main.c linux-3.2.24-fbx/drivers/net/ethernet/intel/e1000/e1000_main.c
--- linux-3.2.24/drivers/net/ethernet/intel/e1000/e1000_main.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/net/ethernet/intel/e1000/e1000_main.c	2013-06-13 15:52:30.469198251 +0200
@@ -32,6 +32,12 @@
 #include <linux/prefetch.h>
 #include <linux/bitops.h>
 #include <linux/if_vlan.h>
+#include <linux/fbxserial.h>
+
+#ifdef CONFIG_FBX6HD
+#include <linux/gpio.h>
+#define GPIO_PHY_LED2 20
+#endif
 
 /* Intel Media SOC GbE MDIO physical base address */
 static unsigned long ce4100_gbe_mdio_base_phy;
@@ -1102,6 +1108,14 @@
 
 	e1000_reset_hw(hw);
 
+#ifdef CONFIG_FBX6HD
+	fbxserialinfo_get_mac_addr(hw->mac_addr);
+	printk("e1000: using mac address %02x:%02x:%02x:%02x:%02x:%02x "
+	       "(fbxserial)\n",
+	       hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2],
+	       hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);
+	(void)e1000_validate_eeprom_checksum;
+#else
 	/* make sure the EEPROM is good */
 	if (e1000_validate_eeprom_checksum(hw) < 0) {
 		e_err(probe, "The EEPROM Checksum Is Not Valid\n");
@@ -1120,6 +1134,9 @@
 		if (e1000_read_mac_addr(hw))
 			e_err(probe, "EEPROM Read Error\n");
 	}
+#endif
+
+
 	/* don't block initalization here due to bad MAC address */
 	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
 	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
@@ -1209,6 +1226,13 @@
 			} else
 				break;
 		}
+
+#ifdef CONFIG_FBX6HD
+		/* request gpio use to read link change from PHY */
+		gpio_request(GPIO_PHY_LED2, "phy_leds2");
+		gpio_direction_input(GPIO_PHY_LED2);
+		adapter->last_phy_gpio = -1;
+#endif
 	}
 
 	/* reset the hardware with the new settings */
@@ -2395,6 +2419,26 @@
 	 */
 	switch (hw->media_type) {
 	case e1000_media_type_copper:
+#ifdef CONFIG_FBX6HD
+	{
+		int val;
+
+		val = gpio_get_value(GPIO_PHY_LED2);
+		if (val != adapter->last_phy_gpio)
+			hw->get_link_status = 1;
+		adapter->last_phy_gpio = val;
+
+		if (hw->get_link_status) {
+			e1000_check_for_link(hw);
+			link_active = !hw->get_link_status;
+			hw->get_link_status = 0;
+		} else {
+			link_active = adapter->last_link_active;
+		}
+		adapter->last_link_active = link_active;
+		break;
+	}
+#else
 		if (hw->mac_type == e1000_ce4100)
 			hw->get_link_status = 1;
 		if (hw->get_link_status) {
@@ -2404,6 +2448,7 @@
 			link_active = true;
 		}
 		break;
+#endif
 	case e1000_media_type_fiber:
 		e1000_check_for_link(hw);
 		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
@@ -3492,11 +3537,13 @@
 
 	/* Phy Stats */
 	if (hw->media_type == e1000_media_type_copper) {
+#ifndef CONFIG_FBX6HD
 		if ((adapter->link_speed == SPEED_1000) &&
 		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
 			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
 			adapter->phy_stats.idle_errors += phy_tmp;
 		}
+#endif
 
 		if ((hw->mac_type <= e1000_82546) &&
 		   (hw->phy_type == e1000_phy_m88) &&
diff -ruw linux-3.2.24/drivers/net/ethernet/marvell/Kconfig linux-3.2.24-fbx/drivers/net/ethernet/marvell/Kconfig
--- linux-3.2.24/drivers/net/ethernet/marvell/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/net/ethernet/marvell/Kconfig	2012-07-27 18:10:45.636136344 +0200
@@ -23,6 +23,7 @@
 	depends on (MV64X60 || PPC32 || PLAT_ORION) && INET
 	select INET_LRO
 	select PHYLIB
+	select MII
 	---help---
 	  This driver supports the gigabit ethernet MACs in the
 	  Marvell Discovery PPC/MIPS chipset family (MV643XX) and
diff -ruw linux-3.2.24/drivers/net/Kconfig linux-3.2.24-fbx/drivers/net/Kconfig
--- linux-3.2.24/drivers/net/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/net/Kconfig	2013-06-13 15:06:40.230518348 +0200
@@ -338,4 +338,18 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called vmxnet3.
 
+config TANGO2_ENET
+	tristate "SMP863x Builtin Ethernet support"
+	depends on NET_ETHERNET && TANGO2
+	select MII
+	select CRC32
+	help
+	 This option adds support for the SMP863x integrated Ethernet
+	 controller.  This driver uses NAPI and generic Linux MII
+	 support.
+
+config TANGO2_PCINET_H
+	tristate "SMP863x network over PCI support (smp863x side)"
+	depends on NET_ETHERNET && TANGO2
+
 endif # NETDEVICES
diff -ruw linux-3.2.24/drivers/net/Makefile linux-3.2.24-fbx/drivers/net/Makefile
--- linux-3.2.24/drivers/net/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/net/Makefile	2013-06-13 15:06:40.230518348 +0200
@@ -66,3 +66,5 @@
 obj-$(CONFIG_USB_ZD1201)        += usb/
 obj-$(CONFIG_USB_IPHETH)        += usb/
 obj-$(CONFIG_USB_CDC_PHONET)   += usb/
+obj-$(CONFIG_TANGO2_ENET) += tango2_enet.o
+obj-$(CONFIG_TANGO2_PCINET_H) += tango2_pcinet_h.o
diff -ruw linux-3.2.24/drivers/net/wireless/Kconfig linux-3.2.24-fbx/drivers/net/wireless/Kconfig
--- linux-3.2.24/drivers/net/wireless/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/net/wireless/Kconfig	2013-06-13 15:52:30.517198228 +0200
@@ -268,6 +268,13 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called mwl8k.  If unsure, say N.
 
+config MWL8K_MFG
+	tristate "Marvell 88W8xxx Manufacturing mode"
+	# force build as module, only if mwl8k is built as module or
+	# unselected
+	depends on m && (MWL8K_MODULE || !MWL8K)
+	select CFG80211_WEXT
+
 source "drivers/net/wireless/ath/Kconfig"
 source "drivers/net/wireless/b43/Kconfig"
 source "drivers/net/wireless/b43legacy/Kconfig"
diff -ruw linux-3.2.24/drivers/net/wireless/Makefile linux-3.2.24-fbx/drivers/net/wireless/Makefile
--- linux-3.2.24/drivers/net/wireless/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/net/wireless/Makefile	2013-06-13 15:52:30.517198228 +0200
@@ -40,6 +40,7 @@
 obj-$(CONFIG_ADM8211)	+= adm8211.o
 
 obj-$(CONFIG_MWL8K)	+= mwl8k.o
+obj-$(CONFIG_MWL8K_MFG)	+= mwl8k_mfg.o
 
 obj-$(CONFIG_IWLWIFI)	+= iwlwifi/
 obj-$(CONFIG_IWLWIFI_LEGACY)	+= iwlegacy/
diff -ruw linux-3.2.24/drivers/platform/Kconfig linux-3.2.24-fbx/drivers/platform/Kconfig
--- linux-3.2.24/drivers/platform/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/platform/Kconfig	2011-11-04 14:26:08.939891247 +0100
@@ -1,3 +1,11 @@
 if X86
 source "drivers/platform/x86/Kconfig"
 endif
+
+if TANGO2
+source "drivers/platform/tango2/Kconfig"
+endif
+
+if X86_INTEL_CE
+source "drivers/platform/intelce/Kconfig"
+endif
diff -ruw linux-3.2.24/drivers/platform/Makefile linux-3.2.24-fbx/drivers/platform/Makefile
--- linux-3.2.24/drivers/platform/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/platform/Makefile	2013-06-13 15:06:40.834518058 +0200
@@ -3,3 +3,5 @@
 #
 
 obj-$(CONFIG_X86)		+= x86/
+obj-$(CONFIG_TANGO2)		+= tango2/
+obj-$(CONFIG_X86_INTEL_CE)	+= intelce/
diff -ruw linux-3.2.24/drivers/spi/Kconfig linux-3.2.24-fbx/drivers/spi/Kconfig
--- linux-3.2.24/drivers/spi/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/spi/Kconfig	2013-06-13 15:52:30.637198170 +0200
@@ -268,6 +268,12 @@
 	help
 	  This selects a driver for the PPC4xx SPI Controller.
 
+config SPI_TDM_ORION
+	tristate "Orion TDM SPI master"
+	depends on PLAT_ORION
+	help
+	  This enables using the TDM SPI master controller on the Orion chips.
+
 config SPI_PXA2XX
 	tristate "PXA2xx SSP SPI master"
 	depends on (ARCH_PXA || (X86_32 && PCI)) && EXPERIMENTAL
diff -ruw linux-3.2.24/drivers/spi/Makefile linux-3.2.24-fbx/drivers/spi/Makefile
--- linux-3.2.24/drivers/spi/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/spi/Makefile	2013-06-13 15:06:41.082517939 +0200
@@ -40,6 +40,7 @@
 obj-$(CONFIG_SPI_OMAP_100K)		+= spi-omap-100k.o
 obj-$(CONFIG_SPI_OMAP24XX)		+= spi-omap2-mcspi.o
 obj-$(CONFIG_SPI_ORION)			+= spi-orion.o
+obj-$(CONFIG_SPI_TDM_ORION)		+= orion_tdm_spi.o
 obj-$(CONFIG_SPI_PL022)			+= spi-pl022.o
 obj-$(CONFIG_SPI_PPC4xx)		+= spi-ppc4xx.o
 obj-$(CONFIG_SPI_PXA2XX)		+= spi-pxa2xx.o
@@ -58,4 +59,3 @@
 obj-$(CONFIG_SPI_TOPCLIFF_PCH)		+= spi-topcliff-pch.o
 obj-$(CONFIG_SPI_TXX9)			+= spi-txx9.o
 obj-$(CONFIG_SPI_XILINX)		+= spi-xilinx.o
-
diff -ruw linux-3.2.24/drivers/tty/serial/8250.c linux-3.2.24-fbx/drivers/tty/serial/8250.c
--- linux-3.2.24/drivers/tty/serial/8250.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/tty/serial/8250.c	2013-06-13 15:52:30.673198153 +0200
@@ -44,6 +44,12 @@
 
 #include "8250.h"
 
+#ifdef CONFIG_TANGO2
+#include <asm/mach-tango2/tango2_gbus.h>
+
+extern unsigned long em8xxx_sys_frequency;
+#endif
+
 #ifdef CONFIG_SPARC
 #include "suncore.h"
 #endif
@@ -416,14 +422,45 @@
 
 static unsigned int mem_serial_in(struct uart_port *p, int offset)
 {
+
+#ifdef CONFIG_TANGO2
+	unsigned long v;
+
+	/* no EFR on tango2 */
+	if (offset == UART_EFR)
+		v = 0;
+	else
+		v = gbus_readl((unsigned long)p->membase +
+			       (offset << p->regshift));
+	return v;
+#else
 	offset = map_8250_in_reg(p, offset) << p->regshift;
 	return readb(p->membase + offset);
+#endif
 }
 
 static void mem_serial_out(struct uart_port *p, int offset, int value)
 {
+#ifdef CONFIG_TANGO2
+	/*
+	 * we add a special case for UART_DL register, since
+	 * register content has a different meaning for us.
+	 */
+	if (offset == UART_DL) {
+		/* select right clock source */
+		value = (em8xxx_sys_frequency / p->uartclk);
+	}
+
+	/* no EFR on tango2 */
+	if (offset != UART_EFR) {
+		offset = offset << p->regshift;
+		gbus_writel((unsigned long)p->membase + offset,
+			    value);
+	}
+#else
 	offset = map_8250_out_reg(p, offset) << p->regshift;
 	writeb(value, p->membase + offset);
+#endif
 }
 
 static void mem32_serial_out(struct uart_port *p, int offset, int value)
@@ -529,6 +566,7 @@
 #define serial_inp(up, offset)		serial_in(up, offset)
 #define serial_outp(up, offset, value)	serial_out(up, offset, value)
 
+#ifndef CONFIG_TANGO2
 /* Uart divisor latch read */
 static inline int _serial_dl_read(struct uart_8250_port *up)
 {
@@ -581,6 +619,7 @@
 #define serial_dl_read(up) _serial_dl_read(up)
 #define serial_dl_write(up, value) _serial_dl_write(up, value)
 #endif
+#endif
 
 /*
  * For the 16C950
@@ -714,7 +753,11 @@
 static int size_fifo(struct uart_8250_port *up)
 {
 	unsigned char old_fcr, old_mcr, old_lcr;
+#ifdef CONFIG_TANGO2
+	unsigned short old_dll, old_dlm;
+#else
 	unsigned short old_dl;
+#endif
 	int count;
 
 	old_lcr = serial_inp(up, UART_LCR);
@@ -725,8 +768,14 @@
 		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
 	serial_outp(up, UART_MCR, UART_MCR_LOOP);
 	serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
+#ifdef CONFIG_TANGO2
+	old_dll = serial_inp(up, UART_DL) & 0xff;
+	old_dlm = serial_inp(up, UART_DL) >> 8;
+	serial_outp(up, UART_DL, 0x01);
+#else
 	old_dl = serial_dl_read(up);
 	serial_dl_write(up, 0x0001);
+#endif
 	serial_outp(up, UART_LCR, 0x03);
 	for (count = 0; count < 256; count++)
 		serial_outp(up, UART_TX, count);
@@ -737,7 +786,11 @@
 	serial_outp(up, UART_FCR, old_fcr);
 	serial_outp(up, UART_MCR, old_mcr);
 	serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
+#ifdef CONFIG_TANGO2
+	serial_outp(up, UART_DL, (old_dlm << 8) | old_dll);
+#else
 	serial_dl_write(up, old_dl);
+#endif
 	serial_outp(up, UART_LCR, old_lcr);
 
 	return count;
@@ -756,6 +809,16 @@
 	old_lcr = serial_inp(p, UART_LCR);
 	serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_A);
 
+#ifdef CONFIG_TANGO2
+	old_dll = serial_inp(p, UART_DL) & 0xff;
+	old_dlm = serial_inp(p, UART_DL) >> 8;
+
+	serial_outp(p, UART_DL, 0);
+
+	id = serial_inp(p, UART_DL);
+
+	serial_outp(p, UART_DL, (old_dlm << 8) | old_dll);
+#else
 	old_dll = serial_inp(p, UART_DLL);
 	old_dlm = serial_inp(p, UART_DLM);
 
@@ -766,6 +829,7 @@
 
 	serial_outp(p, UART_DLL, old_dll);
 	serial_outp(p, UART_DLM, old_dlm);
+#endif
 	serial_outp(p, UART_LCR, old_lcr);
 
 	return id;
@@ -984,11 +1048,20 @@
 
 			serial_outp(up, UART_LCR, 0xE0);
 
+#ifdef CONFIG_TANGO2
+			quot = serial_inp(up, UART_DL);
+#else
 			quot = serial_dl_read(up);
+#endif
 			quot <<= 3;
 
-			if (ns16550a_goto_highspeed(up))
+			if (ns16550a_goto_highspeed(up)) {
+#ifdef CONFIG_TANGO2
+				serial_outp(up, UART_DL, quot);
+#else
 				serial_dl_write(up, quot);
+#endif
+			}
 
 			serial_outp(up, UART_LCR, 0);
 
@@ -2436,7 +2509,11 @@
 		serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
 	}
 
+#ifdef CONFIG_TANGO2
+	serial_outp(up, UART_DL, quot);
+#else
 	serial_dl_write(up, quot);
+#endif
 
 	/*
 	 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
diff -ruw linux-3.2.24/drivers/tty/serial/8250_early.c linux-3.2.24-fbx/drivers/tty/serial/8250_early.c
--- linux-3.2.24/drivers/tty/serial/8250_early.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/tty/serial/8250_early.c	2013-06-13 15:06:41.394517787 +0200
@@ -121,8 +121,13 @@
 
 	lcr = serial_in(port, UART_LCR);
 	serial_out(port, UART_LCR, lcr | UART_LCR_DLAB);
+#ifdef CONFIG_TANGO2
+	dll = serial_in(port, UART_DL) & 0xff;
+	dlm = serial_in(port, UART_DL) >> 8;
+#else
 	dll = serial_in(port, UART_DLL);
 	dlm = serial_in(port, UART_DLM);
+#endif
 	serial_out(port, UART_LCR, lcr);
 
 	quot = (dlm << 8) | dll;
@@ -143,8 +148,12 @@
 	divisor = port->uartclk / (16 * device->baud);
 	c = serial_in(port, UART_LCR);
 	serial_out(port, UART_LCR, c | UART_LCR_DLAB);
+#ifdef CONFIG_TANGO2
+	serial_out(port, UART_DL, divisor & 0xffff);
+#else
 	serial_out(port, UART_DLL, divisor & 0xff);
 	serial_out(port, UART_DLM, (divisor >> 8) & 0xff);
+#endif
 	serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
 }
 
diff -ruw linux-3.2.24/drivers/tty/serial/8250_pci.c linux-3.2.24-fbx/drivers/tty/serial/8250_pci.c
--- linux-3.2.24/drivers/tty/serial/8250_pci.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/tty/serial/8250_pci.c	2013-06-13 15:52:30.677198151 +0200
@@ -1060,7 +1060,7 @@
 {
 	int ret;
 
-	ret = setup_port(priv, port, 0, 0, board->reg_shift);
+	ret = setup_port(priv, port, idx, 0, board->reg_shift);
 	port->iotype = UPIO_MEM32;
 	port->type = PORT_XSCALE;
 	port->flags = (port->flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
@@ -2548,8 +2548,8 @@
 		.first_offset	= 0x1000,
 	},
 	[pbn_ce4100_1_115200] = {
-		.flags		= FL_BASE0,
-		.num_ports	= 1,
+		.flags		= FL_BASE_BARS,
+		.num_ports	= 2,
 		.base_baud	= 921600,
 		.reg_shift      = 2,
 	},
diff -ruw linux-3.2.24/drivers/usb/gadget/Kconfig linux-3.2.24-fbx/drivers/usb/gadget/Kconfig
--- linux-3.2.24/drivers/usb/gadget/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/usb/gadget/Kconfig	2013-06-13 15:06:41.454517760 +0200
@@ -157,7 +157,7 @@
 
 config USB_FSL_USB2
 	tristate "Freescale Highspeed USB DR Peripheral Controller"
-	depends on FSL_SOC || ARCH_MXC
+	depends on FSL_SOC || ARCH_MXC || PLAT_ORION
 	select USB_GADGET_DUALSPEED
 	select USB_FSL_MPH_DR_OF if OF
 	help
diff -ruw linux-3.2.24/drivers/usb/gadget/Makefile linux-3.2.24-fbx/drivers/usb/gadget/Makefile
--- linux-3.2.24/drivers/usb/gadget/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/usb/gadget/Makefile	2013-06-13 15:06:41.454517760 +0200
@@ -19,6 +19,7 @@
 obj-$(CONFIG_USB_FSL_USB2)	+= fsl_usb2_udc.o
 fsl_usb2_udc-y			:= fsl_udc_core.o
 fsl_usb2_udc-$(CONFIG_ARCH_MXC)	+= fsl_mxc_udc.o
+fsl_usb2_udc-$(CONFIG_PLAT_ORION) += fsl_orion_udc.o
 obj-$(CONFIG_USB_M66592)	+= m66592-udc.o
 obj-$(CONFIG_USB_R8A66597)	+= r8a66597-udc.o
 obj-$(CONFIG_USB_FSL_QE)	+= fsl_qe_udc.o
diff -ruw linux-3.2.24/drivers/usb/host/ehci-hcd.c linux-3.2.24-fbx/drivers/usb/host/ehci-hcd.c
--- linux-3.2.24/drivers/usb/host/ehci-hcd.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/usb/host/ehci-hcd.c	2013-06-13 15:52:30.717198132 +0200
@@ -1337,6 +1337,16 @@
 #define PLATFORM_DRIVER		ehci_xls_driver
 #endif
 
+#ifdef CONFIG_USB_EHCI_BCM63XX
+#include "ehci-bcm63xx.c"
+#define	PLATFORM_DRIVER		ehci_hcd_bcm63xx_driver
+#endif
+
+#ifdef CONFIG_TANGO2
+#include "ehci-tango2.c"
+#define	PLATFORM_DRIVER		ehci_hcd_tango2_driver
+#endif
+
 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
     !defined(XILINX_OF_PLATFORM_DRIVER)
diff -ruw linux-3.2.24/drivers/usb/host/ehci-hub.c linux-3.2.24-fbx/drivers/usb/host/ehci-hub.c
--- linux-3.2.24/drivers/usb/host/ehci-hub.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/usb/host/ehci-hub.c	2013-06-13 15:06:41.498517737 +0200
@@ -813,12 +813,14 @@
 			 * power switching; they're allowed to just limit the
 			 * current.  khubd will turn the power back on.
 			 */
+#ifndef CONFIG_BCM63XX
 			if ((temp & PORT_OC) && HCS_PPC(ehci->hcs_params)) {
 				ehci_writel(ehci,
 					temp & ~(PORT_RWC_BITS | PORT_POWER),
 					status_reg);
 				temp = ehci_readl(ehci, status_reg);
 			}
+#endif
 		}
 
 		/* whoever resumes must GetPortStatus to complete it!! */
diff -ruw linux-3.2.24/drivers/usb/host/Kconfig linux-3.2.24-fbx/drivers/usb/host/Kconfig
--- linux-3.2.24/drivers/usb/host/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/usb/host/Kconfig	2013-06-13 15:06:41.494517739 +0200
@@ -106,7 +106,7 @@
 	depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \
 				    ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
 				    PPC_MPC512x || CPU_CAVIUM_OCTEON || \
-				    PMC_MSP || SPARC_LEON)
+				    PMC_MSP || SPARC_LEON || BCM63XX)
 	default y
 
 config USB_EHCI_BIG_ENDIAN_DESC
@@ -129,6 +129,14 @@
 config USB_FSL_MPH_DR_OF
 	tristate
 
+config USB_EHCI_BCM63XX
+	bool "Support for Broadcom 63xx on-chip EHCI USB controller"
+	depends on USB_EHCI_HCD && BCM63XX
+	select USB_EHCI_BIG_ENDIAN_MMIO
+	---help---
+	  Enables support for the on-chip EHCI controller on
+	  BCM6358 and later chips.
+
 config USB_EHCI_FSL
 	bool "Support for Freescale on-chip EHCI USB controller"
 	depends on USB_EHCI_HCD && FSL_SOC
@@ -287,6 +295,15 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called ohci-hcd.
 
+config USB_OHCI_BCM63XX
+	bool "Support for Broadcom 63xx on-chip OHCI USB controller"
+	depends on USB_OHCI_HCD && BCM63XX
+	select USB_OHCI_BIG_ENDIAN_DESC
+	select USB_OHCI_BIG_ENDIAN_MMIO
+	---help---
+	  Enables support for the on-chip OHCI controller on
+	  BCM63XX chips.
+
 config USB_OHCI_HCD_OMAP1
 	bool "OHCI support for OMAP1/2 chips"
 	depends on USB_OHCI_HCD && (ARCH_OMAP1 || ARCH_OMAP2)
diff -ruw linux-3.2.24/drivers/usb/storage/usb.c linux-3.2.24-fbx/drivers/usb/storage/usb.c
--- linux-3.2.24/drivers/usb/storage/usb.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/usb/storage/usb.c	2013-06-13 15:06:41.558517710 +0200
@@ -78,7 +78,7 @@
 MODULE_DESCRIPTION("USB Mass Storage driver for Linux");
 MODULE_LICENSE("GPL");
 
-static unsigned int delay_use = 1;
+static unsigned int delay_use = 5;
 module_param(delay_use, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
 
diff -ruw linux-3.2.24/drivers/video/Kconfig linux-3.2.24-fbx/drivers/video/Kconfig
--- linux-3.2.24/drivers/video/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/video/Kconfig	2013-06-13 15:06:41.762517612 +0200
@@ -477,6 +477,17 @@
 	  this driver, say Y or M; otherwise say N. You must specify the
 	  GPIO IO address to be used for setting control and data.
 
+config FB_SSD1327
+	tristate "SSD1327 OLED driver"
+	depends on FB
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_BACKLIGHT
+	select SPI
+	default n
+
 config FB_ATARI
 	bool "Atari native chipset support"
 	depends on (FB = y) && ATARI
diff -ruw linux-3.2.24/drivers/video/Makefile linux-3.2.24-fbx/drivers/video/Makefile
--- linux-3.2.24/drivers/video/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/drivers/video/Makefile	2013-06-13 15:06:41.762517612 +0200
@@ -31,6 +31,7 @@
 # Hardware specific drivers go first
 obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
 obj-$(CONFIG_FB_ARC)              += arcfb.o
+obj-$(CONFIG_FB_SSD1327)          += ssd1327.o
 obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
 obj-$(CONFIG_FB_GRVGA)            += grvga.o
diff -ruw linux-3.2.24/firmware/Makefile linux-3.2.24-fbx/firmware/Makefile
--- linux-3.2.24/firmware/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/firmware/Makefile	2013-06-13 15:52:30.953198019 +0200
@@ -68,6 +68,11 @@
 fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
 fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
 			     e100/d102e_ucode.bin
+fw-shipped-$(CONFIG_MWL8K) += mwl8k/helper_8366.fw mwl8k/fmimage_8764_ap-2.fw \
+				mwl8k/fmimage_8366_ap-4.fw
+
+fw-shipped-$(CONFIG_MWL8K_MFG) += mwl8k/mfg_fmimage_8764.fw
+
 fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
 fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \
 				     cis/DP83903.cis cis/NE2K.cis \
@@ -255,3 +260,10 @@
 obj-n := dummy
 
 hostprogs-y := ihex2fw
+
+# hack for 'make mrproper' and mwl8k .fw files being removed.
+quiet_cmd_shipped = SHIPPED $@
+cmd_shipped = cat $< > $@
+
+%.fw: %.fw_shipped
+	$(call cmd,shipped)
diff -ruw linux-3.2.24/fs/exec.c linux-3.2.24-fbx/fs/exec.c
--- linux-3.2.24/fs/exec.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/exec.c	2013-06-13 15:52:30.993197999 +0200
@@ -61,6 +61,14 @@
 #include <asm/tlb.h>
 #include "internal.h"
 
+enum {
+	CORE_ENV_PID,
+	CORE_ENV_SIGNAL,
+	CORE_ENV_EXECUTABLE,
+	CORE_ENV_TIME,
+	CORE_ENV_NR,
+};
+
 int core_uses_pid;
 char core_pattern[CORENAME_MAX_SIZE] = "core";
 unsigned int core_pipe_limit;
@@ -1241,6 +1249,13 @@
 			bprm->unsafe |= LSM_UNSAFE_PTRACE;
 	}
 
+	/*
+	 * This isn't strictly necessary, but it makes it harder for LSMs to
+	 * mess up.
+	 */
+	if (current->no_new_privs)
+		bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS;
+
 	n_fs = 1;
 	spin_lock(&p->fs->lock);
 	rcu_read_lock();
@@ -1284,7 +1299,8 @@
 	bprm->cred->euid = current_euid();
 	bprm->cred->egid = current_egid();
 
-	if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) {
+	if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) &&
+	    !current->no_new_privs) {
 		/* Set-uid? */
 		if (mode & S_ISUID) {
 			bprm->per_clear |= PER_CLEAR_ON_SETID;
@@ -2096,7 +2112,8 @@
 	struct cred *cred;
 	int retval = 0;
 	int flag = 0;
-	int ispipe;
+	int ispipe, i;
+	char *helper_envp[CORE_ENV_NR + 1];
 	static atomic_t core_dump_count = ATOMIC_INIT(0);
 	struct coredump_params cprm = {
 		.signr = signr,
@@ -2110,6 +2127,7 @@
 		.mm_flags = mm->flags,
 	};
 
+	memset(helper_envp, 0, sizeof (helper_envp));
 	audit_core_dumps(signr);
 
 	binfmt = mm->binfmt;
@@ -2149,6 +2167,7 @@
  	if (ispipe) {
 		int dump_count;
 		char **helper_argv;
+		struct timeval tv;
 
 		if (ispipe < 0) {
 			printk(KERN_WARNING "format_corename failed\n");
@@ -2194,9 +2213,22 @@
 			goto fail_dropcount;
 		}
 
+		/* Set pipe helper environment */
+		do_gettimeofday(&tv);
+
+		helper_envp[CORE_ENV_PID] = kasprintf(GFP_KERNEL,
+			"CORE_PID=%d", current->tgid);
+		helper_envp[CORE_ENV_SIGNAL] = kasprintf(GFP_KERNEL,
+			"CORE_SIGNAL=%ld", signr);
+		helper_envp[CORE_ENV_EXECUTABLE] = kasprintf(GFP_KERNEL,
+			"CORE_EXECUTABLE=%s", current->comm);
+		helper_envp[CORE_ENV_TIME] = kasprintf(GFP_KERNEL,
+			"CORE_TIME=%lu", tv.tv_sec);
+		helper_envp[CORE_ENV_NR] = NULL;
+
 		retval = call_usermodehelper_fns(helper_argv[0], helper_argv,
-					NULL, UMH_WAIT_EXEC, umh_pipe_setup,
-					NULL, &cprm);
+					helper_envp, UMH_WAIT_EXEC,
+					umh_pipe_setup, NULL, &cprm);
 		argv_free(helper_argv);
 		if (retval) {
  			printk(KERN_INFO "Core dump to %s pipe failed\n",
@@ -2254,6 +2286,9 @@
 	kfree(cn.corename);
 fail_corename:
 	coredump_finish(mm);
+	for (i = 0; i < CORE_ENV_NR; i++)
+		kfree(helper_envp[i]);
+
 	revert_creds(old_cred);
 fail_creds:
 	put_cred(cred);
diff -ruw linux-3.2.24/fs/hfsplus/hfsplus_fs.h linux-3.2.24-fbx/fs/hfsplus/hfsplus_fs.h
--- linux-3.2.24/fs/hfsplus/hfsplus_fs.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/hfsplus/hfsplus_fs.h	2013-06-13 15:06:42.598517210 +0200
@@ -163,6 +163,7 @@
 #define HFSPLUS_SB_HFSX		3
 #define HFSPLUS_SB_CASEFOLD	4
 #define HFSPLUS_SB_NOBARRIER	5
+#define HFSPLUS_SB_NOOWNERS	6
 
 static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb)
 {
diff -ruw linux-3.2.24/fs/hfsplus/inode.c linux-3.2.24-fbx/fs/hfsplus/inode.c
--- linux-3.2.24/fs/hfsplus/inode.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/hfsplus/inode.c	2013-06-13 15:06:42.598517210 +0200
@@ -233,11 +233,13 @@
 	mode = be16_to_cpu(perms->mode);
 
 	inode->i_uid = be32_to_cpu(perms->owner);
-	if (!inode->i_uid && !mode)
+	if ((!inode->i_uid && !mode) ||
+	    test_bit(HFSPLUS_SB_NOOWNERS, &sbi->flags))
 		inode->i_uid = sbi->uid;
 
 	inode->i_gid = be32_to_cpu(perms->group);
-	if (!inode->i_gid && !mode)
+	if ((!inode->i_gid && !mode) ||
+	    test_bit(HFSPLUS_SB_NOOWNERS, &sbi->flags))
 		inode->i_gid = sbi->gid;
 
 	if (dir) {
@@ -290,12 +292,16 @@
 static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
 {
 	struct inode *inode = dentry->d_inode;
+	struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
 	int error;
 
 	error = inode_change_ok(inode, attr);
 	if (error)
 		return error;
 
+	if (test_bit(HFSPLUS_SB_NOOWNERS, &sbi->flags))
+		attr->ia_valid &= ~(ATTR_UID | ATTR_GID);
+
 	if ((attr->ia_valid & ATTR_SIZE) &&
 	    attr->ia_size != i_size_read(inode)) {
 		inode_dio_wait(inode);
@@ -389,8 +395,13 @@
 
 	inode->i_ino = sbi->next_cnid++;
 	inode->i_mode = mode;
+	if (test_bit(HFSPLUS_SB_NOOWNERS, &sbi->flags)) {
+		inode->i_uid = sbi->uid;
+		inode->i_gid = sbi->gid;
+	} else {
 	inode->i_uid = current_fsuid();
 	inode->i_gid = current_fsgid();
+	}
 	set_nlink(inode, 1);
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 
diff -ruw linux-3.2.24/fs/hfsplus/options.c linux-3.2.24-fbx/fs/hfsplus/options.c
--- linux-3.2.24/fs/hfsplus/options.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/hfsplus/options.c	2013-06-13 15:06:42.598517210 +0200
@@ -24,7 +24,7 @@
 	opt_part, opt_session, opt_nls,
 	opt_nodecompose, opt_decompose,
 	opt_barrier, opt_nobarrier,
-	opt_force, opt_err
+	opt_force, opt_noowners, opt_err
 };
 
 static const match_table_t tokens = {
@@ -41,6 +41,7 @@
 	{ opt_barrier, "barrier" },
 	{ opt_nobarrier, "nobarrier" },
 	{ opt_force, "force" },
+	{ opt_noowners, "noowners" },
 	{ opt_err, NULL }
 };
 
@@ -188,6 +189,9 @@
 		case opt_force:
 			set_bit(HFSPLUS_SB_FORCE, &sbi->flags);
 			break;
+		case opt_noowners:
+			set_bit(HFSPLUS_SB_NOOWNERS, &sbi->flags);
+			break;
 		default:
 			return 0;
 		}
@@ -226,5 +230,7 @@
 		seq_printf(seq, ",nodecompose");
 	if (test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags))
 		seq_printf(seq, ",nobarrier");
+	if (test_bit(HFSPLUS_SB_NOOWNERS, &sbi->flags))
+		seq_printf(seq, ",noowners");
 	return 0;
 }
diff -ruw linux-3.2.24/fs/Kconfig linux-3.2.24-fbx/fs/Kconfig
--- linux-3.2.24/fs/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/Kconfig	2013-06-13 15:06:42.398517306 +0200
@@ -172,6 +172,17 @@
 config HUGETLB_PAGE
 	def_bool HUGETLBFS
 
+config RAMFS_XATTR
+	bool
+	default n
+ 
+config RAMFS_XATTR_USER
+	bool "Enable user extended attributes on RAMFS filesystem"
+	select RAMFS_XATTR
+	help
+	  Select this to enable extended user attributes on RAMFS
+	  filesystem.
+
 source "fs/configfs/Kconfig"
 
 endmenu
diff -ruw linux-3.2.24/fs/namespace.c linux-3.2.24-fbx/fs/namespace.c
--- linux-3.2.24/fs/namespace.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/namespace.c	2013-06-13 15:52:31.037197978 +0200
@@ -1694,7 +1694,7 @@
 
 static int flags_to_propagation_type(int flags)
 {
-	int type = flags & ~(MS_REC | MS_SILENT);
+	int type = flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE);
 
 	/* Fail if any non-propagation flags are set */
 	if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
diff -ruw linux-3.2.24/fs/open.c linux-3.2.24-fbx/fs/open.c
--- linux-3.2.24/fs/open.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/open.c	2013-06-13 15:52:31.073197961 +0200
@@ -418,10 +418,39 @@
 	return error;
 }
 
+static bool is_chrooted(struct fs_struct *fs)
+{
+	bool ret;
+
+	/*
+	 * This is equivalent to checking whether "/.." is the same
+	 * directory as "/", where the ".." part ignores the current
+	 * root.  This logic is the same as follow_dotdot except that we
+	 * ignore fs->root and we don't need to follow the final
+	 * mountpoint we end up on.
+	 */
+	struct path path = fs->root;
+	path_get(&path);
+	while (true) {
+		if (path.dentry != path.mnt->mnt_root) {
+			ret = true;  /* .. moves up within a vfsmount. */
+			break;
+		}
+
+		if (!follow_up(&path)) {
+			ret = false;  /* We've hit the real root. */
+			break;
+		}
+	}
+	path_put(&path);
+	return ret;
+}
+
 SYSCALL_DEFINE1(chroot, const char __user *, filename)
 {
 	struct path path;
 	int error;
+	struct fs_struct *fs = current->fs;
 
 	error = user_path_dir(filename, &path);
 	if (error)
@@ -432,13 +461,26 @@
 		goto dput_and_out;
 
 	error = -EPERM;
-	if (!capable(CAP_SYS_CHROOT))
+	/*
+	 * Chroot is dangerous unless no_new_privs is set, and we also
+	 * don't want to allow unprivileged users to break out of chroot
+	 * jail with another chroot call.
+	 *
+	 * We therefore allow chroot under one of two circumstances:
+	 *  a) no_new_privs (so setuid and similar programs can't be
+	 *     exploited), fs not shared (to avoid bypassing no_new_privs),
+	 *     and not already chrooted (so there's no chroot jail to break
+	 *     out of)
+	 *  b) CAP_SYS_CHROOT
+	 */
+	if (!(current->no_new_privs && fs->users == 1 && !is_chrooted(fs)) &&
+	    !capable(CAP_SYS_CHROOT))
 		goto dput_and_out;
 	error = security_path_chroot(&path);
 	if (error)
 		goto dput_and_out;
 
-	set_fs_root(current->fs, &path);
+	set_fs_root(fs, &path);
 	error = 0;
 dput_and_out:
 	path_put(&path);
diff -ruw linux-3.2.24/fs/ramfs/file-mmu.c linux-3.2.24-fbx/fs/ramfs/file-mmu.c
--- linux-3.2.24/fs/ramfs/file-mmu.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/ramfs/file-mmu.c	2012-11-30 16:07:20.038641711 +0100
@@ -27,6 +27,7 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/ramfs.h>
+#include <linux/xattr.h>
 
 #include "internal.h"
 
@@ -52,4 +53,11 @@
 const struct inode_operations ramfs_file_inode_operations = {
 	.setattr	= simple_setattr,
 	.getattr	= simple_getattr,
+#ifdef CONFIG_RAMFS_XATTR
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.listxattr	= generic_listxattr,
+	.removexattr	= generic_removexattr,
+#endif
 };
+
diff -ruw linux-3.2.24/fs/ramfs/inode.c linux-3.2.24-fbx/fs/ramfs/inode.c
--- linux-3.2.24/fs/ramfs/inode.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/ramfs/inode.c	2013-06-13 15:06:42.690517166 +0200
@@ -36,12 +36,14 @@
 #include <linux/magic.h>
 #include <linux/slab.h>
 #include <asm/uaccess.h>
+#include <linux/xattr.h>
 #include "internal.h"
 
 #define RAMFS_DEFAULT_MODE	0755
 
 static const struct super_operations ramfs_ops;
 static const struct inode_operations ramfs_dir_inode_operations;
+static struct kmem_cache *ramfs_inode_cache;
 
 static struct backing_dev_info ramfs_backing_dev_info = {
 	.name		= "ramfs",
@@ -51,6 +53,28 @@
 			  BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP,
 };
 
+static struct inode *ramfs_alloc_inode(struct super_block *sb)
+{
+	struct ramfs_inode_info *rii;
+
+	rii = kmem_cache_alloc(ramfs_inode_cache, GFP_KERNEL);
+	if (!rii)
+		return NULL;
+	return &rii->vfs_inode;
+}
+
+static void ramfs_destroy_inode(struct inode *ino)
+{
+	struct ramfs_inode_info *rii;
+
+	rii = RAMFS_I(ino);
+
+#ifdef CONFIG_RAMFS_XATTR
+	ramfs_inode_purge_xattrs(rii);
+#endif
+	kmem_cache_free(ramfs_inode_cache, rii);
+}
+
 struct inode *ramfs_get_inode(struct super_block *sb,
 				const struct inode *dir, int mode, dev_t dev)
 {
@@ -148,9 +172,17 @@
 	.rmdir		= simple_rmdir,
 	.mknod		= ramfs_mknod,
 	.rename		= simple_rename,
+#ifdef CONFIG_RAMFS_XATTR
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.listxattr	= generic_listxattr,
+	.removexattr	= generic_removexattr,
+#endif
 };
 
 static const struct super_operations ramfs_ops = {
+	.alloc_inode	= ramfs_alloc_inode,
+	.destroy_inode	= ramfs_destroy_inode,
 	.statfs		= simple_statfs,
 	.drop_inode	= generic_delete_inode,
 	.show_options	= generic_show_options,
@@ -232,6 +264,9 @@
 	sb->s_magic		= RAMFS_MAGIC;
 	sb->s_op		= &ramfs_ops;
 	sb->s_time_gran		= 1;
+#ifdef CONFIG_RAMFS_XATTR
+	sb->s_xattr = ramfs_xattr_handlers;
+#endif
 
 	inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);
 	if (!inode) {
@@ -283,6 +318,16 @@
 	.kill_sb	= kill_litter_super,
 };
 
+static void ramfs_inode_init_once(void *ptr)
+{
+	struct ramfs_inode_info *p = (struct ramfs_inode_info *)ptr;
+
+	inode_init_once(&p->vfs_inode);
+#ifdef CONFIG_RAMFS_XATTR_USER
+	INIT_LIST_HEAD(&p->xattr_user_list);
+#endif
+}
+
 static int __init init_ramfs_fs(void)
 {
 	return register_filesystem(&ramfs_fs_type);
@@ -297,9 +342,18 @@
 	if (err)
 		return err;
 
-	err = register_filesystem(&rootfs_fs_type);
-	if (err)
+	ramfs_inode_cache = kmem_cache_create("ramfs_inode_cache",
+					      sizeof (struct ramfs_inode_info),
+					      0, 0, ramfs_inode_init_once);
+	if (!ramfs_inode_cache) {
 		bdi_destroy(&ramfs_backing_dev_info);
+		return -ENOMEM;
+	}
 
+	err = register_filesystem(&rootfs_fs_type);
+	if (err) {
+		kmem_cache_destroy(ramfs_inode_cache);
+		bdi_destroy(&ramfs_backing_dev_info);
+	}
 	return err;
 }
diff -ruw linux-3.2.24/fs/ramfs/internal.h linux-3.2.24-fbx/fs/ramfs/internal.h
--- linux-3.2.24/fs/ramfs/internal.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/ramfs/internal.h	2012-11-30 16:07:20.038641711 +0100
@@ -9,6 +9,42 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#ifndef RAMFS_INTERNAL_H
+# define RAMFS_INTERNAL_H
+
+/* need list_head */
+#include <linux/list.h>
 
 extern const struct address_space_operations ramfs_aops;
 extern const struct inode_operations ramfs_file_inode_operations;
+
+
+struct ramfs_xattr
+{
+	char *name;
+	void *data;
+	size_t data_len;
+
+	struct list_head list;
+};
+
+struct ramfs_inode_info
+{
+	struct inode vfs_inode;
+#ifdef CONFIG_RAMFS_XATTR_USER
+	struct list_head xattr_user_list;
+#endif
+};
+
+static inline struct ramfs_inode_info *RAMFS_I(struct inode *inode)
+{
+	return container_of(inode, struct ramfs_inode_info, vfs_inode);
+}
+
+#ifdef CONFIG_RAMFS_XATTR
+void ramfs_inode_purge_xattrs(struct ramfs_inode_info *rii);
+extern const struct xattr_handler *ramfs_xattr_handlers[];
+#endif
+
+
+#endif /* !RAMFS_INTERNAL_H */
diff -ruw linux-3.2.24/fs/ramfs/Makefile linux-3.2.24-fbx/fs/ramfs/Makefile
--- linux-3.2.24/fs/ramfs/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/ramfs/Makefile	2012-11-30 16:07:20.038641711 +0100
@@ -6,4 +6,5 @@
 
 file-mmu-y := file-nommu.o
 file-mmu-$(CONFIG_MMU) := file-mmu.o
-ramfs-objs += inode.o $(file-mmu-y)
+ramfs-xattr-$(CONFIG_RAMFS_XATTR) += xattr.o
+ramfs-objs += inode.o $(file-mmu-y) $(ramfs-xattr-y)
diff -ruw linux-3.2.24/fs/xfs/xfs_buf.c linux-3.2.24-fbx/fs/xfs/xfs_buf.c
--- linux-3.2.24/fs/xfs/xfs_buf.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/xfs/xfs_buf.c	2013-06-13 15:06:42.730517147 +0200
@@ -378,6 +378,40 @@
 	return error;
 }
 
+#ifdef CONFIG_MIPS
+static void cache_flush_buf_page(xfs_buf_t *bp, int page_id)
+{
+	struct page *page;
+	void *vmaddr, *addr;
+
+	if (!(bp->b_flags & XBF_MAPPED))
+		return;
+
+	if (bp->b_page_count <= 1)
+		return;
+
+	page = bp->b_pages[page_id];
+	vmaddr = bp->b_addr - bp->b_offset + (page_id * PAGE_CACHE_SIZE);
+	addr = page_address(page);
+
+	if (pages_do_alias((unsigned long)addr, (unsigned long)vmaddr)) {
+		local_flush_data_cache_page(vmaddr);
+		local_flush_data_cache_page(addr);
+	}
+}
+
+static void cache_flush_buf(xfs_buf_t *bp)
+{
+	unsigned int i;
+
+	for (i = 0; i < bp->b_page_count; i++)
+		cache_flush_buf_page(bp, i);
+}
+#else
+static inline void cache_flush_buf_page(xfs_buf_t *bp, int page_id) { }
+static inline void cache_flush_buf(xfs_buf_t *bp) { }
+#endif
+
 /*
  *	Map buffer into kernel address-space if necessary.
  */
@@ -406,6 +440,7 @@
 			return -ENOMEM;
 		bp->b_addr += bp->b_offset;
 		bp->b_flags |= XBF_MAPPED;
+		cache_flush_buf(bp);
 	}
 
 	return 0;
@@ -1226,6 +1261,7 @@
 		if (nbytes > size)
 			nbytes = size;
 
+		cache_flush_buf_page(bp, map_i);
 		rbytes = bio_add_page(bio, bp->b_pages[map_i], nbytes, offset);
 		if (rbytes < nbytes)
 			break;
diff -ruw linux-3.2.24/fs/xfs/xfs_dir2_block.c linux-3.2.24-fbx/fs/xfs/xfs_dir2_block.c
--- linux-3.2.24/fs/xfs/xfs_dir2_block.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/xfs/xfs_dir2_block.c	2013-06-13 15:06:42.730517147 +0200
@@ -483,6 +483,9 @@
 	 * Each object is a real entry (dep) or an unused one (dup).
 	 */
 	while (ptr < endptr) {
+		struct xfs_inode *inode;
+		unsigned int type;
+
 		dup = (xfs_dir2_data_unused_t *)ptr;
 		/*
 		 * Unused, skip it.
@@ -507,12 +510,20 @@
 		cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
 					    (char *)dep - (char *)hdr);
 
+		if (xfs_iget(mp, NULL, be64_to_cpu(dep->inumber), 0, 0,
+			     &inode) == 0) {
+			type = (inode->i_d.di_mode >> 12) & 0xf;
+			xfs_iunlock(inode, 0);
+			IRELE(inode);
+		} else
+			type = DT_UNKNOWN;
+
 		/*
 		 * If it didn't fit, set the final offset to here & return.
 		 */
 		if (filldir(dirent, (char *)dep->name, dep->namelen,
 			    cook & 0x7fffffff, be64_to_cpu(dep->inumber),
-			    DT_UNKNOWN)) {
+			    type)) {
 			*offset = cook & 0x7fffffff;
 			xfs_da_brelse(NULL, bp);
 			return 0;
diff -ruw linux-3.2.24/fs/xfs/xfs_dir2_leaf.c linux-3.2.24-fbx/fs/xfs/xfs_dir2_leaf.c
--- linux-3.2.24/fs/xfs/xfs_dir2_leaf.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/xfs/xfs_dir2_leaf.c	2013-06-13 15:06:42.734517146 +0200
@@ -836,6 +836,9 @@
 	 * Get more blocks and readahead as necessary.
 	 */
 	while (curoff < XFS_DIR2_LEAF_OFFSET) {
+		struct xfs_inode *inode;
+		unsigned int type;
+
 		/*
 		 * If we have no buffer, or we're off the end of the
 		 * current buffer, need to get another one.
@@ -1097,9 +1100,17 @@
 		dep = (xfs_dir2_data_entry_t *)ptr;
 		length = xfs_dir2_data_entsize(dep->namelen);
 
+		if (xfs_iget(mp, NULL, be64_to_cpu(dep->inumber), 0, 0,
+			     &inode) == 0) {
+			type = (inode->i_d.di_mode >> 12) & 0xf;
+			xfs_iunlock(inode, 0);
+			IRELE(inode);
+		} else
+			type = DT_UNKNOWN;
+
 		if (filldir(dirent, (char *)dep->name, dep->namelen,
 			    xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff,
-			    be64_to_cpu(dep->inumber), DT_UNKNOWN))
+			    be64_to_cpu(dep->inumber), type))
 			break;
 
 		/*
diff -ruw linux-3.2.24/fs/xfs/xfs_dir2_sf.c linux-3.2.24-fbx/fs/xfs/xfs_dir2_sf.c
--- linux-3.2.24/fs/xfs/xfs_dir2_sf.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/fs/xfs/xfs_dir2_sf.c	2013-06-13 15:06:42.734517146 +0200
@@ -843,6 +843,9 @@
 	 */
 	sfep = xfs_dir2_sf_firstentry(sfp);
 	for (i = 0; i < sfp->count; i++) {
+		struct xfs_inode *inode;
+		unsigned int type;
+
 		off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
 				xfs_dir2_sf_get_offset(sfep));
 
@@ -852,8 +855,16 @@
 		}
 
 		ino = xfs_dir2_sfe_get_ino(sfp, sfep);
+
+		if (xfs_iget(mp, NULL, ino, 0, 0, &inode) == 0) {
+			type = (inode->i_d.di_mode >> 12) & 0xf;
+			xfs_iunlock(inode, 0);
+			IRELE(inode);
+		} else
+			type = DT_UNKNOWN;
+
 		if (filldir(dirent, (char *)sfep->name, sfep->namelen,
-			    off & 0x7fffffff, ino, DT_UNKNOWN)) {
+			    off & 0x7fffffff, ino, type)) {
 			*offset = off & 0x7fffffff;
 			return 0;
 		}
diff -ruw linux-3.2.24/include/asm-generic/siginfo.h linux-3.2.24-fbx/include/asm-generic/siginfo.h
--- linux-3.2.24/include/asm-generic/siginfo.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/asm-generic/siginfo.h	2013-06-13 15:06:42.770517128 +0200
@@ -90,9 +90,18 @@
 			__ARCH_SI_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
+
+		/* SIGSYS */
+		struct {
+			void __user *_call_addr; /* calling user insn */
+			int _syscall;	/* triggering system call number */
+			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
+		} _sigsys;
 	} _sifields;
 } siginfo_t;
 
+/* If the arch shares siginfo, then it has SIGSYS. */
+#define __ARCH_SIGSYS
 #endif
 
 /*
@@ -116,6 +125,11 @@
 #define si_addr_lsb	_sifields._sigfault._addr_lsb
 #define si_band		_sifields._sigpoll._band
 #define si_fd		_sifields._sigpoll._fd
+#ifdef __ARCH_SIGSYS
+#define si_call_addr	_sifields._sigsys._call_addr
+#define si_syscall	_sifields._sigsys._syscall
+#define si_arch		_sifields._sigsys._arch
+#endif
 
 #ifdef __KERNEL__
 #define __SI_MASK	0xffff0000u
@@ -126,6 +140,7 @@
 #define __SI_CHLD	(4 << 16)
 #define __SI_RT		(5 << 16)
 #define __SI_MESGQ	(6 << 16)
+#define __SI_SYS	(7 << 16)
 #define __SI_CODE(T,N)	((T) | ((N) & 0xffff))
 #else
 #define __SI_KILL	0
@@ -135,6 +150,7 @@
 #define __SI_CHLD	0
 #define __SI_RT		0
 #define __SI_MESGQ	0
+#define __SI_SYS	0
 #define __SI_CODE(T,N)	(N)
 #endif
 
@@ -232,6 +248,12 @@
 #define NSIGPOLL	6
 
 /*
+ * SIGSYS si_codes
+ */
+#define SYS_SECCOMP		(__SI_SYS|1)	/* seccomp triggered */
+#define NSIGSYS	1
+
+/*
  * sigevent definitions
  * 
  * It seems likely that SIGEV_THREAD will have to be handled from 
diff -ruw linux-3.2.24/include/linux/audit.h linux-3.2.24-fbx/include/linux/audit.h
--- linux-3.2.24/include/linux/audit.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/audit.h	2013-06-13 15:06:42.778517124 +0200
@@ -430,6 +430,7 @@
 extern void __audit_inode(const char *name, const struct dentry *dentry);
 extern void __audit_inode_child(const struct dentry *dentry,
 				const struct inode *parent);
+extern void __audit_seccomp(unsigned long syscall, long signr);
 extern void __audit_ptrace(struct task_struct *t);
 
 static inline int audit_dummy_context(void)
@@ -453,6 +454,12 @@
 }
 void audit_core_dumps(long signr);
 
+static inline void audit_seccomp(unsigned long syscall, long signr)
+{
+	if (unlikely(!audit_dummy_context()))
+		__audit_seccomp(syscall, signr);
+}
+
 static inline void audit_ptrace(struct task_struct *t)
 {
 	if (unlikely(!audit_dummy_context()))
@@ -558,6 +565,7 @@
 #define audit_inode(n,d) do { (void)(d); } while (0)
 #define audit_inode_child(i,p) do { ; } while (0)
 #define audit_core_dumps(i) do { ; } while (0)
+#define audit_seccomp(i, s) do { ; } while (0)
 #define auditsc_get_stamp(c,t,s) (0)
 #define audit_get_loginuid(t) (-1)
 #define audit_get_sessionid(t) (-1)
diff -ruw linux-3.2.24/include/linux/filter.h linux-3.2.24-fbx/include/linux/filter.h
--- linux-3.2.24/include/linux/filter.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/filter.h	2013-06-13 15:06:42.802517113 +0200
@@ -10,6 +10,7 @@
 
 #ifdef __KERNEL__
 #include <linux/atomic.h>
+#include <linux/compat.h>
 #endif
 
 /*
@@ -132,6 +133,16 @@
 
 #ifdef __KERNEL__
 
+#ifdef CONFIG_COMPAT
+/*
+ * A struct sock_filter is architecture independent.
+ */
+struct compat_sock_fprog {
+	u16		len;
+	compat_uptr_t	filter;		/* struct sock_filter * */
+};
+#endif
+
 struct sk_buff;
 struct sock;
 
@@ -228,6 +239,7 @@
 	BPF_S_ANC_HATYPE,
 	BPF_S_ANC_RXHASH,
 	BPF_S_ANC_CPU,
+	BPF_S_ANC_SECCOMP_LD_W,
 };
 
 #endif /* __KERNEL__ */
diff -ruw linux-3.2.24/include/linux/if_tunnel.h linux-3.2.24-fbx/include/linux/if_tunnel.h
--- linux-3.2.24/include/linux/if_tunnel.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/if_tunnel.h	2013-06-13 15:06:42.814517105 +0200
@@ -38,6 +38,11 @@
 	__be16			o_flags;
 	__be32			i_key;
 	__be32			o_key;
+
+	/* this is the first bits to match on ipv6 address */
+	struct in6_addr		fbx6to4_zone;
+	__u8			fbx6to4_prefix;
+
 	struct iphdr		iph;
 };
 
diff -ruw linux-3.2.24/include/linux/in.h linux-3.2.24-fbx/include/linux/in.h
--- linux-3.2.24/include/linux/in.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/in.h	2013-06-13 15:06:42.814517105 +0200
@@ -264,6 +264,9 @@
 		return 0;
 	case IPPROTO_AH:	/* SPI */
 		return 4;
+	case IPPROTO_IPV6:
+		/* third byte of ipv6 destination address */
+		return 36;
 	default:
 		return -EINVAL;
 	}
diff -ruw linux-3.2.24/include/linux/Kbuild linux-3.2.24-fbx/include/linux/Kbuild
--- linux-3.2.24/include/linux/Kbuild	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/Kbuild	2013-06-13 15:52:31.093197951 +0200
@@ -126,6 +126,10 @@
 header-y += fanotify.h
 header-y += fb.h
 header-y += fcntl.h
+header-y += fbxatm.h
+header-y += fbxbridge.h
+header-y += fbxjtag.h
+header-y += fbxmtd_map_ioctl.h
 header-y += fd.h
 header-y += fdreg.h
 header-y += fib_rules.h
@@ -329,6 +333,7 @@
 header-y += sched.h
 header-y += screen_info.h
 header-y += sdla.h
+header-y += seccomp.h
 header-y += securebits.h
 header-y += selinux_netlink.h
 header-y += sem.h
@@ -402,3 +407,5 @@
 header-y += x25.h
 header-y += xattr.h
 header-y += xfrm.h
+header-y += remoti/
+header-y += hdmi-cec/
diff -ruw linux-3.2.24/include/linux/major.h linux-3.2.24-fbx/include/linux/major.h
--- linux-3.2.24/include/linux/major.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/major.h	2012-11-30 16:07:20.430641729 +0100
@@ -171,7 +171,16 @@
 
 #define VIOTAPE_MAJOR		230
 
-#define BLOCK_EXT_MAJOR		259
+/*
+ * Until userland gets decent support for large majors number (if the
+ * day ever comes), use 242 for BLOCK_EXT_MAJOR. According to
+ * devices.txt area 240 to 254 is assigned for "LOCAL/EXPERIMENTAL
+ * USE". This kind of hack would fall in this category.
+ */
+/* #define BLOCK_EXT_MAJOR		259 */
+#define BLOCK_EXT_MAJOR		242
+
+
 #define SCSI_OSD_MAJOR		260	/* open-osd's OSD scsi device */
 
 #endif
diff -ruw linux-3.2.24/include/linux/mtd/mtd.h linux-3.2.24-fbx/include/linux/mtd/mtd.h
--- linux-3.2.24/include/linux/mtd/mtd.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/mtd/mtd.h	2013-06-13 15:06:42.834517098 +0200
@@ -157,6 +157,11 @@
 	unsigned int erasesize_mask;
 	unsigned int writesize_mask;
 
+	/* NAND related attributes */
+	const char *nand_type;
+	const char *nand_manufacturer;
+	const char *onfi_version;
+
 	// Kernel-only stuff starts here.
 	const char *name;
 	int index;
diff -ruw linux-3.2.24/include/linux/mtd/nand.h linux-3.2.24-fbx/include/linux/mtd/nand.h
--- linux-3.2.24/include/linux/mtd/nand.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/mtd/nand.h	2013-06-13 15:06:42.834517098 +0200
@@ -213,7 +213,8 @@
 #define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
 /* Large page NAND with SOFT_ECC should support subpage reads */
 #define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \
-					&& (chip->page_shift > 9))
+					&& (chip->page_shift > 9) \
+					&& !(chip->options & NAND_NO_RNDOUT))
 
 /* Mask to zero out the chip options, which come from the id table */
 #define NAND_CHIPOPTIONS_MSK	(0x0000ffff & ~NAND_NO_AUTOINCR)
@@ -229,6 +230,10 @@
 /* Chip may not exist, so silence any errors in scan */
 #define NAND_SCAN_SILENT_NODEV	0x00040000
 
+
+/* NAND controller does not want RNDOUT commands, even in NAND_ECC_SOFT */
+#define NAND_NO_RNDOUT		0x00800000
+
 /* Options set by nand scan */
 /* Nand scan has allocated controller struct */
 #define NAND_CONTROLLER_ALLOC	0x80000000
diff -ruw linux-3.2.24/include/linux/netdevice.h linux-3.2.24-fbx/include/linux/netdevice.h
--- linux-3.2.24/include/linux/netdevice.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/netdevice.h	2013-06-13 15:52:31.105197946 +0200
@@ -1288,6 +1288,11 @@
 	/* GARP */
 	struct garp_port __rcu	*garp_port;
 
+#if defined(CONFIG_FBXBRIDGE) || defined(CONFIG_FBXBRIDGE_MODULE)
+	struct fbxbridge	*fbx_bridge;
+	struct fbxbridge	*fbx_bridge_port;
+#endif
+
 	/* class/net/name entry */
 	struct device		dev;
 	/* space for optional device, statistics, and wireless sysfs groups */
diff -ruw linux-3.2.24/include/linux/netfilter/nf_conntrack_ftp.h linux-3.2.24-fbx/include/linux/netfilter/nf_conntrack_ftp.h
--- linux-3.2.24/include/linux/netfilter/nf_conntrack_ftp.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/netfilter/nf_conntrack_ftp.h	2012-11-30 16:07:20.466641731 +0100
@@ -25,6 +25,11 @@
 	u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
 	/* 0 means seq_match_aft_nl not set */
 	int seq_aft_nl_num[IP_CT_DIR_MAX];
+#if defined(CONFIG_FREEBOX_BRIDGE) || defined(CONFIG_FREEBOX_BRIDGE_MODULE)
+	unsigned int is_fbxbridge;
+	unsigned long fbxbridge_remote;
+	unsigned long fbxbridge_wan;
+#endif
 };
 
 struct nf_conntrack_expect;
diff -ruw linux-3.2.24/include/linux/ppp_channel.h linux-3.2.24-fbx/include/linux/ppp_channel.h
--- linux-3.2.24/include/linux/ppp_channel.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/ppp_channel.h	2012-11-30 16:07:20.534641734 +0100
@@ -49,6 +49,9 @@
 /* Called by the channel when it can send some more data. */
 extern void ppp_output_wakeup(struct ppp_channel *);
 
+/* Called by the channel when it want to prevent further transmit on it */
+extern void ppp_output_stop(struct ppp_channel *);
+
 /* Called by the channel to process a received PPP packet.
    The packet should have just the 2-byte PPP protocol header. */
 extern void ppp_input(struct ppp_channel *, struct sk_buff *);
diff -ruw linux-3.2.24/include/linux/prctl.h linux-3.2.24-fbx/include/linux/prctl.h
--- linux-3.2.24/include/linux/prctl.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/prctl.h	2013-06-13 15:06:42.854517088 +0200
@@ -102,4 +102,31 @@
 
 #define PR_MCE_KILL_GET 34
 
+/*
+ * If no_new_privs is set, then operations that grant new privileges (i.e.
+ * execve) will either fail or not grant them.  This affects suid/sgid,
+ * file capabilities, and LSMs.
+ *
+ * Operations that merely manipulate or drop existing privileges (setresuid,
+ * capset, etc.) will still work.  Drop those privileges if you want them gone.
+ *
+ * Changing LSM security domain is considered a new privilege.  So, for example,
+ * asking selinux for a specific new context (e.g. with runcon) will result
+ * in execve returning -EPERM.
+ */
+#define PR_SET_NO_NEW_PRIVS 36
+#define PR_GET_NO_NEW_PRIVS 37
+
+#define PR_SET_JAIL 38
+#define PR_GET_JAIL 39
+#define PR_JAIL_EXEC_ALL	0x0
+#define PR_JAIL_EXEC_ONCE	0x1
+#define PR_JAIL_EXEC_NO		0x2
+
+#define PR_SET_JAIL_ENTRIES 40
+
+#define PR_ADD_JAIL_FILES 41
+#define PR_JAIL_FILE_READ		0x1
+#define PR_JAIL_FILE_WRITE		0x2
+
 #endif /* _LINUX_PRCTL_H */
diff -ruw linux-3.2.24/include/linux/printk.h linux-3.2.24-fbx/include/linux/printk.h
--- linux-3.2.24/include/linux/printk.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/printk.h	2013-06-13 15:06:42.854517088 +0200
@@ -99,6 +99,7 @@
 int vprintk(const char *fmt, va_list args);
 asmlinkage __printf(1, 2) __cold
 int printk(const char *fmt, ...);
+extern void console_emergency_dump(char *buf, int *len);
 
 /*
  * Please don't use printk_ratelimit(), because it shares ratelimiting state
@@ -144,6 +145,10 @@
 static inline void setup_log_buf(int early)
 {
 }
+
+static inline void console_emergency_dump(char *buf, int *len)
+{
+}
 #endif
 
 extern void dump_stack(void) __cold;
diff -ruw linux-3.2.24/include/linux/ptrace.h linux-3.2.24-fbx/include/linux/ptrace.h
--- linux-3.2.24/include/linux/ptrace.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/ptrace.h	2013-06-13 15:06:42.854517088 +0200
@@ -62,8 +62,9 @@
 #define PTRACE_O_TRACEEXEC	0x00000010
 #define PTRACE_O_TRACEVFORKDONE	0x00000020
 #define PTRACE_O_TRACEEXIT	0x00000040
+#define PTRACE_O_TRACESECCOMP	0x00000080
 
-#define PTRACE_O_MASK		0x0000007f
+#define PTRACE_O_MASK		0x000000ff
 
 /* Wait extended result codes for the above trace options.  */
 #define PTRACE_EVENT_FORK	1
@@ -73,6 +74,7 @@
 #define PTRACE_EVENT_VFORK_DONE	5
 #define PTRACE_EVENT_EXIT	6
 #define PTRACE_EVENT_STOP	7
+#define PTRACE_EVENT_SECCOMP	8
 
 #include <asm/ptrace.h>
 
@@ -101,8 +103,9 @@
 #define PT_TRACE_EXEC		PT_EVENT_FLAG(PTRACE_EVENT_EXEC)
 #define PT_TRACE_VFORK_DONE	PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE)
 #define PT_TRACE_EXIT		PT_EVENT_FLAG(PTRACE_EVENT_EXIT)
+#define PT_TRACE_SECCOMP	PT_EVENT_FLAG(PTRACE_EVENT_SECCOMP)
 
-#define PT_TRACE_MASK	0x000003f4
+#define PT_TRACE_MASK	0x00000ff4
 
 /* single stepping state bits (used on ARM and PA-RISC) */
 #define PT_SINGLESTEP_BIT	31
diff -ruw linux-3.2.24/include/linux/sched.h linux-3.2.24-fbx/include/linux/sched.h
--- linux-3.2.24/include/linux/sched.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/sched.h	2013-06-13 15:52:31.109197944 +0200
@@ -1297,6 +1297,8 @@
 				 * execve */
 	unsigned in_iowait:1;
 
+	/* task may not gain privileges */
+	unsigned no_new_privs:1;
 
 	/* Revert to default priority/policy when forking */
 	unsigned sched_reset_on_fork:1;
@@ -1401,7 +1403,7 @@
 	uid_t loginuid;
 	unsigned int sessionid;
 #endif
-	seccomp_t seccomp;
+	struct seccomp seccomp;
 
 /* Thread group tracking */
    	u32 parent_exec_id;
diff -ruw linux-3.2.24/include/linux/seccomp.h linux-3.2.24-fbx/include/linux/seccomp.h
--- linux-3.2.24/include/linux/seccomp.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/seccomp.h	2013-06-13 15:06:42.886517073 +0200
@@ -1,25 +1,89 @@
 #ifndef _LINUX_SECCOMP_H
 #define _LINUX_SECCOMP_H
 
+#include <linux/compiler.h>
+#include <linux/types.h>
 
+
+/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */
+#define SECCOMP_MODE_DISABLED	0 /* seccomp is not in use. */
+#define SECCOMP_MODE_STRICT	1 /* uses hard-coded filter. */
+#define SECCOMP_MODE_FILTER	2 /* uses user-supplied filter. */
+
+/*
+ * All BPF programs must return a 32-bit value.
+ * The bottom 16-bits are for optional return data.
+ * The upper 16-bits are ordered from least permissive values to most.
+ *
+ * The ordering ensures that a min_t() over composed return values always
+ * selects the least permissive choice.
+ */
+#define SECCOMP_RET_KILL	0x00000000U /* kill the task immediately */
+#define SECCOMP_RET_TRAP	0x00020000U /* disallow and force a SIGSYS */
+#define SECCOMP_RET_ERRNO	0x00030000U /* returns an errno */
+#define SECCOMP_RET_TRACE	0x7ffe0000U /* pass to a tracer or disallow */
+#define SECCOMP_RET_ALLOW	0x7fff0000U /* allow */
+
+/* Masks for the return value sections. */
+#define SECCOMP_RET_ACTION	0xffff0000U
+#define SECCOMP_RET_DATA	0x0000ffffU
+
+/**
+ * struct seccomp_data - the format the BPF program executes over.
+ * @nr: the system call number
+ * @arch: indicates system call convention as an AUDIT_ARCH_* value
+ *        as defined in <linux/audit.h>.
+ * @instruction_pointer: at the time of the system call.
+ * @args: up to 6 system call arguments always stored as 64-bit values
+ *        regardless of the architecture.
+ */
+struct seccomp_data {
+	int nr;
+	__u32 arch;
+	__u64 instruction_pointer;
+	__u64 args[6];
+};
+
+#ifdef __KERNEL__
 #ifdef CONFIG_SECCOMP
 
 #include <linux/thread_info.h>
 #include <asm/seccomp.h>
 
-typedef struct { int mode; } seccomp_t;
-
-extern void __secure_computing(int);
-static inline void secure_computing(int this_syscall)
+struct seccomp_filter;
+/**
+ * struct seccomp - the state of a seccomp'ed process
+ *
+ * @mode:  indicates one of the valid values above for controlled
+ *         system calls available to a process.
+ * @filter: The metadata and ruleset for determining what system calls
+ *          are allowed for a task.
+ *
+ *          @filter must only be accessed from the context of current as there
+ *          is no locking.
+ */
+struct seccomp {
+	int mode;
+	struct seccomp_filter *filter;
+};
+
+/*
+ * Direct callers to __secure_computing should be updated as
+ * CONFIG_HAVE_ARCH_SECCOMP_FILTER propagates.
+ */
+extern void __secure_computing(int) __deprecated;
+extern int __secure_computing_int(int);
+static inline int secure_computing(int this_syscall)
 {
 	if (unlikely(test_thread_flag(TIF_SECCOMP)))
-		__secure_computing(this_syscall);
+		return  __secure_computing_int(this_syscall);
+	return 0;
 }
 
 extern long prctl_get_seccomp(void);
-extern long prctl_set_seccomp(unsigned long);
+extern long prctl_set_seccomp(unsigned long, char __user *);
 
-static inline int seccomp_mode(seccomp_t *s)
+static inline int seccomp_mode(struct seccomp *s)
 {
 	return s->mode;
 }
@@ -28,25 +92,43 @@
 
 #include <linux/errno.h>
 
-typedef struct { } seccomp_t;
+struct seccomp { };
+struct seccomp_filter { };
 
-#define secure_computing(x) do { } while (0)
+static inline int secure_computing(int this_syscall)
+{
+	return 0;
+}
 
 static inline long prctl_get_seccomp(void)
 {
 	return -EINVAL;
 }
 
-static inline long prctl_set_seccomp(unsigned long arg2)
+static inline long prctl_set_seccomp(unsigned long arg2, char __user *arg3)
 {
 	return -EINVAL;
 }
 
-static inline int seccomp_mode(seccomp_t *s)
+static inline int seccomp_mode(struct seccomp *s)
 {
 	return 0;
 }
-
 #endif /* CONFIG_SECCOMP */
 
+#ifdef CONFIG_SECCOMP_FILTER
+extern void put_seccomp_filter(struct task_struct *tsk);
+extern void get_seccomp_filter(struct task_struct *tsk);
+extern u32 seccomp_bpf_load(int off);
+#else  /* CONFIG_SECCOMP_FILTER */
+static inline void put_seccomp_filter(struct task_struct *tsk)
+{
+	return;
+}
+static inline void get_seccomp_filter(struct task_struct *tsk)
+{
+	return;
+}
+#endif /* CONFIG_SECCOMP_FILTER */
+#endif /* __KERNEL__ */
 #endif /* _LINUX_SECCOMP_H */
diff -ruw linux-3.2.24/include/linux/security.h linux-3.2.24-fbx/include/linux/security.h
--- linux-3.2.24/include/linux/security.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/security.h	2013-06-13 15:06:42.886517073 +0200
@@ -130,6 +130,7 @@
 #define LSM_UNSAFE_SHARE	1
 #define LSM_UNSAFE_PTRACE	2
 #define LSM_UNSAFE_PTRACE_CAP	4
+#define LSM_UNSAFE_NO_NEW_PRIVS	8
 
 #ifdef CONFIG_MMU
 /*
diff -ruw linux-3.2.24/include/linux/serial_reg.h linux-3.2.24-fbx/include/linux/serial_reg.h
--- linux-3.2.24/include/linux/serial_reg.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/serial_reg.h	2012-11-30 16:07:20.582641736 +0100
@@ -18,9 +18,18 @@
  * DLAB=0
  */
 #define UART_RX		0	/* In:  Receive buffer */
+#ifdef CONFIG_TANGO2
+#define UART_TX		1	/* Out: Transmit buffer */
+#else
 #define UART_TX		0	/* Out: Transmit buffer */
+#endif
 
+#ifdef CONFIG_TANGO2
+#define UART_IER	2	/* Out: Interrupt Enable Register */
+#else
 #define UART_IER	1	/* Out: Interrupt Enable Register */
+#endif
+
 #define UART_IER_MSI		0x08 /* Enable Modem status interrupt */
 #define UART_IER_RLSI		0x04 /* Enable receiver line status interrupt */
 #define UART_IER_THRI		0x02 /* Enable Transmitter holding register int. */
@@ -30,7 +39,12 @@
  */
 #define UART_IERX_SLEEP		0x10 /* Enable sleep mode */
 
+#ifdef CONFIG_TANGO2
+#define UART_IIR	3	/* In:  Interrupt ID Register */
+#else
 #define UART_IIR	2	/* In:  Interrupt ID Register */
+#endif
+
 #define UART_IIR_NO_INT		0x01 /* No interrupts pending */
 #define UART_IIR_ID		0x06 /* Mask for the interrupt ID */
 #define UART_IIR_MSI		0x00 /* Modem status interrupt */
@@ -40,7 +54,12 @@
 
 #define UART_IIR_BUSY		0x07 /* DesignWare APB Busy Detect */
 
+#ifdef CONFIG_TANGO2
+#define UART_FCR	4	/* Out: FIFO Control Register */
+#else
 #define UART_FCR	2	/* Out: FIFO Control Register */
+#endif
+
 #define UART_FCR_ENABLE_FIFO	0x01 /* Enable the FIFO */
 #define UART_FCR_CLEAR_RCVR	0x02 /* Clear the RCVR FIFO */
 #define UART_FCR_CLEAR_XMIT	0x04 /* Clear the XMIT FIFO */
@@ -84,7 +103,12 @@
 #define UART_FCR6_T_TRIGGER_30	0x30 /* Mask for transmit trigger set at 30 */
 #define UART_FCR7_64BYTE	0x20 /* Go into 64 byte mode (TI16C750) */
 
+#ifdef CONFIG_TANGO2
+#define UART_LCR	5	/* Out: Line Control Register */
+#else
 #define UART_LCR	3	/* Out: Line Control Register */
+#endif
+
 /*
  * Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting 
  * UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
@@ -107,7 +131,11 @@
 #define UART_LCR_CONF_MODE_A	UART_LCR_DLAB	/* Configutation mode A */
 #define UART_LCR_CONF_MODE_B	0xBF		/* Configutation mode B */
 
+#ifdef CONFIG_TANGO2
+#define UART_MCR	6	/* Out: Modem Control Register */
+#else
 #define UART_MCR	4	/* Out: Modem Control Register */
+#endif
 #define UART_MCR_CLKSEL		0x80 /* Divide clock by 4 (TI16C752, EFR[4]=1) */
 #define UART_MCR_TCRTLR		0x40 /* Access TCR/TLR (TI16C752, EFR[4]=1) */
 #define UART_MCR_XONANY		0x20 /* Enable Xon Any (TI16C752, EFR[4]=1) */
@@ -118,8 +146,14 @@
 #define UART_MCR_RTS		0x02 /* RTS complement */
 #define UART_MCR_DTR		0x01 /* DTR complement */
 
+#ifdef CONFIG_TANGO2
+#define UART_LSR	7	/* In:  Line Status Register */
+#else
 #define UART_LSR	5	/* In:  Line Status Register */
+#endif
+
 #define UART_LSR_FIFOE		0x80 /* Fifo error */
+
 #define UART_LSR_TEMT		0x40 /* Transmitter empty */
 #define UART_LSR_THRE		0x20 /* Transmit-hold-register empty */
 #define UART_LSR_BI		0x10 /* Break interrupt indicator */
@@ -129,7 +163,11 @@
 #define UART_LSR_DR		0x01 /* Receiver data ready */
 #define UART_LSR_BRK_ERROR_BITS	0x1E /* BI, FE, PE, OE bits */
 
+#ifdef CONFIG_TANGO2
+#define UART_MSR	8	/* In:  Modem Status Register */
+#else
 #define UART_MSR	6	/* In:  Modem Status Register */
+#endif
 #define UART_MSR_DCD		0x80 /* Data Carrier Detect */
 #define UART_MSR_RI		0x40 /* Ring Indicator */
 #define UART_MSR_DSR		0x20 /* Data Set Ready */
@@ -140,18 +178,37 @@
 #define UART_MSR_DCTS		0x01 /* Delta CTS */
 #define UART_MSR_ANY_DELTA	0x0F /* Any of the delta bits! */
 
+#ifdef CONFIG_TANGO2
+#define UART_SCR	9	/* I/O: Scratch Register */
+#else
 #define UART_SCR	7	/* I/O: Scratch Register */
+#endif
 
 /*
  * DLAB=1
  */
+#ifdef CONFIG_TANGO2
+/*
+ * smp863x has DLM and DLM in one register
+ */
+#define UART_DL		10
+#define UART_CLKSEL     11      /* Clock selection */
+#else
 #define UART_DLL	0	/* Out: Divisor Latch Low */
 #define UART_DLM	1	/* Out: Divisor Latch High */
+#endif
 
 /*
  * LCR=0xBF (or DLAB=1 for 16C660)
  */
+#ifdef CONFIG_TANGO2
+/* EFR does not exist on TANGO2, we use a magic to catch accesses and
+ * make them nop */
+#define UART_EFR	42
+#else
 #define UART_EFR	2	/* I/O: Extended Features Register */
+#endif
+
 #define UART_XR_EFR	9	/* I/O: Extended Features Register (XR17D15x) */
 #define UART_EFR_CTS		0x80 /* CTS flow control */
 #define UART_EFR_RTS		0x40 /* RTS flow control */
diff -ruw linux-3.2.24/include/linux/skbuff.h linux-3.2.24-fbx/include/linux/skbuff.h
--- linux-3.2.24/include/linux/skbuff.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/skbuff.h	2013-06-13 15:52:31.109197944 +0200
@@ -306,6 +306,13 @@
 #define NET_SKBUFF_NF_DEFRAG_NEEDED 1
 #endif
 
+enum {
+	FFN_STATE_INIT = 0,
+	FFN_STATE_FORWARDABLE,
+	FFN_STATE_FAST_FORWARDED,
+	FFN_STATE_INCOMPATIBLE,
+};
+
 /** 
  *	struct sk_buff - socket buffer
  *	@next: Next buffer in list
@@ -420,6 +427,9 @@
 #endif
 #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
 	struct sk_buff		*nfct_reasm;
+#ifdef CONFIG_IP_FFN
+	int			ffn_state;
+#endif
 #endif
 #ifdef CONFIG_BRIDGE_NETFILTER
 	struct nf_bridge_info	*nf_bridge;
@@ -458,6 +468,8 @@
 		__u32		avail_size;
 	};
 
+	__u32			rx_class;
+
 	__u16			vlan_tci;
 
 	sk_buff_data_t		transport_header;
@@ -1542,6 +1554,10 @@
  * get_rps_cpus() for example only access one 64 bytes aligned block :
  * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
  */
+#ifdef CONFIG_NETSKBPAD
+#define NET_SKB_PAD	CONFIG_NETSKBPAD
+#endif
+
 #ifndef NET_SKB_PAD
 #define NET_SKB_PAD	max(32, L1_CACHE_BYTES)
 #endif
diff -ruw linux-3.2.24/include/linux/sockios.h linux-3.2.24-fbx/include/linux/sockios.h
--- linux-3.2.24/include/linux/sockios.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/sockios.h	2012-11-30 16:07:20.586641737 +0100
@@ -127,6 +127,14 @@
 /* hardware time stamping: parameters in linux/net_tstamp.h */
 #define SIOCSHWTSTAMP   0x89b0
 
+/* fbxdiverter call */
+#define SIOCGFBXDIVERT  0x89c0		/* fbxdiverter support          */
+#define SIOCSFBXDIVERT  0x89c1		/* Set fbxdiverter options      */
+
+/* fbxbridge call */
+#define SIOCGFBXBRIDGE	0x89b2		/* fbxbridge support          */
+#define SIOCSFBXBRIDGE	0x89b3		/* Set fbxbridge options      */
+
 /* Device private ioctl calls */
 
 /*
diff -ruw linux-3.2.24/include/linux/tty.h linux-3.2.24-fbx/include/linux/tty.h
--- linux-3.2.24/include/linux/tty.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/linux/tty.h	2013-06-13 15:06:42.902517064 +0200
@@ -34,6 +34,7 @@
 #define N_TI_WL		22	/* for TI's WL BT, FM, GPS combo chips */
 #define N_TRACESINK	23	/* Trace data routing for MIPI P1149.7 */
 #define N_TRACEROUTER	24	/* Trace data routing for MIPI P1149.7 */
+#define N_REMOTI	25	/* RemoTI over UART */
 
 #ifdef __KERNEL__
 #include <linux/fs.h>
diff -ruw linux-3.2.24/include/net/ip.h linux-3.2.24-fbx/include/net/ip.h
--- linux-3.2.24/include/net/ip.h	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/include/net/ip.h	2013-06-13 15:06:42.922517053 +0200
@@ -423,6 +423,20 @@
 int ip_frag_nqueues(struct net *net);
 
 /*
+ *     Functions provided by ip_ffn.c
+ */
+
+enum {
+	IP_FFN_FINISH_OUT,
+	IP_FFN_LOCAL_IN,
+};
+
+extern void ip_ffn_init(void);
+extern int ip_ffn_process(struct sk_buff *skb);
+extern void ip_ffn_add(struct sk_buff *skb, int when);
+extern void ip_ffn_flush_all(void);
+
+/*
  *	Functions provided by ip_forward.c
  */
  
diff -ruw linux-3.2.24/init/do_mounts.c linux-3.2.24-fbx/init/do_mounts.c
--- linux-3.2.24/init/do_mounts.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/init/do_mounts.c	2013-06-13 15:52:31.121197938 +0200
@@ -17,6 +17,10 @@
 #include <linux/fs_struct.h>
 #include <linux/slab.h>
 
+#ifdef CONFIG_DMCRYPTATBOOT
+#include <linux/dm-ioctl.h>
+#endif
+
 #include <linux/nfs_fs.h>
 #include <linux/nfs_fs_sb.h>
 #include <linux/nfs_mount.h>
@@ -496,6 +500,121 @@
 #endif
 }
 
+#ifdef CONFIG_DMCRYPTATBOOT
+/*
+ * Create dm device
+ */
+long dm_ctl_ioctl(struct file *file, uint command, ulong u);
+
+static int dm_run_setup(void)
+{
+	struct dm_ioctl dm, *dmp;
+	struct dm_target_spec *spec;
+	uint64_t size;
+	char *data, *tmp, *major, *minor;
+	uint8_t *target_info;
+	dev_t tomap;
+	int ret, fd;
+	uint8_t key[128];
+
+	/* read config */
+	ret = -EINVAL;
+	tmp = CONFIG_DMCRYPTATBOOT_DEVICE;
+	major = minor = NULL;
+	if (tmp)
+		major = strsep(&tmp, ":");
+	if (tmp)
+		minor = strsep(&tmp, ":");
+	if (!major || !minor)
+		goto end;
+
+	/* create device to map */
+	tomap = MKDEV(simple_strtoul(major, NULL, 10),
+		      simple_strtoul(minor, NULL, 10));
+	if (create_dev("/dev/tomap", tomap))
+		goto end;
+
+	fd = sys_open("/dev/tomap", 0, 0);
+	if (fd < 0)
+		goto end;
+
+	/* fetch its size */
+	if (sys_ioctl(fd, BLKGETSIZE64, (unsigned long)&size)) {
+		sys_close(fd);
+		goto end;
+	}
+	sys_close(fd);
+	size /= 512;
+
+	/* create dm device */
+	memset(&dm, 0, sizeof (dm));
+	dm.version[0] = DM_VERSION_MAJOR;
+	dm.version[1] = DM_VERSION_MINOR;
+	dm.version[2] = DM_VERSION_PATCHLEVEL;
+	dm.data_size = sizeof (dm);
+	strcpy(dm.name, "root");
+
+	ret = dm_ctl_ioctl(NULL, DM_DEV_CREATE, (ulong)&dm);
+	if (ret < 0) {
+		printk("dm_ctl_ioctl create failed\n");
+		goto end;
+	}
+
+	/* create table */
+	data = kmalloc(sizeof (*dmp) + sizeof (*spec) + 128, GFP_KERNEL);
+	if (!data)
+		goto end;
+	dmp = (struct dm_ioctl *)data;
+	spec = (struct dm_target_spec *)(dmp + 1);
+	target_info = (uint8_t *)(spec + 1);
+
+	memset(dmp, 0, sizeof (*dmp));
+	dmp->version[0] = DM_VERSION_MAJOR;
+	dmp->version[1] = DM_VERSION_MINOR;
+	dmp->version[2] = DM_VERSION_PATCHLEVEL;
+	dmp->data_size = sizeof (*dmp) + sizeof (*spec) + 128;
+	dmp->data_start = sizeof (*dmp);
+	dmp->target_count = 1;
+	strcpy(dmp->name, "root");
+
+	memset(spec, 0, sizeof (*spec));
+	spec->sector_start = 0;
+	spec->length = size;
+	strcpy(spec->target_type, "crypt");
+
+	strcpy(key, CONFIG_DMCRYPTATBOOT_KEY);
+
+	memset(target_info, 0, 128);
+	snprintf((char *)target_info, 128, "%s %s 0 /dev/tomap 0",
+		 CONFIG_DMCRYPTATBOOT_CIPHER, key);
+	target_info[127] = 0;
+
+	ret = dm_ctl_ioctl(NULL, DM_TABLE_LOAD, (ulong)data);
+	if (ret < 0) {
+		printk("dm_ctl_ioctl table load failed\n");
+		goto end;
+	}
+
+	/* resume device */
+	memset(&dm, 0, sizeof (dm));
+	dm.version[0] = DM_VERSION_MAJOR;
+	dm.version[1] = DM_VERSION_MINOR;
+	dm.version[2] = DM_VERSION_PATCHLEVEL;
+	dm.data_size = sizeof (dm);
+	strcpy(dm.name, "root");
+
+	ret = dm_ctl_ioctl(NULL, DM_DEV_SUSPEND, (ulong)&dm);
+	if (ret < 0) {
+		printk("dm_ctl_ioctl resume failed\n");
+		goto end;
+	}
+
+	strcpy(saved_root_name, "/dev/dm-0");
+end:
+	return ret;
+}
+#endif
+
 /*
  * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
  */
@@ -520,6 +639,16 @@
 
 	md_run_setup();
 
+#ifdef CONFIG_DMCRYPTATBOOT
+#ifdef CONFIG_DMCRYPTATBOOT_ONLY
+	if (dm_run_setup() != 0)
+		/* disallow other root= value */
+		saved_root_name[0] = 0;
+#else
+	dm_run_setup();
+#endif
+#endif
+
 	if (saved_root_name[0]) {
 		root_device_name = saved_root_name;
 		if (!strncmp(root_device_name, "mtd", 3) ||
diff -ruw linux-3.2.24/init/Kconfig linux-3.2.24-fbx/init/Kconfig
--- linux-3.2.24/init/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/init/Kconfig	2013-06-13 15:06:42.990517021 +0200
@@ -565,6 +565,41 @@
 		     13 =>  8 KB
 		     12 =>  4 KB
 
+
+config DMCRYPTATBOOT
+	bool "Create device-mapper crypt target before root"
+	depends on DM_CRYPT
+	default n
+
+config DMCRYPTATBOOT_DEVICE
+	string "Device major:minor"
+	depends on DMCRYPTATBOOT
+
+config DMCRYPTATBOOT_CIPHER
+	string "Cipher"
+	depends on DMCRYPTATBOOT
+
+config DMCRYPTATBOOT_KEY
+	string "Key"
+	depends on DMCRYPTATBOOT
+
+config DMCRYPTATBOOT_KEY_DECRYPT
+	string "Decryption key"
+	depends on DMCRYPTATBOOT
+
+config DMCRYPTATBOOT_ONLY
+	bool "Refuse to mount something else"
+	depends on DMCRYPTATBOOT
+
+config FBX_DECRYPT_INITRD
+	bool "Decrypt initrd at boot"
+	depends on BLK_DEV_RAM
+	default n
+
+config FBX_DECRYPT_INITRD_KEY
+	string "Decryption key"
+	depends on FBX_DECRYPT_INITRD
+
 #
 # Architectures with an unreliable sched_clock() should select this:
 #
@@ -930,7 +965,6 @@
 menuconfig EXPERT
 	bool "Configure standard kernel features (expert users)"
 	# Unhide debug options, to make the on-by-default options visible
-	select DEBUG_KERNEL
 	help
 	  This option allows certain base kernel options and settings
           to be disabled or tweaked. This is for specialized
diff -ruw linux-3.2.24/init/Makefile linux-3.2.24-fbx/init/Makefile
--- linux-3.2.24/init/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/init/Makefile	2013-06-13 15:06:42.990517021 +0200
@@ -10,11 +10,17 @@
 endif
 obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
 
+obj-$(CONFIG_FBX_DECRYPT_INITRD)+= fbx_decrypt_initrd.o rc4.o
+
 mounts-y			:= do_mounts.o
 mounts-$(CONFIG_BLK_DEV_RAM)	+= do_mounts_rd.o
 mounts-$(CONFIG_BLK_DEV_INITRD)	+= do_mounts_initrd.o
 mounts-$(CONFIG_BLK_DEV_MD)	+= do_mounts_md.o
 
+
+# files to be removed upon make clean
+clean-files := ../include/linux/compile.h dmcryptatboot_decrypt.c
+
 # dependencies on generated files need to be listed explicitly
 $(obj)/version.o: include/generated/compile.h
 
diff -ruw linux-3.2.24/kernel/fork.c linux-3.2.24-fbx/kernel/fork.c
--- linux-3.2.24/kernel/fork.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/kernel/fork.c	2013-06-13 15:52:31.125197936 +0200
@@ -34,6 +34,7 @@
 #include <linux/cgroup.h>
 #include <linux/security.h>
 #include <linux/hugetlb.h>
+#include <linux/seccomp.h>
 #include <linux/swap.h>
 #include <linux/syscalls.h>
 #include <linux/jiffies.h>
@@ -168,6 +169,7 @@
 	free_thread_info(tsk->stack);
 	rt_mutex_debug_task_free(tsk);
 	ftrace_graph_exit_task(tsk);
+	put_seccomp_filter(tsk);
 	free_task_struct(tsk);
 }
 EXPORT_SYMBOL(free_task);
@@ -1094,6 +1096,7 @@
 		goto fork_out;
 
 	ftrace_graph_init_task(p);
+	get_seccomp_filter(p);
 
 	rt_mutex_init_task(p);
 
diff -ruw linux-3.2.24/kernel/nsproxy.c linux-3.2.24-fbx/kernel/nsproxy.c
--- linux-3.2.24/kernel/nsproxy.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/kernel/nsproxy.c	2013-06-13 15:06:43.010517012 +0200
@@ -191,7 +191,13 @@
 			       CLONE_NEWNET)))
 		return 0;
 
-	if (!capable(CAP_SYS_ADMIN))
+	/* We require either no_new_privs or CAP_SYS_ADMIN for all modes */
+	if (!current->no_new_privs && !capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	/* NEWNS and NEWNET always require CAP_SYS_ADMIN. */
+	if ((unshare_flags & (CLONE_NEWNS | CLONE_NEWNET)) &&
+	    !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	*new_nsp = create_new_namespaces(unshare_flags, current,
diff -ruw linux-3.2.24/kernel/pid.c linux-3.2.24-fbx/kernel/pid.c
--- linux-3.2.24/kernel/pid.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/kernel/pid.c	2013-06-13 15:06:43.014517009 +0200
@@ -79,7 +79,7 @@
 	.level = 0,
 	.child_reaper = &init_task,
 };
-EXPORT_SYMBOL_GPL(init_pid_ns);
+EXPORT_SYMBOL(init_pid_ns);
 
 int is_container_init(struct task_struct *tsk)
 {
diff -ruw linux-3.2.24/kernel/printk.c linux-3.2.24-fbx/kernel/printk.c
--- linux-3.2.24/kernel/printk.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/kernel/printk.c	2013-06-13 15:06:43.014517009 +0200
@@ -53,6 +53,10 @@
 
 #define __LOG_BUF_LEN	(1 << CONFIG_LOG_BUF_SHIFT)
 
+#ifdef CONFIG_DEBUG_LL
+extern void printascii(char *);
+#endif
+
 /* printk's without a loglevel use this.. */
 #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL
 
@@ -329,6 +333,29 @@
 	return 0;
 }
 
+/*
+ * dump log buffer content in given buffer
+ */
+void console_emergency_dump(char *buf, int *len)
+{
+	int i, limit;
+
+	if (*len > log_buf_len)
+		*len = log_buf_len;
+	if (*len > logged_chars)
+		*len = logged_chars;
+	limit = log_end;
+
+	for (i = 0; i < *len; i++) {
+		int j;
+
+		j = limit - 1 -i;
+		if (j + log_buf_len < log_end)
+			break;
+		buf[*len - 1 - i] = LOG_BUF(j);
+	}
+}
+
 int do_syslog(int type, char __user *buf, int len, bool from_file)
 {
 	unsigned i, j, limit, count;
@@ -876,6 +903,10 @@
 	printed_len += vscnprintf(printk_buf + printed_len,
 				  sizeof(printk_buf) - printed_len, fmt, args);
 
+#ifdef CONFIG_DEBUG_LL
+	printascii(printk_buf);
+#endif
+
 	p = printk_buf;
 
 	/* Read log level and handle special printk prefix */
diff -ruw linux-3.2.24/kernel/ptrace.c linux-3.2.24-fbx/kernel/ptrace.c
--- linux-3.2.24/kernel/ptrace.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/kernel/ptrace.c	2013-06-13 15:06:43.014517009 +0200
@@ -543,6 +543,9 @@
 	if (data & PTRACE_O_TRACEEXIT)
 		child->ptrace |= PT_TRACE_EXIT;
 
+	if (data & PTRACE_O_TRACESECCOMP)
+		child->ptrace |= PT_TRACE_SECCOMP;
+
 	return (data & ~PTRACE_O_MASK) ? -EINVAL : 0;
 }
 
diff -ruw linux-3.2.24/kernel/signal.c linux-3.2.24-fbx/kernel/signal.c
--- linux-3.2.24/kernel/signal.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/kernel/signal.c	2013-06-13 15:52:31.149197925 +0200
@@ -159,7 +159,7 @@
 
 #define SYNCHRONOUS_MASK \
 	(sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \
-	 sigmask(SIGTRAP) | sigmask(SIGFPE))
+	 sigmask(SIGTRAP) | sigmask(SIGFPE) | sigmask(SIGSYS))
 
 int next_signal(struct sigpending *pending, sigset_t *mask)
 {
@@ -2629,6 +2629,13 @@
 		err |= __put_user(from->si_uid, &to->si_uid);
 		err |= __put_user(from->si_ptr, &to->si_ptr);
 		break;
+#ifdef __ARCH_SIGSYS
+	case __SI_SYS:
+		err |= __put_user(from->si_call_addr, &to->si_call_addr);
+		err |= __put_user(from->si_syscall, &to->si_syscall);
+		err |= __put_user(from->si_arch, &to->si_arch);
+		break;
+#endif
 	default: /* this is just in case for now ... */
 		err |= __put_user(from->si_pid, &to->si_pid);
 		err |= __put_user(from->si_uid, &to->si_uid);
diff -ruw linux-3.2.24/kernel/sys.c linux-3.2.24-fbx/kernel/sys.c
--- linux-3.2.24/kernel/sys.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/kernel/sys.c	2013-06-13 15:06:43.026517005 +0200
@@ -1781,7 +1781,7 @@
 			error = prctl_get_seccomp();
 			break;
 		case PR_SET_SECCOMP:
-			error = prctl_set_seccomp(arg2);
+			error = prctl_set_seccomp(arg2, (char __user *)arg3);
 			break;
 		case PR_GET_TSC:
 			error = GET_TSC_CTL(arg2);
@@ -1841,6 +1841,16 @@
 			else
 				error = PR_MCE_KILL_DEFAULT;
 			break;
+		case PR_SET_NO_NEW_PRIVS:
+			if (arg2 != 1 || arg3 || arg4 || arg5)
+				return -EINVAL;
+
+			current->no_new_privs = 1;
+			break;
+		case PR_GET_NO_NEW_PRIVS:
+			if (arg2 || arg3 || arg4 || arg5)
+				return -EINVAL;
+			return current->no_new_privs ? 1 : 0;
 		default:
 			error = -EINVAL;
 			break;
diff -ruw linux-3.2.24/kernel/sysctl.c linux-3.2.24-fbx/kernel/sysctl.c
--- linux-3.2.24/kernel/sysctl.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/kernel/sysctl.c	2013-06-13 15:52:31.149197925 +0200
@@ -192,6 +192,21 @@
 
 #endif
 
+/* Return standard mode bits for table entry. */
+static int sysctl_permissions(struct ctl_table_root *root,
+			       struct nsproxy *nsproxy,
+			       struct ctl_table *table)
+{
+	/* Allow system administrator to have same access as root. */
+	if (capable(CAP_SYS_ADMIN)) {
+		int mode = (table->mode >> 6) & 7;
+		return (mode << 6) | (mode << 3) | mode;
+	}
+
+	/* read-only otherwise */
+	return table->mode & ~0222;
+}
+
 static struct ctl_table root_table[];
 static struct ctl_table_root sysctl_table_root;
 static struct ctl_table_header root_table_header = {
@@ -204,6 +219,7 @@
 static struct ctl_table_root sysctl_table_root = {
 	.root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
 	.default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry),
+	.permissions = sysctl_permissions,
 };
 
 static struct ctl_table kern_table[];
diff -ruw linux-3.2.24/lib/Kconfig linux-3.2.24-fbx/lib/Kconfig
--- linux-3.2.24/lib/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/lib/Kconfig	2013-06-13 15:06:43.038516999 +0200
@@ -276,4 +276,7 @@
 	  so its calculations are in fixed point. Modules can select this
 	  when they require this function. Module will be called cordic.
 
+config FBXSERIAL
+	bool
+
 endmenu
diff -ruw linux-3.2.24/lib/Makefile linux-3.2.24-fbx/lib/Makefile
--- linux-3.2.24/lib/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/lib/Makefile	2013-06-13 15:06:43.042516996 +0200
@@ -86,6 +86,8 @@
 obj-$(CONFIG_SMP) += percpu_counter.o
 obj-$(CONFIG_AUDIT_GENERIC) += audit.o
 
+obj-$(CONFIG_FBXSERIAL) += fbxserial.o
+
 obj-$(CONFIG_SWIOTLB) += swiotlb.o
 obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o
 obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o
diff -ruw linux-3.2.24/net/8021q/vlan.c linux-3.2.24-fbx/net/8021q/vlan.c
--- linux-3.2.24/net/8021q/vlan.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/8021q/vlan.c	2013-06-13 15:06:43.074516981 +0200
@@ -226,7 +226,7 @@
 /*  Attach a VLAN device to a mac address (ie Ethernet Card).
  *  Returns 0 if the device was created or a negative error code otherwise.
  */
-static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
+int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
 {
 	struct net_device *new_dev;
 	struct net *net = dev_net(real_dev);
diff -ruw linux-3.2.24/net/8021q/vlan_core.c linux-3.2.24-fbx/net/8021q/vlan_core.c
--- linux-3.2.24/net/8021q/vlan_core.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/8021q/vlan_core.c	2013-06-13 15:06:43.074516981 +0200
@@ -53,6 +53,7 @@
 	}
 
 	skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci);
+	skb->rx_class = skb->priority;
 	skb->vlan_tci = 0;
 
 	rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_pcpu_stats);
diff -ruw linux-3.2.24/net/core/dev.c linux-3.2.24-fbx/net/core/dev.c
--- linux-3.2.24/net/core/dev.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/core/dev.c	2013-06-13 15:52:31.201197900 +0200
@@ -137,6 +137,7 @@
 #include <linux/if_pppox.h>
 #include <linux/ppp_defs.h>
 #include <linux/net_tstamp.h>
+#include <linux/kthread.h>
 
 #include "net-sysfs.h"
 
@@ -181,6 +182,19 @@
 static struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
 static struct list_head ptype_all __read_mostly;	/* Taps */
 
+#ifdef CONFIG_NETRXTHREAD
+
+#define RXTHREAD_MAX_PROCESS    CONFIG_NETRXTHREAD_MAX_PROCESS
+#define RXTHREAD_MAX_PKTS       128
+
+static struct task_struct *krxd;
+static struct sk_buff_head krxd_pkt_queue[CONFIG_NETRXTHREAD_RX_QUEUE];
+static unsigned int krxd_stats_pkts[CONFIG_NETRXTHREAD_RX_QUEUE];
+static unsigned int krxd_stats_dropped[CONFIG_NETRXTHREAD_RX_QUEUE];
+static wait_queue_head_t krxd_wq;
+static unsigned int krxd_pkts_count;
+#endif
+
 /*
  * The @dev_base_head list is protected by @dev_base_lock and the rtnl
  * semaphore.
@@ -2948,6 +2962,23 @@
 	return NET_RX_DROP;
 }
 
+/* Start Freebox added code */
+#if defined(CONFIG_FREEBOX_DIVERTER) || defined(CONFIG_FREEBOX_DIVERTER_MODULE)
+int (*fbxdiverter_hook)(struct sk_buff *);
+
+static int handle_fbxdiverter(struct sk_buff *skb)
+{
+	/* try_module_get is missing here, so there is a race on
+	 * fbxdiverter module deletion */
+	if (!fbxdiverter_hook)
+		return 0;
+	return fbxdiverter_hook(skb);
+}
+
+EXPORT_SYMBOL(fbxdiverter_hook);
+#endif
+
+
 /**
  *	netif_rx	-	post buffer to the network code
  *	@skb: buffer to post
@@ -3083,6 +3114,36 @@
 EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook);
 #endif
 
+#if defined(CONFIG_FBXBRIDGE) || defined(CONFIG_FBXBRIDGE_MODULE)
+struct sk_buff *(*fbxbridge_handle_frame_hook)(struct fbxbridge *p, struct sk_buff *skb);
+
+struct fbxbridge;
+
+static inline struct sk_buff *handle_fbxbridge(struct sk_buff *skb,
+					       struct packet_type **pt_prev, int *ret,
+					       struct net_device *orig_dev)
+{
+	struct fbxbridge *fbxbr;
+
+	if (skb->pkt_type == PACKET_LOOPBACK ||
+	    (fbxbr = skb->dev->fbx_bridge_port) == NULL)
+		return skb;
+
+	if (skb->protocol != __constant_htons(ETH_P_IP) &&
+	    skb->protocol != __constant_htons(ETH_P_ARP))
+		return skb;
+
+	if (*pt_prev) {
+		*ret = deliver_skb(skb, *pt_prev, orig_dev);
+		*pt_prev = NULL;
+	}
+
+	return fbxbridge_handle_frame_hook(fbxbr, skb);
+}
+#else
+#define handle_fbxbridge(skb, pt_prev, ret, orig_dev)   (skb)
+#endif
+
 #ifdef CONFIG_NET_CLS_ACT
 /* TODO: Maybe we should just force sch_ingress to be compiled in
  * when CONFIG_NET_CLS_ACT is? otherwise some useless instructions
@@ -3194,7 +3255,9 @@
 }
 EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
 
-static int __netif_receive_skb(struct sk_buff *skb)
+static int __netif_receive_skb(struct sk_buff *skb);
+
+static int __netif_receive_skb_end(struct sk_buff *skb)
 {
 	struct packet_type *ptype, *pt_prev;
 	rx_handler_func_t *rx_handler;
@@ -3204,23 +3267,6 @@
 	int ret = NET_RX_DROP;
 	__be16 type;
 
-	if (!netdev_tstamp_prequeue)
-		net_timestamp_check(skb);
-
-	trace_netif_receive_skb(skb);
-
-	/* if we've gotten here through NAPI, check netpoll */
-	if (netpoll_receive_skb(skb))
-		return NET_RX_DROP;
-
-	if (!skb->skb_iif)
-		skb->skb_iif = skb->dev->ifindex;
-	orig_dev = skb->dev;
-
-	skb_reset_network_header(skb);
-	skb_reset_transport_header(skb);
-	skb_reset_mac_len(skb);
-
 	pt_prev = NULL;
 
 	rcu_read_lock();
@@ -3242,6 +3288,8 @@
 	}
 #endif
 
+	orig_dev = skb->dev;
+
 	list_for_each_entry_rcu(ptype, &ptype_all, list) {
 		if (!ptype->dev || ptype->dev == skb->dev) {
 			if (pt_prev)
@@ -3250,6 +3298,10 @@
 		}
 	}
 
+	skb = handle_fbxbridge(skb, &pt_prev, &ret, orig_dev);
+	if (!skb)
+		goto out;
+
 #ifdef CONFIG_NET_CLS_ACT
 	skb = handle_ing(skb, &pt_prev, &ret, orig_dev);
 	if (!skb)
@@ -3319,6 +3371,187 @@
 	return ret;
 }
 
+#ifdef CONFIG_NETRXTHREAD
+
+
+static int krxd_action(void *unused)
+{
+	struct sk_buff *skb;
+	unsigned int maxpkt_in_loop;
+
+	set_user_nice(current, -5);
+	current->flags |= PF_NOFREEZE;
+	__set_current_state(TASK_RUNNING);
+
+	maxpkt_in_loop = RXTHREAD_MAX_PROCESS;
+	while (1) {
+		unsigned int i, queue, count;
+
+		local_bh_disable();
+		count = CONFIG_NETRXTHREAD_RX_QUEUE;
+		for (i = 0; i < count; i++) {
+			queue = count - i - 1;
+			skb = skb_dequeue(&krxd_pkt_queue[queue]);
+			if (!skb)
+				continue;
+			krxd_pkts_count--;
+			break;
+		}
+
+		if (!skb) {
+			local_bh_enable();
+			wait_event_interruptible(krxd_wq,
+						 krxd_pkts_count != 0);
+			set_current_state(TASK_RUNNING);
+			maxpkt_in_loop = RXTHREAD_MAX_PROCESS;
+			continue;
+		}
+
+		__netif_receive_skb_end(skb);
+		local_bh_enable();
+
+		/* only schedule when working on lowest prio queue */
+		if (queue == 0) {
+			if (--maxpkt_in_loop == 0) {
+				maxpkt_in_loop = RXTHREAD_MAX_PROCESS;
+				schedule();
+			}
+		}
+	}
+	return 0;
+}
+
+#ifdef CONFIG_PROC_FS
+/*
+ *	This is invoked by the /proc filesystem handler to display a device
+ *	in detail.
+ */
+void *krxthread_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	int *queue;
+
+	if (*pos > CONFIG_NETRXTHREAD_RX_QUEUE)
+		return NULL;
+
+	queue = kmalloc(sizeof(*queue), GFP_KERNEL);
+	if (!queue)
+		return NULL;
+	*queue = ((int)*pos - 1);
+
+	return queue;
+}
+
+void *krxthread_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	int *queue = v;
+
+	if (*pos == CONFIG_NETRXTHREAD_RX_QUEUE)
+		return NULL;
+
+	++*queue;
+	*pos = *queue + 1;
+	return queue;
+}
+
+void krxthread_seq_stop(struct seq_file *seq, void *v)
+{
+	kfree(v);
+}
+
+static void krxthread_seq_printf_stats(struct seq_file *seq, int queue)
+{
+	seq_printf(seq, "%8u %12u %12u\n",
+		   queue,
+		   krxd_stats_pkts[queue],
+		   krxd_stats_dropped[queue]);
+}
+
+static int krxthread_seq_show(struct seq_file *seq, void *v)
+{
+	int *queue = v;
+
+	if (*queue == -1)
+		seq_printf(seq, "%8s %12s %12s\n",
+			   "queue", "packets", "drops");
+	else
+		krxthread_seq_printf_stats(seq, *queue);
+	return 0;
+}
+
+static const struct seq_operations krxthread_seq_ops = {
+	.start = krxthread_seq_start,
+	.next  = krxthread_seq_next,
+	.stop  = krxthread_seq_stop,
+	.show  = krxthread_seq_show,
+};
+
+static int krxthread_seq_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &krxthread_seq_ops);
+}
+
+static const struct file_operations krxthread_seq_fops = {
+	.owner	 = THIS_MODULE,
+	.open    = krxthread_seq_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
+#endif /* PROCFS */
+#endif /* RXTHREAD */
+
+static int __netif_receive_skb(struct sk_buff *skb)
+{
+#ifdef CONFIG_NETRXTHREAD
+	unsigned int len, queue;
+#endif
+
+	if (!netdev_tstamp_prequeue)
+		net_timestamp_check(skb);
+
+	trace_netif_receive_skb(skb);
+
+	/* if we've gotten here through NAPI, check netpoll */
+	if (netpoll_receive_skb(skb))
+		return NET_RX_DROP;
+
+	if (!skb->skb_iif)
+		skb->skb_iif = skb->dev->ifindex;
+
+	skb_reset_network_header(skb);
+	skb_reset_transport_header(skb);
+	skb_reset_mac_len(skb);
+
+#if defined(CONFIG_FREEBOX_DIVERTER) || defined(CONFIG_FREEBOX_DIVERTER_MODULE)
+	if (handle_fbxdiverter(skb))
+		return NET_RX_SUCCESS;
+#endif
+
+#ifndef CONFIG_NETRXTHREAD
+	return __netif_receive_skb_end(skb);
+#else
+	queue = skb->rx_class;
+	if (queue >= CONFIG_NETRXTHREAD_RX_QUEUE)
+		queue = CONFIG_NETRXTHREAD_RX_QUEUE - 1;
+
+	/* queue the packet to the rx thread */
+	local_bh_disable();
+	len = skb_queue_len(&krxd_pkt_queue[queue]);
+	if (len < RXTHREAD_MAX_PKTS) {
+		__skb_queue_tail(&krxd_pkt_queue[queue], skb);
+		krxd_pkts_count++;
+		krxd_stats_pkts[queue]++;
+		if (!len)
+			wake_up(&krxd_wq);
+	} else {
+		krxd_stats_dropped[queue]++;
+		dev_kfree_skb(skb);
+	}
+	local_bh_enable();
+	return NET_RX_SUCCESS;
+#endif
+}
+
 /**
  *	netif_receive_skb - process receive buffer from network
  *	@skb: buffer to process
@@ -4380,7 +4613,11 @@
 		goto out_dev;
 	if (!proc_net_fops_create(net, "ptype", S_IRUGO, &ptype_seq_fops))
 		goto out_softnet;
-
+#ifdef CONFIG_NETRXTHREAD
+	if (!proc_net_fops_create(net, "krxthread", S_IRUGO,
+				  &krxthread_seq_fops))
+		goto out;
+#endif
 	if (wext_proc_init(net))
 		goto out_ptype;
 	rc = 0;
@@ -5768,7 +6005,7 @@
 			rebroadcast_time = jiffies;
 		}
 
-		msleep(250);
+		msleep(1);
 
 		refcnt = netdev_refcnt_read(dev);
 
@@ -6618,6 +6855,19 @@
 	open_softirq(NET_TX_SOFTIRQ, net_tx_action);
 	open_softirq(NET_RX_SOFTIRQ, net_rx_action);
 
+#ifdef CONFIG_NETRXTHREAD
+	for (i = 0; i < CONFIG_NETRXTHREAD_RX_QUEUE; i++)
+		skb_queue_head_init(&krxd_pkt_queue[i]);
+	krxd_pkts_count = 0;
+	init_waitqueue_head(&krxd_wq);
+	krxd = kthread_create(krxd_action, NULL, "krxthread");
+	if (IS_ERR(krxd)) {
+		printk(KERN_ERR "unable to create krxd\n");
+		return -ENOMEM;
+	}
+	wake_up_process(krxd);
+#endif
+
 	hotcpu_notifier(dev_cpu_callback, 0);
 	dst_init();
 	dev_mcast_init();
@@ -6636,3 +6886,6 @@
 
 late_initcall_sync(initialize_hashrnd);
 
+#if defined(CONFIG_FBXBRIDGE_MODULE)
+EXPORT_SYMBOL(fbxbridge_handle_frame_hook);
+#endif
diff -ruw linux-3.2.24/net/core/filter.c linux-3.2.24-fbx/net/core/filter.c
--- linux-3.2.24/net/core/filter.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/core/filter.c	2013-06-13 15:06:43.114516962 +0200
@@ -350,6 +350,11 @@
 				A = 0;
 			continue;
 		}
+#ifdef CONFIG_SECCOMP_FILTER
+		case BPF_S_ANC_SECCOMP_LD_W:
+			A = seccomp_bpf_load(fentry->k);
+			continue;
+#endif
 		default:
 			WARN_RATELIMIT(1, "Unknown code:%u jt:%u tf:%u k:%u\n",
 				       fentry->code, fentry->jt,
diff -ruw linux-3.2.24/net/core/skbuff.c linux-3.2.24-fbx/net/core/skbuff.c
--- linux-3.2.24/net/core/skbuff.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/core/skbuff.c	2013-06-13 15:52:31.209197896 +0200
@@ -556,7 +556,11 @@
 #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
 	new->ipvs_property	= old->ipvs_property;
 #endif
+#ifdef CONFIG_IP_FFN
+	new->ffn_state		= FFN_STATE_INIT;
+#endif
 	new->protocol		= old->protocol;
+	new->rx_class		= old->rx_class;
 	new->mark		= old->mark;
 	new->skb_iif		= old->skb_iif;
 	__nf_copy(new, old);
diff -ruw linux-3.2.24/net/ipv4/ipconfig.c linux-3.2.24-fbx/net/ipv4/ipconfig.c
--- linux-3.2.24/net/ipv4/ipconfig.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/ipv4/ipconfig.c	2013-06-13 15:06:43.146516946 +0200
@@ -189,15 +189,61 @@
 static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
 static struct net_device *ic_dev __initdata = NULL;	/* Selected device */
 
-static bool __init ic_is_init_dev(struct net_device *dev)
+static bool __init ic_is_init_dev(struct net_device *dev, bool partial)
 {
+	char *p = NULL;
+	bool ret;
+
 	if (dev->flags & IFF_LOOPBACK)
 		return false;
-	return user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
+
+	if (partial) {
+		p = strchr(user_dev_name, '.');
+		if (p)
+			*p = 0;
+	}
+
+	ret = false;
+	if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
 	    (!(dev->flags & IFF_LOOPBACK) &&
 	     (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
-	     strncmp(dev->name, "dummy", 5));
+	     strncmp(dev->name, "dummy", 5)))
+		ret = true;
+	if (p)
+		*p = '.';
+	return ret;
+}
+
+#ifdef CONFIG_VLAN_8021Q
+int register_vlan_device(struct net_device *real_dev, u16 vlan_id);
+
+static void __init prepare_vlan(void)
+{
+	unsigned short oflags;
+	struct net_device *dev;
+	char *p;
+	u16 vid;
+
+	if (!strchr(user_dev_name, '.'))
+		return;
+
+	p = strchr(user_dev_name, '.');
+	*p = 0;
+	vid = simple_strtoul(p + 1, NULL, 10);
+	dev = __dev_get_by_name(&init_net, user_dev_name);
+	if (!dev)
+		goto fail;
+
+	oflags = dev->flags;
+	if (dev_change_flags(dev, oflags | IFF_UP) < 0)
+		goto fail;
+
+	register_vlan_device(dev, vid);
+
+fail:
+	*p = '.';
 }
+#endif
 
 static int __init ic_open_devs(void)
 {
@@ -217,8 +263,13 @@
 			printk(KERN_ERR "IP-Config: Failed to open %s\n", dev->name);
 	}
 
+#ifdef CONFIG_VLAN_8021Q
+	/* register vlan device if needed */
+	prepare_vlan();
+#endif
+
 	for_each_netdev(&init_net, dev) {
-		if (ic_is_init_dev(dev)) {
+		if (ic_is_init_dev(dev, false)) {
 			int able = 0;
 			if (dev->mtu >= 364)
 				able |= IC_BOOTP;
@@ -261,7 +312,7 @@
 	start = jiffies;
 	while (jiffies - start < msecs_to_jiffies(CONF_CARRIER_TIMEOUT)) {
 		for_each_netdev(&init_net, dev)
-			if (ic_is_init_dev(dev) && netif_carrier_ok(dev))
+			if (ic_is_init_dev(dev, false) && netif_carrier_ok(dev))
 				goto have_carrier;
 
 		msleep(1);
@@ -688,8 +739,10 @@
 			e += len;
 		}
 		if (*vendor_class_identifier) {
+#ifdef IPCONFIG_DEBUG
 			printk(KERN_INFO "DHCP: sending class identifier \"%s\"\n",
 			       vendor_class_identifier);
+#endif
 			*e++ = 60;	/* Class-identifier */
 			len = strlen(vendor_class_identifier);
 			*e++ = len;
@@ -1348,7 +1401,7 @@
 
 		rtnl_lock();
 		for_each_netdev(&init_net, dev) {
-			if (ic_is_init_dev(dev)) {
+			if (ic_is_init_dev(dev, true)) {
 				found = 1;
 				break;
 			}
diff -ruw linux-3.2.24/net/ipv4/ip_input.c linux-3.2.24-fbx/net/ipv4/ip_input.c
--- linux-3.2.24/net/ipv4/ip_input.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/ipv4/ip_input.c	2013-06-13 15:06:43.142516949 +0200
@@ -185,10 +185,15 @@
 	return 0;
 }
 
-static int ip_local_deliver_finish(struct sk_buff *skb)
+int ip_local_deliver_finish(struct sk_buff *skb)
 {
 	struct net *net = dev_net(skb->dev);
 
+#ifdef CONFIG_IP_FFN
+	if (skb->ffn_state == FFN_STATE_FORWARDABLE)
+		ip_ffn_add(skb, IP_FFN_LOCAL_IN);
+#endif
+
 	__skb_pull(skb, ip_hdrlen(skb));
 
 	/* Point into the IP datagram, just past the header. */
@@ -434,6 +439,11 @@
 		goto drop;
 	}
 
+#ifdef CONFIG_IP_FFN
+	if (!ip_ffn_process(skb))
+		return NET_RX_SUCCESS;
+#endif
+
 	/* Remove any debris in the socket control block */
 	memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
 
diff -ruw linux-3.2.24/net/ipv4/ip_output.c linux-3.2.24-fbx/net/ipv4/ip_output.c
--- linux-3.2.24/net/ipv4/ip_output.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/ipv4/ip_output.c	2013-06-13 15:06:43.142516949 +0200
@@ -205,6 +205,11 @@
 		skb = skb2;
 	}
 
+#ifdef CONFIG_IP_FFN
+	if (skb->ffn_state == FFN_STATE_FORWARDABLE)
+		ip_ffn_add(skb, IP_FFN_FINISH_OUT);
+#endif
+
 	rcu_read_lock();
 	neigh = dst_get_neighbour(dst);
 	if (neigh) {
@@ -314,6 +319,11 @@
 	skb->dev = dev;
 	skb->protocol = htons(ETH_P_IP);
 
+#ifdef CONFIG_IP_FFN
+	if (skb->ffn_state == FFN_STATE_FAST_FORWARDED)
+		return ip_finish_output(skb);
+#endif
+
 	return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL, dev,
 			    ip_finish_output,
 			    !(IPCB(skb)->flags & IPSKB_REROUTED));
@@ -1534,4 +1544,7 @@
 #if defined(CONFIG_IP_MULTICAST) && defined(CONFIG_PROC_FS)
 	igmp_mc_proc_init();
 #endif
+#ifdef CONFIG_IP_FFN
+	ip_ffn_init();
+#endif
 }
diff -ruw linux-3.2.24/net/ipv4/Kconfig linux-3.2.24-fbx/net/ipv4/Kconfig
--- linux-3.2.24/net/ipv4/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/ipv4/Kconfig	2013-06-13 15:06:43.138516952 +0200
@@ -312,6 +312,11 @@
 
 	  If unsure, say N.
 
+config INET_XFRM_GC_THRESH
+	int "IP: xfrm garbage collect threshold"
+	depends on XFRM
+	default 1024
+
 config INET_AH
 	tristate "IP: AH transformation"
 	select XFRM
diff -ruw linux-3.2.24/net/ipv4/Makefile linux-3.2.24-fbx/net/ipv4/Makefile
--- linux-3.2.24/net/ipv4/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/ipv4/Makefile	2013-06-13 15:06:43.138516952 +0200
@@ -14,6 +14,8 @@
 	     inet_fragment.o ping.o
 
 obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
+
+obj-$(CONFIG_IP_FFN) += ip_ffn.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
 obj-$(CONFIG_IP_MROUTE) += ipmr.o
diff -ruw linux-3.2.24/net/ipv4/netfilter/ip_tables.c linux-3.2.24-fbx/net/ipv4/netfilter/ip_tables.c
--- linux-3.2.24/net/ipv4/netfilter/ip_tables.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/ipv4/netfilter/ip_tables.c	2013-06-13 15:06:43.146516946 +0200
@@ -1281,6 +1281,10 @@
 			   tmp.num_counters, tmp.counters);
 	if (ret)
 		goto free_newinfo_untrans;
+
+#ifdef CONFIG_IP_FFN
+	ip_ffn_flush_all();
+#endif
 	return 0;
 
  free_newinfo_untrans:
diff -ruw linux-3.2.24/net/ipv4/netfilter/Kconfig linux-3.2.24-fbx/net/ipv4/netfilter/Kconfig
--- linux-3.2.24/net/ipv4/netfilter/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/ipv4/netfilter/Kconfig	2013-06-13 15:06:43.146516946 +0200
@@ -5,6 +5,13 @@
 menu "IP: Netfilter Configuration"
 	depends on INET && NETFILTER
 
+config IP_FFN
+	bool "IP: Fast forwarding and NAT"
+
+config IP_FFN_PROCFS
+	bool "IP: Fast forwarding and NAT /proc/net entries"
+	depends on IP_FFN
+
 config NF_DEFRAG_IPV4
 	tristate
 	default n
diff -ruw linux-3.2.24/net/ipv4/tcp_input.c linux-3.2.24-fbx/net/ipv4/tcp_input.c
--- linux-3.2.24/net/ipv4/tcp_input.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/ipv4/tcp_input.c	2013-06-13 15:52:31.225197888 +0200
@@ -5838,6 +5838,7 @@
 		if (th->syn) {
 			if (th->fin)
 				goto discard;
+
 			if (icsk->icsk_af_ops->conn_request(sk, skb) < 0)
 				return 1;
 
diff -ruw linux-3.2.24/net/ipv4/xfrm4_policy.c linux-3.2.24-fbx/net/ipv4/xfrm4_policy.c
--- linux-3.2.24/net/ipv4/xfrm4_policy.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/ipv4/xfrm4_policy.c	2013-06-13 15:06:43.166516938 +0200
@@ -236,7 +236,7 @@
 	.destroy =		xfrm4_dst_destroy,
 	.ifdown =		xfrm4_dst_ifdown,
 	.local_out =		__ip_local_out,
-	.gc_thresh =		1024,
+	.gc_thresh =		CONFIG_INET_XFRM_GC_THRESH,
 };
 
 static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
diff -ruw linux-3.2.24/net/ipv6/Kconfig linux-3.2.24-fbx/net/ipv6/Kconfig
--- linux-3.2.24/net/ipv6/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/ipv6/Kconfig	2013-06-13 15:06:43.166516938 +0200
@@ -192,6 +192,11 @@
 config IPV6_NDISC_NODETYPE
 	bool
 
+config IPV6_SIT_FBX6TO4
+	bool "sit support Freebox 6to4 scheme"
+	depends on IPV6_SIT
+	default n
+
 config IPV6_TUNNEL
 	tristate "IPv6: IP-in-IPv6 tunnel (RFC2473)"
 	select INET6_TUNNEL
diff -ruw linux-3.2.24/net/Kconfig linux-3.2.24-fbx/net/Kconfig
--- linux-3.2.24/net/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/Kconfig	2013-06-13 15:06:43.078516980 +0200
@@ -45,6 +45,23 @@
 
 menu "Networking options"
 
+config NETSKBPAD
+	int "Size reserved by dev_alloc_skb"
+	default 16
+
+config NETRXTHREAD
+	bool "Do rx network processing in kernel thread"
+
+config NETRXTHREAD_RX_QUEUE
+	int "Number of rx queues"
+	default 1
+	depends on NETRXTHREAD
+
+config NETRXTHREAD_MAX_PROCESS
+	int "Maximum number of packet to process before schedule"
+	default 4
+	depends on NETRXTHREAD
+
 source "net/packet/Kconfig"
 source "net/unix/Kconfig"
 source "net/xfrm/Kconfig"
@@ -197,6 +214,8 @@
 source "net/tipc/Kconfig"
 source "net/atm/Kconfig"
 source "net/l2tp/Kconfig"
+source "net/fbxatm/Kconfig"
+source "net/fbxbridge/Kconfig"
 source "net/802/Kconfig"
 source "net/bridge/Kconfig"
 source "net/dsa/Kconfig"
diff -ruw linux-3.2.24/net/Makefile linux-3.2.24-fbx/net/Makefile
--- linux-3.2.24/net/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/Makefile	2013-06-13 15:06:43.078516980 +0200
@@ -39,6 +39,12 @@
 obj-$(CONFIG_AF_RXRPC)		+= rxrpc/
 obj-$(CONFIG_ATM)		+= atm/
 obj-$(CONFIG_L2TP)		+= l2tp/
+ifneq ($(CONFIG_FBXATM),)
+obj-y				+= fbxatm/
+endif
+ifneq ($(CONFIG_FBXBRIDGE),)
+obj-y				+= fbxbridge/
+endif
 obj-$(CONFIG_DECNET)		+= decnet/
 obj-$(CONFIG_ECONET)		+= econet/
 obj-$(CONFIG_PHONET)		+= phonet/
diff -ruw linux-3.2.24/net/netfilter/core.c linux-3.2.24-fbx/net/netfilter/core.c
--- linux-3.2.24/net/netfilter/core.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/netfilter/core.c	2013-06-13 15:06:43.202516921 +0200
@@ -151,7 +151,7 @@
 	}
 	return NF_ACCEPT;
 }
-
+EXPORT_SYMBOL(nf_iterate);
 
 /* Returns 1 if okfn() needs to be executed by the caller,
  * -EPERM for NF_DROP, 0 otherwise. */
diff -ruw linux-3.2.24/net/netfilter/nf_conntrack_core.c linux-3.2.24-fbx/net/netfilter/nf_conntrack_core.c
--- linux-3.2.24/net/netfilter/nf_conntrack_core.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/netfilter/nf_conntrack_core.c	2013-06-13 15:06:43.206516919 +0200
@@ -185,6 +185,10 @@
 	nf_ct_remove_expectations(ct);
 }
 
+#ifdef CONFIG_IP_FFN
+extern void ip_ffn_ct_destroy(struct nf_conn *ct);
+#endif
+
 static void
 destroy_conntrack(struct nf_conntrack *nfct)
 {
@@ -196,6 +200,10 @@
 	NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
 	NF_CT_ASSERT(!timer_pending(&ct->timeout));
 
+#ifdef CONFIG_IP_FFN
+	ip_ffn_ct_destroy(ct);
+#endif
+
 	/* To make sure we don't get any weird locking issues here:
 	 * destroy_conntrack() MUST NOT be called with a write lock
 	 * to nf_conntrack_lock!!! -HW */
diff -ruw linux-3.2.24/net/netfilter/nf_conntrack_proto_tcp.c linux-3.2.24-fbx/net/netfilter/nf_conntrack_proto_tcp.c
--- linux-3.2.24/net/netfilter/nf_conntrack_proto_tcp.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/netfilter/nf_conntrack_proto_tcp.c	2013-06-13 15:06:43.210516916 +0200
@@ -1052,6 +1052,17 @@
 	return NF_ACCEPT;
 }
 
+#ifdef CONFIG_IP_FFN
+int external_tcpv4_packet(struct nf_conn *ct,
+			  const struct sk_buff *skb,
+			  unsigned int dataoff,
+			  enum ip_conntrack_info ctinfo)
+{
+	return tcp_packet(ct, skb, dataoff, ctinfo, AF_INET, 0);
+}
+#endif
+
+
 /* Called when a new connection for this protocol found. */
 static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
 		    unsigned int dataoff)
diff -ruw linux-3.2.24/net/netfilter/nf_conntrack_proto_udp.c linux-3.2.24-fbx/net/netfilter/nf_conntrack_proto_udp.c
--- linux-3.2.24/net/netfilter/nf_conntrack_proto_udp.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/netfilter/nf_conntrack_proto_udp.c	2013-06-13 15:06:43.210516916 +0200
@@ -84,6 +84,16 @@
 	return NF_ACCEPT;
 }
 
+#ifdef CONFIG_IP_FFN
+int external_udpv4_packet(struct nf_conn *ct,
+			  const struct sk_buff *skb,
+			  unsigned int dataoff,
+			  enum ip_conntrack_info ctinfo)
+{
+	return udp_packet(ct, skb, dataoff, ctinfo, AF_INET, 0);
+}
+#endif
+
 /* Called when a new connection for this protocol found. */
 static bool udp_new(struct nf_conn *ct, const struct sk_buff *skb,
 		    unsigned int dataoff)
diff -ruw linux-3.2.24/net/netfilter/xt_owner.c linux-3.2.24-fbx/net/netfilter/xt_owner.c
--- linux-3.2.24/net/netfilter/xt_owner.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/netfilter/xt_owner.c	2011-11-04 14:26:12.463894897 +0100
@@ -17,6 +17,62 @@
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_owner.h>
 
+static int __owner_match_simple_gid(gid_t gid,
+				    const struct xt_owner_match_info *info)
+{
+	if (gid >= info->gid_min && gid <= info->gid_max)
+		return 1;
+	return 0;
+}
+
+/*
+ * see kernel/groups.c:groups_to_user() function, which inspired the
+ * content of this function.
+ */
+static int __owner_match_gid_groupinfo(const struct group_info *group_info,
+				       const struct xt_owner_match_info *info)
+{
+	unsigned int count = group_info->ngroups;
+	unsigned int block;
+
+	for (block = 0; block < group_info->nblocks; ++block) {
+		unsigned int cp_count = min(NGROUPS_PER_BLOCK, count);
+		unsigned int i;
+
+		for (i = 0; i < cp_count; ++i) {
+			if (__owner_match_simple_gid(
+					     group_info->blocks[block][i],
+					     info)) {
+				return 1;
+			}
+			count -= cp_count;
+		}
+	}
+	return 0;
+}
+
+static int owner_match_gid(const struct file *filp,
+			   const struct xt_owner_match_info *info)
+{
+	struct task_struct *p;
+
+	/*
+	 * direct match, this is the simple and only case handled by
+	 * the old code, file fsgid matches info gid range.
+	 */
+	if (__owner_match_simple_gid(filp->f_cred->fsgid, info))
+		return 1;
+
+	/*
+	 * otherwise we need to have a look to the group list available
+	 * in f_cred->group_info.
+	 */
+	if (__owner_match_gid_groupinfo(filp->f_cred->group_info, info))
+		return 1;
+
+	return 0;
+}
+
 static bool
 owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
 {
@@ -44,8 +100,7 @@
 			return false;
 
 	if (info->match & XT_OWNER_GID)
-		if ((filp->f_cred->fsgid >= info->gid_min &&
-		    filp->f_cred->fsgid <= info->gid_max) ^
+		if (owner_match_gid(filp, info) ^
 		    !(info->invert & XT_OWNER_GID))
 			return false;
 
diff -ruw linux-3.2.24/net/socket.c linux-3.2.24-fbx/net/socket.c
--- linux-3.2.24/net/socket.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/socket.c	2013-06-13 15:52:31.257197873 +0200
@@ -962,6 +962,31 @@
 	return err;
 }
 
+static DEFINE_MUTEX(fbxdiverter_ioctl_mutex);
+static int (*fbxdiverter_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg) = NULL;
+
+void fbxdiverter_ioctl_set(int (*hook) (struct net *, unsigned int,
+					void __user *))
+{
+	mutex_lock(&fbxdiverter_ioctl_mutex);
+	fbxdiverter_ioctl_hook = hook;
+	mutex_unlock(&fbxdiverter_ioctl_mutex);
+}
+
+EXPORT_SYMBOL(fbxdiverter_ioctl_set);
+
+static DEFINE_MUTEX(fbxbridge_ioctl_mutex);
+static int (*fbxbridge_ioctl_hook)(struct net *, unsigned int cmd, void __user *arg) = NULL;
+
+void fbxbridge_set(int (*hook)(struct net *, unsigned int, void __user *))
+{
+	mutex_lock(&fbxbridge_ioctl_mutex);
+	fbxbridge_ioctl_hook = hook;
+	mutex_unlock(&fbxbridge_ioctl_mutex);
+}
+
+EXPORT_SYMBOL(fbxbridge_set);
+
 /*
  *	With an ioctl, arg may well be a user mode pointer, but we don't know
  *	what to do with it - that's up to the protocol still.
@@ -1034,6 +1059,28 @@
 				err = dlci_ioctl_hook(cmd, argp);
 			mutex_unlock(&dlci_ioctl_mutex);
 			break;
+		case SIOCGFBXDIVERT:
+		case SIOCSFBXDIVERT:
+			err = -ENOPKG;
+			if (!fbxdiverter_ioctl_hook)
+				request_module("fbxdiverter");
+
+			mutex_lock(&fbxdiverter_ioctl_mutex);
+			if (fbxdiverter_ioctl_hook)
+				err = fbxdiverter_ioctl_hook(net, cmd, argp);
+			mutex_unlock(&fbxdiverter_ioctl_mutex);
+			break;
+		case SIOCGFBXBRIDGE:
+		case SIOCSFBXBRIDGE:
+			err = -ENOPKG;
+			if (!fbxbridge_ioctl_hook)
+				request_module("fbxbridge");
+
+			mutex_lock(&fbxbridge_ioctl_mutex);
+			if (fbxbridge_ioctl_hook)
+				err = fbxbridge_ioctl_hook(net, cmd, argp);
+			mutex_unlock(&fbxbridge_ioctl_mutex);
+			break;
 		default:
 			err = sock_do_ioctl(net, sock, cmd, arg);
 			break;
diff -ruw linux-3.2.24/net/sysctl_net.c linux-3.2.24-fbx/net/sysctl_net.c
--- linux-3.2.24/net/sysctl_net.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/net/sysctl_net.c	2013-06-13 15:06:43.250516897 +0200
@@ -51,7 +51,9 @@
 		int mode = (table->mode >> 6) & 7;
 		return (mode << 6) | (mode << 3) | mode;
 	}
-	return table->mode;
+
+	/* read-only otherwise */
+	return table->mode & ~0222;
 }
 
 static struct ctl_table_root net_sysctl_root = {
diff -ruw linux-3.2.24/security/commoncap.c linux-3.2.24-fbx/security/commoncap.c
--- linux-3.2.24/security/commoncap.c	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/security/commoncap.c	2013-06-13 15:52:31.273197865 +0200
@@ -521,14 +521,17 @@
 
 
 	/* Don't let someone trace a set[ug]id/setpcap binary with the revised
-	 * credentials unless they have the appropriate permit
+	 * credentials unless they have the appropriate permit.
+	 *
+	 * In addition, if NO_NEW_PRIVS, then ensure we get no new privs.
 	 */
 	if ((new->euid != old->uid ||
 	     new->egid != old->gid ||
 	     !cap_issubset(new->cap_permitted, old->cap_permitted)) &&
 	    bprm->unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
 		/* downgrade; they get no more than they had, and maybe less */
-		if (!capable(CAP_SETUID)) {
+		if (!capable(CAP_SETUID) ||
+		    (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) {
 			new->euid = new->uid;
 			new->egid = new->gid;
 		}
diff -ruw linux-3.2.24/security/Kconfig linux-3.2.24-fbx/security/Kconfig
--- linux-3.2.24/security/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/security/Kconfig	2013-06-13 15:06:43.278516884 +0200
@@ -187,6 +187,7 @@
 source security/smack/Kconfig
 source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
+source security/fbxlsmjail/Kconfig
 
 source security/integrity/Kconfig
 
diff -ruw linux-3.2.24/security/Makefile linux-3.2.24-fbx/security/Makefile
--- linux-3.2.24/security/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/security/Makefile	2013-06-13 15:06:43.278516884 +0200
@@ -7,6 +7,7 @@
 subdir-$(CONFIG_SECURITY_SMACK)		+= smack
 subdir-$(CONFIG_SECURITY_TOMOYO)        += tomoyo
 subdir-$(CONFIG_SECURITY_APPARMOR)	+= apparmor
+subdir-$(CONFIG_SECURITY_FBXLSMJAIL)	+= fbxlsmjail
 
 # always enable default capabilities
 obj-y					+= commoncap.o
@@ -21,6 +22,7 @@
 obj-$(CONFIG_AUDIT)			+= lsm_audit.o
 obj-$(CONFIG_SECURITY_TOMOYO)		+= tomoyo/built-in.o
 obj-$(CONFIG_SECURITY_APPARMOR)		+= apparmor/built-in.o
+obj-$(CONFIG_SECURITY_FBXLSMJAIL)	+= fbxlsmjail/built-in.o
 obj-$(CONFIG_CGROUP_DEVICE)		+= device_cgroup.o
 
 # Object integrity file lists
diff -ruw linux-3.2.24/sound/soc/codecs/Kconfig linux-3.2.24-fbx/sound/soc/codecs/Kconfig
--- linux-3.2.24/sound/soc/codecs/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/sound/soc/codecs/Kconfig	2013-06-13 15:52:31.293197855 +0200
@@ -28,6 +28,7 @@
 	select SND_SOC_ALC5623 if I2C
 	select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
 	select SND_SOC_CS42L51 if I2C
+	select SND_SOC_CS42L52 if I2C
 	select SND_SOC_CS4270 if I2C
 	select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
 	select SND_SOC_CX20442
@@ -175,6 +176,9 @@
 config SND_SOC_CS42L51
 	tristate
 
+config SND_SOC_CS42L52
+	tristate
+
 # Cirrus Logic CS4270 Codec
 config SND_SOC_CS4270
 	tristate
diff -ruw linux-3.2.24/sound/soc/codecs/Makefile linux-3.2.24-fbx/sound/soc/codecs/Makefile
--- linux-3.2.24/sound/soc/codecs/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/sound/soc/codecs/Makefile	2013-06-13 15:52:31.293197855 +0200
@@ -15,6 +15,7 @@
 snd-soc-ak4671-objs := ak4671.o
 snd-soc-cq93vc-objs := cq93vc.o
 snd-soc-cs42l51-objs := cs42l51.o
+snd-soc-cs42l52-objs := cs42l52.o
 snd-soc-cs4270-objs := cs4270.o
 snd-soc-cs4271-objs := cs4271.o
 snd-soc-cx20442-objs := cx20442.o
@@ -115,6 +116,7 @@
 obj-$(CONFIG_SND_SOC_ALC5623)    += snd-soc-alc5623.o
 obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
 obj-$(CONFIG_SND_SOC_CS42L51)	+= snd-soc-cs42l51.o
+obj-$(CONFIG_SND_SOC_CS42L52)	+= snd-soc-cs42l52.o
 obj-$(CONFIG_SND_SOC_CS4270)	+= snd-soc-cs4270.o
 obj-$(CONFIG_SND_SOC_CS4271)	+= snd-soc-cs4271.o
 obj-$(CONFIG_SND_SOC_CX20442)	+= snd-soc-cx20442.o
diff -ruw linux-3.2.24/sound/soc/kirkwood/Kconfig linux-3.2.24-fbx/sound/soc/kirkwood/Kconfig
--- linux-3.2.24/sound/soc/kirkwood/Kconfig	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/sound/soc/kirkwood/Kconfig	2013-06-13 15:52:31.301197852 +0200
@@ -28,3 +28,15 @@
 	  Say Y if you want to add support for SoC audio on
 	  the HP t5325 thin client.
 
+
+config SND_KIRKWOOD_RD88F6282A
+	tristate "SoC Audio support for RD-88F6282-A"
+	depends on SND_KIRKWOOD_SOC && MACH_RD88F6282A
+	select SND_KIRKWOOD_SOC_I2S
+	select SND_SOC_CS42L51
+
+config SND_KIRKWOOD_SOC_FBXGW2R
+	tristate "Soc Audio support for fbxgw2r"
+	depends on SND_KIRKWOOD_SOC && MACH_FBXGW2R && I2C
+	select SND_KIRKWOOD_SOC_I2S
+	select SND_SOC_CS42L52
diff -ruw linux-3.2.24/sound/soc/kirkwood/Makefile linux-3.2.24-fbx/sound/soc/kirkwood/Makefile
--- linux-3.2.24/sound/soc/kirkwood/Makefile	2012-07-25 05:11:50.000000000 +0200
+++ linux-3.2.24-fbx/sound/soc/kirkwood/Makefile	2013-06-13 15:52:31.301197852 +0200
@@ -6,6 +6,11 @@
 
 snd-soc-openrd-objs := kirkwood-openrd.o
 snd-soc-t5325-objs := kirkwood-t5325.o
+snd-soc-rd88f6282a-objs := kirkwood-rd88f6282a.o
+snd-soc-fbxgw2r-objs := kirkwood-fbxgw2r.o
 
 obj-$(CONFIG_SND_KIRKWOOD_SOC_OPENRD) += snd-soc-openrd.o
 obj-$(CONFIG_SND_KIRKWOOD_SOC_T5325) += snd-soc-t5325.o
+
+obj-$(CONFIG_SND_KIRKWOOD_RD88F6282A) += snd-soc-rd88f6282a.o
+obj-$(CONFIG_SND_KIRKWOOD_SOC_FBXGW2R) += snd-soc-fbxgw2r.o
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/arch/x86/kernel/fbxbootinfo.c	2011-01-06 02:17:50.582153704 +0100
@@ -0,0 +1,42 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fbxbootinfo.h>
+#include <linux/init.h>
+
+#include <asm/bootparam.h>
+
+static struct fbx_bootinfo fbx_bootinfo;
+
+u32 loader_bank_number;
+EXPORT_SYMBOL(loader_bank_number);
+
+char loader_version_str[128];
+EXPORT_SYMBOL(loader_version_str);
+
+u32 loader_bank0_forced;
+EXPORT_SYMBOL(loader_bank0_forced);
+
+char cefdk_version_str[256];
+EXPORT_SYMBOL(cefdk_version_str);
+
+void __init parse_fbxbootinfo(struct setup_data *data)
+{
+	if (data->len != sizeof (fbx_bootinfo)) {
+		printk(KERN_ERR "%s: invalid length: "
+		       "have %i, want %i\n", __func__, data->len,
+			sizeof (fbx_bootinfo));
+	}
+	memcpy(&fbx_bootinfo, data->data, data->len);
+
+	loader_bank_number = fbx_bootinfo.bank_number;
+	memcpy(&loader_version_str, &fbx_bootinfo.uboot_version_str,
+				sizeof(loader_version_str));
+	loader_bank0_forced = fbx_bootinfo.bank0_forced;
+	memcpy(&cefdk_version_str, &fbx_bootinfo.cefdk_version_str,
+				sizeof(cefdk_version_str));
+}
+
+const struct fbx_bootinfo *arch_get_fbxbootinfo(void)
+{
+	return &fbx_bootinfo;
+}
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/arch/x86/kernel/fbxserial.c	2011-11-04 14:26:06.491888712 +0100
@@ -0,0 +1,51 @@
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fbxserial.h>
+#include <linux/init.h>
+#include <linux/random.h>
+
+#include <asm/bootparam.h>
+
+static struct fbx_serial serial_info;
+static int parse_done;
+
+void __init parse_fbxserial_ext(struct setup_data *data)
+{
+	if (data->len != sizeof (serial_info)) {
+		printk(KERN_ERR "parse_fbxserial_ext: invalid length: "
+		       "have %i, want %i\n", data->len, sizeof (serial_info));
+	}
+	fbxserialinfo_read(data->data, &serial_info);
+	parse_done = 1;
+}
+
+static int __init fbxserial_parse_check(void)
+{
+	if (!parse_done) {
+		/*
+		 * just setup magic and crc with bogus values.
+		 */
+		u32 bad_serial[sizeof (struct fbx_serial) / sizeof (u32)] =
+			{ 0xaa55aa55, 0xaa55aa55 };
+
+		/*
+		 * feed serial info deliberately with bad data to
+		 * enforce default settings.
+		 */
+		printk(KERN_ERR "parse_fbxserial_ext was not called. "
+		       "please fix/update your bootloader.\n");
+		fbxserialinfo_read(bad_serial, &serial_info);
+	}
+
+	return 0;
+}
+arch_initcall(fbxserial_parse_check);
+
+
+const struct fbx_serial *arch_get_fbxserial(void)
+{
+	return &serial_info;
+}
+
+EXPORT_SYMBOL(arch_get_fbxserial);
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/arch/x86/platform/ce4100/fbx6hd.dts	2013-06-13 15:52:30.193198383 +0200
@@ -0,0 +1,459 @@
+/*
+ * CE4100 on Falcon Falls
+ *
+ * (c) Copyright 2010 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ */
+/dts-v1/;
+/ {
+	model = "freebox,Freebox v6";
+	compatible = "intel,falconfalls";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "intel,ce4100";
+			reg = <0>;
+			lapic = <&lapic0>;
+		};
+	};
+
+	remoti: ti,cc2530@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "ti,remoti";
+		reset-gpio = <100 0>;	// gpio, polarity
+		id = <0>;
+
+		gpio@0 {
+			compatible = "ti,remoti-gpio";
+			gpios = <200 3>;	// base, number
+			#gpio-cells = <2>;
+			gpio-controller;
+		};
+
+		leds@1 {
+			compatible = "ti,remoti-leds";
+
+			rf-activity@0 {
+				label = "rf_activity:blue";
+			};
+
+			rf-pairing@1 {
+				label = "rf_pairing:red";
+			};
+		};
+
+		hdmi-cec@2 {
+			compatible = "ti,remoti-cec";
+		};
+	};
+
+	soc@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "intel,ce4100-cp";
+		ranges;
+
+		ioapic1: interrupt-controller@fec00000 {
+			#interrupt-cells = <2>;
+			compatible = "intel,ce4100-ioapic";
+			interrupt-controller;
+			reg = <0xfec00000 0x1000>;
+		};
+
+		timer@fed00000 {
+			compatible = "intel,ce4100-hpet";
+			reg = <0xfed00000 0x200>;
+		};
+
+		lapic0: interrupt-controller@fee00000 {
+			compatible = "intel,ce4100-lapic";
+			reg = <0xfee00000 0x1000>;
+		};
+
+		pci@3fc {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			compatible = "intel,ce4100-pci", "pci";
+			device_type = "pci";
+			bus-range = <0 0>;
+			ranges = <0x2000000 0 0xbffff000 0xbffff000 0 0x1000
+				  0x2000000 0 0xdffe0000 0xdffe0000 0 0x1000
+				  0x0000000 0 0x0	 0x0	    0 0x100>;
+
+			/* Secondary IO-APIC */
+			ioapic2: interrupt-controller@0,1 {
+				#interrupt-cells = <2>;
+				compatible = "intel,ce4100-ioapic";
+				interrupt-controller;
+				reg = <0x100 0x0 0x0 0x0 0x0>;
+				assigned-addresses = <0x02000000 0x0 0xbffff000 0x0 0x1000>;
+			};
+
+			pci@1,0 {
+				#address-cells = <3>;
+				#size-cells = <2>;
+				compatible = "intel,ce4100-pci", "pci";
+				device_type = "pci";
+				bus-range = <1 1>;
+				reg = <0x0800 0x0 0x0 0x0 0x0>;
+				ranges = <0x2000000 0 0xdffe0000 0x2000000 0 0xdffe0000 0 0x1000>;
+
+				interrupt-parent = <&ioapic2>;
+
+				display@2,0 {
+					compatible = "pci8086,2e5b.2",
+						   "pci8086,2e5b",
+						   "pciclass038000",
+						   "pciclass0380";
+
+					reg = <0x11000 0x0 0x0 0x0 0x0>;
+					interrupts = <0 1>;
+				};
+
+				multimedia@3,0 {
+					compatible = "pci8086,2e5c.2",
+						   "pci8086,2e5c",
+						   "pciclass048000",
+						   "pciclass0480";
+
+					reg = <0x11800 0x0 0x0 0x0 0x0>;
+					interrupts = <2 1>;
+				};
+
+				multimedia@4,0 {
+					compatible = "pci8086,2e5d.2",
+						   "pci8086,2e5d",
+						   "pciclass048000",
+						   "pciclass0480";
+
+					reg = <0x12000 0x0 0x0 0x0 0x0>;
+					interrupts = <4 1>;
+				};
+
+				multimedia@4,1 {
+					compatible = "pci8086,2e5e.2",
+						   "pci8086,2e5e",
+						   "pciclass048000",
+						   "pciclass0480";
+
+					reg = <0x12100 0x0 0x0 0x0 0x0>;
+					interrupts = <5 1>;
+				};
+
+				sound@6,0 {
+					compatible = "pci8086,2e5f.2",
+						   "pci8086,2e5f",
+						   "pciclass040100",
+						   "pciclass0401";
+
+					reg = <0x13000 0x0 0x0 0x0 0x0>;
+					interrupts = <6 1>;
+				};
+
+				sound@6,1 {
+					compatible = "pci8086,2e5f.2",
+						   "pci8086,2e5f",
+						   "pciclass040100",
+						   "pciclass0401";
+
+					reg = <0x13100 0x0 0x0 0x0 0x0>;
+					interrupts = <7 1>;
+				};
+
+				sound@6,2 {
+					compatible = "pci8086,2e60.2",
+						   "pci8086,2e60",
+						   "pciclass040100",
+						   "pciclass0401";
+
+					reg = <0x13200 0x0 0x0 0x0 0x0>;
+					interrupts = <8 1>;
+				};
+
+				display@8,0 {
+					compatible = "pci8086,2e61.2",
+						   "pci8086,2e61",
+						   "pciclass038000",
+						   "pciclass0380";
+
+					reg = <0x14000 0x0 0x0 0x0 0x0>;
+					interrupts = <9 1>;
+				};
+
+				display@8,1 {
+					compatible = "pci8086,2e62.2",
+						   "pci8086,2e62",
+						   "pciclass038000",
+						   "pciclass0380";
+
+					reg = <0x14100 0x0 0x0 0x0 0x0>;
+					interrupts = <10 1>;
+				};
+
+				multimedia@8,2 {
+					compatible = "pci8086,2e63.2",
+						   "pci8086,2e63",
+						   "pciclass048000",
+						   "pciclass0480";
+
+					reg = <0x14200 0x0 0x0 0x0 0x0>;
+					interrupts = <11 1>;
+				};
+
+				entertainment-encryption@9,0 {
+					compatible = "pci8086,2e64.2",
+						   "pci8086,2e64",
+						   "pciclass101000",
+						   "pciclass1010";
+
+					reg = <0x14800 0x0 0x0 0x0 0x0>;
+					interrupts = <12 1>;
+				};
+
+				localbus@a,0 {
+					compatible = "pci8086,2e65.2",
+						   "pci8086,2e65",
+						   "pciclassff0000",
+						   "pciclassff00";
+
+					reg = <0x15000 0x0 0x0 0x0 0x0>;
+				};
+
+				serial@b,0 {
+					compatible = "pci8086,2e66.2",
+						   "pci8086,2e66",
+						   "pciclass070003",
+						   "pciclass0700";
+
+					reg = <0x15800 0x0 0x0 0x0 0x0>;
+					interrupts = <14 1>;
+				};
+
+				gpio@b,1 {
+					compatible = "pci8086,2e67.2",
+						   "pci8086,2e67",
+						   "pciclassff0000",
+						   "pciclassff00";
+
+					#gpio-cells = <2>;
+					reg = <0x15900 0x0 0x0 0x0 0x0>;
+					interrupts = <15 1>;
+					gpio-controller;
+				};
+
+				i2c-controller@b,2 {
+					#address-cells = <2>;
+					#size-cells = <1>;
+					compatible = "pci8086,2e68.2",
+						   "pci8086,2e68",
+						   "pciclass,ff0000",
+						   "pciclass,ff00";
+
+					reg = <0x15a00 0x0 0x0 0x0 0x0>;
+					interrupts = <16 1>;
+					ranges = <0 0	0x02000000 0 0xdffe0500	0x100
+						  1 0	0x02000000 0 0xdffe0600	0x100
+						  2 0	0x02000000 0 0xdffe0700	0x100>;
+
+					i2c@0 {
+						#address-cells = <1>;
+						#size-cells = <0>;
+						compatible = "intel,ce4100-i2c-controller";
+						reg = <0 0 0x100>;
+					};
+
+					i2c@1 {
+						#address-cells = <1>;
+						#size-cells = <0>;
+						compatible = "intel,ce4100-i2c-controller";
+						reg = <1 0 0x100>;
+					};
+
+					i2c@2 {
+						#address-cells = <1>;
+						#size-cells = <0>;
+						compatible = "intel,ce4100-i2c-controller";
+						reg = <2 0 0x100>;
+
+						pmu@60 {
+							#gpio-cells = <2>;
+							compatible = "freebox,pic16-pmu";
+							reg = <0x60>;
+							gpio-controller;
+						};
+					};
+				};
+
+				smard-card@b,3 {
+					compatible = "pci8086,2e69.2",
+						   "pci8086,2e69",
+						   "pciclass070500",
+						   "pciclass0705";
+
+					reg = <0x15b00 0x0 0x0 0x0 0x0>;
+					interrupts = <15 1>;
+				};
+
+				spi-controller@b,4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible =
+						"pci8086,2e6a.2",
+						"pci8086,2e6a",
+						"pciclass,ff0000",
+						"pciclass,ff00";
+
+					reg = <0x15c00 0x0 0x0 0x0 0x0>;
+					interrupts = <15 1>;
+
+					dac@0 {
+						compatible = "ti,pcm1755";
+						reg = <0>;
+						spi-max-frequency = <115200>;
+					};
+
+					dac@1 {
+						compatible = "ti,pcm1609a";
+						reg = <1>;
+						spi-max-frequency = <115200>;
+					};
+
+					eeprom@2 {
+						compatible = "atmel,at93c46";
+						reg = <2>;
+						spi-max-frequency = <115200>;
+					};
+				};
+
+				multimedia@b,7 {
+					compatible = "pci8086,2e6d.2",
+						   "pci8086,2e6d",
+						   "pciclassff0000",
+						   "pciclassff00";
+
+					reg = <0x15f00 0x0 0x0 0x0 0x0>;
+				};
+
+				ethernet@c,0 {
+					compatible = "pci8086,2e6e.2",
+						   "pci8086,2e6e",
+						   "pciclass020000",
+						   "pciclass0200";
+
+					reg = <0x16000 0x0 0x0 0x0 0x0>;
+					interrupts = <21 1>;
+				};
+
+				clock@c,1 {
+					compatible = "pci8086,2e6f.2",
+						   "pci8086,2e6f",
+						   "pciclassff0000",
+						   "pciclassff00";
+
+					reg = <0x16100 0x0 0x0 0x0 0x0>;
+					interrupts = <3 1>;
+				};
+
+				usb@d,0 {
+					compatible = "pci8086,2e70.2",
+						   "pci8086,2e70",
+						   "pciclass0c0320",
+						   "pciclass0c03";
+
+					reg = <0x16800 0x0 0x0 0x0 0x0>;
+					interrupts = <22 1>;
+				};
+
+				usb@d,1 {
+					compatible = "pci8086,2e70.2",
+						   "pci8086,2e70",
+						   "pciclass0c0320",
+						   "pciclass0c03";
+
+					reg = <0x16900 0x0 0x0 0x0 0x0>;
+					interrupts = <22 1>;
+				};
+
+				sata@e,0 {
+					compatible = "pci8086,2e71.0",
+						   "pci8086,2e71",
+						   "pciclass010601",
+						   "pciclass0106";
+
+					reg = <0x17000 0x0 0x0 0x0 0x0>;
+					interrupts = <23 1>;
+				};
+
+				flash@f,0 {
+					compatible = "pci8086,701.1",
+						   "pci8086,701",
+						   "pciclass050100",
+						   "pciclass0501";
+
+					reg = <0x17800 0x0 0x0 0x0 0x0>;
+					interrupts = <13 1>;
+				};
+
+				entertainment-encryption@10,0 {
+					compatible = "pci8086,702.1",
+						   "pci8086,702",
+						   "pciclass101000",
+						   "pciclass1010";
+
+					reg = <0x18000 0x0 0x0 0x0 0x0>;
+				};
+
+				co-processor@11,0 {
+					compatible = "pci8086,703.1",
+						   "pci8086,703",
+						   "pciclass0b4000",
+						   "pciclass0b40";
+
+					reg = <0x18800 0x0 0x0 0x0 0x0>;
+					interrupts = <1 1>;
+				};
+
+				multimedia@12,0 {
+					compatible = "pci8086,704.0",
+						   "pci8086,704",
+						   "pciclass048000",
+						   "pciclass0480";
+
+					reg = <0x19000 0x0 0x0 0x0 0x0>;
+				};
+			};
+
+			isa@1f,0 {
+				#address-cells = <2>;
+				#size-cells = <1>;
+				compatible = "isa";
+				reg = <0xf800 0x0 0x0 0x0 0x0>;
+				ranges = <1 0 0 0 0 0x100>;
+
+				rtc@70 {
+					compatible = "intel,ce4100-rtc", "motorola,mc146818";
+					interrupts = <8 3>;
+					interrupt-parent = <&ioapic1>;
+					ctrl-reg = <2>;
+					freq-reg = <0x26>;
+					reg = <1 0x70 2>;
+				};
+			};
+		};
+	};
+
+	crashzone@3fffe000 {
+		compatible = "fbx,crashzone";
+		reg = <0x3fffe000 0x1000>;
+	};
+};
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/arch/x86/platform/ce4100/i2c-intelce.c	2013-06-13 15:52:30.193198383 +0200
@@ -0,0 +1,456 @@
+/*
+ * i2c driver for Intel CE
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/msr.h>
+
+#define DEBUG
+
+#ifdef DEBUG
+#define DPRINTF(args...)  printk(args)
+#else
+#define DPRINTF(args...)
+#endif
+
+#define ICR             (0x00)
+#define ISR             (0x04)
+#define ISAR            (0x08)
+#define IBMR            (0x10)
+#define IDBR            (0x0C)
+
+#define ICR_START       (1 << 0)           /* start bit */
+#define ICR_STOP        (1 << 1)           /* stop bit */
+#define ICR_ACKNAK      (1 << 2)           /* send ACK(0) or NAK(1) */
+#define ICR_TB          (1 << 3)           /* transfer byte bit */
+#define ICR_MA          (1 << 4)           /* master abort */
+#define ICR_SCLE        (1 << 5)           /* master clock enable */
+#define ICR_IUE         (1 << 6)           /* unit enable */
+#define ICR_GCD         (1 << 7)           /* general call disable */
+#define ICR_ITEIE       (1 << 8)           /* enable tx interrupts */
+#define ICR_IRFIE       (1 << 9)           /* enable rx interrupts */
+#define ICR_BEIE        (1 << 10)          /* enable bus error ints */
+#define ICR_SSDIE       (1 << 11)          /* slave STOP detected int enable */
+#define ICR_ALDIE       (1 << 12)          /* enable arbitration interrupt */
+#define ICR_SADIE       (1 << 13)          /* slave address detected int enable */
+#define ICR_UR          (1 << 14)          /* unit reset */
+#define ICR_FM          (1 << 15)          /* fast mode */
+
+#define ISR_RWM         (1 << 0)           /* read/write mode */
+#define ISR_ACKNAK      (1 << 1)           /* ack/nak status */
+#define ISR_UB          (1 << 2)           /* unit busy */
+#define ISR_IBB         (1 << 3)           /* bus busy */
+#define ISR_SSD         (1 << 4)           /* slave stop detected */
+#define ISR_ALD         (1 << 5)           /* arbitration loss detected */
+#define ISR_ITE         (1 << 6)           /* tx buffer empty */
+#define ISR_IRF         (1 << 7)           /* rx buffer full */
+#define ISR_GCAD        (1 << 8)           /* general call address detected */
+#define ISR_SAD         (1 << 9)           /* slave address detected */
+#define ISR_BED         (1 << 10)          /* bus error no ACK/NAK */
+#define ISR_RESERVED	0xfffff800
+
+#define I2C_WRITE	0
+#define I2C_READ	1
+
+#define I2C_BUS_ADDR	(0xdffe0500)
+#define I2C_BUS1_ADDR	(I2C_BUS_ADDR + 0x100)
+#define I2C_BUS_SIZE	(0x100 - 1)
+
+#define PFX	"CK505: "
+
+static void __iomem *base_addr;
+
+static inline u32 i2c_reg_read(u32 reg)
+{
+	return readl(base_addr + reg);
+}
+
+static inline void i2c_reg_write(u32 val, u32 reg)
+{
+	writel(val, base_addr + reg);
+}
+
+/*
+ * udelay is not working yet, so provide a dummy version
+ * which is sufficent for polling.
+ */
+static u32 ticks_per_usec = 1000;
+
+static inline void __local_udelay(u32 usec)
+{
+	u64 now;
+	u64 end;
+
+	now = __native_read_tsc();
+	end = now + (u64)usec * ticks_per_usec;
+
+	while (__native_read_tsc() < end)
+		;
+}
+
+/*
+ * this is a hardcoded offset, we do not have working PCI right now to
+ * read the address from the PCI config space. (but it would be
+ * cleaner to do so).
+ */
+#define CRBAR_BASE		0xa0000000
+
+/*
+ * inside CRBAR_BASE
+ */
+#define CRBAR_FSB_REG		0x0
+# define FSB_MASK		0x03
+# define FSB_100		0x0
+# define FSB_133		0x1
+# define FSB_166		0x2
+# define FSB_200		0x3
+
+#define CRBAR_STRAP_RATIO_REG	0x14
+# define STRAP_RATIO_MASK	0xf
+
+/*
+ * name guessed from context in intel source code.
+ */
+#define FUSING_RATIO_MSR	0x198
+# define FUSING_RATIO_SHIFT	8
+# define FUSING_RATIO_MASK	0x1f
+
+static void __iomem *crbar_base;
+
+/*
+ * FSB is found inside CRBAR zone.
+ */
+static u32 get_cpu_fsb_mhz(void)
+{
+	u32 fsb_reg;
+
+	fsb_reg = readl(crbar_base + CRBAR_FSB_REG);
+	switch (fsb_reg & FSB_MASK) {
+	case FSB_100:
+		return 100;
+		break;
+	case FSB_133:
+		return 133;
+		break;
+	case FSB_166:
+		return 166;
+		break;
+	case FSB_200:
+		return 200;
+	}
+	/* safe default ? */
+	return 100;
+}
+
+/*
+ * strapped ratio is found on CRBAR zone too.
+ */
+static u32 get_cpu_strap_ratio(void)
+{
+	u32 strap_ratio_reg;
+
+	strap_ratio_reg = readl(crbar_base + CRBAR_STRAP_RATIO_REG);
+	return 21 - (strap_ratio_reg & STRAP_RATIO_MASK);
+}
+
+/*
+ * use MSRs to get fused limit.
+ */
+static u32 get_cpu_fusing_ratio(void)
+{
+	u32 dummy, fusing_ratio_msr;
+
+	rdmsr(FUSING_RATIO_MSR, dummy, fusing_ratio_msr);
+
+	return (fusing_ratio_msr >> FUSING_RATIO_SHIFT) & FUSING_RATIO_MASK;
+
+}
+
+static unsigned long __get_cpu_mhz(void)
+{
+	u32 fsb_mhz;
+	u32 strap_ratio;
+	u32 fusing_ratio;
+	u32 ratio;
+	u32 cpu_mhz;
+
+	crbar_base = early_ioremap(CRBAR_BASE, 0x20);
+	if (!crbar_base) {
+		printk(KERN_ERR "failde to remap CRBAR base\n");
+		return 1200;
+	}
+
+	fsb_mhz = get_cpu_fsb_mhz();
+	strap_ratio = get_cpu_strap_ratio();
+	fusing_ratio = get_cpu_fusing_ratio();
+
+	if (strap_ratio > fusing_ratio) {
+		printk("warning: strap ratio higher than fused ratio, "
+		       "will use fused ratio.\n");
+		ratio = fusing_ratio;
+	} else
+		ratio = strap_ratio;
+
+	cpu_mhz = ratio * fsb_mhz;
+
+	early_iounmap(crbar_base, 0x20);
+
+	return cpu_mhz;
+}
+
+
+static int i2c_hw_init(void)
+{
+	u32 reg = 0;
+	unsigned long cpu_hz;
+
+	/*
+	 * initialize udelay
+	 */
+	cpu_hz = __get_cpu_mhz() * 1000000;
+	ticks_per_usec = cpu_hz / 1000000;
+
+	base_addr = early_ioremap(I2C_BUS1_ADDR, I2C_BUS_SIZE);
+	if (!base_addr) {
+		printk(KERN_ERR PFX "failed to early_ioremap 0x%08x\n", I2C_BUS1_ADDR);
+		return -1;
+	}
+
+	/*
+	 * reset the unit and clear any pending interrupt
+	 */
+	reg |= ICR_UR;
+	i2c_reg_write(reg, ICR);
+	i2c_reg_write(0, ICR);
+	i2c_reg_write(0, ISR);
+
+	/*
+	 * TX empty and RX full interrupts are set automatically
+	 */
+	reg = ICR_IUE | ICR_SCLE | ICR_GCD;
+	i2c_reg_write(reg, ICR);
+	__local_udelay(100);
+
+	return 0;
+}
+
+static void i2c_clear_interrupt(void)
+{
+	u32 reg;
+
+	reg = i2c_reg_read(ISR);
+	reg &= (ISR_SSD | ISR_ALD | ISR_ITE | ISR_IRF | ISR_SAD | ISR_BED);
+	i2c_reg_write(reg, ISR);
+}
+
+static int i2c_wait(u32 cond, u32 *last_reg)
+{
+	volatile u32 reg;
+	int count = 100;
+
+	while (count) {
+		reg = i2c_reg_read(ISR);
+		if (reg & cond) {
+			*last_reg = reg;
+			i2c_clear_interrupt();
+			return 0;
+		}
+		count--;
+		__local_udelay(10);
+	}
+
+	i2c_clear_interrupt();
+	return -1;
+}
+
+static int i2c_send_start(u8 addr, unsigned op)
+{
+	u32 reg;
+	int status;
+
+	/* write slave address */
+	i2c_reg_write((addr << 1) | op, IDBR);
+
+	reg = i2c_reg_read(ICR);
+	reg &= ~(ICR_START | ICR_STOP | ICR_ALDIE | ICR_ACKNAK | ICR_TB);
+	reg |= ICR_START | ICR_TB;
+	i2c_reg_write(reg, ICR);
+
+	status = i2c_wait(ISR_ITE | ISR_BED, &reg);
+	if (status < 0) {
+		DPRINTF("%s: timeout\n", __func__);
+		return -1;
+	}
+
+	if (reg & ISR_BED) {
+		DPRINTF("%s: bus error\n", __func__);
+		return -1;
+	}
+
+	if (reg & ISR_ACKNAK) {
+		DPRINTF("%s: invalid return: %08x\n", __func__, reg);
+		return -2;
+	}
+
+	return 0;
+}
+
+static int i2c_tx_byte(u8 byte, unsigned stop)
+{
+	u32 reg;
+	int status;
+
+	/* load data */
+	i2c_reg_write(byte, IDBR);
+
+	reg = i2c_reg_read(ICR);
+	reg &= ~(ICR_START | ICR_STOP | ICR_ALDIE | ICR_ACKNAK | ICR_TB);
+	reg |= ICR_ALDIE | ICR_TB;
+	if (stop)
+		reg |= ICR_STOP;
+
+	i2c_reg_write(reg, ICR);
+
+	status = i2c_wait(ISR_ITE, &reg);
+	if (status < 0) {
+		DPRINTF("%s: timeout\n", __func__);
+		return -1;
+	}
+
+	if (reg & ISR_BED) {
+		DPRINTF("%s: bus error\n", __func__);
+		return -1;
+	}
+
+	if (reg & ISR_ACKNAK) {
+		DPRINTF("%s: invalid return: %08x\n", __func__, reg);
+		return -2;
+	}
+
+	return 0;
+}
+
+static int i2c_rx_byte(unsigned stop)
+{
+	u32 reg;
+	int status;
+
+	reg = i2c_reg_read(ICR);
+	reg &= ~(ICR_START | ICR_STOP | ICR_ALDIE | ICR_ACKNAK | ICR_TB);
+	reg |= ICR_ALDIE | ICR_TB;
+	if (stop)
+		reg |= ICR_STOP | ICR_ACKNAK;
+
+	i2c_reg_write(reg, ICR);
+	status = i2c_wait(ISR_IRF, &reg);
+	if (status < 0) {
+		DPRINTF("%s: timeout\n", __func__);
+		return -1;
+	}
+
+	if (reg & ISR_BED) {
+		DPRINTF("%s: bus error\n", __func__);
+		return -1;
+	}
+
+	return i2c_reg_read(IDBR);
+}
+
+#define CK505_ADDR		(0x69)
+#define CK505_SPREAD_REG	(0x01)
+#define CK505_SPREAD_CENTRAL	(1 << 6)
+
+static int __init try_fixup_ck505(void)
+{
+	int ret;
+	u8 byte;
+
+	i2c_hw_init();
+
+	ret = i2c_send_start(CK505_ADDR, I2C_WRITE);
+	if (ret) {
+		printk(KERN_ERR "[%d]: failed to send i2c_send_start: %d\n", __LINE__, ret);
+		goto out_unmap;
+	}
+
+	ret = i2c_tx_byte(CK505_SPREAD_REG, 1);
+	if (ret) {
+		printk(KERN_ERR "[%d]: failed to write reg: %d\n", __LINE__, ret);
+		goto out_unmap;
+	}
+
+	ret = i2c_send_start(CK505_ADDR, I2C_READ);
+	if (ret) {
+		printk(KERN_ERR "[%d]: failed to i2c_send_start: %d\n", __LINE__, ret);
+		goto out_unmap;
+	}
+
+	byte = i2c_rx_byte(0);
+	if (byte < 0) {
+		printk(KERN_ERR "[%d]: failed to read: %d\n", __LINE__, byte);
+		goto out_unmap;
+	}
+
+	byte = i2c_rx_byte(1);
+	if (byte < 0) {
+		printk(KERN_ERR "[%d]: failed to read: %d\n", __LINE__, byte);
+		goto out_unmap;
+	}
+
+	if (byte & CK505_SPREAD_CENTRAL) {
+		printk(KERN_INFO PFX "no fixup required: 0x%02x\n", byte);
+		goto out_unmap;
+	}
+
+	printk(KERN_INFO PFX "fixing up: 0x%02x -> 0x%02x\n",
+				byte, byte | CK505_SPREAD_CENTRAL);
+
+	/* Set the PLL1_SSC_SEL to central spread spectrum mode */
+	byte |= CK505_SPREAD_CENTRAL;
+
+	ret = i2c_send_start(CK505_ADDR, I2C_WRITE);
+	if (ret) {
+		printk(KERN_ERR "[%d]: failed to send start: %d\n", __LINE__, ret);
+		goto out_unmap;
+	}
+
+	ret = i2c_tx_byte(CK505_SPREAD_REG, 0);
+	if (ret) {
+		printk(KERN_ERR "[%d]: failed to write byte\n", ret);
+		goto out_unmap;
+	}
+
+	ret = i2c_tx_byte(CK505_SPREAD_REG, 0);
+	if (ret) {
+		printk(KERN_ERR "[%d]: failed to write byte\n", ret);
+		goto out_unmap;
+	}
+
+	ret = i2c_tx_byte(byte, 1);
+	if (ret) {
+		printk(KERN_ERR "[%d]: failed to write byte\n", ret);
+		goto out_unmap;
+	}
+
+	printk(KERN_INFO PFX "successfully fixed-up\n");
+
+out_unmap:
+	early_iounmap(base_addr, I2C_BUS_SIZE);
+
+	return ret;
+}
+
+int __init sdv_i2c_fixup_ck505(void)
+{
+	size_t i;
+
+	for (i = 0; i < 16; i++) {
+		if (!try_fixup_ck505())
+			break;
+	}
+	return 0;
+}
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/config	2013-06-13 16:05:34.667110680 +0200
@@ -0,0 +1,2715 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/x86 3.2.24 Kernel Configuration
+#
+# CONFIG_64BIT is not set
+CONFIG_X86_32=y
+# CONFIG_X86_64 is not set
+CONFIG_X86=y
+CONFIG_INSTRUCTION_DECODER=y
+CONFIG_OUTPUT_FORMAT="elf32-i386"
+CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_MMU=y
+# CONFIG_ZONE_DMA is not set
+# CONFIG_NEED_DMA_MAP_STATE is not set
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME_VSYSCALL is not set
+CONFIG_ARCH_HAS_CPU_RELAX=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_ZONE_DMA32 is not set
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+# CONFIG_AUDIT_ARCH is not set
+CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_X86_32_SMP=y
+CONFIG_X86_HT=y
+CONFIG_X86_32_LAZY_GS=y
+CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-ecx -fcall-saved-edx"
+CONFIG_KTIME_SCALAR=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE="/opt/toolchains/atom32-eglibc-std-2.13-gcc-4.6.2-binutils-2.22/bin/i686-linux-"
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_KERNEL_XZ=y
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HAVE_SPARSE_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_SPARSE_IRQ=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_FREEZER=y
+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_PERF=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+CONFIG_MM_OWNER=y
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_HAVE_PCSPKR_PLATFORM=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_OPTPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
+CONFIG_HAVE_USER_RETURN_NOTIFIER=y
+CONFIG_HAVE_PERF_EVENTS_NMI=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB 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=y
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_FREEZER=y
+
+#
+# Processor type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
+CONFIG_SMP=y
+CONFIG_X86_MPPARSE=y
+# CONFIG_X86_BIGSMP is not set
+CONFIG_X86_EXTENDED_PLATFORM=y
+CONFIG_X86_INTEL_CE=y
+CONFIG_FBX6HD=y
+# CONFIG_X86_WANT_INTEL_MID is not set
+# CONFIG_X86_RDC321X is not set
+# CONFIG_X86_32_NON_STANDARD is not set
+CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
+# CONFIG_X86_32_IRIS is not set
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+# CONFIG_PARAVIRT_GUEST is not set
+CONFIG_NO_BOOTMEM=y
+# CONFIG_MEMTEST is not set
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
+# CONFIG_M686 is not set
+# CONFIG_MPENTIUMII is not set
+# CONFIG_MPENTIUMIII is not set
+# CONFIG_MPENTIUMM is not set
+# CONFIG_MPENTIUM4 is not set
+# CONFIG_MK6 is not set
+# CONFIG_MK7 is not set
+# CONFIG_MK8 is not set
+# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP3D is not set
+# CONFIG_MELAN is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
+# CONFIG_MCYRIXIII is not set
+# CONFIG_MVIAC3_2 is not set
+# CONFIG_MVIAC7 is not set
+# CONFIG_MCORE2 is not set
+CONFIG_MATOM=y
+# CONFIG_X86_GENERIC is not set
+CONFIG_X86_INTERNODE_CACHE_SHIFT=6
+CONFIG_X86_CMPXCHG=y
+CONFIG_CMPXCHG_LOCAL=y
+CONFIG_CMPXCHG_DOUBLE=y
+CONFIG_X86_L1_CACHE_SHIFT=6
+CONFIG_X86_XADD=y
+CONFIG_X86_WP_WORKS_OK=y
+CONFIG_X86_INVLPG=y
+CONFIG_X86_BSWAP=y
+CONFIG_X86_POPAD_OK=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_TSC=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_CMOV=y
+CONFIG_X86_MINIMUM_CPU_FAMILY=5
+CONFIG_X86_DEBUGCTLMSR=y
+CONFIG_PROCESSOR_SELECT=y
+CONFIG_CPU_SUP_INTEL=y
+# CONFIG_CPU_SUP_CYRIX_32 is not set
+# CONFIG_CPU_SUP_AMD is not set
+# CONFIG_CPU_SUP_CENTAUR is not set
+# CONFIG_CPU_SUP_TRANSMETA_32 is not set
+# CONFIG_CPU_SUP_UMC_32 is not set
+CONFIG_HPET_TIMER=y
+# CONFIG_DMI is not set
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_NR_CPUS=2
+CONFIG_SCHED_SMT=y
+CONFIG_SCHED_MC=y
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_IO_APIC=y
+# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
+CONFIG_X86_MCE=y
+CONFIG_X86_MCE_INTEL=y
+# CONFIG_X86_MCE_AMD is not set
+# CONFIG_X86_ANCIENT_MCE is not set
+CONFIG_X86_MCE_THRESHOLD=y
+# CONFIG_X86_MCE_INJECT is not set
+CONFIG_X86_THERMAL_VECTOR=y
+# CONFIG_VM86 is not set
+# CONFIG_TOSHIBA is not set
+# CONFIG_I8K is not set
+CONFIG_X86_REBOOTFIXUPS=y
+# CONFIG_MICROCODE is not set
+# CONFIG_X86_MSR is not set
+# CONFIG_X86_CPUID is not set
+CONFIG_NOHIGHMEM=y
+# CONFIG_HIGHMEM4G is not set
+# CONFIG_HIGHMEM64G is not set
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_X86_PAE=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ILLEGAL_POINTER_VALUE=0
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+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_ARCH_SUPPORTS_MEMORY_FAILURE=y
+# CONFIG_MEMORY_FAILURE is not set
+# CONFIG_TRANSPARENT_HUGEPAGE is not set
+# CONFIG_CLEANCACHE is not set
+# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
+CONFIG_X86_RESERVE_LOW=4
+# CONFIG_MATH_EMULATION is not set
+CONFIG_MTRR=y
+CONFIG_MTRR_SANITIZER=y
+CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
+CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
+# CONFIG_X86_PAT is not set
+# CONFIG_ARCH_RANDOM is not set
+# CONFIG_EFI is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+CONFIG_HZ_300=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=300
+CONFIG_SCHED_HRTICK=y
+# CONFIG_KEXEC is not set
+CONFIG_PHYSICAL_START=0x100000
+# CONFIG_RELOCATABLE is not set
+CONFIG_PHYSICAL_ALIGN=0x100000
+# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_COMPAT_VDSO is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk=ttyS0,115200 root=/dev/nfs ip=dhcp dhcpclass=linux-fbx6hd pci=noacpi mem=672M"
+CONFIG_CMDLINE_OVERRIDE=y
+
+#
+# Power management and ACPI options
+#
+# CONFIG_SUSPEND is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ACPI=y
+# CONFIG_ACPI_PROCFS is not set
+# CONFIG_ACPI_PROCFS_POWER is not set
+# CONFIG_ACPI_EC_DEBUGFS is not set
+# CONFIG_ACPI_PROC_EVENT is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_BATTERY is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_FAN is not set
+# CONFIG_ACPI_DOCK is not set
+# CONFIG_ACPI_PROCESSOR is not set
+# CONFIG_ACPI_CUSTOM_DSDT is not set
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_PCI_SLOT is not set
+CONFIG_X86_PM_TIMER=y
+# CONFIG_ACPI_CONTAINER is not set
+# CONFIG_ACPI_SBS is not set
+# CONFIG_ACPI_HED is not set
+# CONFIG_ACPI_CUSTOM_METHOD is not set
+# CONFIG_ACPI_APEI is not set
+# CONFIG_SFI is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_INTEL_IDLE=y
+
+#
+# Bus options (PCI etc.)
+#
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GOMMCONFIG is not set
+CONFIG_PCI_GODIRECT=y
+# CONFIG_PCI_GOANY is not set
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCI_CNB20LE_QUIRK is not set
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+CONFIG_HT_IRQ=y
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCI_PRI is not set
+# CONFIG_PCI_PASID is not set
+CONFIG_PCI_IOAPIC=y
+CONFIG_PCI_LABEL=y
+CONFIG_ISA_DMA_API=y
+# CONFIG_ISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SCx200 is not set
+# CONFIG_ALIX is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_RAPIDIO is not set
+
+#
+# Executable file formats / Emulations
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_HAVE_ATOMIC_IOMAP=y
+CONFIG_HAVE_TEXT_POKE_SMP=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_NETSKBPAD=16
+# CONFIG_NETRXTHREAD is not set
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_XFRM_GC_THRESH=1024
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY 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 is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL 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=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+CONFIG_NF_CONNTRACK=y
+# CONFIG_NF_CONNTRACK_MARK is not set
+# CONFIG_NF_CONNTRACK_EVENTS is not set
+# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
+# CONFIG_NF_CT_PROTO_DCCP is not set
+# CONFIG_NF_CT_PROTO_SCTP is not set
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+# CONFIG_NF_CONNTRACK_FTP is not set
+# CONFIG_NF_CONNTRACK_H323 is not set
+# CONFIG_NF_CONNTRACK_IRC is not set
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+# CONFIG_NF_CONNTRACK_SNMP is not set
+# CONFIG_NF_CONNTRACK_PPTP is not set
+# CONFIG_NF_CONNTRACK_SANE is not set
+# CONFIG_NF_CONNTRACK_SIP is not set
+# CONFIG_NF_CONNTRACK_TFTP is not set
+# CONFIG_NF_CT_NETLINK is not set
+CONFIG_NETFILTER_XTABLES=y
+
+#
+# Xtables combined modules
+#
+# CONFIG_NETFILTER_XT_MARK is not set
+# CONFIG_NETFILTER_XT_CONNMARK is not set
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+# CONFIG_NETFILTER_XT_TARGET_LED is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+
+#
+# Xtables matches
+#
+# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
+# CONFIG_NETFILTER_XT_MATCH_HL is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+CONFIG_NETFILTER_XT_MATCH_OWNER=y
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_FFN is not set
+CONFIG_NF_DEFRAG_IPV4=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_LOG=y
+# CONFIG_IP_NF_TARGET_ULOG is not set
+# CONFIG_NF_NAT is not set
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV6 is not set
+# CONFIG_NF_CONNTRACK_IPV6 is not set
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=y
+# CONFIG_IP6_NF_MATCH_AH is not set
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
+# CONFIG_IP6_NF_MATCH_FRAG is not set
+# CONFIG_IP6_NF_MATCH_OPTS is not set
+# CONFIG_IP6_NF_MATCH_HL is not set
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
+# CONFIG_IP6_NF_MATCH_MH is not set
+# CONFIG_IP6_NF_MATCH_RT is not set
+CONFIG_IP6_NF_TARGET_LOG=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+# CONFIG_IP6_NF_MANGLE is not set
+# CONFIG_IP6_NF_RAW is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_FBXATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=y
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+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_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
+# CONFIG_NFC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_FREEBOX_PROCFS=y
+CONFIG_MTD=y
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_ERASE_PRINTK=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+CONFIG_MTD_FBX6HD_PARTS=y
+# CONFIG_MTD_FBX6HD_PARTS_WRITE_ALL is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_TS5500 is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_FORCE_BAD_BLOCK_ERASE=y
+# CONFIG_MTD_NAND_DENALI is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_RICOH is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_CS553X is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+CONFIG_MTD_NAND_DENALI_FBX=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_FREEBOX_MTD is not set
+CONFIG_DTC=y
+CONFIG_OF=y
+
+#
+# Device Tree and Open Firmware support
+#
+CONFIG_PROC_DEVICETREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_DEVICE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
+CONFIG_OF_NET=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+# CONFIG_PARPORT is not set
+CONFIG_PNP=y
+CONFIG_PNP_DEBUG_MESSAGES=y
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_IBM_ASM is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_INTEL_MID_PTI 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_VMWARE_BALLOON is not set
+CONFIG_INTELCE_PIC16PMU=y
+# CONFIG_BMP085 is not set
+# CONFIG_PCH_PHUB is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+CONFIG_CRASHZONE=y
+# 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_TI_ST is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+
+#
+# RemoTI support
+#
+CONFIG_REMOTI=y
+CONFIG_REMOTI_LEDS=y
+# CONFIG_REMOTI_GPIO is not set
+CONFIG_REMOTI_USER=y
+
+#
+# HDMI CEC support
+#
+CONFIG_HDMI_CEC=m
+CONFIG_HDMI_CEC_REMOTI=m
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# 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=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_ATA_ACPI=y
+CONFIG_SATA_PMP=y
+
+#
+# Controllers with non-SFF native interface
+#
+CONFIG_SATA_AHCI=m
+# CONFIG_SATA_AHCI_PLATFORM is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_SATA_ACARD_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_ATA_SFF 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_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_FC is not set
+# CONFIG_MII is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_NET_VENDOR_INTEL=y
+# CONFIG_E100 is not set
+CONFIG_E1000=y
+# CONFIG_E1000E is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_IXGB is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
+# CONFIG_NET_VENDOR_I825XX is not set
+# CONFIG_IP1000 is not set
+# CONFIG_JME is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_SFC is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_NET_SB1000 is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_TR is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN 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=y
+CONFIG_INPUT_POLLDEV=y
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_JOYSTICK=y
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
+# CONFIG_JOYSTICK_GUILLEMOT is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_JOYSTICK_IFORCE is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+# CONFIG_JOYSTICK_MAGELLAN is not set
+# CONFIG_JOYSTICK_SPACEORB is not set
+# CONFIG_JOYSTICK_SPACEBALL is not set
+# CONFIG_JOYSTICK_STINGER is not set
+# CONFIG_JOYSTICK_TWIDJOY is not set
+# CONFIG_JOYSTICK_ZHENHUA is not set
+# CONFIG_JOYSTICK_AS5011 is not set
+# CONFIG_JOYSTICK_JOYDUMP is not set
+# CONFIG_JOYSTICK_XPAD is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_BMA150 is not set
+# CONFIG_INPUT_MMA8450 is not set
+# CONFIG_INPUT_MPU3050 is not set
+# CONFIG_INPUT_APANEL is not set
+# CONFIG_INPUT_WISTRON_BTNS is not set
+# CONFIG_INPUT_ATLAS_BTNS is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_KXTJ9 is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=y
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_CMA3000 is not set
+# CONFIG_INPUT_SMSC_CAP1066 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_DEVPHYSMEM=y
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250_DW is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MFD_HSU is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_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_SERIAL_XILINX_PS_UART is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_HW_RANDOM_INTEL is not set
+# CONFIG_HW_RANDOM_AMD is not set
+# CONFIG_HW_RANDOM_GEODE is not set
+# CONFIG_HW_RANDOM_VIA is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_SONYPI is not set
+# CONFIG_MWAVE is not set
+# CONFIG_PC8736x_GPIO is not set
+# CONFIG_NSC_GPIO is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+# CONFIG_HANGCHECK_TIMER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK 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
+
+#
+# ACPI drivers
+#
+# CONFIG_I2C_SCMI is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE_PCI is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_INTEL_MID is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+CONFIG_I2C_PXA=y
+CONFIG_I2C_PXA_PCI=y
+# 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_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_SCx200_ACB 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
+#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_SCH is not set
+# CONFIG_GPIO_VX855 is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
+# CONFIG_GPIO_PCH is not set
+# CONFIG_GPIO_ML_IOH is not set
+# CONFIG_GPIO_RDC321X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MCP23S08 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_FREEBOX_GPIO is not set
+# CONFIG_FREEBOX_JTAG is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ20Z75 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_GPIO is not set
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+CONFIG_SENSORS_ADT7475=y
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_K8TEMP is not set
+# CONFIG_SENSORS_K10TEMP is not set
+# CONFIG_SENSORS_FAM15H_POWER is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_FSCHMD is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+CONFIG_SENSORS_CORETEMP=y
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+CONFIG_SENSORS_LM85=y
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_LM95245 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX1668 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_NTC_THERMISTOR is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH56XX_COMMON is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_SCH5636 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VIA_CPUTEMP is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_APPLESMC is not set
+
+#
+# ACPI drivers
+#
+# CONFIG_SENSORS_ACPI_POWER is not set
+# CONFIG_SENSORS_ATK0110 is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_HWMON=y
+# CONFIG_FREEBOX_WATCHDOG is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912_I2C 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_MFD_CS5535 is not set
+# CONFIG_MFD_TIMBERDALE 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_MFD_AAT2870_CORE is not set
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CONTROLLER is not set
+# CONFIG_VIDEO_DEV is not set
+CONFIG_DVB_CORE=y
+# CONFIG_DVB_NET is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+CONFIG_RC_CORE=y
+CONFIG_LIRC=y
+CONFIG_RC_MAP=y
+# CONFIG_IR_NEC_DECODER is not set
+# CONFIG_IR_RC5_DECODER is not set
+CONFIG_IR_RC6_DECODER=y
+# CONFIG_IR_JVC_DECODER is not set
+# CONFIG_IR_SONY_DECODER is not set
+# CONFIG_IR_RC5_SZ_DECODER is not set
+# CONFIG_IR_MCE_KBD_DECODER is not set
+CONFIG_IR_LIRC_CODEC=y
+# CONFIG_RC_ATI_REMOTE is not set
+# CONFIG_IR_ENE is not set
+# CONFIG_IR_IMON is not set
+CONFIG_IR_MCEUSB=y
+# CONFIG_IR_ITE_CIR is not set
+# CONFIG_IR_FINTEK is not set
+# CONFIG_IR_NUVOTON is not set
+# CONFIG_IR_REDRAT3 is not set
+# CONFIG_IR_STREAMZAP is not set
+# CONFIG_IR_WINBOND_CIR is not set
+# CONFIG_RC_LOOPBACK is not set
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+CONFIG_MEDIA_TUNER_CUSTOMISE=y
+
+#
+# Customize TV tuners
+#
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_XC4000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
+CONFIG_DVB_MAX_ADAPTERS=8
+# CONFIG_DVB_DYNAMIC_MINORS is not set
+CONFIG_DVB_CAPTURE_DRIVERS=y
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+# CONFIG_TTPCI_EEPROM is not set
+# CONFIG_DVB_BUDGET_CORE is not set
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=y
+# CONFIG_DVB_USB_DEBUG is not set
+# CONFIG_DVB_USB_A800 is not set
+# CONFIG_DVB_USB_DIBUSB_MB is not set
+# CONFIG_DVB_USB_DIBUSB_MC is not set
+CONFIG_DVB_USB_DIB0700=m
+# CONFIG_DVB_USB_UMT_010 is not set
+# CONFIG_DVB_USB_CXUSB is not set
+# CONFIG_DVB_USB_M920X is not set
+# CONFIG_DVB_USB_GL861 is not set
+# CONFIG_DVB_USB_AU6610 is not set
+# CONFIG_DVB_USB_DIGITV is not set
+# CONFIG_DVB_USB_VP7045 is not set
+# CONFIG_DVB_USB_VP702X is not set
+# CONFIG_DVB_USB_GP8PSK is not set
+# CONFIG_DVB_USB_NOVA_T_USB2 is not set
+# CONFIG_DVB_USB_TTUSB2 is not set
+# CONFIG_DVB_USB_DTT200U is not set
+# CONFIG_DVB_USB_OPERA1 is not set
+# CONFIG_DVB_USB_AF9005 is not set
+# CONFIG_DVB_USB_PCTV452E is not set
+# CONFIG_DVB_USB_DW2102 is not set
+# CONFIG_DVB_USB_CINERGY_T2 is not set
+# CONFIG_DVB_USB_ANYSEE is not set
+# CONFIG_DVB_USB_DTV5100 is not set
+# CONFIG_DVB_USB_AF9015 is not set
+# CONFIG_DVB_USB_CE6230 is not set
+# CONFIG_DVB_USB_FRIIO is not set
+# CONFIG_DVB_USB_EC168 is not set
+# CONFIG_DVB_USB_AZ6027 is not set
+# CONFIG_DVB_USB_LME2510 is not set
+# CONFIG_DVB_USB_TECHNISAT_USB2 is not set
+# CONFIG_DVB_USB_IT913X is not set
+# CONFIG_DVB_USB_MXL111SF is not set
+# CONFIG_DVB_TTUSB_BUDGET is not set
+# CONFIG_DVB_TTUSB_DEC is not set
+# CONFIG_SMS_SIANO_MDTV is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported BT878 Adapters
+#
+
+#
+# Supported Pluto2 Adapters
+#
+# CONFIG_DVB_PLUTO2 is not set
+
+#
+# Supported SDMC DM1105 Adapters
+#
+# CONFIG_DVB_DM1105 is not set
+
+#
+# Supported Earthsoft PT1 Adapters
+#
+# CONFIG_DVB_PT1 is not set
+
+#
+# Supported Mantis Adapters
+#
+# CONFIG_MANTIS_CORE is not set
+
+#
+# Supported nGene Adapters
+#
+# CONFIG_DVB_NGENE is not set
+
+#
+# Supported ddbridge ('Octopus') Adapters
+#
+# CONFIG_DVB_DDBRIDGE is not set
+
+#
+# Supported DVB Frontends
+#
+CONFIG_DVB_FE_CUSTOMISE=y
+
+#
+# Customise DVB Frontends
+#
+
+#
+# Multistandard (satellite) frontends
+#
+# CONFIG_DVB_STB0899 is not set
+# CONFIG_DVB_STB6100 is not set
+# CONFIG_DVB_STV090x is not set
+# CONFIG_DVB_STV6110x is not set
+
+#
+# Multistandard (cable + terrestrial) frontends
+#
+# CONFIG_DVB_DRXK is not set
+# CONFIG_DVB_TDA18271C2DD is not set
+
+#
+# DVB-S (satellite) frontends
+#
+# CONFIG_DVB_CX24110 is not set
+# CONFIG_DVB_CX24123 is not set
+# CONFIG_DVB_MT312 is not set
+# CONFIG_DVB_ZL10036 is not set
+# CONFIG_DVB_ZL10039 is not set
+# CONFIG_DVB_S5H1420 is not set
+# CONFIG_DVB_STV0288 is not set
+# CONFIG_DVB_STB6000 is not set
+# CONFIG_DVB_STV0299 is not set
+# CONFIG_DVB_STV6110 is not set
+# CONFIG_DVB_STV0900 is not set
+# CONFIG_DVB_TDA8083 is not set
+# CONFIG_DVB_TDA10086 is not set
+# CONFIG_DVB_TDA8261 is not set
+# CONFIG_DVB_VES1X93 is not set
+# CONFIG_DVB_TUNER_ITD1000 is not set
+# CONFIG_DVB_TUNER_CX24113 is not set
+# CONFIG_DVB_TDA826X is not set
+# CONFIG_DVB_TUA6100 is not set
+# CONFIG_DVB_CX24116 is not set
+# CONFIG_DVB_SI21XX is not set
+# CONFIG_DVB_DS3000 is not set
+# CONFIG_DVB_MB86A16 is not set
+# CONFIG_DVB_TDA10071 is not set
+
+#
+# DVB-T (terrestrial) frontends
+#
+# CONFIG_DVB_SP8870 is not set
+# CONFIG_DVB_SP887X is not set
+# CONFIG_DVB_CX22700 is not set
+# CONFIG_DVB_CX22702 is not set
+# CONFIG_DVB_S5H1432 is not set
+# CONFIG_DVB_DRXD is not set
+# CONFIG_DVB_L64781 is not set
+# CONFIG_DVB_TDA1004X is not set
+# CONFIG_DVB_NXT6000 is not set
+# CONFIG_DVB_MT352 is not set
+# CONFIG_DVB_ZL10353 is not set
+# CONFIG_DVB_DIB3000MB is not set
+# CONFIG_DVB_DIB3000MC is not set
+CONFIG_DVB_DIB7000M=y
+CONFIG_DVB_DIB7000P=y
+# CONFIG_DVB_DIB9000 is not set
+# CONFIG_DVB_TDA10048 is not set
+# CONFIG_DVB_AF9013 is not set
+# CONFIG_DVB_EC100 is not set
+# CONFIG_DVB_STV0367 is not set
+# CONFIG_DVB_CXD2820R is not set
+
+#
+# DVB-C (cable) frontends
+#
+# CONFIG_DVB_VES1820 is not set
+# CONFIG_DVB_TDA10021 is not set
+# CONFIG_DVB_TDA10023 is not set
+# CONFIG_DVB_STV0297 is not set
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+# CONFIG_DVB_NXT200X is not set
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_OR51132 is not set
+# CONFIG_DVB_BCM3510 is not set
+# CONFIG_DVB_LGDT330X is not set
+# CONFIG_DVB_LGDT3305 is not set
+# CONFIG_DVB_S5H1409 is not set
+# CONFIG_DVB_S5H1411 is not set
+
+#
+# ISDB-T (terrestrial) frontends
+#
+# CONFIG_DVB_S921 is not set
+# CONFIG_DVB_DIB8000 is not set
+# CONFIG_DVB_MB86A20S is not set
+
+#
+# Digital terrestrial only tuners/PLL
+#
+# CONFIG_DVB_PLL is not set
+CONFIG_DVB_TUNER_DIB0070=y
+# CONFIG_DVB_TUNER_DIB0090 is not set
+
+#
+# SEC control devices for DVB-S
+#
+# CONFIG_DVB_LNBP21 is not set
+# CONFIG_DVB_LNBP22 is not set
+# CONFIG_DVB_ISL6405 is not set
+# CONFIG_DVB_ISL6421 is not set
+# CONFIG_DVB_ISL6423 is not set
+# CONFIG_DVB_A8293 is not set
+# CONFIG_DVB_LGS8GL5 is not set
+# CONFIG_DVB_LGS8GXX is not set
+# CONFIG_DVB_ATBM8830 is not set
+# CONFIG_DVB_TDA665x is not set
+# CONFIG_DVB_IX2505V is not set
+# CONFIG_DVB_IT913X_FE is not set
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_VGA_ARB is not set
+# CONFIG_VGA_SWITCHEROO 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+# CONFIG_SND_MIXER_OSS is not set
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_PCM_OSS_PLUGINS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_DMA_SGBUF=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_PCI=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ASIHPI is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AW2 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_OXYGEN is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5530 is not set
+# CONFIG_SND_CS5535AUDIO is not set
+# CONFIG_SND_CTXFI is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_LOLA is not set
+# CONFIG_SND_LX6464ES is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SIS7019 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VIRTUOSO is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_USX2Y is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_US122L is not set
+# CONFIG_SND_USB_6FIRE is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF is not set
+# CONFIG_HID_EMS_FF is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_KEYTOUCH is not set
+CONFIG_HID_KYE=y
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=y
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=y
+CONFIG_HID_LOGITECH_DJ=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_MULTITOUCH is not set
+CONFIG_HID_NTRIG=y
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_SAMSUNG is not set
+CONFIG_HID_SONY=y
+# CONFIG_HID_SPEEDLINK is not set
+CONFIG_HID_SUNPLUS=y
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+CONFIG_HID_TOPSEED=y
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB_ARCH_HAS_XHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+# CONFIG_USB_UAS is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_LM3530 is not set
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_LP5523 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGER_TIMER=y
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_FREEBOX_PANEL is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_PCI is not set
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+# CONFIG_STAGING is not set
+# CONFIG_X86_PLATFORM_DEVICES is not set
+
+#
+# IntelCE devices
+#
+CONFIG_INTELCE_GPIO=y
+CONFIG_INTELCE_DFX=y
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_CLKSRC_I8253=y
+CONFIG_CLKEVT_I8253=y
+CONFIG_CLKBLD_I8253=y
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_VIRT_DRIVERS is not set
+# CONFIG_HYPERV is not set
+# CONFIG_PM_DEVFREQ is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_EDD is not set
+CONFIG_FIRMWARE_MEMMAP=y
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+# CONFIG_ISCSI_IBFT_FIND is not set
+# CONFIG_SIGMA is not set
+# CONFIG_GOOGLE_FIRMWARE is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_XFS_FS=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# 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=y
+# 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=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS_XATTR=y
+CONFIG_RAMFS_XATTR_USER=y
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
+CONFIG_HFS_FS=y
+CONFIG_HFSPLUS_FS=y
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# 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=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFS_USE_LEGACY_DNS is not set
+CONFIG_NFS_USE_KERNEL_DNS=y
+# CONFIG_NFS_USE_NEW_IDMAPPER is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=0
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_HARDLOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=1
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_VIRTUAL is not set
+# 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_ARCH_WANT_FRAME_POINTERS=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_HAVE_ARCH_KMEMCHECK=y
+# CONFIG_TEST_KSTRTOX is not set
+CONFIG_STRICT_DEVMEM=y
+CONFIG_X86_VERBOSE_BOOTUP=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_EARLY_PRINTK_DBGP is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_X86_PTDUMP is not set
+CONFIG_DEBUG_RODATA=y
+CONFIG_DEBUG_RODATA_TEST=y
+# CONFIG_DEBUG_SET_MODULE_RONX is not set
+# CONFIG_DEBUG_NX_TEST is not set
+CONFIG_DOUBLEFAULT=y
+# CONFIG_IOMMU_STRESS is not set
+CONFIG_HAVE_MMIOTRACE_SUPPORT=y
+CONFIG_IO_DELAY_TYPE_0X80=0
+CONFIG_IO_DELAY_TYPE_0XED=1
+CONFIG_IO_DELAY_TYPE_UDELAY=2
+CONFIG_IO_DELAY_TYPE_NONE=3
+CONFIG_IO_DELAY_0X80=y
+# CONFIG_IO_DELAY_0XED is not set
+# CONFIG_IO_DELAY_UDELAY is not set
+# CONFIG_IO_DELAY_NONE is not set
+CONFIG_DEFAULT_IO_DELAY_TYPE=0
+# CONFIG_DEBUG_BOOT_PARAMS is not set
+# CONFIG_CPA_DEBUG is not set
+# CONFIG_OPTIMIZE_INLINING is not set
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_ENCRYPTED_KEYS is not set
+# CONFIG_KEYS_DEBUG_PROC_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_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_BUILTIN_TEST=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_USER is not set
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CRC32C_INTEL is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_586 is not set
+# CONFIG_CRYPTO_AES_NI_INTEL is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SALSA20_586 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_TWOFISH_586 is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_PADLOCK is not set
+# CONFIG_CRYPTO_DEV_GEODE is not set
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_HAVE_KVM=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+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_CORDIC is not set
+CONFIG_FBXSERIAL=y
diff -Nruw linux-3.2.24-fbx/drivers/fbxgpio./Kconfig linux-3.2.24-fbx/drivers/fbxgpio/Kconfig
--- linux-3.2.24-fbx/drivers/fbxgpio./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxgpio/Kconfig	2012-11-30 16:07:16.526641548 +0100
@@ -0,0 +1,3 @@
+config FREEBOX_GPIO
+	tristate "Freebox GPIO control interface"
+	default n
diff -Nruw linux-3.2.24-fbx/drivers/fbxgpio./Makefile linux-3.2.24-fbx/drivers/fbxgpio/Makefile
--- linux-3.2.24-fbx/drivers/fbxgpio./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxgpio/Makefile	2012-11-30 16:07:16.526641548 +0100
@@ -0,0 +1 @@
+obj-$(CONFIG_FREEBOX_GPIO)	+= fbxgpio_core.o
diff -Nruw linux-3.2.24-fbx/drivers/fbxjtag./Kconfig linux-3.2.24-fbx/drivers/fbxjtag/Kconfig
--- linux-3.2.24-fbx/drivers/fbxjtag./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxjtag/Kconfig	2011-01-06 02:17:51.082068196 +0100
@@ -0,0 +1,3 @@
+config FREEBOX_JTAG
+	tristate "Freebox JTAG control interface"
+	default n
diff -Nruw linux-3.2.24-fbx/drivers/fbxjtag./Makefile linux-3.2.24-fbx/drivers/fbxjtag/Makefile
--- linux-3.2.24-fbx/drivers/fbxjtag./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxjtag/Makefile	2011-01-06 02:17:51.082068196 +0100
@@ -0,0 +1 @@
+obj-$(CONFIG_FREEBOX_JTAG)	+= fbxjtag.o
diff -Nruw linux-3.2.24-fbx/drivers/fbxmtd./Kconfig linux-3.2.24-fbx/drivers/fbxmtd/Kconfig
--- linux-3.2.24-fbx/drivers/fbxmtd./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxmtd/Kconfig	2012-11-30 16:07:16.530641548 +0100
@@ -0,0 +1,41 @@
+menuconfig FREEBOX_MTD
+	tristate "Freebox Memory Technology Devices (FBXMTD) support"
+
+if FREEBOX_MTD
+
+config FREEBOX_MTD_BACKEND_AMD
+	bool "Support for AMD compatible flash"
+
+config FREEBOX_MTD_BACKEND_INTEL
+	bool "Support for Intel Strataflash"
+
+config FREEBOX_MTD_BLK
+	tristate "Block device access to fbxmtd"
+	depends on BLOCK
+
+config FREEBOX_MTD_CHAR
+	tristate "Character device access to fbxmtd"
+
+
+comment "Mapping drivers"
+
+#
+# Generic mapping driver.
+#
+config FREEBOX_MTD_MAP_DRV_FBX
+	tristate "Freebox mapping Driver."
+	select CRC32
+
+config FREEBOX_MTD_MAP_DRV_BCM963XX
+	tristate "Broadcom 963xx flash format"
+	select CRC32
+
+#
+# Freebox MTD Map Control interface
+#
+config FREEBOX_MTD_MAP_IOCTL
+	tristate "IOCTL control interface"
+	depends on FREEBOX_MTD_MAP_DRV_FBX
+
+endif
+
diff -Nruw linux-3.2.24-fbx/drivers/fbxmtd./Makefile linux-3.2.24-fbx/drivers/fbxmtd/Makefile
--- linux-3.2.24-fbx/drivers/fbxmtd./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxmtd/Makefile	2012-11-30 16:07:16.530641548 +0100
@@ -0,0 +1,24 @@
+
+# core support
+obj-$(CONFIG_FREEBOX_MTD) += fbxmtd.o
+
+fbxmtd-objs += fbxmtd_core.o fbxmtd_core_io.o
+ifeq ($(CONFIG_FREEBOX_MTD_BACKEND_AMD),y)
+fbxmtd-objs += fbxmtd_core_amd.o
+endif
+
+ifeq ($(CONFIG_FREEBOX_MTD_BACKEND_INTEL),y)
+fbxmtd-objs += fbxmtd_core_intel.o
+endif
+
+# generic character device access support (r/w with read erase modify write)
+obj-$(CONFIG_FREEBOX_MTD_CHAR) += fbxmtd_char.o
+fbxmtd_char-objs += fbxmtd_char_dev.o
+
+# generic r/o block device access support
+obj-$(CONFIG_FREEBOX_MTD_BLK) += fbxmtd_blk.o
+fbxmtd_blk-objs += fbxmtd_blk_dev.o
+
+obj-$(CONFIG_FREEBOX_MTD_MAP_DRV_FBX) += fbxmtd_map_drv_fbx.o
+obj-$(CONFIG_FREEBOX_MTD_MAP_DRV_BCM963XX) += fbxmtd_map_drv_bcm963xx.o
+obj-$(CONFIG_FREEBOX_MTD_MAP_IOCTL) += fbxmtd_map_ioctl.o
diff -Nruw linux-3.2.24-fbx/drivers/fbxpanel./Kconfig linux-3.2.24-fbx/drivers/fbxpanel/Kconfig
--- linux-3.2.24-fbx/drivers/fbxpanel./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxpanel/Kconfig	2012-11-30 16:07:16.530641548 +0100
@@ -0,0 +1,13 @@
+menuconfig FREEBOX_PANEL
+	tristate "Freebox Panel Management"
+	default n
+
+if FREEBOX_PANEL
+
+config FREEBOX_PANEL_HW_PIC_FBX
+	tristate "I2C PIC-based Panel driver."
+	default n
+	select I2C
+
+endif
+
diff -Nruw linux-3.2.24-fbx/drivers/fbxpanel./Makefile linux-3.2.24-fbx/drivers/fbxpanel/Makefile
--- linux-3.2.24-fbx/drivers/fbxpanel./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxpanel/Makefile	2012-11-30 16:07:16.546641550 +0100
@@ -0,0 +1,5 @@
+obj-$(CONFIG_FREEBOX_PANEL)	+= fbxpanel.o
+
+fbxpanel-objs = fbxpanel_class.o fbxpanel_anim.o
+
+obj-$(CONFIG_FREEBOX_PANEL_HW_PIC_FBX)	+= fbxpanel_hw_pic_fbx.o
diff -Nruw linux-3.2.24-fbx/drivers/fbxprocfs./fbxprocfs.c linux-3.2.24-fbx/drivers/fbxprocfs/fbxprocfs.c
--- linux-3.2.24-fbx/drivers/fbxprocfs./fbxprocfs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxprocfs/fbxprocfs.c	2011-11-04 14:26:06.983889222 +0100
@@ -0,0 +1,205 @@
+/*
+ * Freebox ProcFs interface
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+
+#include <linux/fbxprocfs.h>
+
+#define PFX	"fbxprocfs: "
+
+
+static struct list_head clients;
+static struct mutex clients_mutex;
+
+static struct proc_dir_entry *root;
+
+/*
+ * register  a  fbxprocfs client  with  given  dirname, caller  should
+ * consider returned struct opaque
+ */
+struct fbxprocfs_client *fbxprocfs_add_client(const char *dirname,
+					      struct module *owner)
+{
+	struct fbxprocfs_client *ret, *p;
+
+	ret = NULL;
+	mutex_lock(&clients_mutex);
+
+	/* check for duplicate */
+	list_for_each_entry(p, &clients, list) {
+		if (!strcmp(dirname, p->dirname))
+			goto out;
+	}
+
+	if (!(ret = kmalloc(sizeof (*ret), GFP_KERNEL))) {
+		printk(KERN_ERR PFX "kmalloc failed\n");
+		goto out;
+	}
+
+	/* try to create client directory */
+	if (!(ret->dir = proc_mkdir(dirname, root))) {
+		printk(KERN_ERR PFX "can't create %s dir\n", dirname);
+		kfree(ret);
+		ret = NULL;
+		goto out;
+	}
+
+	atomic_set(&ret->refcount, 1);
+	ret->dirname = dirname;
+	list_add(&ret->list, &clients);
+
+out:
+	mutex_unlock(&clients_mutex);
+	return ret;
+}
+
+/*
+ * unregister  a  fbxprocfs client, make sure usage count is zero
+ */
+int fbxprocfs_remove_client(struct fbxprocfs_client *client)
+{
+	int ret;
+
+	mutex_lock(&clients_mutex);
+
+	ret = 0;
+	if (atomic_read(&client->refcount) > 1) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	remove_proc_entry(client->dirname, root);
+	list_del(&client->list);
+	kfree(client);
+
+out:
+	mutex_unlock(&clients_mutex);
+	return ret;
+}
+
+/*
+ * remove given entries from client directory
+ */
+static int
+__remove_entries(struct fbxprocfs_client *client,
+		 const struct fbxprocfs_ro_desc *ro_desc,
+		 const struct fbxprocfs_rw_desc *rw_desc)
+{
+	int i;
+
+	for (i = 0; ro_desc && ro_desc[i].name; i++) {
+		remove_proc_entry(ro_desc[i].name, client->dir);
+		atomic_dec(&client->refcount);
+	}
+
+	for (i = 0; rw_desc && rw_desc[i].name; i++) {
+		remove_proc_entry(rw_desc[i].name, client->dir);
+		atomic_dec(&client->refcount);
+	}
+
+	return 0;
+}
+
+/*
+ * create given entries in client directory
+ */
+static int
+__create_entries(struct fbxprocfs_client *client,
+		 const struct fbxprocfs_ro_desc *ro_desc,
+		 const struct fbxprocfs_rw_desc *rw_desc)
+{
+	struct proc_dir_entry	*proc;
+	int			i;
+
+	for (i = 0; ro_desc && ro_desc[i].name; i++) {
+		if (!(proc = create_proc_read_entry(ro_desc[i].name, 0,
+						    client->dir,
+						    ro_desc[i].rfunc,
+						    (void *) ro_desc[i].id))) {
+			printk(KERN_ERR PFX "can't create %s/%s entry\n",
+			       client->dirname, ro_desc[i].name);
+			goto err;
+		}
+		atomic_inc(&client->refcount);
+	}
+
+	for (i = 0; rw_desc && rw_desc[i].name; i++) {
+		if (!(proc = create_proc_entry(rw_desc[i].name, 0,
+					       client->dir))) {
+			printk(KERN_ERR PFX "can't create %s/%s entry\n",
+			       client->dirname, ro_desc[i].name);
+			goto err;
+		}
+
+		proc->read_proc  = rw_desc[i].rfunc;
+		proc->write_proc = rw_desc[i].wfunc;
+		proc->data = (void *)rw_desc[i].id;
+		atomic_inc(&client->refcount);
+	}
+
+	return 0;
+
+err:
+	__remove_entries(client, ro_desc, rw_desc);
+	return -1;
+}
+
+int
+fbxprocfs_create_entries(struct fbxprocfs_client *client,
+			 const struct fbxprocfs_ro_desc *ro_desc,
+			 const struct fbxprocfs_rw_desc *rw_desc)
+{
+	int	ret;
+
+	ret = __create_entries(client, ro_desc, rw_desc);
+	return ret;
+}
+
+int
+fbxprocfs_remove_entries(struct fbxprocfs_client *client,
+			 const struct fbxprocfs_ro_desc *ro_desc,
+			 const struct fbxprocfs_rw_desc *rw_desc)
+{
+	int	ret;
+
+	ret = __remove_entries(client, ro_desc, rw_desc);
+	return ret;
+}
+
+
+static int __init
+fbxprocfs_init(void)
+{
+	INIT_LIST_HEAD(&clients);
+	mutex_init(&clients_mutex);
+
+	/* create freebox directory */
+	if (!(root = proc_mkdir("freebox", NULL))) {
+		printk(KERN_ERR PFX "can't create freebox/ dir\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+static void __exit
+fbxprocfs_exit(void)
+{
+	remove_proc_entry("freebox", NULL);
+}
+
+module_init(fbxprocfs_init);
+module_exit(fbxprocfs_exit);
+
+EXPORT_SYMBOL(fbxprocfs_create_entries);
+EXPORT_SYMBOL(fbxprocfs_remove_entries);
+EXPORT_SYMBOL(fbxprocfs_add_client);
+EXPORT_SYMBOL(fbxprocfs_remove_client);
+
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
+
diff -Nruw linux-3.2.24-fbx/drivers/fbxprocfs./Kconfig linux-3.2.24-fbx/drivers/fbxprocfs/Kconfig
--- linux-3.2.24-fbx/drivers/fbxprocfs./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxprocfs/Kconfig	2011-01-06 02:17:51.082068196 +0100
@@ -0,0 +1,2 @@
+config FREEBOX_PROCFS
+	tristate "Freebox procfs interface"
diff -Nruw linux-3.2.24-fbx/drivers/fbxprocfs./Makefile linux-3.2.24-fbx/drivers/fbxprocfs/Makefile
--- linux-3.2.24-fbx/drivers/fbxprocfs./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxprocfs/Makefile	2011-01-06 02:17:51.082068196 +0100
@@ -0,0 +1 @@
+obj-$(CONFIG_FREEBOX_PROCFS) += fbxprocfs.o
diff -Nruw linux-3.2.24-fbx/drivers/fbxwatchdog./Kconfig linux-3.2.24-fbx/drivers/fbxwatchdog/Kconfig
--- linux-3.2.24-fbx/drivers/fbxwatchdog./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxwatchdog/Kconfig	2012-11-30 16:07:16.546641550 +0100
@@ -0,0 +1,20 @@
+menuconfig FREEBOX_WATCHDOG
+	tristate "Freebox Watchdog"
+	default n
+
+if FREEBOX_WATCHDOG
+
+config FREEBOX_WATCHDOG_CHAR
+	bool "Freebox Watchdog char device interface."
+	default n
+
+config FREEBOX_WATCHDOG_ORION
+	tristate "Marvell Orion support"
+	depends on PLAT_ORION
+
+config FREEBOX_WATCHDOG_BCM63XX
+	tristate "Broadcom 63xx Freebox Watchdog support"
+	depends on BCM63XX
+	default n
+
+endif
diff -Nruw linux-3.2.24-fbx/drivers/fbxwatchdog./Makefile linux-3.2.24-fbx/drivers/fbxwatchdog/Makefile
--- linux-3.2.24-fbx/drivers/fbxwatchdog./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/fbxwatchdog/Makefile	2012-11-30 16:07:16.546641550 +0100
@@ -0,0 +1,9 @@
+obj-$(CONFIG_FREEBOX_WATCHDOG) += fbxwatchdog.o
+
+fbxwatchdog-objs = fbxwatchdog_core.o
+ifeq ($(CONFIG_FREEBOX_WATCHDOG_CHAR),y)
+fbxwatchdog-objs += fbxwatchdog_char.o
+endif
+
+obj-$(CONFIG_FREEBOX_WATCHDOG_ORION)	+= fbxwatchdog_orion.o
+obj-$(CONFIG_FREEBOX_WATCHDOG_BCM63XX)	+= fbxwatchdog_bcm63xx.o
diff -Nruw linux-3.2.24-fbx/drivers/media/dvb/tango2./Kconfig linux-3.2.24-fbx/drivers/media/dvb/tango2/Kconfig
--- linux-3.2.24-fbx/drivers/media/dvb/tango2./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/media/dvb/tango2/Kconfig	2012-11-30 16:14:27.562661608 +0100
@@ -0,0 +1,11 @@
+config DVB_TANGO2
+	tristate "Tango2 DVB adapter"
+	depends on DVB_CORE && ARCH_FBX5_B
+	select I2C
+	select I2C_ALGOBIT
+	select DVB_TDA1004X
+	select DVB_PLL
+
+config DVB_TANGO2_TESTBED
+	bool "extended testing and useful error codes"
+	depends on DVB_TANGO2
diff -Nruw linux-3.2.24-fbx/drivers/media/dvb/tango2./Makefile linux-3.2.24-fbx/drivers/media/dvb/tango2/Makefile
--- linux-3.2.24-fbx/drivers/media/dvb/tango2./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/media/dvb/tango2/Makefile	2012-11-30 16:07:17.278641583 +0100
@@ -0,0 +1,5 @@
+obj-$(CONFIG_DVB_TANGO2) = tango2_dvb.o
+
+tango2_dvb-objs := tango2.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/drivers/media/rc/keymaps/rc-rc6-freebox.c	2013-06-13 15:52:30.397198286 +0200
@@ -0,0 +1,135 @@
+/* rc-rc6-freebox.c - Keytable for Freebox/Alicebox IR controller
+ *
+ * Copyright (c) 2012 by Nicolas Pouillon <npouillon@freebox.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 <media/rc-map.h>
+#include <linux/module.h>
+
+#define RC6_FREEBOX_TV 0xf2
+#define RC6_FREEBOX_WIDE 0x49
+#define RC6_FREEBOX_POWER 0x0c
+#define RC6_FREEBOX_STOP 0x31
+#define RC6_FREEBOX_REC 0x37
+#define RC6_FREEBOX_REW 0x2f
+#define RC6_FREEBOX_PLAY 0xb8
+#define RC6_FREEBOX_FF 0x2e
+#define RC6_FREEBOX_PREV 0x4d
+#define RC6_FREEBOX_NEXT 0x4c
+#define RC6_FREEBOX_RELOAD 0x83
+#define RC6_FREEBOX_MENU 0xcc
+#define RC6_FREEBOX_UP 0x99
+#define RC6_FREEBOX_LEFT 0x9b
+#define RC6_FREEBOX_RIGHT 0x9c
+#define RC6_FREEBOX_DOWN 0x9a
+#define RC6_FREEBOX_OK 0x5c
+#define RC6_FREEBOX_VOL_INC 0x5b
+#define RC6_FREEBOX_VOL_DEC 0x5a
+#define RC6_FREEBOX_MUTE 0x0d
+#define RC6_FREEBOX_PROG_UP 0x58
+#define RC6_FREEBOX_PROG_DOWN 0x59
+#define RC6_FREEBOX_FREEBOX 0xd7
+#define RC6_FREEBOX_RED 0x6d
+#define RC6_FREEBOX_GREEN 0x6e
+#define RC6_FREEBOX_YELLOW 0x6f
+#define RC6_FREEBOX_BLUE 0x70
+#define RC6_FREEBOX_1 0x01
+#define RC6_FREEBOX_2 0x02
+#define RC6_FREEBOX_3 0x03
+#define RC6_FREEBOX_4 0x04
+#define RC6_FREEBOX_5 0x05
+#define RC6_FREEBOX_6 0x06
+#define RC6_FREEBOX_7 0x07
+#define RC6_FREEBOX_8 0x08
+#define RC6_FREEBOX_9 0x09
+#define RC6_FREEBOX_BACK 0x9e
+#define RC6_FREEBOX_0 0x00
+#define RC6_FREEBOX_SWAP 0x0a
+#define RC6_FREEBOX_HELP 0x81
+#define RC6_FREEBOX_INFO 0x0f
+#define RC6_FREEBOX_GUIDE 0x97
+#define RC6_FREEBOX_OPTIONS 0x54
+
+#define MAP(x,y) { 0x80382600 + RC6_FREEBOX_##x, KEY_##y }
+
+static struct rc_map_table rc6_freebox[] = {
+	MAP(0, NUMERIC_0),
+	MAP(1, NUMERIC_1),
+	MAP(2, NUMERIC_2),
+	MAP(3, NUMERIC_3),
+	MAP(4, NUMERIC_4),
+	MAP(5, NUMERIC_5),
+	MAP(6, NUMERIC_6),
+	MAP(7, NUMERIC_7),
+	MAP(8, NUMERIC_8),
+	MAP(9, NUMERIC_9),
+	MAP(SWAP, BACK),
+	MAP(POWER, POWER),
+	MAP(MUTE, MUTE),
+	MAP(INFO, INFO),
+
+	MAP(FF, FASTFORWARD),
+	MAP(REW, REWIND),
+	MAP(STOP, STOP),
+	MAP(REC, RECORD),
+	MAP(WIDE, ZOOM),
+	MAP(PREV, PREVIOUS),
+	MAP(NEXT, NEXT),
+
+	MAP(OPTIONS, OPTION),
+	MAP(PROG_UP, CHANNELUP),
+	MAP(PROG_DOWN, CHANNELDOWN),
+	MAP(VOL_DEC, VOLUMEDOWN),
+	MAP(VOL_INC, VOLUMEUP),
+	MAP(OK, OK),
+
+	MAP(RED, RED),
+	MAP(GREEN, GREEN),
+	MAP(YELLOW, YELLOW),
+	MAP(BLUE, BLUE),
+
+	MAP(HELP, HELP),
+	MAP(RELOAD, REFRESH),
+
+	MAP(GUIDE, PROGRAM),
+	MAP(UP, UP),
+	MAP(DOWN, DOWN),
+	MAP(LEFT, LEFT),
+	MAP(RIGHT, RIGHT),
+	MAP(BACK, BACKSPACE),
+	MAP(PLAY, PLAY),
+
+	MAP(MENU, LIST),
+	MAP(FREEBOX, HOME),
+	MAP(TV, SCREEN),
+};
+
+static struct rc_map_list rc6_freebox_map = {
+	.map = {
+		.scan    = rc6_freebox,
+		.size    = ARRAY_SIZE(rc6_freebox),
+		.rc_type = RC_TYPE_RC6,
+		.name    = "rc-rc6-freebox",
+	}
+};
+
+static int __init init_rc_map_rc6_freebox(void)
+{
+	return rc_map_register(&rc6_freebox_map);
+}
+
+static void __exit exit_rc_map_rc6_freebox(void)
+{
+	rc_map_unregister(&rc6_freebox_map);
+}
+
+module_init(init_rc_map_rc6_freebox)
+module_exit(exit_rc_map_rc6_freebox)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nicolas Pouillon <npouillon@freebox.fr>");
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/drivers/misc/crash_zone.c	2013-06-13 15:06:40.162518380 +0200
@@ -0,0 +1,192 @@
+#include <linux/init.h>
+#include <linux/crash_zone.h>
+#include <linux/proc_fs.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <asm/checksum.h>
+
+static unsigned char *dead_zone = NULL;
+static unsigned int dead_zone_size;
+
+#define CRASH_DATA_SIZE	(dead_zone_size - sizeof (struct crash_zone))
+
+static inline unsigned short int csum_data(const unsigned char *buff, int len)
+{
+	return csum_fold(csum_partial(buff, len, 0));
+}
+
+static int crash_zone_read_proc(char *page, char **start, off_t off,
+				int count, int *eof, void *data)
+{
+	struct crash_header *crash_zone;
+	int datalen;
+
+	/* check crash zone */
+	if (!dead_zone) {
+		printk(KERN_DEBUG "dead zone unset\n");
+		goto empty;
+	}
+
+	crash_zone = (struct crash_header *)dead_zone;
+	if (crash_zone->magic != CRASH_MAGIC) {
+		printk(KERN_DEBUG "bad crash zone magic\n");
+		goto empty;
+	}
+
+	if (crash_zone->len > dead_zone_size) {
+		printk(KERN_DEBUG "bad crash zone len\n");
+		goto empty;
+	}
+
+	if (csum_data((unsigned char *)crash_zone, crash_zone->len)) {
+		printk(KERN_DEBUG "bad crash zone checksum\n");
+		goto empty;
+	}
+
+	/* copy crash data */
+	datalen = crash_zone->len - sizeof (struct crash_header);
+	if (off + count >= datalen) {
+		*eof = 1;
+		count = datalen - off;
+	}
+
+	*start = page;
+	if (count > 0) {
+		memcpy(page, &crash_zone->data + off, count);
+		return count;
+	}
+
+	return 0;
+
+empty:
+	*eof = 1;
+	return 0;
+}
+
+static int crash_zone_write_proc(struct file *file, const char *buffer,
+				 unsigned long count, void *data)
+{
+	struct crash_header *crash_zone;
+	int len;
+
+	if (!dead_zone)
+		return count;
+
+	/* empty the crash zone */
+	crash_zone = (struct crash_header *)dead_zone;
+	len = sizeof (struct crash_header);
+	crash_zone->magic = CRASH_MAGIC;
+	crash_zone->len = len;
+	crash_zone->checksum = 0;
+	crash_zone->checksum = csum_data((unsigned char *)crash_zone, len);
+
+	return count;
+}
+
+static int crash_zone_panic_event(struct notifier_block *self,
+				  unsigned long event, void *data)
+{
+	struct crash_header *crash_zone;
+	int data_len, len;
+
+	if (!dead_zone)
+		return NOTIFY_DONE;
+
+	crash_zone = (struct crash_header *)dead_zone;
+
+	/* copy current kernel log into crash zone */
+	data_len = dead_zone_size - sizeof (struct crash_header);
+	console_emergency_dump(&crash_zone->data, &data_len);
+
+	/* checksum area */
+	len = data_len + sizeof (struct crash_header);
+	crash_zone->magic = CRASH_MAGIC;
+	crash_zone->len = len;
+	crash_zone->checksum = 0;
+	crash_zone->checksum = csum_data((unsigned char *)crash_zone, len);
+	printk("Panic log saved in crash zone\n");
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block crash_panic_block = {
+	crash_zone_panic_event,
+	NULL,
+	INT_MAX /* try to do it first */
+};
+
+void __init crash_zone_set_param(unsigned char *zone, unsigned int size)
+{
+	dead_zone = zone;
+	dead_zone_size = size;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id crash_zone_of_ids[] __initdata = {
+	{ .compatible = "fbx,crashzone" },
+	{ /* sentinel */ },
+};
+
+int __init crash_zone_of_init(void)
+{
+	struct device_node *np;
+	void __iomem *base;
+	struct resource res;
+	int ret = 0;
+
+	np = of_find_matching_node(NULL, crash_zone_of_ids);
+	if (!np) {
+		pr_err("no crashzone node found in dtb\n");
+		return -ENODEV;
+	}
+
+	ret = of_address_to_resource(np, 0, &res);
+	if (ret) {
+		pr_err("unable to find crashzone registers\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_err("unable to remap crashzone resource\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	crash_zone_set_param(base, resource_size(&res));
+out:
+	of_node_put(np);
+	return ret;
+}
+#else
+int __init crash_zone_of_init(void)
+{
+	return 0;
+}
+#endif
+
+static int __init crash_zone_init(void)
+{
+	struct proc_dir_entry	*proc;
+
+	/* create crash proc entry */
+	proc = create_proc_entry("crash_zone", 0, NULL);
+	if (!proc)
+		return 1;
+	proc->read_proc  = crash_zone_read_proc;
+	proc->write_proc = crash_zone_write_proc;
+
+	/* register panic notifier */
+	atomic_notifier_chain_register(&panic_notifier_list,
+				       &crash_panic_block);
+	return 0;
+}
+
+static void __exit crash_zone_exit(void)
+{
+
+}
+
+module_init(crash_zone_init);
+module_exit(crash_zone_exit);
diff -Nruw linux-3.2.24-fbx/drivers/misc/hdmi-cec./core.c linux-3.2.24-fbx/drivers/misc/hdmi-cec/core.c
--- linux-3.2.24-fbx/drivers/misc/hdmi-cec./core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/hdmi-cec/core.c	2013-06-13 15:52:30.405198282 +0200
@@ -0,0 +1,554 @@
+/*
+ * HDMI Consumer Electronics Control, core module
+ *
+ * Copyright (C) 2011, Florian Fainelli <ffainelli@freebox;fr>
+ *
+ * This file is subject to the GPLv2 licensing terms.
+ *
+ */
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+
+#include <linux/hdmi-cec/hdmi-cec.h>
+#include <linux/hdmi-cec/dev.h>
+
+#include "hdmi-cec-priv.h"
+
+static unsigned cec_adapter_count;
+
+#define CEC_RX_QUEUE_MAX_LEN	(20)
+
+/**
+ * cec_set_logical_address() - sets the cec logical address
+ * @adapter:	adapter pointer
+ * @addr:	logical address
+ *
+ * calls the adapter specific set_logical_address callback
+ */
+int cec_set_logical_address(struct cec_adapter *adapter, const u8 addr)
+{
+	int ret;
+
+	if (addr > CEC_ADDR_MAX)
+		return -EINVAL;
+
+	mutex_lock(&adapter->lock);
+	if (adapter->dead)
+		ret = -ENODEV;
+	else
+		ret = adapter->ops->set_logical_address(adapter, addr);
+	mutex_unlock(&adapter->lock);
+
+	return ret;
+}
+
+/**
+ *  __cec_rx_queue_len() - returns the lenght of a cec driver rx queue
+ * @adapter:	adapter pointer
+ */
+unsigned __cec_rx_queue_len(struct cec_adapter *adapter)
+{
+	unsigned qlen;
+
+	spin_lock(&adapter->rx_msg_list_lock);
+	qlen = adapter->rx_msg_len;
+	spin_unlock(&adapter->rx_msg_list_lock);
+
+	return qlen;
+}
+
+/**
+ * adapter_rx_done() - called by an adapter when message is received
+ * @adapter:	adapter pointer
+ * @data:	message blob
+ * @len:	message length
+ */
+int adapter_rx_done(struct cec_adapter *adapter,
+		    const u8 *data, const u8 len,
+		    bool valid, u8 rx_flags)
+{
+	struct cec_rx_kmsg *kmsg;
+	struct cec_rx_msg *msg;
+	int ret = 0;
+
+	if (!len || len > CEC_MAX_MSG_LEN)
+		return -EINVAL;
+
+	if (!adapter->attached) {
+		pr_debug("%s: no client attached, dropping", adapter->name);
+		goto out;
+	}
+
+	spin_lock(&adapter->rx_msg_list_lock);
+	if (adapter->rx_msg_len >= CEC_RX_QUEUE_MAX_LEN) {
+		pr_debug("%s: queue full!\n", adapter->name);
+		ret = -ENOSPC;
+		goto out_unlock;
+	}
+
+	kmsg = kzalloc(sizeof(*kmsg), GFP_ATOMIC);
+	if (!kmsg) {
+		ret = ENOMEM;
+		goto out_unlock;
+	}
+
+	msg = &kmsg->msg;
+	memcpy(&msg->data, data, len);
+	msg->len = len;
+	msg->valid = valid;
+	msg->flags = rx_flags;
+	list_add_tail(&kmsg->next, &adapter->rx_msg_list);
+	adapter->rx_msg_len++;
+
+out_unlock:
+	spin_unlock(&adapter->rx_msg_list_lock);
+
+	/* wake up clients, they can dequeue a buffer now */
+	wake_up_interruptible(&adapter->wait);
+
+out:
+	return ret;
+}
+EXPORT_SYMBOL(adapter_rx_done);
+
+/**
+ * cec_read_message() - reads a cec message from the adapter's rx queue
+ * @adapter:	adapter pointer
+ * @msg:	cec user-space exposed message pointer
+ *
+ * Reads a CEC message from the adapter's RX queue in blocking mode with
+ * either a finite or inifinite timeout
+ */
+int cec_read_message(struct cec_adapter *adapter,
+		     struct cec_rx_msg *msg,
+		     bool non_block)
+{
+	struct cec_rx_kmsg *kmsg;
+	int ret = 0;
+
+	if (!non_block) {
+		ret = wait_event_interruptible(adapter->wait,
+					       __cec_rx_queue_len(adapter) != 0 ||
+					       adapter->dead);
+		if (ret)
+			return ret;
+	}
+
+	if (adapter->dead)
+		return -ENODEV;
+
+	spin_lock(&adapter->rx_msg_list_lock);
+	if (list_empty(&adapter->rx_msg_list)) {
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	kmsg = list_first_entry(&adapter->rx_msg_list,
+				struct cec_rx_kmsg, next);
+	memcpy(msg, &kmsg->msg, sizeof (*msg));
+	list_del(&kmsg->next);
+	kfree(kmsg);
+	adapter->rx_msg_len--;
+
+out:
+	spin_unlock(&adapter->rx_msg_list_lock);
+	return ret;
+}
+
+/**
+ * cec_send_message() - sends an user fed cec message
+ * @adapter:	adapter pointer
+ * @msg:	user-exposed cec message pointer
+ *
+ * Send a message using the specific adapter
+ */
+int cec_send_message(struct cec_adapter *adapter, struct cec_tx_msg *msg)
+{
+	int ret;
+
+	if (!msg->len || msg->len > CEC_MAX_MSG_LEN)
+		return -EINVAL;
+
+	mutex_lock(&adapter->lock);
+
+	if (adapter->dead) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	/* prevent queuing more than one message */
+	if (test_bit(0, &adapter->tx_pending)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/* try to send it */
+	set_bit(0, &adapter->tx_pending);
+	ret = adapter->ops->send(adapter, msg->expire_ms,
+				 msg->data, msg->len);
+	if (ret)
+		clear_bit(0, &adapter->tx_pending);
+
+out:
+	mutex_unlock(&adapter->lock);
+	return ret;
+}
+
+/**
+ * adapter_tx_done() - called by adapter when tx is complete
+ * @adapter:	adapter pointer
+ *
+ */
+void adapter_tx_done(struct cec_adapter *adapter, bool success,
+		     u8 flags, u8 tries)
+{
+	adapter->last_tx_success = success;
+	adapter->last_tx_flags = flags;
+	adapter->last_tx_tries = tries;
+	smp_mb__before_clear_bit();
+        clear_bit(0, &adapter->tx_pending);
+	wake_up_interruptible(&adapter->wait);
+}
+
+EXPORT_SYMBOL(adapter_tx_done);
+
+/**
+ * cec_reset_device() - resets a cec adapter
+ * @adapter:	adapter pointer
+ *
+ * Resets a CEC device to a sane state
+ */
+int cec_reset_device(struct cec_adapter *adapter)
+{
+	int ret;
+
+	mutex_lock(&adapter->lock);
+	if (adapter->dead)
+		ret = -ENODEV;
+	else
+		ret = adapter->ops->reset(adapter);
+	mutex_unlock(&adapter->lock);
+	return ret;
+}
+
+/**
+ * cec_get_counters() - gets counters from a cec adapter
+ * @adapter:	adapter pointer
+ * @cnt:	struct cec_counters pointer
+ *
+ * Get counters from the CEC adapter if supported, adapter should advertise
+ * CEC_HW_HAS_COUNTERS flag
+ */
+int cec_get_counters(struct cec_adapter *adapter, struct cec_counters *cnt)
+{
+	int ret;
+
+	mutex_lock(&adapter->lock);
+	if (!(adapter->flags & CEC_HW_HAS_COUNTERS))
+		ret = -ENOTSUPP;
+	else if (adapter->dead)
+		ret = -ENODEV;
+	else
+		ret = adapter->ops->get_counters(adapter, cnt);
+	mutex_unlock(&adapter->lock);
+
+	return ret;
+}
+
+/**
+ * cec_set_detached_config() - send detached config to adapter
+ * @adapter:	adapter pointer
+ * @config:	config
+ *
+ */
+int cec_set_detached_config(struct cec_adapter *adapter,
+			    const struct cec_detached_config *config)
+{
+	int ret;
+
+	mutex_lock(&adapter->lock);
+	if (adapter->dead)
+		ret = -ENODEV;
+	else
+		ret = adapter->ops->set_detached_config(adapter, config);
+	mutex_unlock(&adapter->lock);
+
+	return ret;
+}
+
+/**
+ * cec_set_rx_mode() - sets the adapter receive mode
+ * @adapter:	adapter pointer
+ * @mode:	receive mode (accept all, unicast only)
+ *
+ * Set the receive mode filter of the adapter
+ */
+int cec_set_rx_mode(struct cec_adapter *adapter, enum cec_rx_mode mode)
+{
+	int ret;
+
+	if (~adapter->flags & CEC_HW_HAS_RX_FILTER)
+		return -ENOTSUPP;
+
+	if (mode >= CEC_RX_MODE_MAX)
+		return -EINVAL;
+
+	mutex_lock(&adapter->lock);
+	if (adapter->dead)
+		ret = -ENODEV;
+	else
+		ret = adapter->ops->set_rx_mode(adapter, mode);
+	mutex_unlock(&adapter->lock);
+
+	return ret;
+}
+
+/**
+ * cec_attach_host - attaches a host to the adapter
+ * @adapter:	adapter pointer
+ *
+ * Attaches the host to the adapter. In case the hardware is able
+ * to process CEC messages itself, it should now send them to the
+ * host for processing
+ */
+int cec_attach_host(struct cec_adapter *adapter)
+{
+	int ret = 0;
+
+	if (adapter->attached)
+		return -EBUSY;
+
+	mutex_lock(&adapter->lock);
+	if (adapter->dead)
+		ret = -ENODEV;
+	else {
+		if (adapter->ops->attach)
+			ret = adapter->ops->attach(adapter);
+		if (!ret)
+			adapter->attached = true;
+	}
+	mutex_unlock(&adapter->lock);
+	return ret;
+}
+
+/**
+ * cec_detach_host - detaches a host from the adapter
+ * @adapter:	adapter pointer
+ *
+ * Detaches the host from the adapter. In case the hardware is able
+ * to process CEC messages itself, it should now keep the messages for
+ * itself and no longer send them to the host
+ */
+int cec_detach_host(struct cec_adapter *adapter)
+{
+	int ret;
+
+	mutex_lock(&adapter->lock);
+	if (adapter->dead)
+		ret = -ENODEV;
+	else {
+		if (adapter->ops->detach(adapter))
+			adapter->ops->detach(adapter);
+		adapter->attached = false;
+	}
+	mutex_unlock(&adapter->lock);
+
+	return 0;
+}
+
+/**
+ * alloc_cec_adapter() - allocate a new cec adapter
+ * @priv_size:	sizeof of adapter private date
+ */
+struct cec_adapter *alloc_cec_adapter(size_t priv_size)
+{
+	size_t size;
+
+	size = sizeof (struct cec_adapter) + priv_size + CECDEV_PRIV_ALIGN;
+	return kzalloc(size, GFP_KERNEL);
+}
+EXPORT_SYMBOL(alloc_cec_adapter);
+
+/**
+ * cec_flush_queues() - flushes a cec adapter queues
+ * @adapter:	adapter pointer
+ */
+void cec_flush_queues(struct cec_adapter *adapter)
+{
+	struct cec_rx_kmsg *cur, *next;
+
+	spin_lock(&adapter->rx_msg_list_lock);
+
+	list_for_each_entry_safe(cur, next, &adapter->rx_msg_list, next)
+		kfree(cur);
+	INIT_LIST_HEAD(&adapter->rx_msg_list);
+	adapter->rx_msg_len = 0;
+
+	spin_unlock(&adapter->rx_msg_list_lock);
+}
+
+/*
+ * device refcounting
+ */
+int cec_get_adapter(struct cec_adapter *adapter)
+{
+	int ret;
+
+	mutex_lock(&adapter->lock);
+	ret = adapter->dead;
+	if (!ret)
+		atomic_inc(&adapter->users);
+	mutex_unlock(&adapter->lock);
+	return ret;
+}
+
+void cec_put_adapter(struct cec_adapter *adapter)
+{
+	if (atomic_dec_and_test(&adapter->users))
+		kfree(adapter);
+}
+
+/**
+ * free_cec_adapter() - free cec adapter
+ */
+void free_cec_adapter(struct cec_adapter *adapter)
+{
+	cec_put_adapter(adapter);
+}
+EXPORT_SYMBOL(free_cec_adapter);
+
+/*
+ * called by sysfs when all device references have been dropped
+ */
+static void cec_adapter_sysfs_release(struct device *dev)
+{
+	struct cec_adapter *adapter = to_cec_adapter(dev);
+	free_cec_adapter(adapter);
+}
+
+/*
+ * cec device sysfs class
+ */
+static struct class cec_class = {
+	.name		= "cec",
+	.dev_release	= cec_adapter_sysfs_release,
+};
+
+/**
+ * register_cec_adapter() - registers a new cec adapter
+ * @cec_adapter:	cec_adapter pointer
+ */
+int register_cec_adapter(struct cec_adapter *adapter)
+{
+	struct device *dev = &adapter->dev;
+	int ret;
+
+	memset(dev, 0, sizeof (*dev));
+
+	adapter->attached = false;
+	mutex_init(&adapter->lock);
+
+	adapter->tx_pending = 0;
+	init_waitqueue_head(&adapter->wait);
+
+	spin_lock_init(&adapter->rx_msg_list_lock);
+	INIT_LIST_HEAD(&adapter->rx_msg_list);
+	adapter->rx_msg_len = 0;
+
+	snprintf(adapter->name, sizeof (adapter->name),
+		 "%s%d", adapter->driver_name,
+		 cec_adapter_count++);
+
+	/* create char device */
+	ret = cec_create_adapter_node(adapter);
+	if (ret < 0)
+		return ret;
+
+	/* register to sysfs */
+	dev_set_name(dev, adapter->name);
+	dev->class = &cec_class;
+
+	ret = device_register(dev);
+	if (ret < 0)
+		return ret;
+
+	/* 2 users, driver itself + sysfs */
+	atomic_set(&adapter->users, 2);
+	dev_info(dev, "registered cec adapter\n");
+	return 0;
+}
+EXPORT_SYMBOL(register_cec_adapter);
+
+/**
+ * unregister_cec_adapter() - unregisters a cec adapter
+ * @cec_adapter:	cec_adapter pointer
+ */
+void unregister_cec_adapter(struct cec_adapter *adapter)
+{
+	/* mark as dead */
+	mutex_lock(&adapter->lock);
+	adapter->dead = true;
+	mutex_unlock(&adapter->lock);
+
+	/* from this point, no adapter ops can be called again */
+
+	/* unregister char dev openers */
+	cec_remove_adapter_node(adapter);
+
+	/* wake up any sleeper */
+	adapter->last_tx_success = false;
+	adapter->last_tx_flags = 0;
+	adapter->tx_pending = 0;
+	wake_up_all(&adapter->wait);
+
+	cec_detach_host(adapter);
+	cec_flush_queues(adapter);
+	device_unregister(&adapter->dev);
+	/* let sysfs release the device */
+	dev_info(&adapter->dev, "unregistered cec adapter\n");
+}
+
+EXPORT_SYMBOL(unregister_cec_adapter);
+
+static int __init cec_init(void)
+{
+	int ret;
+
+	ret = class_register(&cec_class);
+	if (ret) {
+		pr_err("failed to create cec device class\n");
+		return ret;
+	}
+
+	ret = cec_cdev_init();
+	if (ret) {
+		pr_err("failed to create devices\n");
+		goto failed_class;
+	}
+
+	return 0;
+
+failed_class:
+	class_unregister(&cec_class);
+	return 1;
+}
+
+static void __exit cec_exit(void)
+{
+	cec_cdev_exit();
+	class_unregister(&cec_class);
+}
+
+module_init(cec_init);
+module_exit(cec_exit);
+
+MODULE_AUTHOR("Florian Fainelli <ffainelli@freebox.fr>");
+MODULE_DESCRIPTION("HDMI CEC core driver");
+MODULE_LICENSE("GPL");
diff -Nruw linux-3.2.24-fbx/drivers/misc/hdmi-cec./dev.c linux-3.2.24-fbx/drivers/misc/hdmi-cec/dev.c
--- linux-3.2.24-fbx/drivers/misc/hdmi-cec./dev.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/hdmi-cec/dev.c	2013-06-13 15:52:30.405198282 +0200
@@ -0,0 +1,295 @@
+/*
+ * HDMI CEC character device code
+ *
+ * Copyright (C), 2011 Florian Fainelli <ffainelli@freebox.fr>
+ *
+ * This file is subject to the GPLv2 licensing terms
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/spinlock.h>
+#include <linux/ioctl.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+
+#include <linux/hdmi-cec/hdmi-cec.h>
+#include <linux/hdmi-cec/dev.h>
+
+#include "hdmi-cec-priv.h"
+
+static int cec_major;
+
+static DEFINE_MUTEX(cec_minors_lock);
+static bool cec_minors[256];
+
+static int cec_dev_open(struct inode *i, struct file *f)
+{
+	struct cdev *cdev = i->i_cdev;
+	struct cec_adapter *adapter =
+			container_of(cdev, struct cec_adapter, cdev);
+
+	if (f->private_data)
+		return -EBUSY;
+
+	if (cec_get_adapter(adapter))
+		return -ENODEV;
+
+	f->private_data = adapter;
+	return cec_attach_host(adapter);
+}
+
+static int cec_dev_close(struct inode *i, struct file *f)
+{
+	struct cdev *cdev = i->i_cdev;
+	struct cec_adapter *adapter =
+			container_of(cdev, struct cec_adapter, cdev);
+
+	cec_detach_host(adapter);
+	cec_flush_queues(adapter);
+	f->private_data = NULL;
+	cec_put_adapter(adapter);
+	return 0;
+}
+
+static int wait_tx_done(struct cec_adapter *adapter)
+{
+	int ret;
+
+	ret = wait_event_interruptible(adapter->wait,
+				       !test_bit(0, &adapter->tx_pending) ||
+				       adapter->dead);
+	if (ret)
+		return ret;
+
+	if (adapter->dead)
+		return -ENODEV;
+
+	return 0;
+}
+
+static long cec_dev_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+{
+	struct cec_adapter *adapter;
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+	int val, ret;
+	struct cec_counters cnt;
+	struct cec_tx_status tx_status;
+	struct cec_detached_config config;
+
+	if (!f->private_data)
+		return -EINVAL;
+
+	adapter = f->private_data;
+
+	ret = -ENOTTY;
+	switch (cmd) {
+	case CEC_SET_LOGICAL_ADDRESS:
+		if (get_user(val, p))
+			return -EFAULT;
+
+		ret = cec_set_logical_address(adapter, (u8)val);
+		break;
+
+	case CEC_RESET_DEVICE:
+		ret = cec_reset_device(adapter);
+		break;
+
+	case CEC_GET_COUNTERS:
+		memset(&cnt, 0, sizeof(cnt));
+
+		ret = cec_get_counters(adapter, &cnt);
+		if (ret)
+			return ret;
+
+		if (copy_to_user(argp, &cnt, sizeof(cnt)))
+			return -EFAULT;
+		break;
+
+	case CEC_GET_TX_STATUS:
+		tx_status.sent = !test_bit(0, &adapter->tx_pending);
+		tx_status.success = adapter->last_tx_success;
+		tx_status.flags = adapter->last_tx_flags;
+		tx_status.tries = adapter->last_tx_tries;
+
+		if (copy_to_user(argp, &tx_status, sizeof(tx_status)))
+			return -EFAULT;
+
+		ret = 0;
+		break;
+
+	case CEC_SET_RX_MODE:
+		if (get_user(val, p))
+			return -EFAULT;
+
+		ret = cec_set_rx_mode(adapter, (enum cec_rx_mode)val);
+		break;
+
+	case CEC_SET_DETACHED_CONFIG:
+		if (copy_from_user(&config, argp, sizeof (config)))
+			return -EFAULT;
+
+		ret = cec_set_detached_config(adapter, &config);
+		break;
+
+	default:
+		dev_err(&adapter->dev, "unsupported ioctl: %08x\n", cmd);
+		break;
+	}
+
+	return ret;
+}
+
+static int cec_dev_write(struct file *f, const char __user *buf,
+			size_t count, loff_t *pos)
+{
+	struct cec_adapter *adapter = f->private_data;
+	struct cec_tx_msg msg;
+	int ret;
+
+	if (count != sizeof (struct cec_tx_msg))
+		return -EINVAL;
+
+	if (copy_from_user(&msg, buf, sizeof (msg)))
+		return -EFAULT;
+
+	ret = cec_send_message(adapter, &msg);
+	if (ret)
+		return ret;
+
+	if (!(f->f_flags & O_NONBLOCK)) {
+		ret = wait_tx_done(adapter);
+		if (ret)
+			return ret;
+	}
+
+	/* update status */
+	msg.success = adapter->last_tx_success;
+	msg.flags = adapter->last_tx_flags;
+	msg.tries = adapter->last_tx_tries;
+
+	if (copy_to_user((char __user *)buf, &msg, sizeof (msg)))
+		return -EFAULT;
+
+	return count;
+}
+
+static int cec_dev_read(struct file *f, char __user *buf,
+			size_t count, loff_t *pos)
+{
+	struct cec_adapter *adapter = f->private_data;
+	int ret;
+	struct cec_rx_msg msg;
+
+	if (count != sizeof (struct cec_rx_msg))
+		return -EINVAL;
+
+	ret = cec_read_message(adapter, &msg, f->f_flags & O_NONBLOCK);
+	if (ret)
+		return ret;
+
+	if (copy_to_user(buf, &msg, sizeof (msg)))
+		return -EFAULT;
+
+	return sizeof (msg);
+}
+
+static unsigned int cec_dev_poll(struct file *f, poll_table *wait)
+{
+	struct cec_adapter *adapter = f->private_data;
+	unsigned int flags;
+
+	if (adapter->dead)
+		return POLLERR | POLLHUP;
+
+	poll_wait(f, &adapter->wait, wait);
+
+	flags = 0;
+	if (__cec_rx_queue_len(adapter))
+		flags |= POLLIN;
+
+	if (!test_bit(0, &adapter->tx_pending))
+		flags |= POLLOUT;
+
+	return flags;
+}
+
+static const struct file_operations cec_adapter_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= cec_dev_open,
+	.release	= cec_dev_close,
+	.unlocked_ioctl	= cec_dev_ioctl,
+	.read		= cec_dev_read,
+	.write		= cec_dev_write,
+	.poll		= cec_dev_poll,
+};
+
+int cec_create_adapter_node(struct cec_adapter *adapter)
+{
+	size_t i;
+	dev_t devno;
+	int ret;
+
+	cdev_init(&adapter->cdev, &cec_adapter_fops);
+	adapter->cdev.owner = THIS_MODULE;
+
+	/* allocate minor */
+	mutex_lock(&cec_minors_lock);
+	for (i = 0; i < ARRAY_SIZE(cec_minors); i++) {
+		if (!cec_minors[i])
+			break;
+	}
+	mutex_unlock(&cec_minors_lock);
+
+	if (i == ARRAY_SIZE(cec_minors)) {
+		dev_err(&adapter->dev, "no minor available\n");
+		return 1;
+	}
+
+	devno = MKDEV(cec_major, i);
+	ret = cdev_add(&adapter->cdev, devno, 1);
+	if (ret) {
+		dev_err(&adapter->dev, "failed to add char device\n");
+		return ret;
+	}
+
+	adapter->dev.devt = devno;
+	return 0;
+}
+
+void cec_remove_adapter_node(struct cec_adapter *adapter)
+{
+	mutex_lock(&cec_minors_lock);
+	cec_minors[MINOR(adapter->cdev.dev)] = false;
+	mutex_unlock(&cec_minors_lock);
+	cdev_del(&adapter->cdev);
+}
+
+int __init cec_cdev_init(void)
+{
+	dev_t dev = 0;
+	int ret;
+
+	ret = alloc_chrdev_region(&dev, 0, CEC_MAX_DEVS, "cec");
+	if (ret < 0) {
+		printk(KERN_ERR "alloc_chrdev_region() failed for cec\n");
+		goto out;
+	}
+
+	cec_major = MAJOR(dev);
+	return 0;
+
+out:
+	unregister_chrdev_region(MKDEV(cec_major, 0), CEC_MAX_DEVS);
+	return ret;
+}
+
+void __exit cec_cdev_exit(void)
+{
+	unregister_chrdev_region(MKDEV(cec_major, 0), CEC_MAX_DEVS);
+}
+
diff -Nruw linux-3.2.24-fbx/drivers/misc/hdmi-cec./hdmi-cec-priv.h linux-3.2.24-fbx/drivers/misc/hdmi-cec/hdmi-cec-priv.h
--- linux-3.2.24-fbx/drivers/misc/hdmi-cec./hdmi-cec-priv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/hdmi-cec/hdmi-cec-priv.h	2013-06-13 15:52:30.405198282 +0200
@@ -0,0 +1,34 @@
+#ifndef __HDMI_CEC_PRIV_H
+#define __HDMI_CEC_PRIV_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+/**
+ * struct cec_rx_kmsg - kernel-side cec message cookie
+ * @msg:	user-side cec message cookie
+ * @next:	list pointer to next message
+ */
+struct cec_rx_kmsg {
+	struct cec_rx_msg	msg;
+	struct list_head	next;
+};
+
+int cec_get_adapter(struct cec_adapter *);
+void cec_put_adapter(struct cec_adapter *);
+int cec_read_message(struct cec_adapter *, struct cec_rx_msg *msg,
+		     bool non_block);
+int cec_send_message(struct cec_adapter *, struct cec_tx_msg *msg);
+int cec_reset_device(struct cec_adapter *);
+int cec_get_counters(struct cec_adapter *, struct cec_counters *cnt);
+int cec_set_logical_address(struct cec_adapter *, const u8 addr);
+int cec_set_rx_mode(struct cec_adapter *, enum cec_rx_mode mode);
+void cec_flush_queues(struct cec_adapter *);
+unsigned __cec_rx_queue_len(struct cec_adapter *);
+int cec_attach_host(struct cec_adapter *);
+int cec_detach_host(struct cec_adapter *);
+int cec_set_detached_config(struct cec_adapter *,
+			    const struct cec_detached_config *);
+
+#endif /* __HDMI_CEC_PRIV_H */
+
diff -Nruw linux-3.2.24-fbx/drivers/misc/hdmi-cec./Kconfig linux-3.2.24-fbx/drivers/misc/hdmi-cec/Kconfig
--- linux-3.2.24-fbx/drivers/misc/hdmi-cec./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/hdmi-cec/Kconfig	2013-06-13 15:52:30.405198282 +0200
@@ -0,0 +1,15 @@
+menu "HDMI CEC support"
+
+config HDMI_CEC
+	tristate "HDMI CEC (Consumer Electronics Control) support"
+	---help---
+	   HDMI Consumer Electronics Control support.
+
+config HDMI_CEC_REMOTI
+	tristate "RemoTI CEC driver"
+	depends on HDMI_CEC
+	select REMOTI
+	---help---
+	   HDMI CEC driver using RemoTI IPCs.
+
+endmenu
diff -Nruw linux-3.2.24-fbx/drivers/misc/hdmi-cec./Makefile linux-3.2.24-fbx/drivers/misc/hdmi-cec/Makefile
--- linux-3.2.24-fbx/drivers/misc/hdmi-cec./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/hdmi-cec/Makefile	2012-07-27 18:10:45.080135814 +0200
@@ -0,0 +1,6 @@
+obj-$(CONFIG_HDMI_CEC)		+= hdmi-cec.o
+hdmi-cec-objs			+= core.o dev.o
+
+# drivers
+obj-$(CONFIG_HDMI_CEC_REMOTI)	+= remoti-cec.o
+remoti-cec-objs			:= remoti.o
diff -Nruw linux-3.2.24-fbx/drivers/misc/hdmi-cec./remoti.c linux-3.2.24-fbx/drivers/misc/hdmi-cec/remoti.c
--- linux-3.2.24-fbx/drivers/misc/hdmi-cec./remoti.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/hdmi-cec/remoti.c	2013-06-13 15:52:30.405198282 +0200
@@ -0,0 +1,637 @@
+/*
+ * HDMI CEC driver using RemoTI IPCs
+ *
+ * Copyright (C) Florian Fainelli <ffainelli@freebox.fr>
+ *
+ * This file is subject to the GPLv2 licensing terms
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/remoti/remoti.h>
+#include <linux/of.h>
+
+#include <linux/hdmi-cec/hdmi-cec.h>
+
+/* HDMI CEC command (util subsystem) */
+#define RTI_CEC_SET_LADDR		0x20
+#define RTI_CEC_GET_CNT			0x21
+#define RTI_CEC_RST			0x22
+#define RTI_CEC_MODE			0x23
+#define RTI_CEC_ATTACH			0x24
+#define RTI_CEC_DETACH			0x25
+#define RTI_CEC_RECV_MSG_IND		0x26
+
+#define RTI_CEC_SEND_MSG_REQ		0x28
+#define RTI_CEC_SEND_MSG_CNF		0x29
+
+#define RTI_CEC_RECV_RAW_IND		0x2a
+#define RTI_CEC_SET_DETACHED_CONFIG	0x2b
+
+
+/*
+ * Exposed return status codes
+ */
+enum {
+	RTI_CEC_SUCCESS = 0,
+	RTI_CEC_INVALID,
+	RTI_CEC_TX_BUSY,
+	RTI_CEC_TX_FAIL,
+};
+
+/*
+ * Exposed modes
+ */
+enum {
+	RTI_CEC_MODE_DISABLED = 0,
+	RTI_CEC_MODE_NORMAL,
+	RTI_CEC_MODE_RAW,
+};
+
+/*
+ * rx filtering (normal mode)
+ */
+enum {
+	RTI_CEC_RX_FILTER_DEFAULT = 0,
+	RTI_CEC_RX_FILTER_PROMISC,
+};
+
+/*
+ * RTI data for rx message
+ *
+ * we send this as-is to host (no memcpy to create a message) so don't
+ * change field order
+ */
+enum rti_cec_rx_msg_flags {
+	/* global valid bit for all message (got eom & ack) */
+	RTI_CEC_RX_FLAG_VALID		= (1 << 0),
+
+	/* true if this is a complete message (else its truncated) */
+	RTI_CEC_RX_FLAG_GOT_EOM		= (1 << 1),
+
+	/* true if the message has been acked */
+	RTI_CEC_RX_FLAG_ACKED		= (1 << 2),
+};
+
+struct rti_cec_rx_msg {
+	/* bitmask of rti_cec_rx_msg_flags */
+	uint8_t	flags;
+
+	/* number of bits in data */
+	uint8_t	len;
+
+	/* all message data (no eom/ack bit here), we only send "len"
+	 * bytes of this array */
+	uint8_t	data[16];
+};
+
+#define RTI_CEC_RX_MSG_CONSTANT_LEN         \
+		offsetof(struct rti_cec_rx_msg, data)
+
+
+/*
+ * RTI data for tx completion
+ */
+enum rti_cec_tx_flags  {
+	/*
+	 * message was nacked at some point
+	 */
+	RTI_CEC_TX_F_NACK		= (1 << 0),
+
+	/*
+	 * abort sending because total time to send was elapsed
+	 */
+	RTI_CEC_TX_F_TIMEOUT		= (1 << 1),
+
+	/*
+	 * abort sending because maximum number of retry has passed
+	 */
+	RTI_CEC_TX_F_MAX_RETRIES	= (1 << 2),
+
+	/*
+	 * abort sending because of arbitration loss
+	 */
+	RTI_CEC_TX_F_ARBITRATION_LOST	= (1 << 3),
+
+	/*
+	 * abort sending because we failed to respect timings
+	 */
+	RTI_CEC_TX_F_MISSED_DEADLINE	= (1 << 4),
+};
+
+struct rti_cec_tx_status {
+	uint8_t	status;
+
+	uint8_t	flags;
+
+	/* number of tx tries we did (0 = no try done because of busy
+	 * bus) */
+	uint8_t	tries;
+};
+
+
+static inline int remoti_cec_map_error(const u8 ret)
+{
+	switch (ret) {
+	case RTI_CEC_SUCCESS:
+		return 0;
+	default:
+		return -EINVAL;
+	case RTI_CEC_TX_BUSY:
+		return -EBUSY;
+	case RTI_CEC_TX_FAIL:
+		return -EIO;
+	}
+}
+
+static DEFINE_MUTEX(remoti_cec_list_mutex);
+static struct list_head remoti_cec_list;
+
+/*
+ * Driver private context
+ */
+struct remoti_cec_priv {
+	struct platform_device	*pdev;
+	unsigned int		rti_dev_id;
+
+	struct rti_udev		*udev;
+	struct cec_adapter	*adapter;
+	struct list_head	next;
+};
+
+struct remoti_cec_adapter_priv {
+	struct remoti_cec_priv	*priv;
+};
+
+static int remoti_cec_send(struct cec_adapter *adapter,
+			   u16 expire_ms,
+			   const u8 *data,
+			   const u8 len)
+{
+	struct remoti_cec_adapter_priv *apriv = cec_adapter_priv(adapter);
+	struct remoti_cec_priv *priv = apriv->priv;
+	struct rti_msg msg;
+	int ret;
+
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_SREQ;
+	msg.subsys = NPI_SYS_UTIL;
+	msg.cmd = RTI_CEC_SEND_MSG_REQ;
+
+	msg.data[0] = expire_ms & 0xff;
+	msg.data[1] = (expire_ms >> 8) & 0xff;
+	memcpy(msg.data + 2, data, len);
+	msg.data_len = len + 2;
+
+	ret = rti_send_sync_msg(priv->udev, &msg);
+	if (ret)
+		return ret;
+
+	if (msg.reply_len != 1)
+		return -EIO;
+
+	if (msg.reply[0] != RTI_CEC_SUCCESS)
+		return remoti_cec_map_error(msg.reply[0]);
+
+	return 0;
+}
+
+
+static int remoti_cec_set_logical_address(struct cec_adapter *adapter,
+					  const u8 logical_address)
+{
+	struct remoti_cec_adapter_priv *apriv = cec_adapter_priv(adapter);
+	struct remoti_cec_priv *priv = apriv->priv;
+	struct rti_msg msg;
+	int ret;
+
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_SREQ;
+	msg.subsys = NPI_SYS_UTIL;
+	msg.cmd = RTI_CEC_SET_LADDR;
+
+	memcpy(msg.data, &logical_address, 1);
+	msg.data_len = sizeof (logical_address);
+
+	ret = rti_send_sync_msg(priv->udev, &msg);
+	if (ret)
+		return ret;
+
+	if (msg.reply_len != 1)
+		return -EIO;
+
+	return remoti_cec_map_error(msg.reply[0]);
+}
+
+static int remoti_cec_get_counters(struct cec_adapter *adapter,
+				   struct cec_counters *cnt)
+{
+	struct remoti_cec_adapter_priv *apriv = cec_adapter_priv(adapter);
+	struct remoti_cec_priv *priv = apriv->priv;
+	struct rti_msg msg;
+	int ret;
+
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_SREQ;
+	msg.subsys = NPI_SYS_UTIL;
+	msg.cmd = RTI_CEC_GET_CNT;
+
+	ret = rti_send_sync_msg(priv->udev, &msg);
+	if (ret)
+		return ret;
+
+	if (msg.reply_len != sizeof (*cnt)) {
+		printk(KERN_ERR "invalid cec counters size\n");
+		return -EIO;
+	}
+
+	memcpy(cnt, msg.reply, msg.reply_len);
+	return 0;
+}
+
+static int remoti_cec_reset(struct cec_adapter *adapter)
+{
+	struct remoti_cec_adapter_priv *apriv = cec_adapter_priv(adapter);
+	struct remoti_cec_priv *priv = apriv->priv;
+	struct rti_msg msg;
+
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_SREQ;
+	msg.subsys = NPI_SYS_UTIL;
+	msg.cmd = RTI_CEC_RST;
+
+	return rti_send_sync_msg(priv->udev, &msg);
+}
+
+static int remoti_cec_set_detached_config(struct cec_adapter *adapter,
+					  const struct cec_detached_config *cfg)
+{
+	struct remoti_cec_adapter_priv *apriv = cec_adapter_priv(adapter);
+	struct remoti_cec_priv *priv = apriv->priv;
+	struct rti_msg msg;
+
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_SREQ;
+	msg.subsys = NPI_SYS_UTIL;
+	msg.cmd = RTI_CEC_SET_DETACHED_CONFIG;
+
+	msg.data_len = 4;
+	msg.data[0] = cfg->phys_addr_valid ? 1 : 0;
+	msg.data[1] = cfg->phys_addr[0];
+	msg.data[2] = cfg->phys_addr[1];
+	msg.data[3] = cfg->flags;
+
+	return rti_send_sync_msg(priv->udev, &msg);
+}
+
+static int remoti_cec_set_rx_mode(struct cec_adapter *adapter,
+				  enum cec_rx_mode rx_mode)
+{
+	struct remoti_cec_adapter_priv *apriv = cec_adapter_priv(adapter);
+	struct remoti_cec_priv *priv = apriv->priv;
+	struct rti_msg msg;
+	int ret;
+
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_SREQ;
+	msg.subsys = NPI_SYS_UTIL;
+	msg.cmd = RTI_CEC_MODE;
+
+	msg.data_len = 2;
+	if (rx_mode == CEC_RX_MODE_DISABLED)
+		msg.data[0] = RTI_CEC_MODE_DISABLED;
+	else {
+		msg.data[0] = RTI_CEC_MODE_NORMAL;
+		if (rx_mode == CEC_RX_MODE_ACCEPT_ALL)
+			msg.data[1] = RTI_CEC_RX_FILTER_PROMISC;
+		else
+			msg.data[1] = RTI_CEC_RX_FILTER_DEFAULT;
+	}
+
+	ret = rti_send_sync_msg(priv->udev, &msg);
+	if (ret)
+		return ret;
+
+	if (msg.reply_len != 1)
+		return -EIO;
+
+	return remoti_cec_map_error(msg.reply[0]);
+}
+
+static int remoti_cec_attach(struct cec_adapter *adapter)
+{
+	struct remoti_cec_adapter_priv *apriv = cec_adapter_priv(adapter);
+	struct remoti_cec_priv *priv = apriv->priv;
+	struct rti_msg msg;
+	int ret;
+
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_SREQ;
+	msg.subsys = NPI_SYS_UTIL;
+	msg.cmd = RTI_CEC_ATTACH;
+
+	ret = rti_send_sync_msg(priv->udev, &msg);
+	if (ret)
+		return ret;
+
+	if (msg.reply_len != 1)
+		return -EIO;
+
+	return remoti_cec_map_error(msg.reply[0]);
+}
+
+static int remoti_cec_detach(struct cec_adapter *adapter)
+{
+	struct remoti_cec_adapter_priv *apriv = cec_adapter_priv(adapter);
+	struct remoti_cec_priv *priv = apriv->priv;
+	struct rti_msg msg;
+	int ret;
+
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_SREQ;
+	msg.subsys = NPI_SYS_UTIL;
+	msg.cmd = RTI_CEC_DETACH;
+
+	ret = rti_send_sync_msg(priv->udev, &msg);
+	if (ret)
+		return ret;
+
+	if (msg.reply_len != 1)
+		return -EIO;
+
+	return remoti_cec_map_error(msg.reply[0]);
+}
+
+static void remoti_cec_recv_ind(void *cb_data,
+				const struct rti_msg *msg)
+{
+	struct remoti_cec_priv *priv = (struct remoti_cec_priv *)cb_data;
+	const struct rti_cec_rx_msg *rti_rx_msg;
+	u8 rx_flags;
+
+	if (msg->data_len < RTI_CEC_RX_MSG_CONSTANT_LEN) {
+		printk(KERN_ERR "invalid recv message size\n");
+		return;
+	}
+
+	rti_rx_msg = (const struct rti_cec_rx_msg *)msg->data;
+
+	/* ignore message with non full bytes */
+	if (rti_rx_msg->len % 8)
+		return;
+
+	/* send message to upper layers */
+	rx_flags = 0;
+	if (rti_rx_msg->flags & RTI_CEC_RX_FLAG_ACKED)
+		rx_flags |= CEC_RX_F_ACKED;
+	if (rti_rx_msg->flags & RTI_CEC_RX_FLAG_GOT_EOM)
+		rx_flags |= CEC_RX_F_COMPLETE;
+
+	adapter_rx_done(priv->adapter,
+			rti_rx_msg->data,
+			rti_rx_msg->len / 8,
+			rti_rx_msg->flags & RTI_CEC_RX_FLAG_VALID,
+			rx_flags);
+}
+
+static void remoti_cec_send_cnf(void *cb_data,
+				const struct rti_msg *msg)
+{
+	struct remoti_cec_priv *priv = (struct remoti_cec_priv *)cb_data;
+	const struct rti_cec_tx_status *rti_tx_status;
+	bool tx_success;
+	u8 tx_flags, tx_tries;
+
+	if (msg->data_len < sizeof (*rti_tx_status)) {
+		printk(KERN_ERR "bad completion status\n");
+		tx_success = false;
+		tx_flags = CEC_TX_F_UNKNOWN_ERROR;
+		tx_tries = 0;
+	} else {
+		rti_tx_status = (const struct rti_cec_tx_status *)msg->data;
+		tx_success = (rti_tx_status->status == RTI_CEC_SUCCESS);
+		tx_flags = 0;
+		if (rti_tx_status->flags & RTI_CEC_TX_F_NACK)
+			tx_flags |= CEC_TX_F_NACK;
+		if (rti_tx_status->flags & RTI_CEC_TX_F_TIMEOUT)
+			tx_flags |= CEC_TX_F_TIMEOUT;
+		if (rti_tx_status->flags & RTI_CEC_TX_F_MAX_RETRIES)
+			tx_flags |= CEC_TX_F_MAX_RETRIES;
+		if (rti_tx_status->flags & RTI_CEC_TX_F_ARBITRATION_LOST)
+			tx_flags |= CEC_TX_F_ARBITRATION_LOST;
+		if (rti_tx_status->flags & RTI_CEC_TX_F_MISSED_DEADLINE)
+			tx_flags |= CEC_TX_F_UNKNOWN_ERROR;
+		tx_tries = rti_tx_status->tries;
+	}
+	adapter_tx_done(priv->adapter, tx_success, tx_flags, tx_tries);
+}
+
+static const struct rti_kcallback callbacks[] = {
+	{
+		.subsys		= NPI_SYS_UTIL,
+		.cmd		= RTI_CEC_RECV_MSG_IND,
+		.cb		= remoti_cec_recv_ind,
+	},
+
+	{
+		.subsys		= NPI_SYS_UTIL,
+		.cmd		= RTI_CEC_SEND_MSG_CNF,
+		.cb		= remoti_cec_send_cnf,
+	},
+};
+
+static const struct cec_adapter_ops remoti_cec_ops = {
+	.set_logical_address	= remoti_cec_set_logical_address,
+	.send			= remoti_cec_send,
+	.reset			= remoti_cec_reset,
+	.get_counters		= remoti_cec_get_counters,
+	.set_rx_mode		= remoti_cec_set_rx_mode,
+	.attach			= remoti_cec_attach,
+	.detach			= remoti_cec_detach,
+	.set_detached_config	= remoti_cec_set_detached_config,
+};
+
+static int try_register_cec_adapter(struct remoti_cec_priv *priv)
+{
+	struct cec_adapter *adapter;
+	struct remoti_cec_adapter_priv *apriv;
+	int ret;
+
+	BUG_ON(priv->udev);
+
+	priv->udev = rti_get_udevice(priv->rti_dev_id);
+	if (!priv->udev)
+		return 0;
+
+	adapter = alloc_cec_adapter(sizeof (*apriv));
+	if (!adapter) {
+		dev_err(&priv->pdev->dev, "failed to allocate memory\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	/* setup adapter */
+	adapter->driver_name = "remoti-cec";
+	adapter->ops = &remoti_cec_ops;
+	adapter->module = THIS_MODULE;
+	adapter->flags = CEC_HW_HAS_COUNTERS | CEC_HW_HAS_RX_FILTER;
+
+	/* setup adapter private data */
+	apriv = cec_adapter_priv(adapter);
+	apriv->priv = priv;
+
+	ret = register_cec_adapter(adapter);
+	if (ret) {
+		dev_err(&priv->pdev->dev, "unable to register cec adapter\n");
+		goto fail_free;
+	}
+
+	priv->adapter = adapter;
+
+	ret = rti_register_cmds_callback(priv->udev,
+					 callbacks, ARRAY_SIZE(callbacks),
+					 priv);
+	if (ret) {
+		dev_err(&priv->pdev->dev, "unable to register rti callback\n");
+		goto fail_unregister;
+	}
+
+	return 0;
+
+fail_unregister:
+	unregister_cec_adapter(adapter);
+
+fail_free:
+	free_cec_adapter(adapter);
+	priv->adapter = NULL;
+
+fail:
+	rti_release_udevice(priv->udev);
+	priv->udev = NULL;
+	return ret;
+}
+
+static int rti_udev_notifier_cb(struct notifier_block *n,
+				unsigned long id, void *data)
+{
+	struct remoti_cec_priv *priv;
+	enum rti_udev_state *st = (enum rti_udev_state *)data;
+
+	mutex_lock(&remoti_cec_list_mutex);
+
+	list_for_each_entry(priv, &remoti_cec_list, next) {
+
+		if (priv->rti_dev_id != id)
+			continue;
+
+		switch (*st) {
+		case RTI_UDEV_UP:
+			if (priv->udev)
+				continue;
+
+			try_register_cec_adapter(priv);
+			break;
+
+		case RTI_UDEV_GOING_DOWN:
+			if (!priv->udev)
+				continue;
+
+			unregister_cec_adapter(priv->adapter);
+			free_cec_adapter(priv->adapter);
+			rti_release_udevice(priv->udev);
+			priv->udev = NULL;
+			break;
+		}
+	}
+
+	mutex_unlock(&remoti_cec_list_mutex);
+	return 0;
+}
+
+static struct notifier_block rti_udev_notifier_block = {
+	.notifier_call = rti_udev_notifier_cb,
+};
+
+
+static int __devinit remoti_cec_probe(struct platform_device *pdev)
+{
+	struct remoti_cec_priv *priv;
+
+	priv = kzalloc(sizeof (*priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	priv->pdev = pdev;
+	platform_set_drvdata(pdev, priv);
+
+	mutex_lock(&remoti_cec_list_mutex);
+	try_register_cec_adapter(priv);
+	list_add_tail(&priv->next, &remoti_cec_list);
+	mutex_unlock(&remoti_cec_list_mutex);
+	return 0;
+}
+
+static int __devexit remoti_cec_remove(struct platform_device *pdev)
+{
+	struct remoti_cec_priv *priv = platform_get_drvdata(pdev);
+
+	mutex_lock(&remoti_cec_list_mutex);
+	if (priv->udev) {
+		rti_unregister_cmds_callback(priv->udev,
+					     callbacks, ARRAY_SIZE(callbacks));
+		unregister_cec_adapter(priv->adapter);
+		free_cec_adapter(priv->adapter);
+		rti_release_udevice(priv->udev);
+	}
+	mutex_unlock(&remoti_cec_list_mutex);
+	kfree(priv);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static struct of_device_id remoti_cec_of_ids[] = {
+	{ .compatible = "ti,remoti-cec" },
+	{ /* sentinel*/ },
+};
+MODULE_DEVICE_TABLE(of, remoti_cec_of_ids);
+
+static struct platform_driver remoti_cec_driver = {
+	.driver	= {
+		.name	= "remoti-cec",
+		.owner	= THIS_MODULE,
+		.of_match_table = remoti_cec_of_ids,
+	},
+	.probe	= remoti_cec_probe,
+	.remove	= __devexit_p(remoti_cec_remove),
+};
+
+static int __init remoti_cec_init(void)
+{
+	int ret;
+
+	INIT_LIST_HEAD(&remoti_cec_list);
+
+	ret = platform_driver_register(&remoti_cec_driver);
+	if (ret)
+		return ret;
+
+	rti_register_udevice_notifier(&rti_udev_notifier_block);
+	return 0;
+}
+
+static void __exit remoti_cec_exit(void)
+{
+	rti_unregister_udevice_notifier(&rti_udev_notifier_block);
+	platform_driver_unregister(&remoti_cec_driver);
+}
+
+module_init(remoti_cec_init);
+module_exit(remoti_cec_exit);
+
+MODULE_AUTHOR("Florian Fainelli <ffainelli@freebox.fr>");
+MODULE_DESCRIPTION("CEC transport over RemoTI");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:remoti-cec");
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/drivers/misc/pic16-pmu.c	2012-07-27 18:10:45.084135817 +0200
@@ -0,0 +1,700 @@
+/*
+ * PIC16F72x PMU / LED / button driver
+ *
+ * Copyright (C) 2010, Florian Fainelli <ffainelli@freebox.fr>
+ *
+ * This file is subject to the GPLv2 licensing terms
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/input-polldev.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+
+#define PIC16_PMU_LED_COUNT		3
+#define PIC16_PMU_PWR_COUNT		3
+#define PIC16_PMU_BTN_COUNT		3
+#define PIC16_PMU_RST_COUNT		1
+
+/*
+ * Per LED private structure
+ */
+struct pic16_pmu_led_data {
+	u8 id;
+	u8 status:1;
+	u8 blink:1;
+	struct led_classdev ldev;
+	struct i2c_client *client;
+	struct work_struct work;
+};
+
+struct pic16_pmu_input_data {
+	struct i2c_client *client;
+	struct input_polled_dev	*poll_dev;
+	unsigned short keymap[PIC16_PMU_BTN_COUNT];
+};
+
+static unsigned short default_map[PIC16_PMU_BTN_COUNT] = {
+	BTN_0,
+	BTN_1,
+	BTN_2,
+};
+
+/*
+ * Global device structure
+ */
+struct pic16_pmu_data {
+	struct device *hwmon_dev;
+	struct attribute_group attrs;
+	struct mutex lock;
+	unsigned long last_updated;
+	struct i2c_client *client;
+	struct pic16_pmu_led_data leds[PIC16_PMU_LED_COUNT];
+	struct pic16_pmu_input_data btns;
+	u8 model;
+	u8 revision;
+	u8 power;
+	u8 buttons;
+	u8 resets;
+	u8 hw_revision;
+	struct gpio_chip chip;
+};
+
+static const unsigned short normal_i2c[] = { 0x60, I2C_CLIENT_END };
+
+static const struct i2c_device_id pic16_pmu_idtable[] = {
+	{ "pic16-pmu", 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, pic16_pmu_idtable);
+
+/*
+ * device registers
+ */
+#define PIC16_PMU_REG_DEV	0x00
+#define  PIC16_PMU_16F722	0x22
+
+#define PIC16_PMU_REG_REV	0x01
+#define PIC16_PMU_REG_LED	0x02
+#define PIC16_PMU_REG_PWR	0x03
+#define  PIC16_PMU_REG_PWR_MSK	0x1f
+#define PIC16_PMU_REG_BTN	0x04
+#define PIC16_PMU_REG_RST	0x05
+#define  PIC16_PMU_REG_RST_MSK	0x05
+#define PIC16_PMU_REG_CTL	0x06
+#define PIC16_PMU_REG_BLINK	0x07
+#define PIC16_PMU_REG_HW_REV	0x08
+
+#define PIC16_PMU_REFRESH	(60 * HZ)	/* 1 minute */
+
+static inline int pic16_pmu_reg_read(struct i2c_client *client, u8 reg, u8 *value)
+{
+	int tmp;
+
+	tmp = i2c_smbus_read_byte_data(client, reg);
+	if (tmp < 0)
+		tmp = i2c_smbus_read_byte_data(client, reg);
+		if (tmp < 0)
+			return -EINVAL;
+
+	*value = tmp;
+
+	return 0;
+}
+
+static inline int pic16_pmu_reg_write(struct i2c_client *client, u8 reg, u8 value)
+{
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static struct pic16_pmu_data *pic16_pmu_update(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct pic16_pmu_data *data = i2c_get_clientdata(client);
+	u8 val;
+	int ret;
+	unsigned long local_jiffies = jiffies;
+
+	mutex_lock(&data->lock);
+	if (time_before(local_jiffies, data->last_updated +
+			PIC16_PMU_REFRESH))
+		goto exit;
+
+	ret = pic16_pmu_reg_read(client, PIC16_PMU_REG_DEV, &val);
+	if (ret) {
+		dev_err(&client->dev, "error reading device model\n");
+		goto exit;
+	}
+	data->model = val;
+
+	ret = pic16_pmu_reg_read(client, PIC16_PMU_REG_REV, &val);
+	if (ret) {
+		dev_err(&client->dev, "error reading revision\n");
+		goto exit;
+	}
+	data->revision = val;
+
+	ret = pic16_pmu_reg_read(client, PIC16_PMU_REG_PWR, &val);
+	if (ret) {
+		dev_err(&client->dev, "erorr reading power status\n");
+		goto exit;
+	}
+	data->power = val;
+
+	ret = pic16_pmu_reg_read(client, PIC16_PMU_REG_BTN, &val);
+	if (ret) {
+		dev_err(&client->dev, "error reading button status\n");
+		goto exit;
+	}
+	data->buttons = val;
+
+	ret = pic16_pmu_reg_read(client, PIC16_PMU_REG_RST, &val);
+	if (ret) {
+		dev_err(&client->dev, "error reading reset status\n");
+		goto exit;
+	}
+	data->resets = val;
+
+	ret = pic16_pmu_reg_read(client, PIC16_PMU_REG_HW_REV, &val);
+	if (ret) {
+		dev_err(&client->dev, "error reading hw revision\n");
+		goto exit;
+	}
+	data->hw_revision = val;
+
+	data->last_updated = local_jiffies;
+exit:
+	mutex_unlock(&data->lock);
+	return data;
+}
+
+static ssize_t show_pwr(struct device *dev,
+			struct device_attribute *devattr,
+			char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct pic16_pmu_data *data = pic16_pmu_update(dev);
+	int val;
+
+	val = (((data->power & PIC16_PMU_REG_PWR_MSK) &
+					(1 << attr->index)) >> attr->index);
+
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t show_model(struct device *dev,
+			struct device_attribute *devattr,
+			char *buf)
+{
+	struct pic16_pmu_data *data = pic16_pmu_update(dev);
+	return sprintf(buf, "Microchip PIC16F%02x\n", data->model);
+}
+
+static ssize_t show_revision(struct device *dev,
+			struct device_attribute *devattrr,
+			char *buf)
+{
+	struct pic16_pmu_data *data = pic16_pmu_update(dev);
+	return sprintf(buf, "%02x\n", data->revision);
+}
+
+static ssize_t show_hw_revision(struct device *dev,
+			struct device_attribute *devattrr,
+			char *buf)
+{
+	struct pic16_pmu_data *data = pic16_pmu_update(dev);
+	return sprintf(buf, "%02x\n", data->hw_revision);
+}
+
+static ssize_t show_rst(struct device *dev,
+			struct device_attribute *devattr,
+			char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct pic16_pmu_data *data = pic16_pmu_update(dev);
+	int val;
+
+	val = (((data->resets & PIC16_PMU_REG_RST_MSK) &
+					(1 << attr->index)) >> attr->index);
+
+	return sprintf(buf, "%d\n", val);
+}
+
+static int pic16_pmu_set_reset(struct i2c_client *client,
+				struct pic16_pmu_data *data,
+				unsigned int index, long value)
+{
+	int ret;
+	u8 val = data->resets;
+
+	if (value)
+		val |= (1 << index);
+	else
+		val &= ~(1 << index);
+
+	data->resets = val;
+
+	mutex_lock(&data->lock);
+	ret = pic16_pmu_reg_write(client, PIC16_PMU_REG_RST, val);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static ssize_t set_rst(struct device *dev,
+			struct device_attribute *devattr,
+			const char *buf,
+			size_t count)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct pic16_pmu_data *data = pic16_pmu_update(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+	long temp;
+
+	if (strict_strtol(buf, 10, &temp))
+		return -EINVAL;
+
+	pic16_pmu_set_reset(client, data, attr->index, temp);
+
+	return count;
+}
+
+static ssize_t show_btn(struct device *dev,
+			struct device_attribute *devattr,
+			char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct pic16_pmu_data *data = i2c_get_clientdata(client);
+	u8 val = 0;
+	int ret;
+
+	mutex_lock(&data->lock);
+	ret = pic16_pmu_reg_read(client, PIC16_PMU_REG_BTN, &val);
+	if (ret) {
+		dev_err(&client->dev, "unable to read status\n");
+		goto out_unlock;
+	}
+
+	val = (val & (1 << attr->index)) >> attr->index;
+
+out_unlock:
+	mutex_unlock(&data->lock);
+	return sprintf(buf, "%u\n", 1 - val);
+}
+
+/*
+ * Power attributes
+ */
+static SENSOR_DEVICE_ATTR(pwrgd_ps, S_IRUGO, show_pwr, NULL, 0);
+static SENSOR_DEVICE_ATTR(vcc1p5_ddr_pg, S_IRUGO, show_pwr, NULL, 1);
+static SENSOR_DEVICE_ATTR(vcc0p95_core_ok, S_IRUGO, show_pwr, NULL, 2);
+static SENSOR_DEVICE_ATTR(power_state, S_IRUGO, show_pwr, NULL, 3);
+static SENSOR_DEVICE_ATTR(standby_state, S_IRUGO, show_pwr, NULL, 4);
+
+/*
+ * Device revision attributes
+ */
+static SENSOR_DEVICE_ATTR(revision, S_IRUGO, show_revision, NULL, 0);
+static SENSOR_DEVICE_ATTR(model, S_IRUGO, show_model, NULL, 0);
+static SENSOR_DEVICE_ATTR(hw_revision, S_IRUGO, show_hw_revision, NULL, 0);
+
+/*
+ * Reset control attributes
+ */
+static SENSOR_DEVICE_ATTR(rf_rst, S_IWUSR | S_IRUGO, show_rst, set_rst, 0);
+static SENSOR_DEVICE_ATTR(cold_rst, S_IWUSR | S_IRUGO, show_rst, set_rst, 1);
+static SENSOR_DEVICE_ATTR(dvd_en, S_IWUSR | S_IRUGO, show_rst, set_rst, 2);
+
+/*
+ * Button attributes
+ */
+static SENSOR_DEVICE_ATTR(bank0_btn, S_IRUGO, show_btn, NULL, 0);
+static SENSOR_DEVICE_ATTR(reset_btn, S_IRUGO, show_btn, NULL, 1);
+static SENSOR_DEVICE_ATTR(power_btn, S_IRUGO, show_btn, NULL, 2);
+
+static struct attribute *pic16_pmu_attr[] = {
+	&sensor_dev_attr_pwrgd_ps.dev_attr.attr,
+	&sensor_dev_attr_vcc1p5_ddr_pg.dev_attr.attr,
+	&sensor_dev_attr_vcc0p95_core_ok.dev_attr.attr,
+	&sensor_dev_attr_power_state.dev_attr.attr,
+	&sensor_dev_attr_standby_state.dev_attr.attr,
+	&sensor_dev_attr_revision.dev_attr.attr,
+	&sensor_dev_attr_model.dev_attr.attr,
+	&sensor_dev_attr_rf_rst.dev_attr.attr,
+	&sensor_dev_attr_cold_rst.dev_attr.attr,
+	&sensor_dev_attr_dvd_en.dev_attr.attr,
+	&sensor_dev_attr_hw_revision.dev_attr.attr,
+	&sensor_dev_attr_bank0_btn.dev_attr.attr,
+	&sensor_dev_attr_reset_btn.dev_attr.attr,
+	&sensor_dev_attr_power_btn.dev_attr.attr,
+	NULL
+};
+
+static void pic16_pmu_set_brightness(struct led_classdev *led_cdev,
+				enum led_brightness brightness)
+{
+	struct pic16_pmu_led_data *led;
+
+	led = container_of(led_cdev, struct pic16_pmu_led_data, ldev);
+	led->status = brightness;
+	schedule_work(&led->work);
+}
+
+static int pic16_pmu_set_blink(struct led_classdev *led_cdev,
+				unsigned long *delay_on, unsigned long *delay_off)
+{
+	struct pic16_pmu_led_data *led;
+
+	led = container_of(led_cdev, struct pic16_pmu_led_data, ldev);
+	led->blink = !led->blink;
+	schedule_work(&led->work);
+
+	return 0;
+}
+
+static int pic16_pmu_led_set(struct pic16_pmu_led_data *led, u8 status, u8 blink)
+{
+	struct pic16_pmu_data *data = i2c_get_clientdata(led->client);
+	int ret;
+	u8 val = 0;
+
+	mutex_lock(&data->lock);
+
+	ret = pic16_pmu_reg_read(led->client, PIC16_PMU_REG_BLINK, &val);
+	if( ret) {
+		dev_err(&led->client->dev, "error reading BLINK reg for %d\n",
+								led->id);
+		goto exit;
+	}
+
+	if (blink)
+		val |= (1 << led->id);
+	else
+		val &= ~(1 << led->id);
+
+	ret = pic16_pmu_reg_write(led->client, PIC16_PMU_REG_BLINK, val);
+	if (ret) {
+		dev_err(&led->client->dev, "error writing back to BLINK reg value"
+							" for %d\n", led->id);
+		goto exit;
+	}
+
+	val = (1 << (led->id + 4));
+	if (status)
+		val |= (1 << led->id);
+
+	ret = pic16_pmu_reg_write(led->client, PIC16_PMU_REG_LED, val);
+	if (ret) {
+		dev_err(&led->client->dev, "error writing back to LED reg value"
+			" for %d\n", led->id);
+		goto exit;
+	}
+
+exit:
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static void pic16_pmu_led_work(struct work_struct *work)
+{
+	struct pic16_pmu_led_data *led;
+
+	led = container_of(work, struct pic16_pmu_led_data, work);
+	pic16_pmu_led_set(led, led->status, led->blink);
+}
+
+static struct led_classdev pic16_pmu_leds[] = {
+	{	.name			= "power:red", },
+	{ 	.name			= "power:blue", },
+	{	.name			= "error:red",},
+};
+
+static int pic16_pmu_led_configure(struct i2c_client *client)
+{
+	int i, err = 0;
+	struct pic16_pmu_data *data = i2c_get_clientdata(client);
+	u8 val;
+
+	mutex_lock(&data->lock);
+	err = pic16_pmu_reg_read(client, PIC16_PMU_REG_LED, &val);
+	mutex_unlock(&data->lock);
+
+	if (err)
+		return err;
+
+	data->last_updated = jiffies - PIC16_PMU_REFRESH - 1;
+
+	for (i = 0; i < PIC16_PMU_LED_COUNT; i++) {
+		struct pic16_pmu_led_data *led = &data->leds[i];
+
+		led->id = i;
+		led->client = client;
+
+		led->status = val & (1 << i);
+		memcpy(&led->ldev, &pic16_pmu_leds[i], sizeof(struct led_classdev));
+
+		led->ldev.max_brightness = 1;
+		led->ldev.brightness_set = pic16_pmu_set_brightness;
+		led->ldev.blink_set = pic16_pmu_set_blink;
+		led->ldev.flags	= LED_CORE_SUSPENDRESUME;
+
+		INIT_WORK(&led->work, pic16_pmu_led_work);
+		err = led_classdev_register(&client->dev, &led->ldev);
+		if (err < 0) {
+			dev_err(&client->dev, "cannot register LED %s\n",
+				led->ldev.name);
+			goto exit;
+		}
+	}
+
+	return err;
+exit:
+	if (i > 0) {
+		for (i = i - 1; i >= 0; i--) {
+			led_classdev_unregister(&data->leds[i].ldev);
+			cancel_work_sync(&data->leds[i].work);
+		}
+	}
+	return err;
+}
+
+static int pic16_pmu_detect(struct i2c_client *client,
+			    struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	int device, revision;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	device = i2c_smbus_read_byte_data(client, PIC16_PMU_REG_DEV);
+	if (device != PIC16_PMU_16F722)
+		return -ENODEV;
+
+	revision = i2c_smbus_read_byte_data(client, PIC16_PMU_REG_REV);
+	dev_info(&client->dev, "device: PIC16F%02x rev: %02x\n",
+		 device, revision);
+
+	strlcpy(info->type, "pic16-pmu", I2C_NAME_SIZE);
+
+	return 0;
+}
+
+/*
+ * input callbacks
+ */
+static void pic16_pmu_input_poll(struct input_polled_dev *dev)
+{
+	struct pic16_pmu_input_data *priv = dev->private;
+	struct input_dev *input = dev->input;
+	struct pic16_pmu_data *data = i2c_get_clientdata(priv->client);
+	u8 val;
+	int ret, i;
+
+	mutex_lock(&data->lock);
+	ret = pic16_pmu_reg_read(priv->client, PIC16_PMU_REG_BTN, &val);
+	if (ret) {
+		dev_err(&input->dev, "unable to read status\n");
+		goto out_unlock;
+	}
+
+	for (i = 0; i < PIC16_PMU_BTN_COUNT; i++)
+		input_report_key(input, priv->keymap[i],
+				(val & (1 << i)) ? 0 : 1);
+	input_sync(input);
+
+out_unlock:
+	mutex_unlock(&data->lock);
+}
+
+/*
+ * gpiolib callbacks
+ */
+static void pic16_pmu_gpio_set(struct gpio_chip *chip,
+				unsigned offset, int value)
+{
+	struct pic16_pmu_data *data;
+
+	data = container_of(chip, struct pic16_pmu_data, chip);
+
+	pic16_pmu_set_reset(data->client, data, offset, value);
+}
+
+static int pic16_pmu_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct pic16_pmu_data *data;
+
+	data = container_of(chip, struct pic16_pmu_data, chip);
+
+	return data->resets & (1 << offset);
+}
+
+static int pic16_pmu_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return 0;
+}
+
+static int pic16_pmu_gpio_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
+{
+	return 0;
+}
+
+static int __devinit pic16_pmu_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct pic16_pmu_data *data;
+	struct input_polled_dev *poll_dev;
+	struct input_dev *input;
+	int err, i;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	data->client = client;
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->lock);
+
+	dev_info(&client->dev, "%s chip found\n", client->name);
+
+	data->attrs.attrs = pic16_pmu_attr;
+	err = sysfs_create_group(&client->dev.kobj, &data->attrs);
+	if (err)
+		goto exit_free;
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		goto exit_remove;
+	}
+
+	poll_dev = input_allocate_polled_device();
+	if (!poll_dev) {
+		err = -ENOMEM;
+		goto exit_hwmon;
+	}
+
+	data->btns.client = client;
+	data->btns.poll_dev = poll_dev;
+	memcpy(data->btns.keymap, default_map, sizeof(default_map));
+	poll_dev->private = &data->btns;
+	poll_dev->poll = pic16_pmu_input_poll;
+	poll_dev->poll_interval = 200; /* ms */
+
+	input = poll_dev->input;
+	input->name = "pic16-pmu";
+	input->phys = "pic16-pmu/input0";
+	input->id.bustype = BUS_I2C;
+	input->dev.parent = &client->dev;
+	input->keycode = data->btns.keymap;
+	input->keycodemax = ARRAY_SIZE(data->btns.keymap);
+	input->keycodesize = sizeof(unsigned short);
+
+	set_bit(EV_KEY, input->evbit);
+	for (i = 0; i < ARRAY_SIZE(data->btns.keymap); i++)
+		set_bit(data->btns.keymap[i], input->keybit);
+
+	err = input_register_polled_device(poll_dev);
+	if (err)
+		goto exit_input;
+
+	/*
+	 * update device on startup to provide consistent
+	 * informations
+	 */
+	pic16_pmu_update(&client->dev);
+
+	/* Register gpiochip driver */
+	data->chip.label = "pic16-pmu";
+	data->chip.set = pic16_pmu_gpio_set;
+	data->chip.get = pic16_pmu_gpio_get;
+	data->chip.direction_input = pic16_pmu_gpio_direction_input;
+	data->chip.direction_output = pic16_pmu_gpio_direction_output;
+	data->chip.base = 100;
+	data->chip.ngpio = PIC16_PMU_RST_COUNT;
+
+	err = gpiochip_add(&data->chip);
+	if (err)
+		goto exit_input;
+
+	return pic16_pmu_led_configure(client);
+
+exit_input:
+	input_free_polled_device(poll_dev);
+exit_hwmon:
+	hwmon_device_unregister(data->hwmon_dev);
+exit_remove:
+	sysfs_remove_group(&client->dev.kobj, &data->attrs);
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int __devexit pic16_pmu_remove(struct i2c_client *client)
+{
+	int i;
+	struct pic16_pmu_data *data = i2c_get_clientdata(client);
+
+	gpiochip_remove(&data->chip);
+
+	for (i = 0; i < PIC16_PMU_LED_COUNT; i++) {
+		led_classdev_unregister(&data->leds[i].ldev);
+		cancel_work_sync(&data->leds[i].work);
+	}
+
+	input_unregister_polled_device(data->btns.poll_dev);
+	input_free_polled_device(data->btns.poll_dev);
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &data->attrs);
+	kfree(data);
+	i2c_set_clientdata(client, NULL);
+
+	return 0;
+}
+
+static struct i2c_driver pic16_pmu_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver	= {
+		.name	= "pic16-pmu",
+	},
+	.id_table	= pic16_pmu_idtable,
+	.probe		= pic16_pmu_probe,
+	.remove		= __devexit_p(pic16_pmu_remove),
+	.detect		= pic16_pmu_detect,
+};
+
+static int __init pic16_pmu_init(void)
+{
+	return i2c_add_driver(&pic16_pmu_driver);
+}
+
+static void __exit pic16_pmu_exit(void)
+{
+	i2c_del_driver(&pic16_pmu_driver);
+}
+
+module_init(pic16_pmu_init);
+module_exit(pic16_pmu_exit);
+
+MODULE_AUTHOR("Florian Fainelli <ffainelli@freebox.fr>");
+MODULE_DESCRIPTION("PIC16F7xx PMU / LED i2c driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pic16-pmu");
diff -Nruw linux-3.2.24-fbx/drivers/misc/remoti./core.c linux-3.2.24-fbx/drivers/misc/remoti/core.c
--- linux-3.2.24-fbx/drivers/misc/remoti./core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/remoti/core.c	2013-06-13 15:52:30.409198280 +0200
@@ -0,0 +1,1918 @@
+/*
+ * Copyright (C) 2010 Florian Fainelli <ffainelli@freebox.fr>
+ *
+ * RemoTI core module driver.
+ *
+ * This file is subject to the GPLv2 licensing terms.
+ */
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/completion.h>
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/gpio.h>
+#include <linux/tty.h>
+#include <linux/of.h>
+
+#include "core-priv.h"
+
+#define REMOTI_FW_NAME		"rnp_cc2530.bin"
+#define REMOTI_FW_MAX_SIZE	((256 - 2) * 1024)
+#define REMOTI_MSG_TIMEOUT	(5 * HZ)
+
+/* list of remoti devices */
+static DEFINE_SPINLOCK(remoti_devs_list_lock);
+static struct list_head remoti_devs_list;
+
+static struct blocking_notifier_head udev_notifier;
+
+/*
+ * toggle device hw reset gpio
+ */
+static void dev_hw_reset_set(struct remoti_device *rd, int value)
+{
+	int ret;
+
+	ret = gpio_request(rd->pdata.reset_gpio, rd->pdev->name);
+	if (ret) {
+		dev_err(&rd->pdev->dev, "failed to request reset gpio: %d\n",
+			ret);
+		return;
+	}
+
+	gpio_direction_output(rd->pdata.reset_gpio, value);
+	gpio_set_value(rd->pdata.reset_gpio, value);
+	gpio_free(rd->pdata.reset_gpio);
+}
+
+static void dev_hw_reset_hold(struct remoti_device *rd)
+{
+	dev_hw_reset_set(rd, 1);
+}
+
+static void dev_hw_reset_release(struct remoti_device *rd)
+{
+	dev_hw_reset_set(rd, 0);
+}
+
+static void dev_hw_reset_cycle(struct remoti_device *rd)
+{
+	dev_hw_reset_hold(rd);
+	msleep(1);
+	dev_hw_reset_release(rd);
+	msleep(1);
+}
+
+/*
+ *
+ */
+static void handle_rx_msg(struct remoti_device *rd,
+			  struct remoti_rx_msg *rx_msg)
+{
+	struct remoti_tx_msg *tx_msg;
+	const struct rti_msg *msg;
+
+	rd->stats.rx_packets++;
+	msg = &rx_msg->msg;
+
+	/* sanity check */
+	if (msg->subsys >= NPI_SYS_MAX) {
+		dev_err(&rd->pdev->dev, "received message with "
+			"unknown subsys: %u\n", msg->subsys);
+		rd->stats.rx_subsys_errors++;
+		goto release_msg;
+	}
+
+	if (msg->type >= NPI_TYPE_MAX) {
+		dev_err(&rd->pdev->dev, "received message with "
+			"unknown type: %u\n", msg->type);
+		rd->stats.rx_type_errors++;
+		goto release_msg;
+	}
+
+	switch (msg->subsys) {
+	case NPI_SYS_RCAF:
+		rd->stats.rx_rcaf_packets++;
+		break;
+	case NPI_SYS_BOOT:
+		rd->stats.rx_boot_packets++;
+		break;
+	case NPI_SYS_UTIL:
+		rd->stats.rx_util_packets++;
+		break;
+	default:
+		rd->stats.rx_other_packets++;
+		break;
+	}
+
+	switch (msg->type) {
+	case NPI_AREQ:
+	{
+		struct remoti_cmd_callback *cb;
+		bool found;
+
+		/* async message, deliver to all listeners */
+		found = false;
+		spin_lock(&rd->callback_list_lock);
+		list_for_each_entry(cb, &rd->callback_list, next) {
+			if (msg->subsys == cb->subsys &&
+			    msg->cmd == cb->cmd) {
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			spin_unlock(&rd->callback_list_lock);
+			if (printk_ratelimit())
+				dev_warn(&rd->pdev->dev,
+					 "no callback for async "
+					 "message type:%u subsys:%u "
+					 "cmd:0x%02x data_len:%u\n",
+					 msg->type, msg->subsys,
+					 msg->cmd, msg->data_len);
+			rd->stats.rx_no_callback++;
+			break;
+		}
+
+		cb->cb(cb->cb_priv, msg);
+		spin_unlock(&rd->callback_list_lock);
+		break;
+	}
+
+	case NPI_SREQ:
+		dev_warn(&rd->pdev->dev, "received unexpected sync "
+			 "request type:%u subsys:%u cmd:0x%02x "
+			 "data_len:%u\n",
+			 msg->type, msg->subsys,
+			 msg->cmd, msg->data_len);
+		break;
+
+	case NPI_POLL:
+	case NPI_SRSP:
+		/*
+		 * check if it is a synchronous reply to the currently
+		 * pending tx message, note that we are serialized wrt
+		 * tx_work since we run in the same workqueue
+		 *
+		 * note that we handle NPI_POLL like a response
+		 * because the serial bootloader does not use any
+		 * type, but still behave like synchronous
+		 */
+		tx_msg = NULL;
+		spin_lock(&rd->tx_msg_list_lock);
+		if (!list_empty(&rd->tx_msg_list)) {
+			tx_msg = list_first_entry(&rd->tx_msg_list,
+						  struct remoti_tx_msg, next);
+			if (tx_msg->tx_state != RTI_TX_MSG_S_WAIT_RX_ACK)
+				tx_msg = NULL;
+		}
+		spin_unlock(&rd->tx_msg_list_lock);
+
+		if (!tx_msg) {
+			dev_warn(&rd->pdev->dev, "received unexpected sync "
+				 "response type:%u subsys:%u cmd:0x%02x\n",
+				 msg->type, msg->subsys, msg->cmd);
+			goto release_msg;
+		}
+
+		if (tx_msg &&
+		    (tx_msg->msg->subsys != msg->subsys ||
+		     tx_msg->msg->reply_cmd != msg->cmd)) {
+			/* can't find any corresponding synchronous
+			 * request */
+			dev_warn(&rd->pdev->dev, "received unexpected sync "
+				 "response type:%u subsys:%u cmd:0x%02x - "
+				 "pending subsys:%u cmd:0x%02x\n",
+				 msg->type, msg->subsys, msg->cmd,
+				 tx_msg->msg->subsys,
+				 tx_msg->msg->reply_cmd);
+			goto release_msg;
+		}
+
+		/* copy message data inside tx message and complete
+		 * its transmission */
+		memcpy(tx_msg->msg->reply, msg->data, msg->data_len);
+		tx_msg->msg->reply_len = msg->data_len;
+
+		spin_lock(&rd->tx_msg_list_lock);
+		list_del(&tx_msg->next);
+		spin_unlock(&rd->tx_msg_list_lock);
+
+		/* kick tx work now that message is complete */
+		queue_work(rd->io_workqueue, &rd->tx_work);
+		complete(&tx_msg->complete);
+		break;
+	}
+
+release_msg:
+	kfree(rx_msg);
+}
+
+/*
+ * workqueue used to handle rx commands
+ */
+static void remoti_rx_work(struct work_struct *work)
+{
+	struct remoti_device *rd =
+		container_of(work, struct remoti_device, rx_work);
+
+	/* stop_tty() locking seems unreliable, make sure rx seems
+	 * stopped when we set stopping state */
+	if (dev_is_stopping(rd))
+		return;
+
+	/* dequeue all pending messages */
+	do {
+		struct remoti_rx_msg *rx_msg;
+		unsigned long flags;
+
+		/* tty recv can run from irq context */
+		rx_msg = NULL;
+		spin_lock_irqsave(&rd->rx_msg_list_lock, flags);
+		if (!list_empty(&rd->rx_msg_list)) {
+			rx_msg = list_first_entry(&rd->rx_msg_list,
+						  struct remoti_rx_msg, next);
+			list_del(&rx_msg->next);
+		}
+		spin_unlock_irqrestore(&rd->rx_msg_list_lock, flags);
+
+		if (!rx_msg)
+			break;
+
+		handle_rx_msg(rd, rx_msg);
+
+	} while (1);
+}
+
+/*
+ * generate fcs for uart rti frames
+ */
+static u8 remoti_calc_fcs(const u8 *data, int len, u8 fcs)
+{
+	while (len--)
+		fcs ^= *data++;
+
+	return fcs;
+}
+
+/*
+ * handle valid char received on UART
+ */
+static void remoti_tty_recv_char(struct remoti_device *rd, const u8 c)
+{
+	switch (rd->tty_fsm_state) {
+	case RTI_TTY_FSM_SOF:
+		switch (c) {
+		case RTI_UART_CHR_WAKEUP:
+			complete(&rd->wakeup_complete);
+			break;
+		case RTI_UART_CHR_SOF:
+			rd->tty_fsm_state = RTI_TTY_FSM_LEN;
+			break;
+		default:
+			rd->stats.rx_bad_sof++;
+			break;
+		}
+		break;
+
+	case RTI_TTY_FSM_LEN:
+		if (c == RTI_UART_CHR_SOF)
+			break;
+
+		/* Guard against malformed frames */
+		if (c > NPI_MAX_DATA_LEN) {
+			dev_err(&rd->pdev->dev, "ignoring too big "
+				"frame: len: %u\n", c);
+			rd->stats.rx_len_errors++;
+			rd->tty_fsm_state = RTI_TTY_FSM_SOF;
+			break;
+		}
+
+		rd->rx_buf[0] = c;
+		rd->rx_buf_len = 1;
+		rd->tty_fsm_state = RTI_TTY_FSM_DATA;
+		break;
+
+	case RTI_TTY_FSM_DATA:
+	{
+		size_t total_len;
+
+		rd->rx_buf[rd->rx_buf_len++] = c;
+
+		/* total bytes to read is hdr_size (len + subsys + cmd) +
+		 * data_len */
+		total_len = 3 + rd->rx_buf[0];
+		if (rd->rx_buf_len == total_len)
+			rd->tty_fsm_state = RTI_TTY_FSM_FCS;
+		break;
+	}
+
+	case RTI_TTY_FSM_FCS:
+	{
+		struct remoti_rx_msg *rx_msg;
+		struct rti_msg *msg;
+		u8 fcs;
+
+		rd->tty_fsm_state = RTI_TTY_FSM_SOF;
+
+		fcs = remoti_calc_fcs(rd->rx_buf, rd->rx_buf_len, 0);
+		if (fcs != c) {
+			rd->stats.rx_fcs_errors++;
+			dev_err(&rd->pdev->dev, "got fcs error "
+				"on rx message\n");
+			break;
+		}
+
+
+		rx_msg = kmalloc(sizeof (*rx_msg), GFP_ATOMIC);
+		if (!rx_msg) {
+			rd->stats.rx_full_errors++;
+			break;
+		}
+
+		msg = &rx_msg->msg;
+		msg->type = (rd->rx_buf[1] >> NPI_TYPE_SHIFT) & NPI_TYPE_MASK;
+		msg->subsys = rd->rx_buf[1] & NPI_SYS_MASK;
+		msg->cmd = rd->rx_buf[2];
+		msg->data_len = rd->rx_buf[0];
+		memcpy(msg->data, rd->rx_buf + 3, msg->data_len);
+
+		/* add message to rx queue & schedule work */
+		spin_lock(&rd->rx_msg_list_lock);
+		list_add_tail(&rx_msg->next, &rd->rx_msg_list);
+		spin_unlock(&rd->rx_msg_list_lock);
+		queue_work(rd->io_workqueue, &rd->rx_work);
+		break;
+	}
+	}
+}
+
+/*
+ * kernel callback when there are data to read on uart
+ */
+static void remoti_tty_recv_buf(struct tty_struct *tty, const u8 *data,
+				char *flags, int count)
+{
+	struct remoti_device *rd;
+	const u8 *dp;
+	char flag;
+	char *f;
+	int i;
+
+	/* if line is not yet attached to any device, just ignore */
+	rd = (struct remoti_device *)tty->disc_data;
+	if (!rd)
+		return;
+
+	/* Walk the received buffer in inverse order */
+	for (i = 0, dp = data, f = flags; i < count; i++, dp++) {
+		flag = *f++;
+		switch (flag) {
+		case TTY_NORMAL:
+			remoti_tty_recv_char(rd, *dp);
+			break;
+		case TTY_OVERRUN:
+		case TTY_BREAK:
+		case TTY_PARITY:
+		case TTY_FRAME:
+			rd->tty_fsm_state = RTI_TTY_FSM_SOF;
+			rd->stats.rx_tty_errors++;
+			break;
+		default:
+			pr_err("%s: unknown tty flag %d\n", tty->name, flag);
+			break;
+		}
+	}
+	rd->stats.rx_bytes += count;
+}
+
+/*
+ *
+ */
+static void release_tx_msg(struct remoti_tx_msg *tx_msg)
+{
+	if (!atomic_dec_and_test(&tx_msg->users))
+		return;
+	kfree(tx_msg);
+}
+
+/*
+ * workqueue used to dequeue and push command into tx buf and wait for
+ * completion
+ */
+static void remoti_tx_work(struct work_struct *work)
+{
+	struct remoti_device *rd =
+		container_of(work, struct remoti_device, tx_work);
+	struct remoti_tx_msg *tx_msg;
+	u8 buf[RTI_MAX_FRAME_LEN + 1]; /* +1 is for the wakeup char */
+	unsigned int buf_len;
+	int room, sent;
+
+	/* don't handle with tx message list when we try to stop
+	 * device, we will force complete them from another place */
+	if (dev_is_stopping(rd))
+		return;
+
+	tx_msg = NULL;
+	spin_lock(&rd->tx_msg_list_lock);
+	if (!list_empty(&rd->tx_msg_list))
+		tx_msg = list_first_entry(&rd->tx_msg_list,
+					  struct remoti_tx_msg, next);
+	spin_unlock(&rd->tx_msg_list_lock);
+
+
+	if (!tx_msg) {
+		/* no message to send, send wakeup if requested */
+		if (rd->tx_need_send_wakeup) {
+			buf[0] = RTI_UART_CHR_WAKEUP;
+			sent = rd->tty->ops->write(rd->tty, buf, 1);
+			if (sent)
+				rd->tx_need_send_wakeup = false;
+		}
+		return;
+	}
+
+	if (tx_msg->tx_state == RTI_TX_MSG_S_WAIT_RX_ACK) {
+		/* we are waiting for an rx ack for this message,
+		 * don't send anything */
+		return;
+	}
+
+	room = tty_write_room(rd->tty);
+	if (room == 0) {
+		/* no room, tty resume callback will reschedule tx
+		 * later */
+		return;
+	}
+
+	buf_len = 0;
+	switch (tx_msg->tx_state) {
+	case RTI_TX_MSG_S_WAITING:
+		if (room && rd->tx_need_send_wakeup) {
+			buf[buf_len++] = RTI_UART_CHR_WAKEUP;
+			room--;
+			rd->tx_need_send_wakeup = false;
+		}
+
+		if (!room)
+			break;
+
+		buf[buf_len++] = RTI_UART_CHR_SOF;
+		room--;
+		tx_msg->tx_state = RTI_TX_MSG_S_SOF_SENT;
+		/* fallthrough */
+
+	case RTI_TX_MSG_S_SOF_SENT:
+		/* send all header at once */
+		if (room < 3)
+			break;
+
+		buf[buf_len] = tx_msg->msg->data_len;
+		buf[buf_len + 1] = (tx_msg->msg->type << NPI_TYPE_SHIFT) |
+			(tx_msg->msg->subsys & NPI_SYS_MASK);
+		buf[buf_len + 2] = tx_msg->msg->cmd;
+		tx_msg->fcs = remoti_calc_fcs(buf + buf_len, 3, tx_msg->fcs);
+
+		buf_len += 3;
+		room -= 3;
+		tx_msg->tx_state = RTI_TX_MSG_S_HDR_SENT;
+		/* fallthrough */
+
+	case RTI_TX_MSG_S_HDR_SENT:
+	{
+		size_t to_send;
+
+		/* send as many data as possible */
+		to_send = tx_msg->msg->data_len - tx_msg->tx_data_sent;
+		if (to_send > room)
+			to_send = room;
+
+		memcpy(buf + buf_len,
+		       tx_msg->msg->data + tx_msg->tx_data_sent,
+		       to_send);
+
+		tx_msg->fcs = remoti_calc_fcs(buf + buf_len, to_send,
+					      tx_msg->fcs);
+		buf_len += to_send;
+		tx_msg->tx_data_sent += to_send;
+		room -= to_send;
+
+		if (tx_msg->tx_data_sent != tx_msg->msg->data_len)
+			break;
+
+		tx_msg->tx_state = RTI_TX_MSG_S_DATA_SENT;
+		/* fallthrough */
+	}
+
+	case RTI_TX_MSG_S_DATA_SENT:
+		if (!room)
+			break;
+
+		buf[buf_len++] = tx_msg->fcs;
+		tx_msg->tx_state = RTI_TX_MSG_S_SENT;
+		break;
+
+	default:
+		break;
+	}
+
+	if (!buf_len)
+		return;
+
+#if 0
+	printk("remoti_tx_work: sending buf_len %u\n", buf_len);
+	{
+		size_t i;
+
+		for (i = 0; i < buf_len; i++) {
+			printk("%02x ", buf[i]);
+		}
+		printk("\n");
+	}
+#endif
+
+	sent = rd->tty->ops->write(rd->tty, buf, buf_len);
+	if (unlikely(sent < 0)) {
+		pr_err("tty->ops->write failed with %d\n", sent);
+		return;
+	}
+
+	if (unlikely(sent < buf_len)) {
+		/* since we check available room before calling write,
+		 * this only happen when tty is closing */
+		spin_lock(&rd->tx_msg_list_lock);
+		tx_msg->canceled = true;
+		list_del(&tx_msg->next);
+		complete(&tx_msg->complete);
+		release_tx_msg(tx_msg);
+		spin_unlock(&rd->tx_msg_list_lock);
+		return;
+	}
+
+	rd->stats.tx_bytes += sent;
+
+	if (tx_msg->tx_state == RTI_TX_MSG_S_SENT) {
+
+		/* actually wait for data to be written it hw fifo,
+		 * not just in tty buffer, before we complete message
+		 * sending */
+		rd->tty->ops->wait_until_sent(rd->tty, 0);
+
+		/* send complete, update counters */
+		rd->stats.tx_packets++;
+		switch (tx_msg->msg->subsys) {
+		case NPI_SYS_RCAF:
+			rd->stats.tx_rcaf_packets++;
+			break;
+		case NPI_SYS_UTIL:
+			rd->stats.tx_util_packets++;
+			break;
+		case NPI_SYS_BOOT:
+			rd->stats.tx_boot_packets++;
+			break;
+		default:
+			rd->stats.tx_other_packets++;
+			break;
+		}
+
+		if (tx_msg->need_rx_ack) {
+			/* rx work will complete the message, note
+			 * that we cannot race with rx work since we
+			 * run in the same workqueue */
+			tx_msg->tx_state = RTI_TX_MSG_S_WAIT_RX_ACK;
+			return;
+		}
+
+		spin_lock(&rd->tx_msg_list_lock);
+		list_del(&tx_msg->next);
+		complete(&tx_msg->complete);
+		release_tx_msg(tx_msg);
+		spin_unlock(&rd->tx_msg_list_lock);
+	}
+}
+
+/*
+ * kernel callback when there is room in send buffer
+ */
+static void remoti_tty_write_resume(struct tty_struct *tty)
+{
+	struct remoti_device *rd = (struct remoti_device *)tty->disc_data;
+
+	/* can be called from irq context, defer to userspace to be
+	 * safe */
+	queue_work(rd->io_workqueue, &rd->tx_work);
+}
+
+/*
+ *
+ */
+static int __remoti_send_msg(struct remoti_device *rd,
+			     struct rti_msg *msg, bool async)
+{
+	struct remoti_tx_msg *tx_msg;
+	unsigned int timeout;
+	int ret;
+
+	if (msg->data_len > NPI_MAX_DATA_LEN)
+		return -EFBIG;
+
+	/* alloc & queue message */
+	tx_msg = kzalloc(sizeof (*tx_msg), GFP_KERNEL);
+	if (!tx_msg)
+		return -ENOMEM;
+
+	if (!msg->custom_reply_cmd)
+		msg->reply_cmd = msg->cmd;
+	msg->reply_len = 0;
+
+	tx_msg->msg = msg;
+	tx_msg->need_rx_ack = !async;
+	atomic_set(&tx_msg->users, 1);
+	init_completion(&tx_msg->complete);
+
+	spin_lock(&rd->tx_msg_list_lock);
+	atomic_inc(&tx_msg->users);
+	list_add_tail(&tx_msg->next, &rd->tx_msg_list);
+	spin_unlock(&rd->tx_msg_list_lock);
+
+	/* kick tx queue */
+	queue_work(rd->io_workqueue, &rd->tx_work);
+
+	/* wait for message to be sent */
+	ret = 0;
+	timeout = wait_for_completion_timeout(&tx_msg->complete,
+					      REMOTI_MSG_TIMEOUT);
+	if (!timeout) {
+		dev_err(&rd->pdev->dev, "timeout sending message "
+			"type:%u subsys:%u cmd:0x%02x data_len:%u\n",
+			msg->type, msg->subsys, msg->cmd, msg->data_len);
+		ret = -ETIMEDOUT;
+	}
+
+	if (tx_msg->canceled)
+		ret = -EIO;
+
+	release_tx_msg(tx_msg);
+	return ret;
+}
+
+static int remoti_send_sync_msg(struct remoti_device *rd,
+				struct rti_msg *msg)
+{
+	return __remoti_send_msg(rd, msg, false);
+}
+
+static int remoti_send_async_msg(struct remoti_device *rd,
+				 struct rti_msg *msg)
+{
+	return __remoti_send_msg(rd, msg, true);
+}
+
+/*
+ * high level api to access device
+ */
+struct rti_udev *rti_get_udevice(unsigned int id)
+{
+	struct remoti_device *rd;
+	bool found;
+
+	found = false;
+	spin_lock(&remoti_devs_list_lock);
+	list_for_each_entry(rd, &remoti_devs_list, next) {
+		if (rd->pdata.id == id) {
+			found = true;
+			break;
+		}
+	}
+	spin_unlock(&remoti_devs_list_lock);
+
+	if (!found)
+		return NULL;
+
+	spin_lock(&rd->state_lock);
+	if (rd->state != RTI_DEV_S_OPERATIONAL) {
+		spin_unlock(&rd->state_lock);
+		return NULL;
+	}
+
+	atomic_inc(&rd->user_count);
+	spin_unlock(&rd->state_lock);
+	return (struct rti_udev *)rd;
+}
+
+EXPORT_SYMBOL(rti_get_udevice);
+
+/*
+ *
+ */
+void rti_release_udevice(struct rti_udev *udev)
+{
+	struct remoti_device *rd = (struct remoti_device *)udev;
+	atomic_dec(&rd->user_count);
+}
+
+EXPORT_SYMBOL(rti_release_udevice);
+
+/*
+ *
+ */
+static int __rti_send_msg(struct rti_udev *udev, struct rti_msg *msg,
+			  bool async)
+{
+	struct remoti_device *rd = (struct remoti_device *)udev;
+	int ret;
+
+	if (!dev_is_operational(rd))
+		return -EIO;
+
+	ret = __remoti_send_msg(rd, msg, async);
+	if (ret == -ETIMEDOUT) {
+		/* catch any timeout, assume device is dead and mark
+		 * it as such */
+		rd->timeout = true;
+		queue_work(rd->fsm_workqueue, &rd->hw_fsm_work);
+		ret = -EIO;
+	}
+
+	return ret;
+}
+
+/*
+ *
+ */
+int rti_send_sync_msg(struct rti_udev *udev, struct rti_msg *msg)
+{
+	return __rti_send_msg(udev, msg, false);
+}
+
+EXPORT_SYMBOL(rti_send_sync_msg);
+
+/*
+ *
+ */
+int rti_send_async_msg(struct rti_udev *udev, struct rti_msg *msg)
+{
+	return __rti_send_msg(udev, msg, true);
+}
+
+EXPORT_SYMBOL(rti_send_async_msg);
+
+/*
+ *
+ */
+static int remoti_register_cmd_callback(struct remoti_device *rd,
+					u8 subsys, u8 cmd,
+					void (*cb)(void *cb_priv,
+						   const struct rti_msg *msg),
+					void *cb_priv)
+{
+	struct remoti_cmd_callback *cb_elem, *new_cb_elem;
+	bool found;
+
+	new_cb_elem = kmalloc(sizeof (*cb_elem), GFP_KERNEL);
+	if (!new_cb_elem)
+		return -ENOMEM;
+	new_cb_elem->subsys = subsys;
+	new_cb_elem->cmd = cmd;
+	new_cb_elem->cb = cb;
+	new_cb_elem->cb_priv = cb_priv;
+
+	found = false;
+	spin_lock(&rd->callback_list_lock);
+	list_for_each_entry(cb_elem, &rd->callback_list, next) {
+		if (new_cb_elem->subsys == cb_elem->subsys &&
+		    new_cb_elem->cmd == cb_elem->cmd) {
+			found = true;
+			break;
+		}
+	}
+
+	if (found) {
+		spin_unlock(&rd->callback_list_lock);
+		kfree(new_cb_elem);
+		dev_warn(&rd->pdev->dev, "refuse to register a second "
+			 "callback for subsys:%u cmd:0x%02x\n", subsys, cmd);
+		return -EEXIST;
+	}
+
+	list_add_tail(&new_cb_elem->next, &rd->callback_list);
+	spin_unlock(&rd->callback_list_lock);
+
+	return 0;
+}
+
+static void remoti_unregister_cmd_callback(struct remoti_device *rd,
+					   u8 subsys, u8 cmd)
+{
+	struct remoti_cmd_callback *cb_elem;
+	bool found;
+
+	found = false;
+	spin_lock(&rd->callback_list_lock);
+	list_for_each_entry(cb_elem, &rd->callback_list, next) {
+		if (subsys == cb_elem->subsys &&
+		    cmd == cb_elem->cmd) {
+			found = true;
+			break;
+		}
+	}
+
+	if (found)
+		list_del(&cb_elem->next);
+	else
+		cb_elem = NULL;
+
+	spin_unlock(&rd->callback_list_lock);
+
+	kfree(cb_elem);
+}
+
+/*
+ *
+ */
+int rti_register_cmd_callback(struct rti_udev *udev,
+			      u8 subsys, u8 cmd,
+			      void (*cb)(void *cb_priv,
+					 const struct rti_msg *msg),
+			      void *cb_priv)
+{
+	struct remoti_device *rd = (struct remoti_device *)udev;
+
+	if (!dev_is_operational(rd))
+		return -EIO;
+
+	return remoti_register_cmd_callback(rd, subsys, cmd, cb, cb_priv);
+}
+
+EXPORT_SYMBOL(rti_register_cmd_callback);
+
+void rti_unregister_cmd_callback(struct rti_udev *udev, u8 subsys, u8 cmd)
+{
+	return remoti_unregister_cmd_callback((struct remoti_device *)udev,
+					      subsys, cmd);
+}
+
+EXPORT_SYMBOL(rti_unregister_cmd_callback);
+
+int rti_register_cmds_callback(struct rti_udev *udev,
+			       const struct rti_kcallback *cbs,
+			       size_t cb_count,
+			       void *cb_priv)
+{
+	size_t i, j;
+	int ret;
+
+	for (i = 0; i < cb_count; i++) {
+		ret = rti_register_cmd_callback(udev,
+						cbs[i].subsys,
+						cbs[i].cmd,
+						cbs[i].cb,
+						cb_priv);
+		if (ret)
+			goto fail;
+	}
+
+	return 0;
+
+fail:
+	for (j = 0; j < i; j++)
+		rti_unregister_cmd_callback(udev, cbs[j].subsys, cbs[j].cmd);
+
+	return ret;
+}
+
+EXPORT_SYMBOL(rti_register_cmds_callback);
+
+void rti_unregister_cmds_callback(struct rti_udev *udev,
+				  const struct rti_kcallback *cbs,
+				  size_t cb_count)
+{
+	size_t i;
+
+	for (i = 0; i < cb_count; i++)
+		rti_unregister_cmd_callback(udev, cbs[i].subsys, cbs[i].cmd);
+}
+
+EXPORT_SYMBOL(rti_unregister_cmds_callback);
+
+/*
+ *
+ */
+static void remoti_call_udev_notifier(struct remoti_device *rd)
+{
+	enum rti_udev_state st;
+
+	switch (rd->state) {
+	case RTI_DEV_S_OPERATIONAL:
+		st = RTI_UDEV_UP;
+		break;
+
+	case RTI_DEV_S_STOPPING:
+		st = RTI_UDEV_GOING_DOWN;
+		break;
+
+	default:
+		return;
+	}
+	blocking_notifier_call_chain(&udev_notifier, rd->pdata.id, &st);
+}
+
+/*
+ *
+ */
+void rti_register_udevice_notifier(struct notifier_block *nb)
+{
+	blocking_notifier_chain_register(&udev_notifier, nb);
+}
+
+EXPORT_SYMBOL(rti_register_udevice_notifier);
+
+/*
+ *
+ */
+void rti_unregister_udevice_notifier(struct notifier_block *nb)
+{
+	blocking_notifier_chain_unregister(&udev_notifier, nb);
+}
+
+EXPORT_SYMBOL(rti_unregister_udevice_notifier);
+
+/*
+ *
+ */
+static int send_read_fw_version(struct remoti_device *rd,
+				uint32_t *version)
+{
+	struct rti_msg msg;
+	struct rti_rcaf_read_item_req *req;
+	struct rti_rcaf_read_item_resp *resp;
+	int ret;
+
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_SREQ;
+	msg.subsys = NPI_SYS_RCAF;
+	msg.cmd = RTI_READ_ITEM;
+	msg.data_len = sizeof (*req);
+
+	req = (struct rti_rcaf_read_item_req *)msg.data;
+	req->item = RTI_ITEM_FW_VER;
+	req->item_len = sizeof (*version);
+
+	ret = remoti_send_sync_msg(rd, &msg);
+	if (ret)
+		return ret;
+
+	resp = (struct rti_rcaf_read_item_resp *)msg.reply;
+
+	if (msg.reply_len != sizeof (*resp) + sizeof (*version) ||
+	    resp->status != RTI_SUCCESS) {
+		dev_err(&rd->pdev->dev, "invalid read item "
+			"version response\n");
+		return 1;
+	}
+
+	memcpy(version, msg.reply + sizeof (*resp), sizeof (*version));
+	*version = __le32_to_cpu(*version);
+	return 0;
+}
+
+/*
+ *
+ */
+static int send_fw_erase(struct remoti_device *rd)
+{
+	struct rti_msg msg;
+	int ret;
+
+	/* send a boot subsystem message to the operational firmware,
+	 * it will erase itself and trigger watchdog to reboot */
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_AREQ;
+	msg.subsys = NPI_SYS_BOOT;
+	msg.cmd = RTI_SB_RELOAD;
+
+	ret = remoti_send_async_msg(rd, &msg);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/*
+ *
+ */
+static int serial_boot_send_firmware(struct remoti_device *rd,
+				     const struct firmware *fw)
+{
+	struct rti_msg msg;
+	struct rti_sb_write_req *wr_req;
+	int frame, num_frames;
+	int ret;
+	u8 *p;
+
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_POLL;
+	msg.subsys = NPI_SYS_BOOT;
+	msg.cmd = RTI_SB_WRITE_REQ;
+	msg.custom_reply_cmd = true;
+	msg.reply_cmd = (1 << 7) | msg.cmd;
+	msg.data_len = sizeof (*wr_req);
+	wr_req = (struct rti_sb_write_req *)msg.data;
+
+	/* Round-up to the right number of frames */
+	num_frames = DIV_ROUND_UP(fw->size, SB_DATA_SIZE);
+
+	for (frame = 0; frame < num_frames; frame++) {
+		unsigned int flash_offset;
+
+		p = (u8 *)(fw->data + (SB_DATA_SIZE * frame));
+
+		flash_offset = frame * (SB_DATA_SIZE / RTI_SB_FLASH_WORD);
+		wr_req->addr = cpu_to_le16(flash_offset);
+		memcpy(wr_req->data, p, SB_DATA_SIZE);
+
+		ret = remoti_send_sync_msg(rd, &msg);
+		if (ret)
+			return ret;
+
+		if (msg.reply_len != 1 || msg.reply[0] != SB_SUCCESS) {
+			dev_err(&rd->pdev->dev, "flash write failed at "
+				"offset 0x%04x\n", flash_offset);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ *
+ */
+static int serial_boot_enable_image(struct remoti_device *rd)
+{
+	struct rti_msg msg;
+	int ret;
+
+        /* Try to enable this image */
+	memset(&msg, 0, sizeof(msg));
+	/* the serial boot loader does not use type */
+	msg.subsys = NPI_SYS_BOOT;
+        msg.cmd = RTI_SB_ENABLE_REQ;
+	msg.custom_reply_cmd = true;
+	msg.reply_cmd = (1 << 7) | msg.cmd;
+
+	ret = remoti_send_sync_msg(rd, &msg);
+	if (ret)
+		return ret;
+
+	if (msg.reply_len != 1 || msg.reply[0] != SB_SUCCESS) {
+		dev_err(&rd->pdev->dev, "invalid serial enable image reply\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ *
+ */
+static int serial_boot_do_handshake(struct remoti_device *rd)
+{
+	struct rti_msg msg;
+	int ret;
+
+	memset(&msg, 0, sizeof (msg));
+	/* the serial boot loader does not use type */
+	msg.subsys = NPI_SYS_BOOT;
+	msg.cmd = RTI_SB_HSK_REQ;
+	msg.custom_reply_cmd = true;
+	msg.reply_cmd = (1 << 7) | msg.cmd;
+
+	ret = remoti_send_sync_msg(rd, &msg);
+	if (ret)
+		return ret;
+
+	if (msg.reply_len != 1 || msg.reply[0] != SB_SUCCESS) {
+		dev_err(&rd->pdev->dev, "invalid serial handshake reply\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * check firmware image and extract its version
+ */
+static int fw_extract_version(const struct firmware *fw, u32 *version)
+{
+	struct remoti_fw_header *hdr;
+
+        if (fw->size < sizeof (*hdr) + RTI_FW_HDR_OFFSET) {
+		pr_err("firmware size is too small\n");
+                return 1;
+	}
+
+        if (fw->size >= REMOTI_FW_MAX_SIZE) {
+		pr_err("firmware size is too big\n");
+                return 1;
+	}
+
+        hdr = (struct remoti_fw_header *)(fw->data + RTI_FW_HDR_OFFSET);
+        if (hdr->enable_op != (uint32_t)~0) {
+		pr_err("firmware enable_op is invalid\n");
+		return 1;
+	}
+
+        *version = le32_to_cpu(hdr->version);
+	return 0;
+}
+
+/*
+ * callback when we receive assertion failed message
+ */
+static void handle_assert_ind(void *cb_priv, const struct rti_msg *msg)
+{
+	struct remoti_device *rd = (struct remoti_device *)cb_priv;
+	if (printk_ratelimit())
+		dev_err(&rd->pdev->dev, "got assertion FAILED message\n");
+}
+
+/*
+ * callback when we receive printk message
+ */
+static void handle_printk_ind(void *cb_priv, const struct rti_msg *msg)
+{
+	struct remoti_device *rd = (struct remoti_device *)cb_priv;
+	char buf[NPI_MAX_DATA_LEN + 1];
+	size_t i;
+
+	/* sanitize string */
+	memcpy(buf, msg->data, msg->data_len);
+	buf[NPI_MAX_DATA_LEN] = 0;
+
+	/* replace non printable char */
+        for (i = 0; i < sizeof (buf); i++) {
+		if (!buf[i])
+			break;
+		else if (buf[i] == '\r' || buf[i] == '\n')
+			buf[i] = ' ';
+                else if (buf[i] < ' ' || buf[i] > 127)
+                        buf[i] = '?';
+	}
+
+	dev_info(&rd->pdev->dev, "printk: %s\n", buf);
+}
+
+/*
+ * callback when we receive INIT_CNF message
+ */
+static void handle_init_cnf(void *cb_priv, const struct rti_msg *msg)
+{
+	struct remoti_device *rd = (struct remoti_device *)cb_priv;
+	complete(&rd->init_cnf_complete);
+}
+
+/*
+ *
+ */
+static const char *dev_states_str[] = {
+	[RTI_DEV_S_STOPPED]		= "stopped",
+	[RTI_DEV_S_BOOTING]		= "booting",
+	[RTI_DEV_S_BOOT_FAILED]		= "boot failed",
+	[RTI_DEV_S_OPERATIONAL]		= "operational",
+	[RTI_DEV_S_STOPPING]		= "stopping",
+	[RTI_DEV_S_DEAD]		= "dead",
+};
+
+static void __dev_set_state(struct remoti_device *rd,
+			    enum rti_dev_state state, bool silent)
+{
+	spin_lock(&rd->state_lock);
+	rd->state = state;
+	spin_unlock(&rd->state_lock);
+
+	if (!silent) {
+		dev_info(&rd->pdev->dev, "RNP state: %s\n",
+			 dev_states_str[state]);
+		remoti_call_udev_notifier(rd);
+		remoti_dev_change_sysfs(rd);
+	}
+}
+
+static void dev_set_state(struct remoti_device *rd, enum rti_dev_state state)
+{
+	return __dev_set_state(rd, state, false);
+}
+
+static void dev_set_state_silent(struct remoti_device *rd,
+				 enum rti_dev_state state)
+{
+	return __dev_set_state(rd, state, true);
+}
+
+/*
+ *
+ */
+static int boot_device(struct remoti_device *rd)
+{
+        const struct firmware *fw;
+	unsigned int timeout;
+	u32 user_fw_version, dev_fw_version, boot_flags;
+
+	/* get the firmware we are supposed to boot the RNP with from
+	 * userspace */
+	if (request_firmware(&fw, REMOTI_FW_NAME, &rd->pdev->dev)) {
+		dev_err(&rd->pdev->dev, "failed to request firmware\n");
+		return 1;
+	}
+
+	/* sanity check on this firmware & extract its version */
+	if (fw_extract_version(fw, &user_fw_version))
+		goto fail;
+
+	dev_info(&rd->pdev->dev, "required firmware version %08x\n",
+		 user_fw_version);
+
+	/* first try to boot it with its current firmare */
+	boot_flags = rd->boot_flags;
+	rd->boot_flags = 0;
+	INIT_COMPLETION(rd->wakeup_complete);
+	INIT_COMPLETION(rd->init_cnf_complete);
+	dev_hw_reset_cycle(rd);
+
+	/* get rnp out of sleep */
+	rd->tx_need_send_wakeup = true;
+	queue_work(rd->io_workqueue, &rd->tx_work);
+
+	/* wait a bit for wakeup char to be received, it won't be sent
+	 * if only a serial bootloader is present and we will wait for
+	 * nothing, but it's not the common case */
+	timeout = wait_for_completion_timeout(&rd->wakeup_complete,
+					      HZ * 2);
+	if (timeout != 0) {
+		dev_info(&rd->pdev->dev, "got RNP wakeup\n");
+
+		/* we got a wakeup; a firmware is running, check its
+		 * version */
+		if (send_read_fw_version(rd, &dev_fw_version)) {
+			dev_err(&rd->pdev->dev, "fail to read "
+				"current fw version\n");
+			goto fail;
+		}
+
+		/* wait for init confirm after we sent first
+		 * command */
+		timeout = wait_for_completion_timeout(&rd->init_cnf_complete,
+						      HZ * 10);
+		if (timeout == 0) {
+			dev_err(&rd->pdev->dev, "timeout waiting for RNP "
+				"init confirm\n");
+			goto fail;
+		}
+
+		/* compare with version we want to run */
+		if (!(boot_flags & RTI_BOOT_FLAGS_FORCE_UPDATE) &&
+		    dev_fw_version == user_fw_version) {
+			/* match, done */
+			rd->fw_version = dev_fw_version;
+			release_firmware(fw);
+			return 0;
+		}
+
+		if ((boot_flags & RTI_BOOT_FLAGS_FORCE_UPDATE))
+			dev_info(&rd->pdev->dev,
+				 "device fw version is %08x, "
+				 "but forcing erase as requested\n",
+				 dev_fw_version);
+		else
+			dev_info(&rd->pdev->dev,
+				 "device fw version is %08x, "
+				 "required %08x, erase\n",
+				 dev_fw_version, user_fw_version);
+
+		/* erase the current firmware and force a reboot */
+		if (send_fw_erase(rd))
+			return 1;
+
+		/* give it some time */
+		msleep(2000);
+
+	} else
+		dev_info(&rd->pdev->dev, "did not get RNP wakeup, "
+			 "assuming serial bootloader\n");
+
+	dev_info(&rd->pdev->dev, "doing serial bootloader handshake\n");
+
+	/* send handshake */
+	if (serial_boot_do_handshake(rd)) {
+		dev_err(&rd->pdev->dev, "failed to get "
+			"bootloader handshake\n");
+		goto fail;
+	}
+
+	dev_info(&rd->pdev->dev, "sending firmware...\n");
+
+	/* upgrade firmware */
+	if (serial_boot_send_firmware(rd, fw))
+		goto fail;
+
+	/* enable image */
+	dev_info(&rd->pdev->dev, "enabling image...\n");
+
+	INIT_COMPLETION(rd->wakeup_complete);
+	INIT_COMPLETION(rd->init_cnf_complete);
+	if (serial_boot_enable_image(rd))
+		goto fail;
+
+	/* wait for wakeup char again */
+	timeout = wait_for_completion_timeout(&rd->wakeup_complete,
+					      HZ * 2);
+	if (timeout == 0) {
+		dev_err(&rd->pdev->dev, "timeout waiting for RNP wakeup\n");
+		goto fail;
+	}
+
+	/* read version and compare  */
+	if (send_read_fw_version(rd, &dev_fw_version))
+		goto fail;
+
+	if (dev_fw_version != user_fw_version) {
+		dev_err(&rd->pdev->dev, "unexpected fw version (%08x) "
+			"should be %08x\n", dev_fw_version, user_fw_version);
+		goto fail;
+	}
+
+	timeout = wait_for_completion_timeout(&rd->init_cnf_complete,
+					      HZ * 10);
+	if (timeout == 0) {
+		dev_err(&rd->pdev->dev, "timeout waiting for RNP "
+			"init confirm\n");
+		goto fail;
+	}
+
+	/* done */
+	rd->fw_version = dev_fw_version;
+	release_firmware(fw);
+	return 0;
+
+fail:
+	dev_hw_reset_hold(rd);
+	release_firmware(fw);
+	return 1;
+}
+
+/*
+ *
+ */
+static void stop_device(struct remoti_device *rd)
+{
+	struct remoti_rx_msg *rx_msg, *rx_tmp;
+	struct remoti_cmd_callback *cb_elem, *cb_tmp;
+	unsigned int users;
+
+	/* make device as stopping, don't tell the world
+	 * yet */
+	dev_set_state_silent(rd, RTI_DEV_S_STOPPING);
+
+	/* stop tty rx */
+	stop_tty(rd->tty);
+	clear_bit(TTY_DO_WRITE_WAKEUP, &rd->tty->flags);
+	cancel_work_sync(&rd->rx_work);
+
+	/* discard all pending rx messages */
+	list_for_each_entry_safe(rx_msg, rx_tmp, &rd->rx_msg_list, next)
+		kfree(rx_msg);
+	INIT_LIST_HEAD(&rd->rx_msg_list);
+
+	/* stop current tx work, it may still be scheduled afterwards
+	 * but will return immediatly since we set stopping state,
+	 * just finish the current run */
+	cancel_work_sync(&rd->tx_work);
+
+	/* any new sendmsg call will be rejected from now on, flush
+	 * pending tx message and wakeup all senders */
+	do {
+		struct remoti_tx_msg *tx_msg, *tx_tmp;
+		bool done;
+
+		spin_lock(&rd->tx_msg_list_lock);
+		list_for_each_entry_safe(tx_msg, tx_tmp,
+					 &rd->tx_msg_list, next) {
+
+			if (atomic_read(&tx_msg->users) == 1) {
+				/* no more users */
+				list_del(&tx_msg->next);
+				kfree(tx_msg);
+			} else {
+				tx_msg->canceled = true;
+				complete(&tx_msg->complete);
+			}
+		}
+
+		done = list_empty(&rd->tx_msg_list);
+
+		spin_unlock(&rd->tx_msg_list_lock);
+		if (done)
+			break;
+
+		dev_set_state(rd, RTI_DEV_S_STOPPING);
+		msleep(100);
+
+	} while (1);
+
+	/* now wait for all users */
+	users = atomic_read(&rd->user_count);
+	if (users)
+		dev_info(&rd->pdev->dev, "waiting for %u users "
+			 "to detach\n", users);
+	do {
+		if (!atomic_read(&rd->user_count))
+			break;
+
+		/* tell the world */
+		dev_set_state(rd, RTI_DEV_S_STOPPING);
+
+		msleep(100);
+
+	} while (1);
+
+	/* flush callback list */
+	list_for_each_entry_safe(cb_elem, cb_tmp,
+				 &rd->callback_list, next)
+		kfree(cb_elem);
+	INIT_LIST_HEAD(&rd->callback_list);
+}
+
+/*
+ *
+ */
+static int fsm_need_change(struct remoti_device *rd, bool *req_state)
+{
+	mutex_lock(&rd->req_state_mutex);
+	if (!rd->req_state_changed) {
+		mutex_unlock(&rd->req_state_mutex);
+		return 0;
+	}
+
+	rd->req_state_changed = false;
+	*req_state = rd->req_state;
+	mutex_unlock(&rd->req_state_mutex);
+	return 1;
+}
+
+/*
+ * state machine for device start/booting/stop, run in private
+ * workqueue
+ */
+static void remoti_hw_fsm_work(struct work_struct *work)
+{
+	struct remoti_device *rd =
+		container_of(work, struct remoti_device, hw_fsm_work);
+	bool req_state;
+
+again:
+	switch (rd->state) {
+	case RTI_DEV_S_STOPPED:
+	case RTI_DEV_S_DEAD:
+		/* do nothing unless we have a start order */
+		if (!fsm_need_change(rd, &req_state) || !req_state)
+			break;
+
+		/* start booting device */
+		dev_set_state(rd, RTI_DEV_S_BOOTING);
+		goto again;
+
+	case RTI_DEV_S_BOOTING:
+		start_tty(rd->tty);
+		set_bit(TTY_DO_WRITE_WAKEUP, &rd->tty->flags);
+
+		/* register debug stuffs */
+		remoti_register_cmd_callback(rd, NPI_SYS_UTIL,
+					     RTI_DBG_PRINT_IND,
+					     handle_printk_ind, rd);
+		remoti_register_cmd_callback(rd, NPI_SYS_UTIL,
+					     RTI_DBG_ASSERT_IND,
+					     handle_assert_ind, rd);
+
+		/* keep init_cnf for us */
+		remoti_register_cmd_callback(rd, NPI_SYS_RCAF, RTI_INIT_CNF,
+					     handle_init_cnf, rd);
+
+		if (boot_device(rd)) {
+			stop_device(rd);
+			dev_set_state(rd, RTI_DEV_S_BOOT_FAILED);
+			dev_err(&rd->pdev->dev, "failed to boot device\n");
+			return;
+		}
+
+		dev_info(&rd->pdev->dev, "RNP firmware version: %08x\n",
+			 rd->fw_version);
+		dev_set_state(rd, RTI_DEV_S_OPERATIONAL);
+		break;
+
+	case RTI_DEV_S_BOOT_FAILED:
+		/* a start command will make us retry booting */
+		if (!fsm_need_change(rd, &req_state))
+			break;
+
+		if (req_state)
+			dev_set_state(rd, RTI_DEV_S_BOOTING);
+		else
+			dev_set_state(rd, RTI_DEV_S_STOPPED);
+		goto again;
+
+	case RTI_DEV_S_OPERATIONAL:
+		/* a stop command or a pending hw error will make stop
+		 * the device */
+		if ((!fsm_need_change(rd, &req_state) || req_state) &&
+		    !rd->timeout)
+			break;
+
+		if (rd->timeout)
+			dev_warn(&rd->pdev->dev, "stopping device after "
+				 "command timeout");
+
+		stop_device(rd);
+
+		if (rd->timeout)
+			dev_set_state(rd, RTI_DEV_S_DEAD);
+		else
+			dev_set_state(rd, RTI_DEV_S_STOPPED);
+		break;
+
+	case RTI_DEV_S_STOPPING:
+		/* transient state */
+		break;
+	}
+}
+
+
+/*
+ * called when userspace issue an ioctl on serial port using remoti
+ * ldisc
+ */
+static int remoti_tty_ioctl(struct tty_struct *tty, struct file *file,
+			    unsigned int cmd, unsigned long arg)
+{
+	struct remoti_device *rd;
+	void __user *useraddr = (void *)arg;
+
+	rd = (struct remoti_device *)tty->disc_data;
+
+	switch (cmd) {
+	case RTI_ATTACH_DEVICE:
+	{
+		bool found;
+		__u32 id;
+
+		/* make sure we are not already attached */
+		if (rd)
+			return -EBUSY;
+
+		if (copy_from_user(&id, useraddr, sizeof (id)))
+			return -EFAULT;
+
+		/* lookup device */
+		found = false;
+		spin_lock(&remoti_devs_list_lock);
+		list_for_each_entry(rd, &remoti_devs_list, next) {
+			if (rd->pdata.id == id) {
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			spin_unlock(&remoti_devs_list_lock);
+			return -ENODEV;
+		}
+
+		rd->tty = tty;
+		tty->disc_data = rd;
+		spin_unlock(&remoti_devs_list_lock);
+
+		/* hack: force release of any gpio export done by
+		 * userspace */
+		gpio_free(rd->pdata.reset_gpio);
+
+		/* hold device reset and set its initial state */
+		dev_hw_reset_hold(rd);
+		rd->state = RTI_DEV_S_STOPPED;
+		break;
+	}
+
+	case RTI_GET_STATUS:
+	{
+		struct rti_dev_status st;
+
+		/* need to be attached */
+		if (!rd)
+			return -ENODEV;
+
+		memset(&st, 0, sizeof (st));
+		st.dev_state = rd->state;
+		st.fw_version = rd->fw_version;
+
+		if (copy_to_user(useraddr,&st, sizeof (st)))
+			return -EFAULT;
+
+		break;
+	}
+
+	case RTI_GET_STATS:
+		/* need to be attached */
+		if (!rd)
+			return -ENODEV;
+
+		rd = (struct remoti_device *)tty->disc_data;
+		if (copy_to_user(useraddr, &rd->stats, sizeof (rd->stats)))
+			return -EFAULT;
+		break;
+
+	case RTI_START_DEVICE:
+	case RTI_STOP_DEVICE:
+		/* need to be attached */
+		if (!rd)
+			return -ENODEV;
+
+		if (cmd == RTI_START_DEVICE) {
+			u32 boot_flags;
+
+			if (copy_from_user(&boot_flags, useraddr,
+					   sizeof (boot_flags)))
+				return -EFAULT;
+			rd->boot_flags = boot_flags;
+		}
+
+		mutex_lock(&rd->req_state_mutex);
+		rd->req_state = (cmd == RTI_START_DEVICE) ? true : false;
+		rd->req_state_changed = true;
+		mutex_unlock(&rd->req_state_mutex);
+		queue_work(rd->fsm_workqueue, &rd->hw_fsm_work);
+		break;
+
+	default:
+		return -ENOTTY;
+	}
+
+	return 0;
+}
+
+/*
+ * callback when userspace set the remoti ldisc on tty device
+ */
+static int remoti_tty_open(struct tty_struct *tty)
+{
+	/* leave unattached for now, ioctl will do it */
+	tty->disc_data = NULL;
+	tty->receive_room = 65536;
+	stop_tty(tty);
+	return 0;
+}
+
+/*
+ *
+ */
+static void remoti_tty_close(struct tty_struct *tty)
+{
+	struct remoti_device *rd;
+
+	rd = (struct remoti_device *)tty->disc_data;
+	if (!rd)
+		return;
+
+	dev_info(&rd->pdev->dev, "tty closing...\n");
+
+	/* no more ioctl possible, so we have control over device fsm,
+	 * ask it to stop device */
+	mutex_lock(&rd->req_state_mutex);
+	rd->req_state = false;
+	rd->req_state_changed = true;
+	mutex_unlock(&rd->req_state_mutex);
+	queue_work(rd->fsm_workqueue, &rd->hw_fsm_work);
+
+	while (rd->state != RTI_DEV_S_STOPPED &&
+	       rd->state != RTI_DEV_S_DEAD)
+		msleep(10);
+
+	dev_info(&rd->pdev->dev, "tty released\n");
+}
+
+static struct tty_ldisc_ops remoti_ldisc = {
+	.owner		= THIS_MODULE,
+	.magic		= TTY_LDISC_MAGIC,
+	.name		= "n_remoti",
+	.open		= remoti_tty_open,
+	.close		= remoti_tty_close,
+	.ioctl		= remoti_tty_ioctl,
+	.receive_buf	= remoti_tty_recv_buf,
+	.write_wakeup	= remoti_tty_write_resume,
+};
+
+/*
+ *
+ */
+static int remoti_probe(struct platform_device *pdev)
+{
+	struct remoti_device *rd;
+	const unsigned int *gpio_prop, *id_prop;
+	char wq_name[32];
+	int proplen;
+	int err;
+
+	/* allocated device & mark it as unattached  */
+	rd = kzalloc(sizeof (*rd), GFP_KERNEL);
+	if (!rd) {
+		dev_err(&pdev->dev, "unable to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	id_prop = of_get_property(pdev->dev.of_node, "id", &proplen);
+	if (!id_prop || proplen < 4) {
+		dev_err(&pdev->dev, "unable to get id property\n");
+		err = -ENODEV;
+		goto out_free;
+	}
+
+	gpio_prop = of_get_property(pdev->dev.of_node, "reset-gpio", &proplen);
+	if (!gpio_prop || proplen < 8) {
+		dev_err(&pdev->dev, "unable to get reset-gpio property\n");
+		err = -ENODEV;
+		goto out_free;
+	}
+
+	rd->pdata.id = be32_to_cpup(id_prop);
+	rd->pdata.reset_gpio = be32_to_cpup(gpio_prop);
+	rd->pdata.reset_polarity = be32_to_cpup(gpio_prop + 1);
+	BUG_ON(rd->pdata.reset_gpio != 100);
+	rd->pdev = pdev;
+
+	scnprintf(wq_name, sizeof (wq_name), "%s-fsm", pdev->name);
+	rd->fsm_workqueue = create_singlethread_workqueue(wq_name);
+	if (!rd->fsm_workqueue) {
+		dev_err(&pdev->dev, "unable to create workqueue\n");
+		err = -ENOMEM;
+		goto out_free;
+	}
+
+	scnprintf(wq_name, sizeof (wq_name), "%s-io", pdev->name);
+	rd->io_workqueue = create_singlethread_workqueue(wq_name);
+	if (!rd->io_workqueue) {
+		dev_err(&pdev->dev, "unable to create workqueue\n");
+		err = -ENOMEM;
+		goto out_free;
+	}
+
+	spin_lock_init(&rd->state_lock);
+
+	INIT_LIST_HEAD(&rd->tx_msg_list);
+	spin_lock_init(&rd->tx_msg_list_lock);
+
+	INIT_LIST_HEAD(&rd->rx_msg_list);
+	spin_lock_init(&rd->rx_msg_list_lock);
+
+	INIT_LIST_HEAD(&rd->callback_list);
+	spin_lock_init(&rd->callback_list_lock);
+
+	INIT_WORK(&rd->hw_fsm_work, remoti_hw_fsm_work);
+	INIT_WORK(&rd->tx_work, remoti_tx_work);
+	INIT_WORK(&rd->rx_work, remoti_rx_work);
+	init_completion(&rd->wakeup_complete);
+	init_completion(&rd->init_cnf_complete);
+	mutex_init(&rd->req_state_mutex);
+
+	platform_set_drvdata(pdev, rd);
+
+	/* create sysfs entries */
+	err = remoti_register_dev_sysfs(rd);
+	if (err)
+		goto out_free;
+
+	spin_lock(&remoti_devs_list_lock);
+	list_add_tail(&rd->next, &remoti_devs_list);
+	spin_unlock(&remoti_devs_list_lock);
+	return 0;
+
+out_free:
+	if (rd->fsm_workqueue)
+		destroy_workqueue(rd->fsm_workqueue);
+
+	if (rd->io_workqueue)
+		destroy_workqueue(rd->io_workqueue);
+
+	kfree(rd);
+	return err;
+}
+
+/*
+ *
+ */
+void __remoti_free_device(struct remoti_device *rd)
+{
+	destroy_workqueue(rd->fsm_workqueue);
+	destroy_workqueue(rd->io_workqueue);
+	kfree(rd);
+}
+
+/*
+ *
+ */
+static int __devexit remoti_remove(struct platform_device *pdev)
+{
+	struct remoti_device *rd = platform_get_drvdata(pdev);
+
+	spin_lock(&remoti_devs_list_lock);
+	list_del(&rd->next);
+	spin_unlock(&remoti_devs_list_lock);
+	platform_set_drvdata(pdev, NULL);
+
+	remoti_unregister_dev_sysfs(rd);
+	/* actual free is done from sysfs */
+	return 0;
+}
+
+static const struct of_device_id remoti_of_ids[] = {
+	{ .compatible = "ti,remoti" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, remoti_of_ids);
+
+static struct platform_driver remoti_driver = {
+	.driver = {
+		.name	= "remoti",
+		.owner	= THIS_MODULE,
+		.of_match_table = remoti_of_ids,
+	},
+	.probe		= remoti_probe,
+	.remove		= __devexit_p(remoti_remove),
+};
+
+/*
+ *
+ */
+static int __init remoti_init(void)
+{
+	int ret;
+
+	INIT_LIST_HEAD(&remoti_devs_list);
+	BLOCKING_INIT_NOTIFIER_HEAD(&udev_notifier);
+
+	ret = remoti_sysfs_init();
+	if (ret) {
+		pr_err("failed to register sysfs class\n");
+		goto out;
+	}
+
+	ret = platform_driver_register(&remoti_driver);
+	if (ret) {
+		pr_err("failed to register platform driver\n");
+		goto out_sysfs;
+	}
+
+	ret = tty_register_ldisc(N_REMOTI, &remoti_ldisc);
+	if (ret) {
+		pr_err("failed to register line discipline\n");
+		goto out_pdev;
+	}
+
+	return 0;
+
+out_sysfs:
+	remoti_sysfs_exit();
+
+out_pdev:
+	platform_driver_unregister(&remoti_driver);
+
+out:
+	return ret;
+}
+
+/*
+ *
+ */
+static void __exit remoti_exit(void)
+{
+	platform_driver_unregister(&remoti_driver);
+	tty_unregister_ldisc(N_REMOTI);
+	remoti_sysfs_exit();
+}
+
+module_init(remoti_init);
+module_exit(remoti_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Florian Fainelli <ffainelli@freebox.fr>");
+MODULE_DESCRIPTION("RemoTI core driver");
+MODULE_ALIAS("platform:remoti");
+MODULE_FIRMWARE(REMOTI_FW_NAME);
diff -Nruw linux-3.2.24-fbx/drivers/misc/remoti./core-priv.h linux-3.2.24-fbx/drivers/misc/remoti/core-priv.h
--- linux-3.2.24-fbx/drivers/misc/remoti./core-priv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/remoti/core-priv.h	2013-06-13 15:52:30.409198280 +0200
@@ -0,0 +1,229 @@
+#ifndef __REMOTI_PRIV_H
+#define __REMOTI_PRIV_H
+
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/completion.h>
+#include <linux/firmware.h>
+#include <linux/workqueue.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+#include <linux/remoti/remoti.h>
+
+/*
+ * firmware related
+ */
+#define RTI_FW_HDR_OFFSET	0xc0
+
+struct remoti_fw_header {
+        __le32		enable_op;
+        __le16		start_addr;
+        __le32		version;
+} __packed;
+
+/*
+ * RCAF RPCs used during boot
+ */
+#define RTI_READ_ITEM		0x01
+#define RTI_SB_RELOAD		0x10
+
+#define RTI_INIT_CNF		0x01
+
+struct rti_rcaf_read_item_req {
+	u8		item;
+	u8		item_len;
+};
+
+struct rti_rcaf_read_item_resp {
+	u8		status;
+	u8		value[0];
+};
+
+#define RTI_ITEM_FW_VER		0xc4
+
+
+/*
+ * Serial bootloader RPCs
+ */
+#define RTI_SB_HSK_REQ		0x04
+#define RTI_SB_WRITE_REQ	0x01
+#define RTI_SB_READ_REQ		0x02
+#define RTI_SB_ENABLE_REQ	0x03
+
+#define RTI_SB_FLASH_WORD	4
+#define SB_SUCCESS		0
+#define SB_DATA_SIZE		64
+
+struct rti_sb_write_req {
+	__le16	addr;
+	u8	data[SB_DATA_SIZE];
+} __packed;
+
+struct rti_sb_read_req {
+	__le16 addr;
+} __packed;
+
+struct rti_sb_read_resp {
+	u8 status;
+	__le16 addr;
+	u8 data[SB_DATA_SIZE];
+} __packed;
+
+/*
+ * util RPC used
+ */
+#define RTI_DBG_PRINT_IND		0x30
+#define RTI_DBG_ASSERT_IND		0x31
+
+/*
+ * uart protocol
+ */
+#define RTI_UART_CHR_WAKEUP		0x00
+#define RTI_UART_CHR_SOF		0xFE
+
+/*
+ * len (1 byte) + subsystem (1 bytes) + command (1 byte) + data (variable)
+ */
+#define RTI_MAX_FRAME_LEN		(3 + NPI_MAX_DATA_LEN)
+
+enum remoti_tty_fsm_state {
+	RTI_TTY_FSM_SOF = 0,
+	RTI_TTY_FSM_LEN,
+	RTI_TTY_FSM_DATA,
+	RTI_TTY_FSM_FCS
+};
+
+/*
+ * message list
+ */
+enum remoti_tx_msg_state {
+	RTI_TX_MSG_S_WAITING = 0,
+	RTI_TX_MSG_S_SOF_SENT,
+	RTI_TX_MSG_S_HDR_SENT,
+	RTI_TX_MSG_S_DATA_SENT,
+	RTI_TX_MSG_S_SENT,
+	RTI_TX_MSG_S_WAIT_RX_ACK,
+};
+
+struct remoti_tx_msg {
+	struct rti_msg			*msg;
+	bool				need_rx_ack;
+	enum remoti_tx_msg_state	tx_state;
+	unsigned int			tx_data_sent;
+	u8				fcs;
+	atomic_t			users;
+	bool				canceled;
+	struct completion		complete;
+	struct list_head		next;
+};
+
+struct remoti_rx_msg {
+	struct rti_msg			msg;
+	struct list_head		next;
+};
+
+/*
+ * callback list
+ */
+struct remoti_cmd_callback {
+	u8				subsys;
+	u8				cmd;
+	/* this callback cannot sleep */
+	void				(*cb)(void *cb_priv,
+					      const struct rti_msg *msg);
+	void				*cb_priv;
+
+	struct list_head		next;
+};
+
+/*
+ * device context
+ */
+struct remoti_device {
+	struct platform_device		*pdev;
+	struct remoti_dev_pdata		pdata;
+	enum rti_dev_state		state;
+	spinlock_t			state_lock;
+	struct rti_dev_stats		stats;
+	u32				fw_version;
+	bool				timeout;
+
+	struct tty_struct		*tty;
+	enum remoti_tty_fsm_state	tty_fsm_state;
+
+	spinlock_t			callback_list_lock;
+	struct list_head		callback_list;
+
+	struct workqueue_struct		*io_workqueue;
+	struct work_struct		tx_work;
+	bool				tx_need_send_wakeup;
+	struct list_head		tx_msg_list;
+	spinlock_t			tx_msg_list_lock;
+
+	struct work_struct		rx_work;
+	u8				rx_buf[RTI_MAX_FRAME_LEN];
+	u8				rx_buf_len;
+	struct list_head		rx_msg_list;
+	spinlock_t			rx_msg_list_lock;
+
+	/* asserted when we receive WAKEUP char on uart */
+	struct completion		wakeup_complete;
+
+	/* asserted when we receive INIT_CNF on uart */
+	struct completion		init_cnf_complete;
+
+	/* device fsm manager */
+	struct workqueue_struct		*fsm_workqueue;
+	struct work_struct		hw_fsm_work;
+	u32				boot_flags;
+	struct mutex			req_state_mutex;
+	bool				req_state;
+	bool				req_state_changed;
+
+	/* high level users */
+	struct device			dev;
+	atomic_t			user_count;
+	struct list_head		next;
+};
+
+/*
+ *
+ */
+static inline bool dev_is_operational(struct remoti_device *rd)
+{
+	bool res;
+
+	spin_lock(&rd->state_lock);
+	res = (rd->state == RTI_DEV_S_OPERATIONAL);
+	spin_unlock(&rd->state_lock);
+
+	return res;
+}
+
+static inline bool dev_is_stopping(struct remoti_device *rd)
+{
+	bool res;
+
+	spin_lock(&rd->state_lock);
+	res = (rd->state == RTI_DEV_S_STOPPING);
+	spin_unlock(&rd->state_lock);
+
+	return res;
+}
+
+/*
+ * core-sysfs.c
+ */
+void remoti_dev_change_sysfs(struct remoti_device *rd);
+
+int remoti_register_dev_sysfs(struct remoti_device *rd);
+
+void remoti_unregister_dev_sysfs(struct remoti_device *rd);
+
+void __remoti_free_device(struct remoti_device *rd);
+
+int __init remoti_sysfs_init(void);
+
+void remoti_sysfs_exit(void);
+
+#endif /* !__REMOTI_PRIV_H */
diff -Nruw linux-3.2.24-fbx/drivers/misc/remoti./core-sysfs.c linux-3.2.24-fbx/drivers/misc/remoti/core-sysfs.c
--- linux-3.2.24-fbx/drivers/misc/remoti./core-sysfs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/remoti/core-sysfs.c	2013-06-13 15:52:30.409198280 +0200
@@ -0,0 +1,114 @@
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/kobject.h>
+#include <linux/stat.h>
+#include "core-priv.h"
+
+#define to_remoti_dev(cldev) container_of(cldev, struct remoti_device, dev)
+
+static ssize_t show_dev_id(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	struct remoti_device *rd = to_remoti_dev(dev);
+	return sprintf(buf, "%d\n", rd->pdata.id);
+}
+
+static ssize_t show_dev_state(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct remoti_device *rd = to_remoti_dev(dev);
+	return sprintf(buf, "%i\n",
+		       dev_is_operational(rd) ? 1 : 0);
+}
+
+static DEVICE_ATTR(id, S_IRUGO, show_dev_id, NULL);
+static DEVICE_ATTR(state, S_IRUGO, show_dev_state, NULL);
+
+static struct device_attribute *remoti_attrs[] = {
+	&dev_attr_id,
+	&dev_attr_state,
+	/* FIXME: export stats too */
+};
+
+static int remoti_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	struct remoti_device *rd;
+
+	if (!dev)
+		return -ENODEV;
+
+	rd = to_remoti_dev(dev);
+	if (!rd)
+		return -ENODEV;
+
+	if (add_uevent_var(env, "STATE=%u",
+			   dev_is_operational(rd) ? 1 : 0))
+		return -ENOMEM;
+
+	if (add_uevent_var(env, "ID=%u", rd->pdata.id))
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void remoti_release(struct device *dev)
+{
+	struct remoti_device *rd = to_remoti_dev(dev);
+	__remoti_free_device(rd);
+}
+
+static struct class remoti_class = {
+	.name		= "remoti",
+	.dev_release	= remoti_release,
+	.dev_uevent	= remoti_uevent,
+};
+
+void remoti_dev_change_sysfs(struct remoti_device *rd)
+{
+	struct device *dev = &rd->dev;
+
+	kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, NULL);
+}
+
+int remoti_register_dev_sysfs(struct remoti_device *rd)
+{
+	struct device *dev = &rd->dev;
+	int i, j, ret;
+
+	dev->class = &remoti_class;
+	dev_set_name(dev, "remoti%u", rd->pdata.id);
+	ret = device_register(dev);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(remoti_attrs); i++) {
+		ret = device_create_file(dev, remoti_attrs[i]);
+		if (ret)
+			goto err;
+	}
+	return 0;
+
+err:
+	for (j = 0; j < i; j++)
+		device_remove_file(dev, remoti_attrs[j]);
+	device_del(dev);
+	return ret;
+}
+
+void remoti_unregister_dev_sysfs(struct remoti_device *rd)
+{
+	struct device *dev = &rd->dev;
+
+	device_unregister(dev);
+}
+
+int __init remoti_sysfs_init(void)
+{
+	return class_register(&remoti_class);
+}
+
+void remoti_sysfs_exit(void)
+{
+	class_unregister(&remoti_class);
+}
diff -Nruw linux-3.2.24-fbx/drivers/misc/remoti./Kconfig linux-3.2.24-fbx/drivers/misc/remoti/Kconfig
--- linux-3.2.24-fbx/drivers/misc/remoti./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/remoti/Kconfig	2013-06-13 15:52:30.409198280 +0200
@@ -0,0 +1,26 @@
+menu "RemoTI support"
+
+config REMOTI
+	tristate "RemoTI support"
+	depends on FBX6HD
+	---help---
+	  Texas Instruments RemoTI stack.
+
+config REMOTI_LEDS
+	tristate "RemoTI LEDS support"
+	depends on REMOTI
+	depends on LEDS_CLASS
+	---help---
+	  RemoTI LEDS class driver support.
+
+config REMOTI_GPIO
+	tristate "RemoTI gpio support"
+	depends on REMOTI
+	---help---
+	  gpiochip driver for the RemoTI RNP
+
+config REMOTI_USER
+	tristate "RemoTI userspace access"
+	depends on REMOTI
+
+endmenu
diff -Nruw linux-3.2.24-fbx/drivers/misc/remoti./leds.c linux-3.2.24-fbx/drivers/misc/remoti/leds.c
--- linux-3.2.24-fbx/drivers/misc/remoti./leds.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/remoti/leds.c	2013-06-13 15:52:30.409198280 +0200
@@ -0,0 +1,249 @@
+/*
+ * LEDs support over RemoTI IPCs
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/leds.h>
+#include <linux/sysfs.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+
+#include <linux/remoti/remoti.h>
+#include <linux/remoti/leds.h>
+#include <linux/of.h>
+
+#define PFX	KBUILD_MODNAME ": "
+
+/* list of remoti gpio devices */
+static DEFINE_MUTEX(remoti_leds_list_mutex);
+static struct list_head remoti_leds_list;
+
+/*
+ * Util RPCs subsystem
+ */
+#define RTI_LEDS_SET		0x00
+#define RTI_LEDS_GET		0x01
+
+#define RTI_LEDS_MODE_MAX	0x01
+
+struct remoti_led_data {
+	unsigned int		rti_dev_id;
+	u8			hw_id;
+	struct led_classdev	ldev;
+	struct rti_udev		*udev;
+	struct platform_device	*pdev;
+	struct list_head	next;
+};
+
+static int send_led_set(struct remoti_led_data *led, u8 status)
+{
+	struct rti_msg msg;
+	u8 *command;
+
+	memset(&msg, 0, sizeof (msg));
+	msg.type = NPI_SREQ;
+	msg.subsys = NPI_SYS_UTIL;
+	msg.cmd = RTI_LEDS_SET;
+
+	command = msg.data;
+	command[0] = led->hw_id;
+	command[1] = status;
+	msg.data_len = 2;
+
+	return rti_send_sync_msg(led->udev, &msg);
+}
+
+/*
+ * LED stuff
+ */
+static void remoti_set_brightness(struct led_classdev *led_cdev,
+				  enum led_brightness brightness)
+{
+	struct remoti_led_data *led;
+
+	led = container_of(led_cdev, struct remoti_led_data, ldev);
+	send_led_set(led, brightness);
+}
+
+/*
+ * We support hardware blinking and flashing
+ */
+static int remoti_set_blink(struct led_classdev *led_cdev,
+			unsigned long *delay_on, unsigned long *delay_off)
+{
+	struct remoti_led_data *led;
+
+	led = container_of(led_cdev, struct remoti_led_data, ldev);
+	return send_led_set(led, 0x04);
+}
+
+static int try_register_led(struct remoti_led_data *led)
+{
+	int ret;
+
+	led->udev = rti_get_udevice(led->rti_dev_id);
+	if (!led->udev)
+		return 0;
+
+	/* register kernel led */
+	ret = led_classdev_register(&led->pdev->dev, &led->ldev);
+	if (ret) {
+		dev_err(&led->pdev->dev, "cannot register LED: %s\n",
+			led->ldev.name);
+		rti_release_udevice(led->udev);
+		led->udev = NULL;
+		return ret;
+	}
+
+	dev_info(&led->pdev->dev, "registered LED %s\n",
+		 led->ldev.name);
+	return 0;
+}
+
+
+static int rti_udev_notifier_cb(struct notifier_block *n,
+				unsigned long id, void *data)
+{
+	struct remoti_led_data *led;
+	enum rti_udev_state *st = (enum rti_udev_state *)data;
+
+	mutex_lock(&remoti_leds_list_mutex);
+
+	list_for_each_entry(led, &remoti_leds_list, next) {
+
+		if (led->rti_dev_id != id)
+			continue;
+
+		switch (*st) {
+		case RTI_UDEV_UP:
+			if (led->udev)
+				continue;
+
+			try_register_led(led);
+			break;
+
+		case RTI_UDEV_GOING_DOWN:
+			if (!led->udev)
+				continue;
+
+			led_classdev_unregister(&led->ldev);
+			rti_release_udevice(led->udev);
+			led->udev = NULL;
+			break;
+		}
+	}
+
+	mutex_unlock(&remoti_leds_list_mutex);
+	return 0;
+}
+
+static struct notifier_block rti_udev_notifier_block = {
+	.notifier_call = rti_udev_notifier_cb,
+};
+
+static int __devinit remoti_leds_probe(struct platform_device *pdev)
+{
+	struct device_node *child;
+	struct remoti_led_data *leds_data;
+	const char *leds_name[REMOTI_LEDS_COUNT];
+	unsigned int num_leds = 0;
+	int i;
+
+	for_each_child_of_node(pdev->dev.of_node, child) {
+		leds_name[num_leds] = of_get_property(child, "label", NULL);
+		if (!leds_name[num_leds])
+			continue;
+		num_leds++;
+	};
+
+	leds_data = kzalloc(num_leds * sizeof(*leds_data), GFP_KERNEL);
+	if (!leds_data) {
+		dev_err(&pdev->dev, "no memory for leds\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < num_leds; i++) {
+		struct remoti_led_data *led = &leds_data[i];
+
+		led->pdev = pdev;
+		led->hw_id = i;
+		memset(&led->ldev, 0, sizeof (led->ldev));
+		led->ldev.name = leds_name[i];
+		led->ldev.max_brightness = 1;
+		led->ldev.brightness_set = remoti_set_brightness;
+		led->ldev.blink_set = remoti_set_blink;
+		led->ldev.flags = LED_CORE_SUSPENDRESUME;
+
+		mutex_lock(&remoti_leds_list_mutex);
+		try_register_led(led);
+		list_add_tail(&led->next, &remoti_leds_list);
+		mutex_unlock(&remoti_leds_list_mutex);
+	}
+
+	platform_set_drvdata(pdev, leds_data);
+	return 0;
+}
+
+static int remoti_leds_remove(struct platform_device *pdev)
+{
+	struct remoti_led_data *leds_data =
+				platform_get_drvdata(pdev);
+	struct remoti_led_data *led;
+
+	mutex_lock(&remoti_leds_list_mutex);
+	list_for_each_entry(led, &remoti_leds_list, next) {
+		if (led->udev) {
+			led_classdev_unregister(&led->ldev);
+			rti_release_udevice(led->udev);
+		}
+	}
+	kfree(leds_data);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static struct of_device_id remoti_leds_of_ids[] = {
+	{ .compatible = "ti,remoti-leds" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, remoti_leds_of_ids);
+
+static struct platform_driver remoti_leds_driver = {
+	.driver	= {
+		.name	= "remoti-leds",
+		.owner	= THIS_MODULE,
+		.of_match_table = remoti_leds_of_ids,
+	},
+	.probe	= remoti_leds_probe,
+	.remove = __devexit_p(remoti_leds_remove),
+};
+
+static int __init remoti_leds_init(void)
+{
+	int ret;
+
+	INIT_LIST_HEAD(&remoti_leds_list);
+
+	ret = platform_driver_register(&remoti_leds_driver);
+	if (ret)
+		return ret;
+
+	rti_register_udevice_notifier(&rti_udev_notifier_block);
+	return 0;
+}
+
+static void __exit remoti_leds_exit(void)
+{
+	rti_unregister_udevice_notifier(&rti_udev_notifier_block);
+	platform_driver_unregister(&remoti_leds_driver);
+}
+
+module_init(remoti_leds_init);
+module_exit(remoti_leds_exit);
+
+MODULE_AUTHOR("Florian Fainelli <ffainelli@freebox.fr>");
+MODULE_DESCRIPTION("RemoTI LEDS class support");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:remoti-leds");
diff -Nruw linux-3.2.24-fbx/drivers/misc/remoti./Makefile linux-3.2.24-fbx/drivers/misc/remoti/Makefile
--- linux-3.2.24-fbx/drivers/misc/remoti./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/remoti/Makefile	2013-06-13 15:52:30.409198280 +0200
@@ -0,0 +1,9 @@
+obj-$(CONFIG_REMOTI)		+= remoti.o
+obj-$(CONFIG_REMOTI_GPIO)	+= remoti-gpio.o
+obj-$(CONFIG_REMOTI_LEDS)	+= remoti-leds.o
+obj-$(CONFIG_REMOTI_USER)	+= remoti-user.o
+
+remoti-objs			:= core.o core-sysfs.o
+remoti-gpio-objs		:= gpio.o
+remoti-leds-objs		:= leds.o
+remoti-user-objs		:= user.o
diff -Nruw linux-3.2.24-fbx/drivers/misc/remoti./user.c linux-3.2.24-fbx/drivers/misc/remoti/user.c
--- linux-3.2.24-fbx/drivers/misc/remoti./user.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/misc/remoti/user.c	2013-06-13 15:52:30.409198280 +0200
@@ -0,0 +1,544 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/socket.h>
+#include <net/sock.h>
+#include <linux/remoti/remoti.h>
+
+struct rti_rx_msg {
+	struct rti_msg		msg;
+	struct list_head	next;
+};
+
+struct rti_sock_callback {
+	struct rti_callback	cb;
+	struct list_head	next;
+};
+
+struct rti_sock {
+	struct sock		sk;
+	unsigned int		rti_dev_id;
+
+	struct mutex		udev_mutex;
+	struct rti_udev		*udev;
+
+	struct list_head	rx_queue;
+	unsigned int		rx_queue_len;
+	spinlock_t		rx_queue_lock;
+
+	struct list_head	callback_list;
+	struct list_head	next;
+};
+
+#define RX_QUEUE_MAX_LEN	128
+
+static DEFINE_MUTEX(remoti_socks_list_mutex);
+static struct list_head remoti_socks_list;
+
+/*
+ *
+ */
+static inline struct rti_sock *to_rti_sock(const struct sock *sk)
+{
+	return container_of(sk, struct rti_sock, sk);
+}
+
+/*
+ *
+ */
+static void remoti_sock_deliver(void *cb_data, const struct rti_msg *msg)
+{
+	struct rti_sock *rti_sk = (struct rti_sock *)cb_data;
+	struct rti_rx_msg *rx_msg;
+
+	if (rti_sk->rx_queue_len > RX_QUEUE_MAX_LEN) {
+		if (printk_ratelimit())
+			printk(KERN_ERR "rti_sock: socket queue rx "
+			       "overflow, dropping\n");
+		return;
+	}
+
+	rx_msg = kmalloc(sizeof (*rx_msg), GFP_ATOMIC);
+	if (!rx_msg)
+		return;
+
+	memcpy(&rx_msg->msg, msg, sizeof (*msg));
+
+	spin_lock(&rti_sk->rx_queue_lock);
+	list_add_tail(&rx_msg->next, &rti_sk->rx_queue);
+	rti_sk->rx_queue_len++;
+	spin_unlock(&rti_sk->rx_queue_lock);
+
+	wake_up(sk_sleep(&rti_sk->sk));
+}
+
+/*
+ *
+ */
+static int remoti_sock_connect(struct socket *sock,
+			       struct sockaddr *vaddr,
+			       int sockaddr_len, int flags)
+{
+	struct sock *sk = sock->sk;
+	struct rti_sock *rti_sk = to_rti_sock(sk);
+	struct sockaddr_rti *rti_addr;
+	int ret;
+
+	lock_sock(sk);
+	ret = 0;
+
+	if (sock->state != SS_UNCONNECTED) {
+		ret = -EISCONN;
+		goto out;
+	}
+
+	if (sockaddr_len != sizeof (struct sockaddr_rti)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	rti_addr = (struct sockaddr_rti *)vaddr;
+
+	mutex_lock(&rti_sk->udev_mutex);
+	rti_sk->udev = rti_get_udevice(rti_addr->device_id);
+	if (!rti_sk->udev) {
+		mutex_unlock(&rti_sk->udev_mutex);
+		ret = -ENODEV;
+		goto out;
+	}
+
+	rti_sk->rti_dev_id = rti_addr->device_id;
+	sock->state = SS_CONNECTED;
+	mutex_unlock(&rti_sk->udev_mutex);
+
+out:
+	release_sock(sk);
+	return ret;
+}
+
+/*
+ *
+ */
+static int remoti_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
+			       struct msghdr *m, size_t total_len)
+{
+	struct rti_sock *rti_sk = to_rti_sock(sock->sk);
+	struct rti_msg msg;
+	bool async;
+	int ret;
+
+	ret = 0;
+	mutex_lock(&rti_sk->udev_mutex);
+
+	if (sock->state != SS_CONNECTED) {
+		ret = -ENOTCONN;
+		goto out;
+	}
+
+	if (!rti_sk->udev) {
+		ret = -ECONNRESET;
+		goto out;
+	}
+
+	if (m->msg_name) {
+		ret = -EISCONN;
+		goto out;
+	}
+
+	if (total_len != sizeof (struct rti_msg)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (memcpy_fromiovecend((unsigned char *)&msg,
+				m->msg_iov, 0, sizeof (msg))) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	/* use message type to know if we need to do a sync or async
+	 * send */
+	async = (msg.type == NPI_AREQ);
+
+	if (async)
+		ret = rti_send_async_msg(rti_sk->udev, &msg);
+	else
+		ret = rti_send_sync_msg(rti_sk->udev, &msg);
+
+	if (ret)
+		goto out;
+
+	if (!async) {
+		/* transfer reply to userspace */
+		if (memcpy_toiovec(m->msg_iov,
+				   (unsigned char *)&msg, sizeof (msg))) {
+			ret = -EFAULT;
+			goto out;
+		}
+	}
+	ret = sizeof (msg);
+
+out:
+	mutex_unlock(&rti_sk->udev_mutex);
+	return ret;
+}
+
+/*
+ *
+ */
+static unsigned int remoti_sock_poll(struct file *file, struct socket *sock,
+				     poll_table *wait)
+{
+	struct sock *sk = sock->sk;
+	struct rti_sock *rti_sk = to_rti_sock(sock->sk);
+	unsigned int mask = 0;
+
+	poll_wait(file, sk_sleep(sk), wait);
+
+	mutex_lock(&rti_sk->udev_mutex);
+	if (!rti_sk->udev)
+		mask |= POLLRDHUP | POLLERR;
+	mutex_unlock(&rti_sk->udev_mutex);
+
+	if (!list_empty(&rti_sk->rx_queue))
+		mask |= POLLIN;
+
+	return mask;
+}
+
+/*
+ *
+ */
+static int remoti_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+			       struct msghdr *m, size_t total_len,
+			       int flags)
+{
+	struct sock *sk = sock->sk;
+	struct rti_sock *rti_sk = to_rti_sock(sk);
+	int nonblock = flags & MSG_DONTWAIT;
+	struct rti_rx_msg *rx_msg;
+	long timeout;
+	size_t copied;
+
+	if (sock->state != SS_CONNECTED)
+		return -ENOTCONN;
+
+	do {
+		/* make sure device is still here */
+		mutex_lock(&rti_sk->udev_mutex);
+		if (!rti_sk->udev) {
+			mutex_unlock(&rti_sk->udev_mutex);
+			return -ECONNRESET;
+		}
+		mutex_unlock(&rti_sk->udev_mutex);
+
+		/* wait for any packet */
+		timeout = sock_rcvtimeo(sk, nonblock);
+		timeout = wait_event_interruptible_timeout(
+			*sk_sleep(sk),
+			!list_empty(&rti_sk->rx_queue) ||
+			!rti_sk->udev,
+			timeout);
+
+		if (list_empty(&rti_sk->rx_queue) && timeout == 0) {
+			/* timeout elapsed */
+			return -EAGAIN;
+		}
+
+		if (signal_pending(current))
+			return -EINTR;
+
+		/* dequeue one message */
+		rx_msg = NULL;
+		spin_lock(&rti_sk->rx_queue_lock);
+		if (!list_empty(&rti_sk->rx_queue)) {
+			rx_msg = list_first_entry(&rti_sk->rx_queue,
+						  struct rti_rx_msg, next);
+			if (!(flags & MSG_PEEK)) {
+				list_del(&rx_msg->next);
+				rti_sk->rx_queue_len--;
+			}
+
+		}
+		spin_unlock(&rti_sk->rx_queue_lock);
+
+		if (!rx_msg) {
+			/* someone took it before us, resleep */
+			continue;
+		}
+
+		copied = sizeof (struct rti_msg);
+		if (total_len < sizeof (struct rti_msg)) {
+			copied = total_len;
+			m->msg_flags |= MSG_TRUNC;
+		}
+
+		/* transfer reply to userspace */
+		if (memcpy_toiovec(m->msg_iov,
+				   (unsigned char *)&rx_msg->msg,
+				   copied)) {
+			return -EFAULT;
+		}
+
+		/* done */
+		return copied;
+
+	} while (1);
+
+	return 0;
+}
+
+/*
+ *
+ */
+static int remoti_sock_setsockopt(struct socket *sock, int level, int optname,
+				  char __user *optval, unsigned int optlen)
+{
+	struct sock *sk = sock->sk;
+	struct rti_sock *rti_sk = to_rti_sock(sk);
+
+	if (level != SOL_REMOTI)
+		return -ENOPROTOOPT;
+
+	switch (optname) {
+	case REMOTI_REGISTER_CB:
+	{
+		struct rti_callback cb;
+		struct rti_sock_callback *cb_elem;
+		int ret;
+
+		if (sock->state != SS_CONNECTED)
+			return -ENOTCONN;
+
+		if (optlen != sizeof (cb))
+			return -EINVAL;
+
+		if (copy_from_user(&cb, optval, sizeof (cb)))
+			return -EFAULT;
+
+		mutex_lock(&rti_sk->udev_mutex);
+		if (!rti_sk->udev) {
+			mutex_unlock(&rti_sk->udev_mutex);
+			return -EIO;
+		}
+
+		cb_elem = kmalloc(sizeof (*cb_elem), GFP_KERNEL);
+		if (!cb_elem) {
+			mutex_unlock(&rti_sk->udev_mutex);
+			return -ENOMEM;
+		}
+
+		memcpy(&cb_elem->cb, &cb, sizeof (cb));
+
+		ret = rti_register_cmd_callback(rti_sk->udev,
+						cb.subsys, cb.cmd,
+						remoti_sock_deliver, rti_sk);
+
+		if (!ret)
+			list_add_tail(&cb_elem->next, &rti_sk->callback_list);
+		else
+			kfree(cb_elem);
+
+		mutex_unlock(&rti_sk->udev_mutex);
+		return ret;
+	}
+
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	return 0;
+}
+
+
+/*
+ *
+ */
+static int remoti_sock_release(struct socket *sock)
+{
+	struct sock *sk;
+	struct rti_sock *rti_sk;
+
+	if (!sock || !sock->sk)
+		return 0;
+
+	sk = sock->sk;
+	rti_sk = to_rti_sock(sk);
+
+	sock_orphan(sk);
+	mutex_lock(&rti_sk->udev_mutex);
+	if (rti_sk->udev) {
+		struct rti_sock_callback *cb_elem, *tmp;
+
+		list_for_each_entry_safe(cb_elem, tmp, &rti_sk->callback_list,
+					 next) {
+			rti_unregister_cmd_callback(rti_sk->udev,
+						    cb_elem->cb.subsys,
+						    cb_elem->cb.cmd);
+			kfree(cb_elem);
+		}
+
+		INIT_LIST_HEAD(&rti_sk->callback_list);
+		rti_release_udevice(rti_sk->udev);
+		rti_sk->udev = NULL;
+	}
+	mutex_unlock(&rti_sk->udev_mutex);
+
+	mutex_lock(&remoti_socks_list_mutex);
+	list_del(&rti_sk->next);
+	mutex_unlock(&remoti_socks_list_mutex);
+
+	sock->sk = NULL;
+	sock_put(sk);
+
+	return 0;
+}
+
+/*
+ *
+ */
+static int rti_udev_notifier_cb(struct notifier_block *n,
+				unsigned long id, void *data)
+{
+	struct rti_sock *rti_sk;
+	enum rti_udev_state *st = (enum rti_udev_state *)data;
+
+	/* only interested in "going down" state */
+	if (*st == RTI_UDEV_UP)
+		return 0;
+
+	mutex_lock(&remoti_socks_list_mutex);
+
+	list_for_each_entry(rti_sk, &remoti_socks_list, next) {
+
+		if (rti_sk->rti_dev_id != id)
+			continue;
+
+		if (!mutex_trylock(&rti_sk->udev_mutex))
+			continue;
+
+		if (rti_sk->udev) {
+			struct rti_sock_callback *cb_elem, *tmp;
+
+			list_for_each_entry_safe(cb_elem, tmp,
+						 &rti_sk->callback_list,
+						 next)
+				kfree(cb_elem);
+
+			INIT_LIST_HEAD(&rti_sk->callback_list);
+			rti_release_udevice(rti_sk->udev);
+			rti_sk->udev = NULL;
+
+			wake_up(sk_sleep(&rti_sk->sk));
+		}
+		mutex_unlock(&rti_sk->udev_mutex);
+	}
+
+	mutex_unlock(&remoti_socks_list_mutex);
+	return 0;
+}
+
+static struct notifier_block rti_udev_notifier_block = {
+	.notifier_call = rti_udev_notifier_cb,
+};
+
+static const struct proto_ops remoti_proto_ops = {
+	.family =	PF_REMOTI,
+
+	.accept =	sock_no_accept,
+	.bind =		sock_no_bind,
+	.connect =	remoti_sock_connect,
+	.getsockopt =	sock_no_getsockopt,
+	.getname =	sock_no_getname,
+	.ioctl =	sock_no_ioctl,
+	.listen =	sock_no_listen,
+	.mmap =		sock_no_mmap,
+	.owner =	THIS_MODULE,
+	.poll =		remoti_sock_poll,
+	.recvmsg =	remoti_sock_recvmsg,
+	.release =	remoti_sock_release,
+	.setsockopt =	remoti_sock_setsockopt,
+	.sendmsg =	remoti_sock_sendmsg,
+	.shutdown =	sock_no_shutdown,
+	.socketpair =	sock_no_socketpair,
+	.sendpage =	sock_no_sendpage,
+};
+
+static struct proto remoti_proto = {
+        .name           = "remoti",
+        .owner          =  THIS_MODULE,
+        .obj_size       = sizeof (struct rti_sock),
+};
+
+static int remoti_sock_create(struct net *net, struct socket *sock,
+			      int protocol, int kern)
+{
+	struct sock *sk;
+	struct rti_sock *rti_sk;
+
+	if (sock->type != SOCK_SEQPACKET || protocol)
+		return -ESOCKTNOSUPPORT;
+
+        sk = sk_alloc(net, PF_REMOTI, GFP_KERNEL, &remoti_proto);
+	if (!sk)
+		return -ENOMEM;
+
+        sock_init_data(sock, sk);
+        sock->state = SS_UNCONNECTED;
+        sock->ops = &remoti_proto_ops;
+
+	rti_sk = to_rti_sock(sk);
+	rti_sk->udev = NULL;
+	mutex_init(&rti_sk->udev_mutex);
+	INIT_LIST_HEAD(&rti_sk->callback_list);
+	INIT_LIST_HEAD(&rti_sk->rx_queue);
+	spin_lock_init(&rti_sk->rx_queue_lock);
+
+	mutex_lock(&remoti_socks_list_mutex);
+	list_add_tail(&rti_sk->next, &remoti_socks_list);
+	mutex_unlock(&remoti_socks_list_mutex);
+
+	return 0;
+}
+
+static struct net_proto_family remoti_family_ops = {
+	.family = PF_REMOTI,
+	.create = remoti_sock_create,
+	.owner = THIS_MODULE,
+};
+
+static int __init remoti_user_init(void)
+{
+	int ret;
+
+	INIT_LIST_HEAD(&remoti_socks_list);
+
+	ret = proto_register(&remoti_proto, 0);
+	if (ret)
+		return ret;
+
+	ret = sock_register(&remoti_family_ops);
+	if (ret)
+		goto fail_proto;
+
+	rti_register_udevice_notifier(&rti_udev_notifier_block);
+	return 0;
+
+fail_proto:
+	proto_unregister(&remoti_proto);
+
+	return ret;
+}
+
+static void __exit remoti_user_exit(void)
+{
+	rti_unregister_udevice_notifier(&rti_udev_notifier_block);
+	sock_unregister(PF_REMOTI);
+	proto_unregister(&remoti_proto);
+}
+
+module_init(remoti_user_init);
+module_exit(remoti_user_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_NETPROTO(PF_REMOTI);
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/drivers/mtd/fbx6hd-mtdparts.c	2012-07-27 18:10:45.116135848 +0200
@@ -0,0 +1,244 @@
+/*
+ * MTD parser for fbx6hd, just return a static mtd partition
+ * list. optionally set all partitions to read/write if requested by
+ * config.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/mtd.h>
+
+#define PFX	"fbx6hd-mtdparts: "
+
+#define SZ_1M	(1 << 20)
+
+#define MBR_BLOCKS	(8)
+#define CEFDK_S1_BLOCKS	(8)
+#define CEFDK_S2_BLOCKS	(8 * 4)
+#define SERIAL_BLOCKS	(16)
+#define KEYS_BLOCKS	(8)
+
+
+#define BANK0_SIZE	(18 * SZ_1M)
+#define CONFIG_SIZE	(7 * SZ_1M)
+#define NEWBANK0_SIZE	BANK0_SIZE
+enum {
+	E_PART_ALL,
+	E_PART_MBR,
+	E_PART_CEFDK_S1_B0,
+	E_PART_CEFDK_S1_B1,
+	E_PART_CEFDK_S2_B0,
+	E_PART_CEFDK_S2_B1,
+	E_PART_SERIALINFO,
+	E_PART_KEYS,
+	E_PART_BANK0,
+	E_PART_CONFIG,
+	E_PART_BANK1,
+	E_PART_NEWBANK0,
+};
+
+static struct mtd_partition fbx6hd_nand_partitions[] = {
+	[E_PART_ALL] = {
+		.name		= "all",
+		.offset		= -1,
+		.size		= -1,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	[E_PART_MBR] = {
+		.name		= "mbr",
+		.offset		= -1,
+		.size		= -1,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	[E_PART_CEFDK_S1_B0] = {
+		.name		= "cefdk-stage1-bank0",
+		.offset		= -1,
+		.size		= -1,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	[E_PART_CEFDK_S1_B1] = {
+		.name		= "cefdk-stage1-bank1",
+		.offset		= -1,
+		.size		= -1,
+	},
+	[E_PART_CEFDK_S2_B0] = {
+		.name		= "cefdk-stage2-bank0",
+		.offset		= -1,
+		.size		= -1,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	[E_PART_CEFDK_S2_B1] = {
+		.name		= "cefdk-stage2-bank1",
+		.offset		= -1,
+		.size		= -1,
+	},
+	[E_PART_SERIALINFO] = {
+		.name		= "serial",
+		.offset		= -1,
+		.size		= -1,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	[E_PART_KEYS] = {
+		.name		= "keys",
+		.offset		= -1,
+		.size		= -1,
+	},
+	[E_PART_BANK0] = {
+		.name		= "bank0",
+		.offset		= -1,
+		.size		= -1,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	[E_PART_CONFIG] = {
+		.name		= "config",
+		.offset		= -1,
+		.size		= -1,
+	},
+	[E_PART_BANK1] = {
+		.name		= "bank1",
+		.offset		= -1,
+		.size		= -1,
+	},
+	[E_PART_NEWBANK0] = {
+		.name		= "newbank0",
+		.offset		= -1,
+		.size		= -1,
+	},
+};
+
+static int fbx6hd_parse_mtd_partitions(struct mtd_info *master,
+				       struct mtd_partition **pparts,
+				       struct mtd_part_parser_data *pdata)
+{
+	struct mtd_partition *bank1;
+	struct mtd_partition *newbank0;
+	struct mtd_partition *cur_part;
+	u32 cur_offset;
+
+	/*
+	 * make all partition cover the whole flash.
+	 */
+	cur_part = &fbx6hd_nand_partitions[E_PART_ALL];
+	cur_part->offset = 0;
+	cur_part->size = master->size;
+
+	/*
+	 * start filling partition offset/size one by one.
+	 */
+	cur_offset = 0;
+	cur_part = &fbx6hd_nand_partitions[E_PART_MBR];
+	cur_part->offset = cur_offset;
+	cur_part->size = MBR_BLOCKS * master->erasesize;
+
+	/*
+	 * CEFDK stage1 partitions
+	 */
+	cur_offset += cur_part->size;
+	cur_part = &fbx6hd_nand_partitions[E_PART_CEFDK_S1_B0];
+	cur_part->offset = cur_offset;
+	cur_part->size = CEFDK_S1_BLOCKS * master->erasesize;
+
+	cur_offset += cur_part->size;
+	cur_part = &fbx6hd_nand_partitions[E_PART_CEFDK_S1_B1];
+	cur_part->offset = cur_offset;
+	cur_part->size = CEFDK_S1_BLOCKS * master->erasesize;
+
+	/*
+	 * CEFDK stage2 partitions
+	 */
+	cur_offset += cur_part->size;
+	cur_part = &fbx6hd_nand_partitions[E_PART_CEFDK_S2_B0];
+	cur_part->offset = cur_offset;
+	cur_part->size = CEFDK_S2_BLOCKS * master->erasesize;
+
+	cur_offset += cur_part->size;
+	cur_part = &fbx6hd_nand_partitions[E_PART_CEFDK_S2_B1];
+	cur_part->offset = cur_offset;
+	cur_part->size = CEFDK_S2_BLOCKS * master->erasesize;
+
+	/*
+	 * Freebox specific
+	 */
+	cur_offset += cur_part->size;
+	cur_part = &fbx6hd_nand_partitions[E_PART_SERIALINFO];
+	cur_part->offset = cur_offset;
+	cur_part->size = SERIAL_BLOCKS * master->erasesize;
+
+	cur_offset += cur_part->size;
+	cur_part = &fbx6hd_nand_partitions[E_PART_KEYS];
+	cur_part->offset = cur_offset;
+	cur_part->size = KEYS_BLOCKS * master->erasesize;
+
+	cur_offset += cur_part->size;
+	cur_part = &fbx6hd_nand_partitions[E_PART_BANK0];
+	cur_part->offset = cur_offset;
+	cur_part->size = BANK0_SIZE;
+
+	cur_offset += cur_part->size;
+	cur_part = &fbx6hd_nand_partitions[E_PART_CONFIG];
+	cur_part->offset = cur_offset;
+	cur_part->size = CONFIG_SIZE;
+
+	cur_offset += cur_part->size;
+	cur_part = &fbx6hd_nand_partitions[E_PART_BANK1];
+	cur_part->offset = cur_offset;
+	cur_part->size = master->size - cur_offset;
+
+	/*
+	 * newbank0 starts inside bank1 partition and ends at the end
+	 * of the flash.
+	 */
+	cur_offset = master->size - NEWBANK0_SIZE;
+	cur_part = &fbx6hd_nand_partitions[E_PART_NEWBANK0];
+	cur_part->offset = cur_offset;
+	cur_part->size = NEWBANK0_SIZE;
+
+	/*
+	 * some basic sanity checks before to avoid botched partitiont
+	 * table.
+	 */
+	bank1 = &fbx6hd_nand_partitions[E_PART_BANK1];
+	newbank0 = &fbx6hd_nand_partitions[E_PART_NEWBANK0];
+	if (bank1->offset > master->size) {
+		printk(KERN_CRIT PFX "bank1 partition starts after flash "
+		       "end: use a bigger flash.\n");
+		return -ENOSPC;
+	}
+
+	if (newbank0->offset < bank1->offset) {
+		printk(KERN_CRIT PFX "newbank0 starts before bank1: use a "
+		       "bigger flash.\n");
+		return -ENOSPC;
+	}
+
+	printk(KERN_INFO PFX "%llu MiB available for bank1.\n",
+	       bank1->size >> 20);
+
+#ifdef CONFIG_MTD_FBX6HD_PARTS_WRITE_ALL
+	int i;
+	for (i = 0; i < ARRAY_SIZE(fbx6hd_nand_partitions); ++i)
+		fbx6hd_nand_partitions[i].mask_flags &= ~MTD_WRITEABLE;
+#endif
+
+	*pparts = kmemdup(fbx6hd_nand_partitions,
+			  sizeof (fbx6hd_nand_partitions), GFP_KERNEL);
+	return ARRAY_SIZE(fbx6hd_nand_partitions);
+}
+
+struct mtd_part_parser fbx6hd_mtd_parser = {
+	.owner		= THIS_MODULE,
+	.parse_fn	= fbx6hd_parse_mtd_partitions,
+	.name		= "fbx6hd-mtdparts",
+};
+
+static int __init fbx6hd_parser_init(void)
+{
+	return register_mtd_parser(&fbx6hd_mtd_parser);
+}
+
+module_init(fbx6hd_parser_init);
+
+
+MODULE_AUTHOR("Nicolas Schichan <nschichan@freebox.fr>");
+MODULE_LICENSE("GPL");
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/drivers/mtd/nand/denali_nand.c	2013-06-13 15:06:40.214518353 +0200
@@ -0,0 +1,1053 @@
+/*
+ * denali nand controller driver.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/mtd.h>
+
+#include <linux/mtd/partitions.h>
+
+#define PFX	"denali_nand: "
+
+#include "denali_nand.h"
+
+static const char *parts_parsers[] = { "fbx6hd-mtdparts", NULL };
+
+static int max_mode __read_mostly = 4;
+module_param(max_mode, int, 0);
+MODULE_PARM_DESC(max_mode, "Maximum ONFI timing mode supported (default: 4)");
+
+static int map_mode __read_mostly;
+module_param(map_mode, int, 0);
+MODULE_PARM_DESC(map_mode, "MAP mode to use (01, 10, 11)");
+
+static int dnl_reset_bank(struct denali_nand_priv *priv);
+
+/*
+ * register accessors
+ */
+static inline u32 dnl_reg_readl(struct denali_nand_priv *priv, u32 addr)
+{
+	return readl(priv->regs + addr);
+}
+
+static inline void dnl_reg_writel(struct denali_nand_priv *priv, u32 val,
+				  u32 addr)
+{
+	writel(val, priv->regs + addr);
+}
+
+/*
+ * mem accessors.
+ */
+static inline u32 dnl_mem_readl(struct denali_nand_priv *priv, u32 addr)
+{
+	return readl(priv->mem + addr);
+}
+
+static inline void dnl_mem_writel(struct denali_nand_priv *priv, u32 val,
+				  u32 addr)
+{
+	writel(val, priv->mem + addr);
+}
+
+/*
+ * read/write to/from a map.
+ */
+static uint32_t dnl_map_read(struct denali_nand_priv *priv, u32 map_ctl)
+{
+	dnl_mem_writel(priv, map_ctl, DNL_MAP_CTL_REG);
+	return dnl_mem_readl(priv, DNL_MAP_DATA_REG);
+}
+
+static void dnl_map_write(struct denali_nand_priv *priv, u32 data,
+				 u32 map_ctl)
+{
+	dnl_mem_writel(priv, map_ctl, DNL_MAP_CTL_REG);
+	dnl_mem_writel(priv, data, DNL_MAP_DATA_REG);
+}
+
+/*
+ * write_buf: support only map11 write, direct NAND bus access.
+ */
+static void dnl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	struct nand_chip *nand;
+	struct denali_nand_priv *priv;
+	int i;
+	u32 map_ctl;
+
+	nand = mtd->priv;
+	priv = nand->priv;
+
+	map_ctl = DNL_MAP_11_MASK;
+	map_ctl |= priv->chip_num << DNL_CHIP_SHIFT;
+	map_ctl |= DNL_MAP_11_DATA_MASK;
+
+	dnl_mem_writel(priv, map_ctl, DNL_MAP_CTL_REG);
+
+	for (i = 0; i < len; ++i)
+		dnl_mem_writel(priv, buf[i], DNL_MAP_DATA_REG);
+}
+
+static u8 dnl_read_map11_byte(struct denali_nand_priv *priv)
+{
+	u8 ret;
+	u32 map_ctl;
+
+	map_ctl = DNL_MAP_11_MASK;
+	map_ctl |= priv->chip_num << DNL_CHIP_SHIFT;
+	map_ctl |= DNL_MAP_11_DATA_MASK;
+
+	ret =  dnl_map_read(priv, map_ctl);
+	return ret;
+}
+
+static u8 dnl_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *nand;
+	struct denali_nand_priv *priv;
+
+	nand = mtd->priv;
+	priv = nand->priv;
+
+	if (priv->buf_mode != E_BUFMODE_MAP11) {
+		printk(KERN_ERR PFX "read_byte() when not in MAP11 mode is "
+		       "not supported.\n");
+		return 0xff;
+	}
+
+	return dnl_read_map11_byte(priv);
+}
+
+/*
+ * map11 read_buf: all accesses will generate a data read on the NAND
+ * bus.
+ */
+static void dnl_read_map11_buf(struct denali_nand_priv *priv,
+			       uint8_t *buf, int len)
+{
+	int i;
+	u32 map_ctl;
+
+	map_ctl = DNL_MAP_11_MASK;
+	map_ctl |= priv->chip_num << DNL_CHIP_SHIFT;
+	map_ctl |= DNL_MAP_11_DATA_MASK;
+
+	dnl_mem_writel(priv, map_ctl, DNL_MAP_CTL_REG);
+
+	for (i = 0; i < len; ++i)
+		buf[i] = dnl_mem_readl(priv, DNL_MAP_DATA_REG);
+}
+
+static void dnl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	struct nand_chip *nand;
+	struct denali_nand_priv *priv;
+
+	nand = mtd->priv;
+	priv = nand->priv;
+
+	dnl_read_map11_buf(priv, buf, len);
+}
+
+/*
+ * enable/disable DMA helpers. DMA MUST be enabled before issuing the
+ * MAP10 four command sequence.
+ */
+static void dnl_enable_dma(struct denali_nand_priv *priv)
+{
+	dnl_reg_writel(priv, 1, DNL_DMA_ENABLE);
+	dnl_reg_readl(priv, DNL_DMA_ENABLE);
+}
+
+static void dnl_disable_dma(struct denali_nand_priv *priv)
+{
+	dnl_reg_writel(priv, 0, DNL_DMA_ENABLE);
+	dnl_reg_readl(priv, DNL_DMA_ENABLE);
+}
+
+/*
+ * used before and after reading/writing OOB.
+ */
+static void dnl_set_transfer_mode(struct denali_nand_priv *priv,
+				  int page, int mode)
+{
+	u32 map_ctl;
+	u32 data;
+
+	map_ctl = DNL_MAP_10_MASK;
+	map_ctl |= (priv->chip_num << DNL_CHIP_SHIFT);
+	map_ctl |= page;
+	data = mode;
+
+	dnl_map_write(priv, data, map_ctl);
+}
+
+static void dnl_clear_all_interrupts(struct denali_nand_priv *priv)
+{
+	u32 reg_offset;
+
+	reg_offset = DNL_0_INTR_STATUS_REG + (priv->chip_num * 0x14) * 4;
+	dnl_reg_writel(priv, 0xffff, reg_offset);
+}
+
+/*
+ * configure a DMA access using the mapped dma buffer in priv. this is
+ * done by issuing the 4 command sequence described in the
+ * documentation, chapter7, page 52.
+ */
+static void dnl_setup_dma(struct denali_nand_priv *priv,
+			  u32 page_addr, int access_mode)
+{
+	uint32_t map_ctl;
+	uint32_t data;
+	uint16_t addr_hi;
+	uint16_t addr_lo;
+
+	addr_hi = ((u32)priv->read_buf_dma >> 16) & 0xffff;
+	addr_lo = (u32)priv->read_buf_dma & 0xffff;
+
+	map_ctl = DNL_MAP_10_MASK | (priv->chip_num << DNL_CHIP_SHIFT);
+
+	/*
+	 * first step, transmit page_addr, select between program or
+	 * read..
+	 */
+	if (access_mode == DNL_E_DMA_PROGRAM)
+		data = DNL_MAP10_DMA_WRITE_PAGE;
+	else
+		data = DNL_MAP10_DMA_READ_PAGE;
+	dnl_map_write(priv, data, map_ctl | page_addr);
+
+	/*
+	 * second step, transmit addr_hi
+	 */
+	dnl_map_write(priv, DNL_MAP10_DMA_SET_ADDR_HI,
+		      map_ctl | (addr_hi << 8));
+
+	/*
+	 * third step, transmit addr_lo
+	 */
+	dnl_map_write(priv, DNL_MAP10_DMA_SET_ADDR_LO,
+		      map_ctl | (addr_lo << 8));
+
+	/*
+	 * fourth step, raise interrupt when complete, 64byte burst.
+	 */
+	dnl_map_write(priv, DNL_MAP10_DMA_SET_PARAMS,
+		      map_ctl | DNL_DMA_PARAM_GEN_INT | DNL_DMA_BURST_64);
+}
+
+/*
+ * wait for specific interrupt flag to be set by hardware. wait at
+ * most for 2 seconds for this to happen or timeout.
+ *
+ * more than one bit can be set in the status_mask (for instance to
+ * watch program_complete and program_failed interrupt events). the
+ * status that caused this function to return is set in *res_status
+ * for the caller layer to sort out.
+ */
+static int dnl_spin_for_mask(struct denali_nand_priv *priv,
+			     u32 status_mask, u32 *res_status)
+{
+	u32 count;
+	u32 status;
+	u32 reg_offset;
+
+	/*
+	 * select the status register of the chip we want to spin on.
+	 */
+	reg_offset = DNL_0_INTR_STATUS_REG + (priv->chip_num * 0x14) * 4;
+
+	/*
+	 * wait, use a two second timeout, should yield a confortable
+	 * margin for any expected irq bit to be set.
+	 */
+	count = 200000;
+	while (count) {
+		status = dnl_reg_readl(priv, reg_offset);
+		if (status & status_mask) {
+			dnl_reg_writel(priv, status_mask, reg_offset);
+			*res_status = status;
+			return 0;
+		}
+		cpu_relax();
+		--count;
+	}
+
+	printk(KERN_ERR PFX "timedout waiting for %08x: status %08x\n",
+	       status_mask, status);
+	return -ETIMEDOUT;
+}
+
+/*
+ * read a page using DMA.
+ */
+static int dnl_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+			     uint8_t *buf, int page)
+{
+	struct denali_nand_priv *priv = nand->priv;
+	u32 status;
+
+	dma_sync_single_for_device(&priv->dev->dev, priv->read_buf_dma,
+				   priv->read_buf_size, DMA_FROM_DEVICE);
+
+	dnl_enable_dma(priv);
+	dnl_setup_dma(priv, page, DNL_E_DMA_READ);
+
+	if (dnl_spin_for_mask(priv,
+			      DNL_INT_DMA_DATA_CMD_COMPLETE |
+			      DNL_INT_BAD_CMD_SEQ,
+			      &status) < 0) {
+		printk(KERN_ERR PFX "timedout waiting for DMA.\n");
+		return -ETIMEDOUT;
+	}
+	udelay(20);
+
+	/*
+	 * disable and sync dma before considering status.
+	 */
+	dnl_disable_dma(priv);
+	dma_sync_single_for_cpu(&priv->dev->dev, priv->read_buf_dma,
+				priv->read_buf_size, DMA_FROM_DEVICE);
+
+	if (status & DNL_INT_BAD_CMD_SEQ) {
+		printk(KERN_ERR PFX "controller reported a bad command "
+		       "sequence.\n");
+		return -EIO;
+	}
+
+	memcpy(buf, priv->read_buf, mtd->writesize);
+	memcpy(nand->oob_poi, priv->read_buf + mtd->writesize, mtd->oobsize);
+
+	return 0;
+}
+
+/*
+ * access oob zone using MAP01 command and no DMA.
+ */
+static int dnl_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
+			int page, int sndcmd)
+{
+	struct denali_nand_priv *priv = nand->priv;
+	u32 map_ctl;
+	u32 pos;
+	u32 *buf32;
+	u32 status;
+
+	dnl_clear_all_interrupts(priv);
+
+	/*
+	 * tell the hardware to read only spare in MAP01 mode.
+	 */
+	dnl_set_transfer_mode(priv, page, DNL_XFER_SPARE_ONLY);
+
+	/*
+	 * select the page to read oob from.
+	 */
+	map_ctl = DNL_MAP_01_MASK | page;
+	dnl_mem_writel(priv, map_ctl, DNL_MAP_CTL_REG);
+
+	/*
+	 * read oob.
+	 */
+	buf32 = (u32*)nand->oob_poi;
+	for (pos = 0; pos < mtd->oobsize; pos += 4)
+		buf32[pos / 4] = dnl_mem_readl(priv, DNL_MAP_DATA_REG);
+
+	/*
+	 * ok, we already have the data in nand->oob_poi, so I guess
+	 * this is in the original driver just to be sure that we have
+	 * not read crap from the controller.
+	 */
+	if (dnl_spin_for_mask(priv, DNL_INT_LOAD_COMPLETE, &status) < 0) {
+		printk("timeouted waiting for oob load completion.\n");
+		return -ETIMEDOUT;
+	}
+
+	/*
+	 * switch back to MAIN + SPARE mode.
+	 */
+	dnl_set_transfer_mode(priv, page, DNL_XFER_SPARE_AND_MAIN);
+
+	return 0;
+}
+
+/*
+ * write oob zone of given page. use MAP01 command, no DMA.
+ */
+static int dnl_write_oob(struct mtd_info *mtd, struct nand_chip *nand, int page)
+{
+	struct denali_nand_priv *priv = nand->priv;
+	u32 map_ctl;
+	u32 *buf32;
+	u32 pos;
+	u32 status;
+
+	dnl_clear_all_interrupts(priv);
+
+	/*
+	 * tell the hardware to read only spare in MAP01 mode.
+	 */
+	dnl_set_transfer_mode(priv, page, DNL_XFER_SPARE_ONLY);
+
+	/*
+	 * select the page to write oob from.
+	 */
+	map_ctl = DNL_MAP_01_MASK | page;
+	dnl_mem_writel(priv, map_ctl, DNL_MAP_CTL_REG);
+
+	/*
+	 * write the oob data to the controller.
+	 */
+	buf32 = (u32*)nand->oob_poi;
+	for (pos = 0; pos < mtd->oobsize; pos += 4)
+		dnl_mem_writel(priv, buf32[pos / 4], DNL_MAP_DATA_REG);
+
+	if (dnl_spin_for_mask(priv,
+			      DNL_INT_PROGRAM_COMPLETE |
+			      DNL_INT_PROGRAM_FAIL,
+			      &status) < 0) {
+		printk(KERN_ERR PFX "timeouted waiting for OOB program.\n");
+		return -ETIMEDOUT;
+	}
+
+
+	/*
+	 * switch back to MAIN + SPARE mode.
+	 */
+	dnl_set_transfer_mode(priv, page, DNL_XFER_SPARE_AND_MAIN);
+
+	if (status & DNL_INT_PROGRAM_FAIL) {
+		printk(KERN_ERR PFX "controller reported a bad OOB program.\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+
+/*
+ * issue an erase command using MAP10 command and wait for command
+ * completion.
+ */
+static void dnl_erase_cmd(struct mtd_info *mtd, int page)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct denali_nand_priv *priv = nand->priv;
+	u32 map_ctl;
+	u32 data;
+	u32 status;
+
+	dnl_clear_all_interrupts(priv);
+
+	map_ctl = DNL_MAP_10_MASK | page;
+	data = DNL_MAP10_ERASE_COMMAND;
+	dnl_map_write(priv, data, map_ctl);
+
+	if (dnl_spin_for_mask(priv,
+			      DNL_INT_ERASE_FAILED | DNL_INT_ERASE_COMPLETE,
+			      &status) < 0) {
+		printk(KERN_ERR PFX "timeouted waiting for erase on page "
+		       "%u.\n", page);
+		return ;
+	}
+
+	if (status & DNL_INT_ERASE_FAILED) {
+		printk(KERN_ERR PFX "controller reported erase failed on "
+		       "block %i\n", page);
+		return ;
+	}
+}
+
+/*
+ * start a page write, use DMA.
+ */
+static void dnl_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+			       const uint8_t *buf)
+{
+	struct denali_nand_priv *priv = nand->priv;
+	u32 status;
+
+	/*
+	 * build buffer for DMA with oob tightly following data.
+	 */
+	memcpy(priv->read_buf, buf, mtd->writesize);
+	memcpy(priv->read_buf + mtd->writesize, nand->oob_poi, mtd->oobsize);
+
+	dma_sync_single_for_device(&priv->dev->dev, priv->read_buf_dma,
+				   priv->read_buf_size, DMA_TO_DEVICE);
+
+	dnl_clear_all_interrupts(priv);
+	dnl_enable_dma(priv);
+	dnl_setup_dma(priv, priv->page, DNL_E_DMA_PROGRAM);
+
+	if (dnl_spin_for_mask(priv,
+			      DNL_INT_DMA_DATA_CMD_COMPLETE |
+			      DNL_INT_PROGRAM_FAIL |
+			      DNL_INT_BAD_CMD_SEQ,
+			      &status) < 0) {
+		printk(KERN_ERR PFX "timedout waiting for program completion "
+		       "on page %u\n", priv->page);
+		return ;
+	}
+
+	dnl_disable_dma(priv);
+	dma_sync_single_for_cpu(&priv->dev->dev, priv->read_buf_dma,
+				priv->read_buf_size, DMA_TO_DEVICE);
+
+	if (status & DNL_INT_PROGRAM_FAIL) {
+		printk(KERN_ERR PFX "controller reported a program failure "
+		       "on page %u\n", priv->page);
+		return ;
+	}
+
+	if (status & DNL_INT_BAD_CMD_SEQ) {
+		printk(KERN_ERR PFX "controller reported a bad command "
+		       "sequence.\n");
+		return ;
+	}
+}
+
+/*
+ * command control: a NAND bus access will be generated with this
+ * function (command, address, or data).
+ */
+static void dnl_cmd_ctrl(struct mtd_info *mtd, int command,
+			 unsigned int ctrl)
+{
+	struct nand_chip *nand;
+	struct denali_nand_priv *priv;
+	u32 map_ctl;
+
+	nand = mtd->priv;
+	priv = nand->priv;
+
+	map_ctl = DNL_MAP_11_MASK;
+	map_ctl |= priv->chip_num << DNL_CHIP_SHIFT;
+
+	if (command == NAND_CMD_NONE)
+		return ;
+
+	/*
+	 * depending on address, or command cycle, set map_ctl with the
+	 * correct bits.
+	 */
+	if (ctrl & NAND_CLE)
+		map_ctl |= DNL_MAP_11_CMD_MASK;
+	else if (ctrl & NAND_ALE)
+		map_ctl |= DNL_MAP_11_ADDR_MASK;
+	else
+		BUG();
+
+	dnl_map_write(priv, command & 0xff, map_ctl);
+}
+
+/*
+ * generate needed address cycles to output column and page to the NAND
+ * bus.
+ */
+static void dnl_shift_addresses(struct mtd_info *mtd,
+				int column, int page)
+{
+	struct nand_chip *nand;
+
+	nand = mtd->priv;
+
+	if (column != -1) {
+		nand->cmd_ctrl(mtd, column, NAND_ALE);
+		nand->cmd_ctrl(mtd, column >> 8, NAND_ALE);
+	}
+
+	if (page != -1) {
+		nand->cmd_ctrl(mtd, page, NAND_ALE);
+		nand->cmd_ctrl(mtd, page >> 8, NAND_ALE);
+		if (nand->chipsize > (128 << 20))
+			nand->cmd_ctrl(mtd, page >> 16, NAND_ALE);
+	}
+}
+
+/*
+ * our cmdfunc callback. this duplicates some code from the upper
+ * layer nand_command_lp() function. page READ (NAND_CMD_READ0
+ * commands) are issued using MAP01/MAP10 commands which are faster.
+ */
+static void dnl_cmdfunc(struct mtd_info *mtd, unsigned int command,
+			int column, int page_addr)
+{
+	struct nand_chip *nand;
+	struct denali_nand_priv *priv;
+
+	nand = mtd->priv;
+	priv = nand->priv;
+
+	switch (command) {
+	case NAND_CMD_RESET:
+		dnl_reset_bank(priv);
+		break;
+
+	case NAND_CMD_READID:
+		/*
+		 * read id page. set bufmode to map11 so that upper
+		 * layer can read the result using the correct method.
+		 */
+		nand->cmd_ctrl(mtd, NAND_CMD_READID, NAND_CLE);
+		dnl_shift_addresses(mtd, column, page_addr);
+		udelay(35);
+		priv->buf_mode = E_BUFMODE_MAP11;
+		break;
+
+	case NAND_CMD_PARAM:
+		nand->cmd_ctrl(mtd, NAND_CMD_PARAM, NAND_CLE);
+		dnl_shift_addresses(mtd, column, page_addr);
+		udelay(35);
+		break;
+
+	case NAND_CMD_SEQIN:
+	case NAND_CMD_READ0:
+		priv->page = page_addr;
+		priv->page = page_addr;
+		break;
+
+	case NAND_CMD_STATUS:
+		/*
+		 * issue status register read command, and tell
+		 * read_buf/read_byte to use MAP11.
+		 */
+		nand->cmd_ctrl(mtd, NAND_CMD_STATUS, NAND_CLE);
+		priv->buf_mode = E_BUFMODE_MAP11;
+		break;
+
+
+	case NAND_CMD_PAGEPROG:
+		break;
+
+	default:
+		printk("warning: unhandled command %x (please report)\n",
+		       command);
+		return ;
+	}
+
+	ndelay(100);
+}
+
+static inline u32 ceil_div(u32 x, u32 y)
+{
+	if (x % y)
+		return x / y + 1;
+	else
+		return x / y;
+}
+
+#define CLK_X		5
+#define CLK_MULTI	4
+
+/*
+ * calculate ONFI timings for given onfi mode. copied from spectra
+ * driver, should yield the same timings.
+ */
+static void dnl_calc_onfi_timings(struct denali_nand_priv *priv,
+			       int onfi_mode)
+{
+	static const u8 Trea[6]	 = { 40, 30, 25, 20, 20, 16 };
+	static const u8 Trp[6]	 = { 50, 25, 17, 15, 12, 10 };
+	static const u8 Treh[6]	 = { 30, 15, 15, 10, 10, 7 };
+	static const u8 Trc[6]	 = { 100, 50, 35, 30, 25, 20 };
+	static const u8 Trhoh[6] = { 0, 15, 15, 15, 15, 15 };
+	static const u8 Trloh[6] = { 0, 0, 0, 0, 5, 5 };
+	static const u8 Tcea[6]	 = { 100, 45, 30, 25, 25, 25 };
+	static const u8 Tadl[6]	 = { 200, 100, 100, 100, 70, 70 };
+	static const u8 Trhw[6]	 = { 200, 100, 100, 100, 100, 100 };
+	static const u8 Trhz[6]	 = { 200, 100, 100, 100, 100, 100 };
+	static const u8 Twhr[6]	 = { 120, 80, 80, 60, 60, 60 };
+	static const u8 Tcs[6]	 = { 70, 35, 25, 25, 20, 15 };
+
+	u16 en_lo, en_hi;
+	u16 acc_clks;
+	u16 dv_window = 0;
+	u16 addr_2_data;
+	u16 re_2_we;
+	u16 re_2_re;
+	u16 we_2_re;
+	u16 cs_cnt;
+
+	en_lo = ceil_div(Trp[onfi_mode], CLK_X);
+	en_hi = ceil_div(Treh[onfi_mode], CLK_X);
+
+	if (en_hi * CLK_X < Treh[onfi_mode] + 2)
+		++en_hi;
+	if (CLK_X * (en_lo + en_hi) < Trc[onfi_mode] + 2)
+		en_lo += ceil_div(Trc[onfi_mode] - (en_lo + en_hi) * CLK_X,
+				  CLK_X);
+
+	if (en_lo + en_hi < CLK_MULTI)
+		en_lo += CLK_MULTI - en_lo - en_hi;
+
+	while (1) {
+		u16 data_invalid_rhoh, data_invalid_rloh, data_invalid;
+
+		data_invalid_rhoh = en_lo * CLK_X + Trhoh[onfi_mode];
+		data_invalid_rloh = (en_lo + en_hi) * CLK_X + Trloh[onfi_mode];
+		data_invalid = min(data_invalid_rhoh, data_invalid_rloh);
+
+		dv_window = data_invalid - Trea[onfi_mode];
+		if (dv_window >= 8)
+			break;
+		++en_lo;
+	}
+
+	acc_clks = ceil_div(Trea[onfi_mode], CLK_X);
+	while (acc_clks * CLK_X - Trea[onfi_mode] < 3)
+		++acc_clks;
+
+	addr_2_data = ceil_div(Tadl[onfi_mode], CLK_X);
+	re_2_we = ceil_div(Trhw[onfi_mode], CLK_X);
+	re_2_re = ceil_div(Trhz[onfi_mode], CLK_X);
+	we_2_re = ceil_div(Twhr[onfi_mode], CLK_X);
+	cs_cnt = ceil_div(Tcs[onfi_mode] - Trp[onfi_mode], CLK_X);
+	if (cs_cnt == 0)
+		cs_cnt = 1;
+
+	if (Tcea[onfi_mode])
+		while (cs_cnt * CLK_X + Trea[onfi_mode] < Tcea[onfi_mode])
+			cs_cnt++;
+
+	/*
+	 * apply calculated timings.
+	 */
+	dnl_reg_writel(priv, acc_clks, DNL_ACC_CLKS_REG);
+	dnl_reg_writel(priv, re_2_we, DNL_RE_2_WE_REG);
+	dnl_reg_writel(priv, re_2_re, DNL_RE_2_RE_REG);
+	dnl_reg_writel(priv, we_2_re, DNL_WE_2_RE_REG);
+	dnl_reg_writel(priv, addr_2_data, DNL_ADDR_2_DATA_REG);
+	dnl_reg_writel(priv, en_lo, DNL_EN_LO_CNT_REG);
+	dnl_reg_writel(priv, en_hi, DNL_EN_HI_CNT_REG);
+	dnl_reg_writel(priv, cs_cnt, DNL_CS_SETUP_CNT_REG);
+}
+
+static void dnl_set_slowest_timings(struct denali_nand_priv *priv)
+{
+	priv->buf_mode = E_BUFMODE_MAP11;
+
+	/*
+	 * use slowest and safest timing possible to read ONFI
+	 * parameter page. we will stay in this mode if we cannot read
+	 * the ONFI parameter page.
+	 */
+	dnl_calc_onfi_timings(priv, 0);
+}
+
+static int dnl_configure_timings(struct denali_nand_priv *priv)
+{
+	struct mtd_info *mtd;
+	struct nand_chip *nand;
+	u16 timing_modes;
+	int mode;
+
+	mtd = priv->mtd;
+	nand = mtd->priv;
+
+	timing_modes = le16_to_cpu(nand->onfi_params.async_timing_mode);
+
+	/*
+	 * walk bitfield storing supported ONFI timings, use the
+	 * highest available mode. start from fastest possible mode
+	 * (mode 5) and go down until we found one mode that is
+	 * supported.
+	 */
+	for (mode = max_mode; mode > 0; --mode) {
+		if (timing_modes & (1 << mode))
+			break;
+	}
+	printk(KERN_INFO PFX "using ONFI timing mode %i\n", mode);
+	dnl_calc_onfi_timings(priv, mode);
+
+	return 0;
+}
+
+static int dnl_reset_bank(struct denali_nand_priv *priv)
+{
+	u32 reg;
+	u32 status;
+
+	dnl_clear_all_interrupts(priv);
+
+	/*
+	 * reset controller.
+	 */
+	reg = dnl_reg_readl(priv, DNL_DEVICE_RESET_REG);
+	reg |= (1 << priv->chip_num);
+	dnl_reg_writel(priv, reg, DNL_DEVICE_RESET_REG);
+
+	/*
+	 * wait for reset completion.
+	 */
+	if (dnl_spin_for_mask(priv, DNL_INT_RESET_DONE | DNL_INT_WDOG_TIMEOUT,
+			      &status) < 0) {
+		printk("timeouted waiting for device reset.\n");
+		return -ETIMEDOUT;
+	}
+
+	if (status & DNL_INT_WDOG_TIMEOUT) {
+		printk("internal hardware watchdog triggered.\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	int err;
+	struct mtd_info *mtd;
+	struct nand_chip *nand;
+	struct denali_nand_priv *priv;
+
+	err = pci_enable_device(dev);
+	if (err) {
+		printk(KERN_ERR PFX "unable to enable pci device: %i.\n", err);
+		return err;
+	}
+
+	priv = kzalloc(sizeof (*priv), GFP_KERNEL);
+	if (!priv) {
+		err = -ENOMEM;
+		goto out_disable_device;
+	}
+	dev_set_drvdata(&dev->dev, priv);
+	priv->dev = dev;
+
+	/*
+	 * mem zone is on the first pci resource, map xx access is done here.
+	 */
+	priv->mem_phys = pci_resource_start(dev, 0);
+	priv->mem_size = pci_resource_end(dev, 0) - priv->mem_phys + 1;
+
+	/*
+	 * registers are on the second pci resource.
+	 */
+	priv->regs_phys = pci_resource_start(dev, 1);
+	priv->regs_size = pci_resource_end(dev, 1) - priv->regs_phys + 1;
+
+	priv->mem = ioremap(priv->mem_phys, priv->mem_size);
+	if (!priv->mem) {
+		err = -ENOMEM;
+		goto out_free_priv;
+	}
+
+	priv->regs = ioremap(priv->regs_phys, priv->regs_size);
+	if (!priv->regs) {
+		err = -ENOMEM;
+		goto out_unmap_mem;
+	}
+
+	mtd = kzalloc(sizeof (*mtd), GFP_KERNEL);
+	if (!mtd) {
+		err = -ENOMEM;
+		goto out_unmap_regs;
+	}
+	priv->mtd = mtd;
+
+	nand = kzalloc(sizeof (*nand), GFP_KERNEL);
+	if (!nand) {
+		err = -ENOMEM;
+		goto out_free_mtd;
+	}
+
+	mtd->priv = nand;
+	mtd->owner = THIS_MODULE;
+
+	/*
+	 * the chip may support it but the controller makes it a pain
+	 * to handle.
+	 */
+	nand->options = NAND_NO_RNDOUT;
+
+	nand->priv = priv;
+	nand->read_byte = dnl_read_byte;
+	nand->write_buf = dnl_write_buf;
+	nand->read_buf = dnl_read_buf;
+	nand->cmd_ctrl = dnl_cmd_ctrl;
+
+	if (map_mode == 11) {
+		/*
+	 	* always use MAP11 accesses, will be slower, but may be
+	 	* usefull for debug.
+	 	*/
+		printk(KERN_INFO PFX "using MAP11 for ALL accesses (slow).\n");
+		priv->buf_mode = E_BUFMODE_MAP11;
+		nand->ecc.mode = NAND_ECC_SOFT;
+		nand->chip_delay = 35;
+
+	} else {
+		/*
+	 	 * use our provided cmdfunc, with the ->ecc callbacks
+	 	 * along, things will go much more faster.
+	 	 */
+		nand->cmdfunc = dnl_cmdfunc;
+
+		nand->ecc.mode = NAND_ECC_SOFT;
+		nand->ecc.read_page_raw = dnl_read_page_raw;
+		nand->ecc.write_page_raw = dnl_write_page_raw;
+		nand->ecc.read_oob = dnl_read_oob;
+		nand->ecc.write_oob = dnl_write_oob;
+		nand->erase_cmd = dnl_erase_cmd;
+	}
+
+	dnl_clear_all_interrupts(priv);
+	dnl_reset_bank(priv);
+	dnl_set_slowest_timings(priv);
+
+	/*
+	 * enable prefetch on page read, to speed up things.
+	 */
+	dnl_reg_writel(priv, 1, DNL_PREFETCH_MODE);
+
+	/*
+	 * disable ECC verification/generation on page read/write.
+	 */
+	dnl_reg_writel(priv, 0, DNL_ECC_ENABLE_REG);
+
+	/*
+	 * allocate read buffer: size should be main size + oob
+	 * size. we do not have the mtd fields populated yet with
+	 * these values, but controller registers do already have them
+	 * populated.
+	 */
+	priv->read_buf_size = dnl_reg_readl(priv, DNL_MAIN_SIZE_REG) +
+		dnl_reg_readl(priv, DNL_SPARE_SIZE_REG);
+	priv->read_buf = kmalloc(2 * 4096, GFP_KERNEL);
+	if (!priv->read_buf) {
+		goto out_free_nand;
+		err = -ENOMEM;
+	}
+
+	if (pci_set_dma_mask(dev, DMA_BIT_MASK(32)) < 0) {
+		printk(KERN_ERR PFX "32bit dma not supported.\n");
+		goto out_free_read_buf;
+	}
+	priv->read_buf_dma = dma_map_single(&dev->dev, priv->read_buf,
+					    priv->read_buf_size,
+					    DMA_BIDIRECTIONAL);
+	if (dma_mapping_error(&dev->dev, priv->read_buf_dma)) {
+		printk(PFX KERN_ERR "unable to map read_buf for dma.\n");
+		goto out_free_read_buf;
+	}
+
+	/*
+	 * FIXME: 4 chips can be supported
+	 */
+	err = nand_scan_ident(mtd, 1, NULL);
+	if (err < 0)
+		goto out_pci_unmap_single;
+
+	if (map_mode != 11)
+		/*
+		 * FIXME: nand_scan_ident does not preserve our
+		 * erase_cmd.
+		 */
+		nand->erase_cmd = dnl_erase_cmd;
+
+
+
+	err = nand_scan_tail(mtd);
+	if (err < 0)
+		goto out_pci_unmap_single;
+
+
+	if (nand->onfi_version)
+		dnl_configure_timings(priv);
+
+	mtd->name = "denali_nand";
+	err = mtd_device_parse_register(mtd, parts_parsers, 0, NULL, 0);
+	if (err) {
+		printk(KERN_WARNING PFX "unable to register MTD dev.\n");
+		goto out_pci_unmap_single;
+	}
+
+	return 0;
+
+out_pci_unmap_single:
+	pci_unmap_single(dev, priv->read_buf_dma, priv->read_buf_size,
+			 PCI_DMA_BIDIRECTIONAL);
+out_free_read_buf:
+	kfree(priv->read_buf);
+out_free_nand:
+	kfree(nand);
+out_free_mtd:
+	kfree(mtd);
+out_unmap_regs:
+	iounmap(priv->regs);
+out_unmap_mem:
+	iounmap(priv->mem);
+out_free_priv:
+	kfree(priv);
+out_disable_device:
+	pci_disable_device(dev);
+	return err;
+}
+
+static void denali_pci_remove(struct pci_dev *dev)
+{
+	struct denali_nand_priv *priv;
+
+	priv = dev_get_drvdata(&dev->dev);
+
+	mtd_device_unregister(priv->mtd);
+	pci_unmap_single(dev, priv->read_buf_dma, priv->read_buf_size,
+			 PCI_DMA_BIDIRECTIONAL);
+	kfree(priv->read_buf);
+	kfree(priv->mtd->priv);
+	kfree(priv->mtd);
+
+	iounmap(priv->regs);
+	iounmap(priv->mem);
+
+	kfree(priv);
+	pci_disable_device(dev);
+}
+
+const struct pci_device_id denali_pci_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0701) },
+	{ 0, },
+};
+
+struct pci_driver	denali_nand_pci_driver =
+{
+	.name		= "denali_nand",
+	.id_table	= denali_pci_table,
+	.probe		= denali_pci_probe,
+	.remove		= denali_pci_remove,
+};
+
+static int __init denali_nand_init(void)
+{
+	int err;
+
+	err = pci_register_driver(&denali_nand_pci_driver);
+	if (err) {
+		printk(KERN_ERR PFX "pci_register_driver failed: %i.\n", err);
+		return err;
+	}
+	return 0;
+}
+
+static void __exit denali_nand_exit(void)
+{
+	pci_unregister_driver(&denali_nand_pci_driver);
+}
+
+module_init(denali_nand_init);
+module_exit(denali_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nicolas Schichan <nschichan@freebox.fr>");
+MODULE_DESCRIPTION("Denali NAND driver");
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/drivers/mtd/nand/denali_nand.h	2011-01-06 02:17:51.972146751 +0100
@@ -0,0 +1,165 @@
+
+#ifndef __DENALI_NAND_H
+# define __DENALI_NAND_H
+
+struct mtd_info;
+
+enum
+{
+	E_BUFMODE_MAP01,
+	E_BUFMODE_MAP11,
+};
+
+struct denali_nand_priv
+{
+	int		chip_num;
+	unsigned long	regs_phys;
+	unsigned long	regs_size;
+
+	unsigned long	mem_phys;
+	unsigned long	mem_size;
+
+	void __iomem	*regs;
+	void __iomem	*mem;
+
+	u8		*read_buf;
+	int		read_buf_size;
+	int		read_buf_offset;
+	int		page;
+
+
+	int		buf_mode;
+
+	dma_addr_t	read_buf_dma;
+
+	struct pci_dev *dev;
+	struct mtd_info	*mtd;
+};
+
+#define DNL_DEVICE_RESET_REG		0x0
+
+#define DNL_XFER_SPARE_REG		(0x4 * 4)
+
+#define DNL_CE_REG			(0x34 * 4)
+#define  DNL_CE_DISABLE			(1 << 0)
+
+#define DNL_RB_PIN_ENABLED_REG		(0x18 * 4)
+# define DNL_RB_PIN_B0_EN		(1 << 0)
+# define DNL_RB_PIN_B1_EN		(1 << 1)
+# define DNL_RB_PIN_B2_EN		(1 << 2)
+# define DNL_RB_PIN_B3_EN		(1 << 3)
+
+#define DNL_PREFETCH_MODE		(0x30 * 4)
+#define DNL_ECC_ENABLE_REG		(0x38 * 4)
+
+#define DNL_INT_ENABLE_REG		(0x3c * 4)
+# define DNL_INT_ENABLE			(1 << 0)
+
+#define DNL_MAIN_SIZE_REG		(0x5c * 4)
+#define DNL_SPARE_SIZE_REG		(0x60 * 4)
+
+#define DNL_0_INTR_STATUS_REG		(0x104 * 4)
+#define DNL_0_INTR_EN_REG		(0x108 * 4)
+#define DNL_0_PAGE_COUNT_REG		(0x10c * 4)
+#define DNL_0_ERR_ADDR_REG		(0x110 * 4)
+#define DNL_0_ERR_BLOCK_REG		(0x114 * 4)
+
+#define DNL_1_INTR_STATUS_REG		(0x118 * 4)
+#define DNL_1_INTR_EN_REG		(0x11c * 4)
+#define DNL_1_PAGE_COUNT_REG		(0x120 * 4)
+#define DNL_1_ERR_ADDR_REG		(0x124 * 4)
+#define DNL_1_ERR_BLOCK_REG		(0x128 * 4)
+
+#define DNL_2_INTR_STATUS_REG		(0x12c * 4)
+#define DNL_2_INTR_EN_REG		(0x130 * 4)
+#define DNL_2_PAGE_COUNT_REG		(0x134 * 4)
+#define DNL_2_ERR_ADDR_REG		(0x138 * 4)
+#define DNL_2_ERR_BLOCK_REG		(0x13c * 4)
+
+#define DNL_3_INTR_STATUS_REG		(0x140 * 4)
+#define DNL_3_INTR_EN_REG		(0x144 * 4)
+#define DNL_3_PAGE_COUNT_REG		(0x148 * 4)
+#define DNL_3_ERR_ADDR_REG		(0x14c * 4)
+#define DNL_3_ERR_BLOCK_REG		(0x150 * 4)
+
+/*
+ * interrupt cause bits valid for all 4 controllers.
+ */
+#define DNL_INT_DMA_DATA_CMD_COMPLETE	(1 << 2)
+#define DNL_INT_WDOG_TIMEOUT		(1 << 3)
+#define DNL_INT_PROGRAM_FAIL		(1 << 4)
+#define DNL_INT_ERASE_FAILED		(1 << 5)
+#define DNL_INT_LOAD_COMPLETE		(1 << 6)
+#define DNL_INT_PROGRAM_COMPLETE	(1 << 7)
+#define DNL_INT_ERASE_COMPLETE		(1 << 8)
+#define DNL_INT_BAD_CMD_SEQ		(1 << 11)
+#define DNL_INT_RESET_DONE		(1 << 13)
+
+
+#define DNL_SKIP_BYTE_REG		(0x8c * 4)
+#define DNL_SPACE_AREA_MARKER_REG	(0x90 * 4)
+
+#define DNL_MANUFACTURER_REG		(0xc0 * 4)
+
+#define DNL_PAGE_SIZE			(0xd4 * 4)
+#define DNL_SPARE_SIZE			(0xd8 * 4)
+
+/*
+ * timing configuration registers
+ */
+#define DNL_WE_2_RE_REG			(0x40 * 4)
+#define DNL_ADDR_2_DATA_REG		(0x44 * 4)
+#define DNL_RE_2_WE_REG			(0x48 * 4)
+#define DNL_ACC_CLKS_REG		(0x4c * 4)
+
+#define DNL_EN_LO_CNT_REG		(0x7c * 4)
+#define DNL_EN_HI_CNT_REG		(0x80 * 4)
+#define DNL_CS_SETUP_CNT_REG		(0x88 * 4)
+#define DNL_RE_2_RE_REG			(0xa4 * 4)
+
+#define DNL_XFER_MODE			(0x100 * 4)
+
+#define DNL_DMA_ENABLE			(0x1c0 * 4)
+
+/*
+ * map xx indirect read/write accessors
+ */
+#define DNL_MAP_01_MASK		0x04000000
+#define DNL_MAP_10_MASK		0x08000000
+#define DNL_MAP_11_MASK		0x0c000000
+
+#define DNL_CHIP_MASK		0x03000000
+#define DNL_CHIP_SHIFT		(24)
+#define DNL_MAP_11_CMD_MASK	(0x0)
+#define DNL_MAP_11_ADDR_MASK	(0x1)
+#define DNL_MAP_11_DATA_MASK	(0x2)
+
+#define DNL_MAP_CTL_REG		0x00
+#define DNL_MAP_DATA_REG	0x10
+
+#define DNL_XFER_SPARE_ONLY		0x41
+#define DNL_XFER_MAIN_ONLY		0x42
+#define DNL_XFER_SPARE_AND_MAIN		0x43
+
+#define DNL_MAP10_READAHEAD_ONCE	0x2001
+
+enum {
+	DNL_E_DMA_READ,
+	DNL_E_DMA_PROGRAM,
+};
+
+#define DNL_MAP10_ERASE_COMMAND		0x1
+
+/*
+ * DMA command sequence.
+ */
+#define DNL_MAP10_DMA_READ_PAGE		0x2001
+#define DNL_MAP10_DMA_WRITE_PAGE	0x2101
+#define DNL_MAP10_DMA_SET_ADDR_HI	0x2200
+#define DNL_MAP10_DMA_SET_ADDR_LO	0x2300
+#define DNL_MAP10_DMA_SET_PARAMS	0x2400
+
+#define DNL_DMA_PARAM_GEN_INT		(1 << 16)
+#define DNL_DMA_BURST_64		(0x40 << 8)
+
+#endif /* !__DENALI_NAND_H */
diff -Nruw linux-3.2.24-fbx/drivers/platform/intelce./dfx.c linux-3.2.24-fbx/drivers/platform/intelce/dfx.c
--- linux-3.2.24-fbx/drivers/platform/intelce./dfx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/platform/intelce/dfx.c	2011-11-04 14:26:08.943891252 +0100
@@ -0,0 +1,286 @@
+/*
+ * Intel CE DFX fuse SysFS export
+ *
+ * Copyright (C) 2009, Florian Fainelli <ffainelli@freebox.fr>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/sysfs.h>
+
+#define DFX_IO_SIZE	(64 * 1024)
+#define PFX		KBUILD_MODNAME
+
+#define DFX_ID_CODE	0x24
+#define DFX_SKU		0x28
+#define DFX_SN1		0x40
+#define DFX_SN2		0x44
+#define DFX_VCFG	0x64
+
+#define CW_CFG_BASE	0xA0000010
+#define DDR_SPEED	0x4
+
+#define CW_BRD_MASK	0x3
+#define CW_SEC_BOOT	7
+#define CW_VDAC_CAL	14
+
+#define DDR_SPEED_MASK	0x7
+
+static void __iomem *dfx_base;
+static void __iomem *cw_cfg_base;
+
+static ssize_t show_fuse_id_code(struct device *dev, struct device_attribute
+		      *devattr, char *buf)
+{
+	return sprintf(buf, "%04x\n",
+			ioread32(dfx_base + DFX_ID_CODE) >> 19 & 0xf);
+}
+
+static ssize_t show_sku_id(struct device *dev, struct device_attribute
+			*devattr, char *buf)
+{
+	return sprintf(buf, "%06x\n", ioread32(dfx_base + DFX_SKU) & 0x7f);
+}
+
+static ssize_t show_dev_serial1(struct device *dev, struct device_attribute
+			*devattr, char *buf)
+{
+	return sprintf(buf, "%08x\n", ioread32(dfx_base + DFX_SN1));
+}
+
+static ssize_t show_dev_serial2(struct device *dev, struct device_attribute
+			*devattr, char *buf)
+{
+	return sprintf(buf, "%08x\n", ioread32(dfx_base + DFX_SN2));
+}
+
+static ssize_t show_ca_vendor_cfg(struct device *dev, struct device_attribute
+			*devattr, char *buf)
+{
+	u32 vcfg = ioread32(dfx_base + DFX_VCFG);
+
+	return sprintf(buf, "%2x%2x\n", (vcfg >> 10) & 0xff, vcfg & 0xff);
+}
+
+static DEVICE_ATTR(fuse_id_code, S_IRUGO, show_fuse_id_code, NULL);
+static DEVICE_ATTR(sku_id, S_IRUGO, show_sku_id, NULL);
+static DEVICE_ATTR(dev_serial1, S_IRUGO, show_dev_serial1, NULL);
+static DEVICE_ATTR(dev_serial2, S_IRUGO, show_dev_serial2, NULL);
+static DEVICE_ATTR(ca_vendor_cfg, S_IRUGO, show_ca_vendor_cfg, NULL);
+
+#define CW_SHOW_ATTR(_name, _bit)					\
+static ssize_t show_##_name(struct device *dev, struct device_attribute \
+			*devattr, char *buf)				\
+{									\
+	return sprintf(buf, "%d\n", (readl(cw_cfg_base) &		\
+				(1 << _bit)) >> _bit);			\
+}									\
+static DEVICE_ATTR(_name, S_IRUGO, show_##_name, NULL);			\
+
+CW_SHOW_ATTR(trusted_mode, CW_SEC_BOOT);
+CW_SHOW_ATTR(vdac_cal, CW_VDAC_CAL);
+
+static ssize_t show_board_model(struct device *dev, struct device_attribute
+			*devattr, char *buf)
+{
+	u32 val = readl(cw_cfg_base) & CW_BRD_MASK;
+	const char *board;
+
+	switch (val) {
+	case 0:
+		board = "GoldenBeach";
+		break;
+	case 1:
+		board = "ChesapeakeBay";
+		break;
+	case 2:
+		board = "FalconFalls";
+		break;
+	case 3:
+		board = "PowerHouseLake";
+		break;
+	default:
+		board = "unknown";
+		break;
+	}
+
+	return sprintf(buf, "%s\n", board);
+}
+
+static DEVICE_ATTR(board_model, S_IRUGO, show_board_model, NULL);
+
+static ssize_t show_ddr_type(struct device *dev, struct device_attribute
+			*devattr, char *buf)
+{
+	u32 speed = (readl(cw_cfg_base + DDR_SPEED) >> 6) & DDR_SPEED_MASK;
+	const char *type;
+	const char *freq;
+
+	if (speed >= 4)
+		type = "DDR2";
+	else
+		type = "DDR3";
+
+	switch (speed) {
+	case 0:
+		freq = "800";
+		break;
+	case 1:
+		freq = "1066";
+		break;
+	case 2:
+		freq = "1333";
+		break;
+	case 3:
+		freq = "1600";
+		break;
+	case 4:
+		freq = "800";
+		break;
+	default:
+		freq = "unknown";
+		break;
+	}
+
+	return sprintf(buf, "%s (%s Mhz)\n", type, freq);
+}
+
+static DEVICE_ATTR(ddr_type, S_IRUGO, show_ddr_type, NULL);
+
+static struct attribute *intelce_dfx_attributes[] = {
+	&dev_attr_fuse_id_code.attr,
+	&dev_attr_sku_id.attr,
+	&dev_attr_dev_serial1.attr,
+	&dev_attr_dev_serial2.attr,
+	&dev_attr_ca_vendor_cfg.attr,
+	&dev_attr_trusted_mode.attr,
+	&dev_attr_vdac_cal.attr,
+	&dev_attr_board_model.attr,
+	&dev_attr_ddr_type.attr,
+	NULL
+};
+
+static const struct attribute_group intelce_dfx_group = {
+	.name = "intelce-dfx",
+	.attrs = intelce_dfx_attributes,
+};
+
+static int __devinit intelce_dfx_probe(struct pci_dev *pdev,
+				       const struct pci_device_id *id)
+{
+	int err;
+	int bar = 0;
+
+	err = pci_enable_device(pdev);
+	if (err)
+		goto err_out;
+
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (err) {
+		printk(KERN_ERR PFX ": 32-bit PCI DMA addresses"
+				"not supported by the card\n");
+		goto err_out;
+	}
+
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (err) {
+		printk(KERN_ERR PFX ": 32-bit PCI DMA addresses"
+				"not supported by the card\n");
+		goto err_out;
+	}
+
+	if (pci_resource_len(pdev, bar) < DFX_IO_SIZE) {
+		printk(KERN_ERR PFX ": Insufficient PCI resources, aborting\n");
+		err = -EIO;
+		goto err_out;
+	}
+
+	pci_set_master(pdev);
+
+	err = pci_request_regions(pdev, PFX);
+	if (err) {
+		printk(KERN_ERR PFX ": could not request PCI regions\n");
+		err = -EIO;
+		goto err_out;
+	}
+
+	dfx_base = pci_iomap(pdev, bar, DFX_IO_SIZE);
+	if (!dfx_base) {
+		printk(KERN_ERR PFX ": ioremap failed for device: %s\n",
+				pci_name(pdev));
+		err = -ENOMEM;
+		goto err_release_regions;
+	}
+
+	cw_cfg_base = ioremap(CW_CFG_BASE, 0x7);
+	if (!cw_cfg_base) {
+		printk(KERN_ERR PFX ": ioremap for CW[] failed\n");
+		err = -ENOMEM;
+		goto err_iounmap;
+	}
+
+	pci_set_drvdata(pdev, dfx_base);
+
+	err = sysfs_create_group(&pdev->dev.kobj, &intelce_dfx_group);
+	if (err) {
+		printk(KERN_ERR PFX ": unable to create sysfs group\n");
+		goto err_iounmap;
+	}
+
+	dev_info(&pdev->dev, "at 0x%p\n", dfx_base);
+
+	return 0;
+
+err_iounmap:
+	iounmap(cw_cfg_base);
+	pci_iounmap(pdev, dfx_base);
+err_release_regions:
+	pci_release_regions(pdev);
+err_out:
+	return err;
+}
+
+static void __exit intelce_dfx_remove(struct pci_dev *pdev)
+{
+	sysfs_remove_group(&pdev->dev.kobj, &intelce_dfx_group);
+	iounmap(cw_cfg_base);
+	pci_iounmap(pdev, dfx_base);
+	pci_set_drvdata(pdev, NULL);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+}
+
+static struct pci_device_id intelce_dfx_id_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6d) },
+	{ 0 }
+};
+
+static struct pci_driver intelce_dfx_driver = {
+	.name		= "intelce-dfx",
+	.id_table	= intelce_dfx_id_tbl,
+	.probe		= intelce_dfx_probe,
+	.remove		= __devexit_p(intelce_dfx_remove),
+};
+
+static int __init intelce_dfx_init(void)
+{
+	return pci_register_driver(&intelce_dfx_driver);
+}
+
+static void __exit intelce_dfx_exit(void)
+{
+	pci_unregister_driver(&intelce_dfx_driver);
+}
+
+module_init(intelce_dfx_init);
+module_exit(intelce_dfx_exit);
+
+MODULE_AUTHOR("Florian Fainelli <ffainelli@freebox.fr>");
+MODULE_DESCRIPTION("Intel CE 3100/4100 sysfs fuse reporting");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff -Nruw linux-3.2.24-fbx/drivers/platform/intelce./gpio-intelce.c linux-3.2.24-fbx/drivers/platform/intelce/gpio-intelce.c
--- linux-3.2.24-fbx/drivers/platform/intelce./gpio-intelce.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/platform/intelce/gpio-intelce.c	2012-07-27 18:10:46.268136945 +0200
@@ -0,0 +1,590 @@
+/*
+ * GPIO bus driver for the Intel CE3100/4100 SoC
+ *
+ * Copyright (C) 2009, Florian Fainelli <ffainelli@freebox.fr>
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/gpio.h>
+
+#define DRV_NAME		"intelce-gpio"
+#define DRV_VERSION		"0.1"
+
+#define GEN3_GPIO_IO_BASE	0x1080
+#define GEN3_GPIO_IO_SIZE	0x40
+#define GEN3_NUM_GPIO_PINS	26
+
+#define NR_BUILTIN_GPIO		GEN3_NUM_GPIO_PINS
+#define GEN3_GPIO_GROUPS	4
+
+/* Starting point for the different GPIO groups on intel_gen3 */
+#define GEN3_GPIO_GROUP_ZERO    0
+#define GEN3_GPIO_GROUP_ONE     12
+#define GEN3_GPIO_GROUP_TWO     15
+#define GEN3_GPIO_GROUP_THREE   22
+
+/* GPIO Group 0 */
+#define GEN3_GPIO0_GPOUTR	0x00
+#define GEN3_GPIO0_GPOER	0x04
+#define GEN3_GPIO0_GPINR	0x08
+#define GEN3_GPIO0_GPSTR	0x0C
+#define GEN3_GPIO0_GPIT1R0	0x10
+#define GEN3_GPIO0_INT		0x14
+#define GEN3_GPIO0_GPIT1R1	0x18
+#define GEN3_GPIO0_MUX_CNTL	0x1C
+
+/* GPIO Group 1*/
+#define GEN3_GPIO1_CGEN		0x00
+#define GEN3_GPIO1_CGIO		0x04
+#define GEN3_GPIO1_CGLV		0x08
+#define GEN3_GPIO1_CGTPE	0x0C
+#define GEN3_GPIO1_CGTNE	0x10
+#define GEN3_GPIO1_CGGPE	0x14
+#define GEN3_GPIO1_CGSMI	0x18
+#define GEN3_GPIO1_CGTS		0x1C
+
+/* GPIO Group 2 */
+#define GEN3_GPIO2_CGEN		0x00
+#define GEN3_GPIO2_CGIO		0x04
+#define GEN3_GPIO2_CGLV		0x08
+#define GEN3_GPIO2_CGTPE	0x0C
+#define GEN3_GPIO2_CGTNE	0x10
+#define GEN3_GPIO2_CGGPE	0x14
+#define GEN3_GPIO2_CGSMI	0x18
+#define GEN3_GPIO2_CGTS		0x1C
+#define GEN3_GPIO2_MUX_CNTL	0x1C
+
+/* GPIO Group 3 */
+#define GEN3_GPIO3_CGEN		0x20
+#define GEN3_GPIO3_CGIO		0x24
+#define GEN3_GPIO3_CGLV		0x28
+#define GEN3_GPIO3_CGTPE	0x2C
+#define GEN3_GPIO3_CGTNE	0x30
+#define GEN3_GPIO3_CGGPE	0x34
+#define GEN3_GPIO3_CGSMI	0x38
+#define GEN3_GPIO3_CGTS		0x3C
+
+/* Controller limits */
+#define INTELCE_GPIO_IO_SIZE	256
+
+#define GEN3_TYPE_PCI		0
+#define GEN3_TYPE_IOPORT	1
+
+/* gpio adapter private structure */
+struct intelce_gpio {
+	struct gpio_chip	chip;
+	struct pci_dev		*pdev;
+	void __iomem		*base;
+	u32			ioport;
+	unsigned int		type:1;
+};
+
+/* Group 0 GPIO helpers */
+static void intelce_gpio0_set_direction(struct gpio_chip *chip,
+				unsigned offset, int direction)
+{
+	u32 mask;
+	struct intelce_gpio *gpch;
+	gpch = container_of(chip, struct intelce_gpio, chip);
+
+	mask = ioread32(gpch->base + GEN3_GPIO0_GPOER);
+	if (direction)
+		mask |= (1 << offset);
+	else
+		mask &= ~(1 << offset);
+	iowrite32(mask, gpch->base + GEN3_GPIO0_GPOER);
+}
+
+static void intelce_gpio0_set_alt_func(struct gpio_chip *chip,
+				unsigned offset, int func)
+{
+	struct intelce_gpio *gpch;
+	unsigned bit;
+	u32 mask;
+	gpch = container_of(chip, struct intelce_gpio, chip);
+
+	if (offset <= 5)
+		bit = 0;
+	else if (offset <= 7)
+		bit = 1;
+	else
+		bit = 2;
+
+	/* Set functionnality */
+	mask = ioread32(gpch->base + GEN3_GPIO0_MUX_CNTL);
+	if (func)
+		mask |= (1 << bit);
+	else
+		mask &= ~(1 << bit);
+	iowrite32(mask, gpch->base + GEN3_GPIO0_MUX_CNTL);
+}
+
+/*
+ * GPIO lib stubs
+ * Note that you should call the direction
+ * helpers first which will set the muxing
+ * correctly
+ */
+static void intelce_gpio0_set_dataout(struct gpio_chip *chip,
+				unsigned offset, int value)
+{
+	u32 mask;
+	struct intelce_gpio *gpch;
+	gpch = container_of(chip, struct intelce_gpio, chip);
+
+	mask = ioread32(gpch->base + GEN3_GPIO0_GPOUTR);
+	if (value)
+		mask |= (1 << offset);
+	else
+		mask &= ~(1 << offset);
+	iowrite32(mask, gpch->base + GEN3_GPIO0_GPOUTR);
+}
+
+static int intelce_gpio0_get_datain(struct gpio_chip *chip,
+				unsigned offset)
+{
+	struct intelce_gpio *gpch;
+	gpch = container_of(chip, struct intelce_gpio, chip);
+
+	return ioread32(gpch->base + GEN3_GPIO0_GPINR) & (1 << offset);
+}
+
+static int intelce_gpio0_set_direction_input(struct gpio_chip *chip,
+				unsigned offset)
+{
+	/* Disable GPIO muxing */
+	intelce_gpio0_set_alt_func(chip, offset, 0);
+	intelce_gpio0_set_direction(chip, offset, 0);
+	return 0;
+}
+
+static int intelce_gpio0_set_direction_output(struct gpio_chip *chip,
+				unsigned offset, int value)
+{
+	/* Disable GPIO muxing */
+	intelce_gpio0_set_alt_func(chip, offset, 0);
+	intelce_gpio0_set_direction(chip, offset, 1);
+	intelce_gpio0_set_dataout(chip, offset, value);
+	return 0;
+}
+
+/* Group 1 GPIO helpers */
+static int intelce_gpio1_get_datain(struct gpio_chip *chip,
+				unsigned offset)
+{
+	struct intelce_gpio *gpch;
+	gpch = container_of(chip, struct intelce_gpio, chip);
+
+	return inl(gpch->ioport + GEN3_GPIO1_CGLV) & (1 << offset);
+}
+
+static void intelce_gpio1_set_dataout(struct gpio_chip *chip,
+				unsigned offset, int value)
+{
+	u32 mask;
+	struct intelce_gpio *gpch;
+	gpch = container_of(chip, struct intelce_gpio, chip);
+
+	mask = inl(gpch->ioport + GEN3_GPIO1_CGLV);
+	if (value)
+		mask |= (1 << offset);
+	else
+		mask &= ~(1 << offset);
+	outl(mask, gpch->ioport + GEN3_GPIO1_CGLV);
+}
+
+static void intelce_gpio1_set_direction(struct gpio_chip *chip,
+				unsigned offset, int direction)
+{
+	u32 mask;
+	struct intelce_gpio *gpch;
+	gpch = container_of(chip, struct intelce_gpio, chip);
+
+	/* Set the correct GPIO mode (no muxing) */
+	mask = inl(gpch->ioport + GEN3_GPIO1_CGEN);
+	mask |= (1 << offset);
+	outl(mask, gpch->ioport + GEN3_GPIO1_CGEN);
+
+	/* Set direction (0 = input, 1 = output) */
+	mask = inl(gpch->ioport + GEN3_GPIO1_CGIO);
+	if (direction)
+		mask &= ~(1 << offset);
+	else
+		mask |= (1 << offset);
+	outl(mask, gpch->ioport + GEN3_GPIO1_CGIO);
+}
+
+static int intelce_gpio1_set_direction_input(struct gpio_chip *chip,
+					unsigned offset)
+{
+	intelce_gpio1_set_direction(chip, offset, 0);
+	return 0;
+}
+
+static int intelce_gpio1_set_direction_output(struct gpio_chip *chip,
+				unsigned offset, int value)
+{
+	intelce_gpio1_set_direction(chip, offset, 1);
+	intelce_gpio1_set_dataout(chip, offset, value);
+	return 0;
+}
+
+/* Group 2 GPIO helpers */
+static void intelce_gpio2_set_dataout(struct gpio_chip *chip,
+				unsigned offset, int value)
+{
+	/* Rework base to call GPIO group 1 functions */
+	offset += chip->base - GEN3_GPIO_GROUP_ONE;
+	intelce_gpio1_set_dataout(chip, offset, value);
+}
+
+static int intelce_gpio2_get_datain(struct gpio_chip *chip,
+				unsigned offset)
+{
+	/* Rework base to call GPIO group 1 functions */
+	offset += chip->base - GEN3_GPIO_GROUP_ONE;
+	return intelce_gpio1_get_datain(chip, offset);
+}
+
+/*
+ * set a gpio offset to alternate function (func = 1)
+ * or gpio mode (func = 0)
+ */
+static void intelce_gpio2_set_alt_func(struct gpio_chip *chip,
+				unsigned offset, int func)
+{
+	u32 mask, bit_num;
+	struct intelce_gpio *gpch;
+	gpch = container_of(chip, struct intelce_gpio, chip);
+
+	/* Clear or set the port GPIO mode */
+	mask = inl(gpch->ioport + GEN3_GPIO2_CGEN);
+	if (func)
+		mask &= ~(1 << offset);
+	else
+		mask |= (1 << offset);
+	outl(mask, gpch->ioport + GEN3_GPIO2_CGEN);
+
+	/* Set alternate function,
+	 * we need to recompute the base number */
+	offset += (chip->base + 3);
+	if (offset <= 4)
+		bit_num = 3;
+	else if (offset <= 7)
+		bit_num = 4;
+	else if (offset == 8)
+		bit_num = 5;
+	else
+		bit_num = 6;
+
+	mask = inl(gpch->ioport + GEN3_GPIO2_MUX_CNTL);
+	if (func)
+		mask |= (1 << bit_num);
+	else
+		mask &= ~(1 << bit_num);
+	outl(mask, gpch->ioport + GEN3_GPIO2_MUX_CNTL);
+}
+
+static void intelce_gpio2_set_direction(struct gpio_chip *chip,
+					unsigned offset, int direction)
+{
+	/* Set to no alternate function */
+	intelce_gpio2_set_alt_func(chip, offset, 0);
+	/* Use GPIO group 1 method here */
+	offset += chip->base  - GEN3_GPIO_GROUP_ONE;
+	intelce_gpio1_set_direction(chip, offset, direction);
+}
+
+static int intelce_gpio2_set_direction_input(struct gpio_chip *chip,
+					unsigned offset)
+{
+	intelce_gpio2_set_direction(chip, offset, 0);
+	return 0;
+}
+
+static int intelce_gpio2_set_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
+{
+	intelce_gpio2_set_direction(chip, offset, 1);
+	intelce_gpio2_set_dataout(chip, offset, value);
+	return 0;
+}
+
+/* Group 3 GPIO helpers */
+static void intelce_gpio3_set_dataout(struct gpio_chip *chip,
+					unsigned offset, int value)
+{
+	u32 mask;
+	struct intelce_gpio *gpch;
+	gpch = container_of(chip, struct intelce_gpio, chip);
+
+	mask = inl(gpch->ioport + GEN3_GPIO3_CGLV);
+	if (value)
+		mask |= (1 << offset);
+	else
+		mask &= ~(1 << offset);
+	outl(mask, gpch->ioport + GEN3_GPIO3_CGLV);
+}
+
+static int intelce_gpio3_get_datain(struct gpio_chip *chip,
+					unsigned offset)
+{
+	struct intelce_gpio *gpch;
+	gpch = container_of(chip, struct intelce_gpio, chip);
+
+	return inl(gpch->ioport + GEN3_GPIO3_CGLV) & (1 << offset);
+}
+
+static void intelce_gpio3_set_direction(struct gpio_chip *chip,
+					unsigned offset, int direction)
+{
+	u32 mask;
+	struct intelce_gpio *gpch;
+	gpch = container_of(chip, struct intelce_gpio, chip);
+
+	/* Set GPIO mode */
+	mask = inl(gpch->ioport + GEN3_GPIO3_CGEN);
+	mask |= (1 << offset);
+	outl(mask, gpch->ioport + GEN3_GPIO3_CGEN);
+
+	/* Set direction */
+	mask = inl(gpch->ioport + GEN3_GPIO3_CGIO);
+	if (direction)
+		mask &= ~(1 << offset);
+	else
+		mask |= (1 << offset);
+	outl(mask, gpch->ioport + GEN3_GPIO3_CGIO);
+}
+
+static int intelce_gpio3_set_direction_input(struct gpio_chip *chip,
+					unsigned offset)
+{
+	intelce_gpio3_set_direction(chip, offset, 0);
+	return 0;
+}
+
+static int intelce_gpio3_set_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
+{
+	intelce_gpio3_set_direction(chip, offset, 1);
+	intelce_gpio3_set_dataout(chip, offset, value);
+	return 0;
+}
+
+/* Array of gpio chips */
+static struct intelce_gpio intelce_gpio_chips[] = {
+	/* GPIO group 0 */
+	{
+		.chip	= {
+			.label			= "intelce-gpio0",
+			.set			= intelce_gpio0_set_dataout,
+			.get			= intelce_gpio0_get_datain,
+			.direction_input 	= intelce_gpio0_set_direction_input,
+			.direction_output 	= intelce_gpio0_set_direction_output,
+			.base			= GEN3_GPIO_GROUP_ZERO,
+			.ngpio			= GEN3_GPIO_GROUP_ONE,
+		}
+	},
+	/* GPIO group 1 */
+	{
+		.chip	= {
+			.label			= "intelce-gpio1",
+			.set			= intelce_gpio1_set_dataout,
+			.get			= intelce_gpio1_get_datain,
+			.direction_input	= intelce_gpio1_set_direction_input,
+			.direction_output	= intelce_gpio1_set_direction_output,
+			.base			= GEN3_GPIO_GROUP_ONE,
+			.ngpio			= GEN3_GPIO_GROUP_TWO - GEN3_GPIO_GROUP_ONE,
+		}
+	},
+	/* GPIO group 2 */
+	{
+		.chip	= {
+			.label			= "intelce-gpio2",
+			.set			= intelce_gpio2_set_dataout,
+			.get			= intelce_gpio2_get_datain,
+			.direction_input	= intelce_gpio2_set_direction_input,
+			.direction_output	= intelce_gpio2_set_direction_output,
+			.base			= GEN3_GPIO_GROUP_TWO,
+			.ngpio			= GEN3_GPIO_GROUP_THREE - GEN3_GPIO_GROUP_TWO,
+		}
+	},
+	/* GPIO group 3 */
+	{
+		.chip	= {
+			.label			= "intelce-gpio3",
+			.set			= intelce_gpio3_set_dataout,
+			.get			= intelce_gpio3_get_datain,
+			.direction_input	= intelce_gpio3_set_direction_input,
+			.direction_output	= intelce_gpio3_set_direction_output,
+			.base			= GEN3_GPIO_GROUP_THREE,
+			.ngpio			= GEN3_NUM_GPIO_PINS - GEN3_GPIO_GROUP_THREE,
+		}
+	},
+};
+
+/* We match on a PCI bus device even to driver GPIO at 0x1080 */
+static int __devinit intelce_gpio_probe(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	int err, io_size = INTELCE_GPIO_IO_SIZE;
+	int bar = 0, i;
+	void __iomem *ioaddr;
+
+	err = pci_enable_device(pdev);
+	if (err)
+		goto err_out;
+
+	/* this should always be supported */
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (err) {
+		printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses"
+				"not supported by the card\n");
+		goto err_out;
+	}
+
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (err) {
+		printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses"
+				"not supported by the card\n");
+		goto err_out;
+	}
+
+	/* IO Size check */
+	if (pci_resource_len(pdev, bar) < io_size) {
+		printk(KERN_ERR DRV_NAME ": Insufficient PCI resources, aborting\n");
+		err = -EIO;
+		goto err_out;
+	}
+
+	pci_set_master(pdev);
+
+	err = pci_request_regions(pdev, DRV_NAME);
+	if (err) {
+		printk(KERN_ERR DRV_NAME ": failed to request PCI region\n");
+		goto err_out;
+	}
+
+	ioaddr = pci_iomap(pdev, bar, io_size);
+	if (!ioaddr) {
+		printk(KERN_ERR DRV_NAME ": ioremap failed for device: %s\n",
+					pci_name(pdev));
+		err = -ENOMEM;
+		goto err_release_pci_region;
+	}
+
+	if (!request_region(GEN3_GPIO_IO_BASE, GEN3_GPIO_IO_SIZE, DRV_NAME)) {
+		printk(KERN_ERR DRV_NAME ": failed to request IO port region\n");
+		err = -ENOMEM;
+		goto err_release_pci_region;
+	}
+
+	pci_set_drvdata(pdev, intelce_gpio_chips);
+
+	intelce_gpio_chips[0].base = ioaddr;
+	intelce_gpio_chips[0].pdev = pdev;
+
+	/* Register our gpio chips */
+	for (i = 0; i < GEN3_GPIO_GROUPS; i++) {
+		/* Set IO base for gpio chips 1 to 3 */
+		if (i > 0) {
+			intelce_gpio_chips[i].ioport = GEN3_GPIO_IO_BASE;
+			intelce_gpio_chips[i].pdev = pdev;
+			intelce_gpio_chips[i].type = GEN3_TYPE_IOPORT;
+		}
+
+		/* Register our gpio chip */
+		err = gpiochip_add(&intelce_gpio_chips[i].chip);
+		if (err) {
+			printk(KERN_ERR DRV_NAME ": failed to register chip %d\n", i);
+			goto err_drvdata;
+		}
+		printk(KERN_INFO DRV_NAME ": registered %s at 0x%08x (%s, %d GPIOs)\n",
+		       intelce_gpio_chips[i].chip.label,
+		       intelce_gpio_chips[i].type ?
+		       intelce_gpio_chips[i].ioport :
+		       (u32)intelce_gpio_chips[i].base,
+		       intelce_gpio_chips[i].type ? "IO port" : "PCI",
+		       intelce_gpio_chips[i].chip.ngpio);
+	}
+
+	return 0;
+
+err_drvdata:
+	pci_set_drvdata(pdev, NULL);
+	pci_iounmap(pdev, ioaddr);
+	release_region(GEN3_GPIO_IO_BASE, GEN3_GPIO_IO_SIZE);
+err_release_pci_region:
+	pci_release_regions(pdev);
+err_out:
+	return err;
+}
+
+static void __exit intelce_gpio_remove(struct pci_dev *pdev)
+{
+	int i;
+
+	for (i = 0; i < GEN3_GPIO_GROUPS; i++)
+		gpiochip_remove(&intelce_gpio_chips[i].chip);
+
+	release_region(GEN3_GPIO_IO_BASE, GEN3_GPIO_IO_SIZE);
+	pci_iounmap(pdev, intelce_gpio_chips[0].base);
+	pci_set_drvdata(pdev, NULL);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+}
+
+static struct pci_device_id intelce_gpio_id_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e67) },
+	{ 0 }
+};
+
+static struct pci_driver intelce_gpio_driver = {
+	.name		= DRV_NAME,
+	.id_table	= intelce_gpio_id_tbl,
+	.probe		= intelce_gpio_probe,
+	.remove		= __devexit_p(intelce_gpio_remove),
+};
+
+static int __init intelce_gpio_init(void)
+{
+	return pci_register_driver(&intelce_gpio_driver);
+}
+
+static void __exit intelce_gpio_exit(void)
+{
+	pci_unregister_driver(&intelce_gpio_driver);
+}
+
+module_init(intelce_gpio_init);
+module_exit(intelce_gpio_exit);
+
+MODULE_AUTHOR("Florian Fainelli <ffainelli@freebox.fr>");
+MODULE_DESCRIPTION("GPIO driver for the Intel CE3100/4100 SoC");
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE("GPL");
diff -Nruw linux-3.2.24-fbx/drivers/platform/intelce./Kconfig linux-3.2.24-fbx/drivers/platform/intelce/Kconfig
--- linux-3.2.24-fbx/drivers/platform/intelce./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/platform/intelce/Kconfig	2011-11-04 14:26:08.939891247 +0100
@@ -0,0 +1,18 @@
+#
+# IntelCE devices configuration
+#
+
+menu "IntelCE devices"
+
+config INTELCE_GPIO
+	tristate "GPIO support"
+	select ARCH_REQUIRE_GPIOLIB
+	---help---
+	  IntelCE 3100/4100 GPIO support.
+
+config INTELCE_DFX
+	tristate "DFX reporting support"
+	---help---
+	  IntelCE 3100/4100 DFX fuse reporting support.
+
+endmenu
diff -Nruw linux-3.2.24-fbx/drivers/platform/intelce./Makefile linux-3.2.24-fbx/drivers/platform/intelce/Makefile
--- linux-3.2.24-fbx/drivers/platform/intelce./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/platform/intelce/Makefile	2011-11-04 14:26:08.939891247 +0100
@@ -0,0 +1,2 @@
+obj-$(CONFIG_INTELCE_GPIO)	+= gpio-intelce.o
+obj-$(CONFIG_INTELCE_DFX)	+= dfx.o
diff -Nruw linux-3.2.24-fbx/drivers/platform/tango2./Kconfig linux-3.2.24-fbx/drivers/platform/tango2/Kconfig
--- linux-3.2.24-fbx/drivers/platform/tango2./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/platform/tango2/Kconfig	2011-01-06 02:17:53.032183471 +0100
@@ -0,0 +1,30 @@
+#
+# TANGO2 devices configuration
+#
+
+menu "Tango2 devices"
+	depends on TANGO2
+
+config TANGO2_FIP
+	tristate "Front panel support"
+	select INPUT
+	---help---
+	  Tango2 FIP front panel support.
+
+config TANGO2_GPIO
+	tristate "GPIO sysfs support"
+	---help---
+	  Export GPIO attributes in sysfs.
+
+config TANGO2_IR
+	tristate "IR support"
+	---help---
+	  Tango2 IR (NEC/RC5/RC6) support.
+
+config TANGO2_FB
+	tristate "Framebuffer support"
+	depends on FB
+	---help---
+	  Tango2 framebuffer support.
+
+endmenu
diff -Nruw linux-3.2.24-fbx/drivers/platform/tango2./Makefile linux-3.2.24-fbx/drivers/platform/tango2/Makefile
--- linux-3.2.24-fbx/drivers/platform/tango2./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/drivers/platform/tango2/Makefile	2011-01-06 02:17:53.032183471 +0100
@@ -0,0 +1,6 @@
+# Makefile for the TANGO2 device drivers
+
+obj-$(CONFIG_TANGO2_FIP) += fip.o
+obj-$(CONFIG_TANGO2_GPIO) += gpio.o
+obj-$(CONFIG_TANGO2_IR) += ir.o
+obj-$(CONFIG_TANGO2_FB) += fb.o
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/fs/ramfs/xattr.c	2012-11-30 16:07:20.038641711 +0100
@@ -0,0 +1,199 @@
+/*
+ * xattr.c for ramfs
+ * Created by <nschichan@freebox.fr> on Wed Aug  8 11:57:18 2007
+ * Freebox SA
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/xattr.h>
+
+#include "internal.h"
+
+void ramfs_inode_purge_xattrs(struct ramfs_inode_info *rii)
+{
+	(void)rii;
+#ifdef CONFIG_RAMFS_XATTR_USER
+	while (!list_empty(&rii->xattr_user_list)) {
+		struct list_head *head;
+		struct ramfs_xattr *elem;
+
+
+		head = rii->xattr_user_list.next;
+		elem = list_entry(head, struct ramfs_xattr, list);
+		list_del(head);
+		kfree(elem->data);
+		kfree(elem->name);
+		kfree(elem);
+	}
+#endif
+
+}
+
+#ifdef CONFIG_RAMFS_XATTR_USER
+static size_t ramfs_xattr_user_list(struct dentry *dentry, char *list,
+				    size_t list_size,
+				    const char *name, size_t namelen,
+				    int handler_flags)
+{
+	struct ramfs_inode_info *rii;
+	struct list_head *it;
+	struct inode *inode = dentry->d_inode;
+	int ret;
+	char *ptr;
+	char *end;
+
+	ret = 0;
+	ptr = list;
+	end = list + list_size;
+	rii = RAMFS_I(inode);
+
+	list_for_each(it, &rii->xattr_user_list) {
+		struct ramfs_xattr *elem;
+		int name_len;
+
+		elem = list_entry(it, struct ramfs_xattr, list);
+		name_len = strlen(elem->name);
+
+		if (ptr + name_len + 1 + XATTR_USER_PREFIX_LEN >= end)
+			break;
+
+		/* copy prefix in buffer */
+		memcpy(ptr, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
+		ptr += XATTR_USER_PREFIX_LEN;
+		ret += XATTR_USER_PREFIX_LEN;
+
+		/* copy attribute name in buffer */
+		memcpy(ptr, elem->name, name_len + 1);
+		ptr += name_len + 1;
+		ret += name_len + 1;
+	}
+
+	return ret;
+}
+
+static struct ramfs_xattr *ramfs_xattr_find(struct ramfs_inode_info *rii,
+					    const char *name)
+{
+	struct list_head *it;
+
+	list_for_each(it, &rii->xattr_user_list) {
+		struct ramfs_xattr *elem;
+
+		elem = list_entry(it, struct ramfs_xattr, list);
+		if (!strcmp(elem->name, name))
+			return elem;
+	}
+	return NULL;
+}
+
+static int ramfs_xattr_user_remove(struct inode *inode, const char *name)
+{
+	struct ramfs_inode_info *rii;
+	struct ramfs_xattr *elem;
+
+	rii = RAMFS_I(inode);
+	elem = ramfs_xattr_find(rii, name);
+	if (!elem)
+		return -ENODATA;
+
+	list_del(&elem->list);
+	kfree(elem->data);
+	kfree(elem->name);
+	kfree(elem);
+
+	return 0;
+}
+
+static int ramfs_xattr_user_set(struct dentry *dentry, const char *name,
+				const void *buffer, size_t size, int flags,
+				int handler_flags)
+{
+	int error;
+	struct ramfs_xattr *elem;
+	struct ramfs_inode_info *rii;
+	struct inode *inode = dentry->d_inode;
+	int new_elem;
+
+	if (buffer == NULL && size == 0)
+		return ramfs_xattr_user_remove(inode, name);
+
+	rii = RAMFS_I(inode);
+	elem = ramfs_xattr_find(rii, name);
+	if (elem) {
+		new_elem = 0;
+		if (flags & XATTR_CREATE)
+			return -EEXIST;
+		kfree(elem->data);
+		elem->data = NULL;
+	} else {
+		new_elem = 1;
+		if (flags & XATTR_REPLACE)
+			return -ENODATA;
+		elem = kzalloc(sizeof (*elem), GFP_KERNEL);
+		if (!elem)
+			return -ENOMEM;
+		elem->name = kstrdup(name, GFP_KERNEL);
+		if (!elem->name) {
+			kfree(elem);
+			return -ENOMEM;
+		}
+	}
+
+	elem->data = kmalloc(size, GFP_KERNEL);
+	if (!elem->data) {
+		error = -ENOMEM;
+		goto out_free_new_elem;
+	}
+	memcpy(elem->data, buffer, size);
+	elem->data_len = size;
+
+	if (new_elem)
+		list_add(&elem->list, &rii->xattr_user_list);
+
+	return 0;
+
+ out_free_new_elem:
+	if (elem && new_elem) {
+		if (elem->name)
+			kfree(elem->name);
+		kfree(elem);
+	}
+	return error;
+}
+
+static int ramfs_xattr_user_get(struct dentry *dentry, const char *name,
+				void *buffer, size_t size, int handler_flags)
+{
+	struct ramfs_xattr *elem;
+	struct ramfs_inode_info *rii;
+	struct inode *inode = dentry->d_inode;
+	int copylen;
+
+	rii = RAMFS_I(inode);
+	elem = ramfs_xattr_find(rii, name);
+	if (elem == NULL)
+		return -ENODATA;
+	copylen = elem->data_len;
+
+	if (size < copylen)
+		copylen = size;
+	memcpy(buffer, elem->data, copylen);
+	return copylen;
+}
+
+static struct xattr_handler ramfs_user_handler = {
+	.prefix = XATTR_USER_PREFIX,
+	.list	= ramfs_xattr_user_list,
+	.get	= ramfs_xattr_user_get,
+	.set	= ramfs_xattr_user_set,
+};
+#endif
+
+const struct xattr_handler *ramfs_xattr_handlers[] = {
+#ifdef CONFIG_RAMFS_XATTR_USER
+	&ramfs_user_handler,
+#endif
+	NULL,
+};
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/include/linux/crash_zone.h	2013-06-13 15:06:42.798517114 +0200
@@ -0,0 +1,18 @@
+#ifndef CRASH_ZONE_H
+#define CRASH_ZONE_H
+
+#define CRASH_MAGIC	0xa7cecd6a
+
+struct crash_header
+{
+	unsigned int magic;
+	unsigned int len;
+	unsigned short checksum;
+	unsigned char data;
+};
+
+void __init crash_zone_set_param(unsigned char *zone, unsigned int size);
+
+int __init crash_zone_of_init(void);
+
+#endif /* ! CRASH_ZONE_H */
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/include/linux/fbxatm.h	2013-06-13 15:06:42.802517113 +0200
@@ -0,0 +1,155 @@
+/*
+ * Generic fbxatm definition, exported to userspace
+ */
+#ifndef LINUX_FBXATM_H_
+#define LINUX_FBXATM_H_
+
+#include <linux/types.h>
+#include <linux/if.h>
+
+#define FBXATM_IOCTL_MAGIC		0xd3
+
+/* allow userspace usage without up to date kernel headers */
+#ifndef PF_FBXATM
+#define PF_FBXATM			32
+#define AF_FBXATM			PF_FBXATM
+#endif
+
+struct fbxatm_vcc_id {
+	int				dev_idx;
+	__u32				vpi;
+	__u32				vci;
+};
+
+enum fbxatm_vcc_user {
+	FBXATM_VCC_USER_NONE = 0,
+	FBXATM_VCC_USER_2684,
+	FBXATM_VCC_USER_PPPOA,
+};
+
+enum fbxatm_vcc_traffic_class {
+	FBXATM_VCC_TC_UBR_NO_PCR = 0,
+	FBXATM_VCC_TC_UBR,
+};
+
+struct fbxatm_vcc_qos {
+	__u32				traffic_class;
+	__u32				max_sdu;
+	__u32				max_buffered_pkt;
+	__u32				priority;
+	__u32				rx_priority;
+};
+
+
+/*
+ * VCC related
+ */
+struct fbxatm_vcc_params {
+	/* ADD/DEL/GET */
+	struct fbxatm_vcc_id		id;
+
+	/* ADD/GET */
+	struct fbxatm_vcc_qos		qos;
+
+	/* GET */
+	enum fbxatm_vcc_user		user;
+};
+
+#define FBXATM_IOCADD		_IOW(FBXATM_IOCTL_MAGIC,	1,	\
+					struct fbxatm_vcc_params)
+
+#define FBXATM_IOCDEL		_IOR(FBXATM_IOCTL_MAGIC,	2,	\
+					struct fbxatm_vcc_params)
+
+#define FBXATM_IOCGET		_IOWR(FBXATM_IOCTL_MAGIC,	3,	\
+					struct fbxatm_vcc_params)
+
+
+struct fbxatm_vcc_drop_params {
+	struct fbxatm_vcc_id		id;
+	unsigned int			drop_count;
+};
+
+#define FBXATM_IOCDROP		_IOWR(FBXATM_IOCTL_MAGIC,	5,	\
+					struct fbxatm_vcc_drop_params)
+
+/*
+ * OAM related
+ */
+enum fbxatm_oam_ping_type {
+	FBXATM_OAM_PING_SEG_F4	= 0,
+	FBXATM_OAM_PING_SEG_F5,
+	FBXATM_OAM_PING_E2E_F4,
+	FBXATM_OAM_PING_E2E_F5,
+};
+
+struct fbxatm_oam_ping_req {
+	/* only dev_idx for F4 */
+	struct fbxatm_vcc_id		id;
+
+	__u8				llid[16];
+	enum fbxatm_oam_ping_type	type;
+};
+
+#define FBXATM_IOCOAMPING	_IOWR(FBXATM_IOCTL_MAGIC,	10,	\
+				      struct fbxatm_oam_ping_req)
+
+
+/*
+ * PPPOA related
+ */
+enum fbxatm_pppoa_encap {
+	FBXATM_EPPPOA_AUTODETECT = 0,
+	FBXATM_EPPPOA_VCMUX,
+	FBXATM_EPPPOA_LLC,
+};
+
+struct fbxatm_pppoa_vcc_params {
+	struct fbxatm_vcc_id		id;
+	__u32				encap;
+	__u32				cur_encap;
+};
+
+#define FBXATM_PPPOA_IOCADD	_IOW(FBXATM_IOCTL_MAGIC,	20,	\
+					struct fbxatm_pppoa_vcc_params)
+
+#define FBXATM_PPPOA_IOCDEL	_IOW(FBXATM_IOCTL_MAGIC,	21,	\
+					struct fbxatm_pppoa_vcc_params)
+
+#define FBXATM_PPPOA_IOCGET	_IOWR(FBXATM_IOCTL_MAGIC,	22,	\
+					struct fbxatm_pppoa_vcc_params)
+
+
+
+/*
+ * 2684 related
+ */
+enum fbxatm_2684_encap {
+	FBXATM_E2684_VCMUX = 0,
+	FBXATM_E2684_LLC,
+};
+
+enum fbxatm_2684_payload {
+	FBXATM_P2684_BRIDGE = 0,
+	FBXATM_P2684_ROUTED,
+};
+
+struct fbxatm_2684_vcc_params {
+	struct fbxatm_vcc_id		id;
+
+	__u32				encap;
+	__u32				payload;
+	char				dev_name[IFNAMSIZ];
+};
+
+
+#define FBXATM_2684_IOCADD	_IOW(FBXATM_IOCTL_MAGIC,	30,	\
+					struct fbxatm_2684_vcc_params)
+
+#define FBXATM_2684_IOCDEL	_IOW(FBXATM_IOCTL_MAGIC,	31,	\
+					struct fbxatm_2684_vcc_params)
+
+#define FBXATM_2684_IOCGET	_IOWR(FBXATM_IOCTL_MAGIC,	32,	\
+					struct fbxatm_2684_vcc_params)
+
+#endif /* LINUX_FBXATM_H_ */
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/include/linux/fbxbootinfo.h	2011-01-06 02:17:56.292062462 +0100
@@ -0,0 +1,11 @@
+#ifndef FBXBOOTINFO_H
+#define FBXBOOTINFO_H
+
+struct fbx_bootinfo {
+	u32 bank_number;
+	char uboot_version_str[128];
+	u32 bank0_forced;
+	char cefdk_version_str[256];
+} __attribute__ ((packed));
+
+#endif /* FBXBOOTINFO_H */
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/include/linux/fbxbridge.h	2013-06-13 15:06:42.802517113 +0200
@@ -0,0 +1,205 @@
+#ifndef _FBXBRIDGE_H
+# define _FBXBRIDGE_H
+
+#include <linux/if.h>
+#include <linux/if_ether.h>
+
+#define MAX_LAN_DEVICES		4
+#define MAX_ALIASES		2
+#define MAX_SMTP_ALLOWED	3
+
+#define FBXBRIDGE_PFX		"fbxbridge: "
+
+#define FBXBRIDGE_LAN_TO_WAN	1
+#define FBXBRIDGE_WAN_TO_LAN	2
+
+#define FBXBRIDGE_FLAGS_FILTER			(1 << 0)
+#define FBXBRIDGE_FLAGS_DHCP_PROXY		(1 << 1)
+#define FBXBRIDGE_FLAGS_DHCPD			(1 << 2)
+#define FBXBRIDGE_FLAGS_QOS			(1 << 3)
+#define FBXBRIDGE_FLAGS_FORBID_INTERACTIVE	(1 << 4)
+#define FBXBRIDGE_FLAGS_BLOCK_SMTP		(1 << 5)
+#define FBXBRIDGE_FLAGS_NETFILTER		(1 << 6)
+
+/*
+ * ioctl command
+ */
+
+enum fbxbridge_ioctl_cmd
+{
+	E_CMD_BR_CHG = 0,
+	E_CMD_BR_DEV_CHG,
+	E_CMD_BR_PARAMS,
+};
+
+struct fbxbridge_ioctl_chg
+{
+	char	brname[IFNAMSIZ];
+	int	action;
+};
+
+struct fbxbridge_ioctl_dev_chg
+{
+	char	brname[IFNAMSIZ];
+	char	devname[IFNAMSIZ];
+	int	wan;
+	int	action;
+};
+
+struct fbxbridge_dev_info
+{
+	char	name[IFNAMSIZ];
+	int	active;
+	int	present;
+};
+
+struct fbxbridge_ioctl_params
+{
+	int				action;
+	char				brname[IFNAMSIZ];
+	struct fbxbridge_dev_info	devs[MAX_LAN_DEVICES + 1];
+	unsigned int			flags;
+	unsigned int			tcp_mss_value;
+	unsigned int			fwmark;
+	unsigned int			stopmark;
+	unsigned char			lan_hwaddr[ETH_ALEN];
+	unsigned char			have_hw_addr;
+	unsigned int			dns1_addr;
+	unsigned int			dns2_addr;
+	unsigned long			ip_aliases[MAX_ALIASES];
+	unsigned long			smtp_allowed[MAX_SMTP_ALLOWED];
+	unsigned long			smtp_mask_allowed[MAX_SMTP_ALLOWED];
+
+	unsigned long			dhcpd_renew_time;
+	unsigned long			dhcpd_rebind_time;
+	unsigned long			dhcpd_lease_time;
+	unsigned int			inputmark;
+};
+
+struct fbxbridge_ioctl_req
+{
+	enum fbxbridge_ioctl_cmd	cmd;
+	unsigned long			arg;
+};
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+
+#define ARP_RATE_LIMIT		(HZ)
+#define ARP_ETHER_SIZE		(8 + ETH_ALEN * 2 + 4 * 2)
+
+struct	fbxbridge;
+
+struct	fbxbridge
+{
+	struct fbxbridge	*next;
+	unsigned int		refcount;
+
+	char			name[IFNAMSIZ];
+	struct net_device	*dev;
+
+	/* local and remote (fbx) ip address */
+	unsigned long		br_ipaddr;
+	unsigned long		br_remote_ipaddr;
+
+	/* list of ip we consider to be local */
+	unsigned long		ip_aliases[MAX_ALIASES];
+
+	/* list of server for which we forward tcp port 25 */
+	unsigned long		smtp_allowed[MAX_SMTP_ALLOWED];
+	unsigned long		smtp_mask_allowed[MAX_SMTP_ALLOWED];
+
+	/* wan side inet info */
+	unsigned long		wan_ipaddr;
+	unsigned long		wan_netmask;
+	/* this is the _client_ gw */
+	unsigned long		wan_gw;
+
+	char			devs_names[MAX_LAN_DEVICES + 1][IFNAMSIZ];
+	struct net_device	*devs[MAX_LAN_DEVICES + 1];
+	int			devs_mask;
+	struct net_device	*active_lan_dev;
+
+	unsigned char		lan_hwaddr[ETH_ALEN];
+	unsigned char		have_hw_addr;
+
+	unsigned int		flags;
+	unsigned int		tcp_mss_value;
+	unsigned int		fwmark;
+	unsigned int		stopmark;
+	unsigned int		inputmark;
+
+	unsigned int		dns1_ipaddr;
+	unsigned int		dns2_ipaddr;
+
+	unsigned char		dhcp_hwaddr[ETH_ALEN];
+	unsigned int		dhcp_use_bcast;
+	unsigned long		last_arp_send;
+
+	unsigned long		dhcpd_renew_time;
+	unsigned long		dhcpd_rebind_time;
+	unsigned long		dhcpd_lease_time;
+};
+
+/* fbxbridge_dev.c */
+void keep_hw_addr(struct fbxbridge *br, unsigned char *hwaddr);
+
+/* fbxbridge_dhcp.c */
+int fbxbridge_dhcp_proxy(struct fbxbridge *br, struct sk_buff *skb,
+			 unsigned direction);
+
+int fbxbridge_dhcpd(struct fbxbridge *br, struct sk_buff *skb);
+
+
+/* fbxbridge_forward.c */
+struct sk_buff *fbxbridge_handle_frame(struct fbxbridge *br,
+				       struct sk_buff *skb);
+
+
+/* fbxbridge_filter.c */
+int fbxbridge_check_ip_packet(struct fbxbridge *br, struct sk_buff *skb,
+			      unsigned direction);
+
+int fbxbridge_nf_hook(struct fbxbridge *br, uint8_t pf, unsigned int hook,
+		      struct sk_buff *skb, struct net_device *in,
+		      struct net_device *out);
+
+/* fbxbridge_local.c */
+void
+handle_local_input_wan_frame(struct fbxbridge *br, struct sk_buff *skb);
+
+void
+handle_local_input_lan_frame(struct fbxbridge *br, struct sk_buff *skb);
+
+void
+handle_local_output_frame(struct fbxbridge *br, struct sk_buff *skb);
+
+
+/* fbxbridge_output.c */
+void output_arp_frame(struct fbxbridge *br, struct net_device *dev,
+		      unsigned short type,
+		      unsigned long src_ip, unsigned char *src_hw,
+		      unsigned long target_ip, unsigned char *target_hw);
+
+void output_lan_frame(struct fbxbridge *br, struct sk_buff *skb);
+
+void output_lan_mcast_frame(struct fbxbridge *br, struct sk_buff *skb);
+
+void output_wan_frame(struct fbxbridge *br, struct sk_buff *skb);
+
+
+/* fbxbridge_utils.c */
+void fbxbridge_snat_packet(struct sk_buff *skb, unsigned long new_addr);
+
+void fbxbridge_dnat_packet(struct sk_buff *skb, unsigned long new_addr);
+
+void
+fbxbridge_tcp_mss_adjust(struct sk_buff **skb, unsigned int mss_value);
+
+#endif /* ! __KERNEL__ */
+
+#endif
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/include/linux/fbxjtag.h	2012-07-27 19:04:58.023001668 +0200
@@ -0,0 +1,88 @@
+#ifndef FBXJTAG_H_
+# define FBXJTAG_H_
+
+#ifdef __KERNEL__
+# include <linux/types.h>
+#endif
+
+# define JTAG_RESET_STEPS	16
+# define JTAG_DATA_READ_SIZE	128
+# define JTAG_INST_READ_SIZE	128
+# define JTAG_DEF_CLOCK_DELAY	500
+# define JTAG_DEF_WAIT_TMS	0
+
+enum jtag_main_state {
+	JTAG_STATE_TEST_MASK	=	0x10,
+	JTAG_STATE_RUN_MASK	=	0x20,
+	JTAG_STATE_DR_MASK	=	0x40,
+	JTAG_STATE_IR_MASK	=	0x80,
+};
+#define JTAG_STATE_MASK			0xF0
+
+enum jtag_sub_state {
+	JTAG_SUB_STATE_SELECT	=	0x0,
+	JTAG_SUB_STATE_CAPTURE	=	0x1,
+	JTAG_SUB_STATE_SHIFT	=	0x2,
+	JTAG_SUB_STATE_EXIT1	=	0x3,
+	JTAG_SUB_STATE_PAUSE	=	0x4,
+	JTAG_SUB_STATE_EXIT2	=	0x5,
+	JTAG_SUB_STATE_UPDATE	=	0x6,
+};
+#define JTAG_SUB_STATE_MASK		0xF
+
+enum jtag_state {
+	JTAG_STATE_UNDEF	= 0,
+	JTAG_STATE_TEST_LOGIC_RESET	= JTAG_STATE_TEST_MASK,
+	JTAG_STATE_RUN_TEST_IDLE	= JTAG_STATE_RUN_MASK,
+
+	JTAG_STATE_SELECT_DR	= JTAG_STATE_DR_MASK | JTAG_SUB_STATE_SELECT,
+	JTAG_STATE_CAPTURE_DR	= JTAG_STATE_DR_MASK | JTAG_SUB_STATE_CAPTURE,
+	JTAG_STATE_SHIFT_DR	= JTAG_STATE_DR_MASK | JTAG_SUB_STATE_SHIFT,
+	JTAG_STATE_EXIT1_DR	= JTAG_STATE_DR_MASK | JTAG_SUB_STATE_EXIT1,
+	JTAG_STATE_PAUSE_DR	= JTAG_STATE_DR_MASK | JTAG_SUB_STATE_PAUSE,
+	JTAG_STATE_EXIT2_DR	= JTAG_STATE_DR_MASK | JTAG_SUB_STATE_EXIT2,
+	JTAG_STATE_UPDATE_DR	= JTAG_STATE_DR_MASK | JTAG_SUB_STATE_UPDATE,
+
+	JTAG_STATE_SELECT_IR	= JTAG_STATE_IR_MASK | JTAG_SUB_STATE_SELECT,
+	JTAG_STATE_CAPTURE_IR	= JTAG_STATE_IR_MASK | JTAG_SUB_STATE_CAPTURE,
+	JTAG_STATE_SHIFT_IR	= JTAG_STATE_IR_MASK | JTAG_SUB_STATE_SHIFT,
+	JTAG_STATE_EXIT1_IR	= JTAG_STATE_IR_MASK | JTAG_SUB_STATE_EXIT1,
+	JTAG_STATE_PAUSE_IR	= JTAG_STATE_IR_MASK | JTAG_SUB_STATE_PAUSE,
+	JTAG_STATE_EXIT2_IR	= JTAG_STATE_IR_MASK | JTAG_SUB_STATE_EXIT2,
+	JTAG_STATE_UPDATE_IR	= JTAG_STATE_IR_MASK | JTAG_SUB_STATE_UPDATE,
+
+	JTAG_STATE_MAX
+};
+
+#define JTAG_STATE_IN_DR(state)	((state) & JTAG_STATE_DR_MASK)
+#define JTAG_STATE_IN_IR(state)	((state) & JTAG_STATE_IR_MASK)
+
+#ifdef __KERNEL__
+
+#define JTAG_BUF_SIZE	2048
+
+struct fbxjtag_data {
+	const char	*name;
+	struct {
+		struct fbxgpio_pin	*tck;
+		struct fbxgpio_pin	*tms;
+		struct fbxgpio_pin	*tdi;
+		struct fbxgpio_pin	*tdo;
+	}		gpios;
+	unsigned long	clock_delay;
+	unsigned long	wait_tms;
+	unsigned long	data_read_size;
+	unsigned long	instruction_read_size;
+	struct device	*dev;
+	enum jtag_state state;
+	char		nb_reset;
+	char		dr_buf[JTAG_BUF_SIZE];
+	unsigned 	dr_w;
+	unsigned 	dr_r;
+	char		ir_buf[JTAG_BUF_SIZE];
+	unsigned 	ir_r;
+	unsigned 	ir_w;
+};
+#endif
+
+#endif /* !FBXJTAG_H_ */
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/include/linux/fbxmtd_map_ioctl.h	2012-11-30 16:14:28.306661642 +0100
@@ -0,0 +1,52 @@
+/*
+ * fbxmtd_map_ioctl.h for linux-freebox
+ * Created by <nschichan@freebox.fr> on Thu Feb  8 20:37:28 2007
+ * Freebox SA
+ */
+
+#ifndef FBXMTD_MAP_IOCTL_H
+# define FBXMTD_MAP_IOCTL_H
+
+/*
+ * IOCTL interface
+ */
+#define FBXMTD_MINOR	242
+
+#define FBXMTD_MAP_IOCTL_MAX_DEV	2
+#define FBXMTD_MAP_IOCTL_MAX_PART	16
+
+struct fbxmtd_map_ioctl_part
+{
+	char		name[32];
+	uint32_t	offset;
+	uint32_t	size;
+	uint32_t	flags;
+};
+
+struct fbxmtd_map_ioctl_dev
+{
+	char				name[32];
+	uint32_t			base_phys;
+	int				bus_width;
+	uint32_t			size;
+	uint32_t			status;
+	struct fbxmtd_map_ioctl_part	parts[FBXMTD_MAP_IOCTL_MAX_PART];
+	int				num_parts;
+};
+
+#define FBXMTD_MAP_IOCTL_NR	0x42
+
+struct fbxmtd_map_ioctl_query
+{
+	uint32_t	cmd;
+	uint32_t	param;
+	int		result;
+	void __user	*user_buf;
+	uint32_t	user_buf_size;
+};
+
+#define FBXMTDCTL_CMD_GET_DEVICES	0x1
+#define FBXMTDCTL_CMD_ADD_DEVICE	0x2
+#define FBXMTDCTL_CMD_DEL_DEVICE	0x3
+
+#endif /* !FBXMTD_MAP_IOCTL_H */
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/include/linux/fbxprocfs.h	2011-01-06 02:17:56.292062462 +0100
@@ -0,0 +1,45 @@
+#ifndef FBXPROCFS_H_
+#define FBXPROCFS_H_
+
+#include <linux/proc_fs.h>
+#include <asm/atomic.h>
+
+struct fbxprocfs_client
+{
+	const char *dirname;
+	struct module *owner;
+	struct proc_dir_entry *dir;
+	atomic_t refcount;
+	struct list_head list;
+};
+
+struct fbxprocfs_ro_desc {
+	char		*name;
+	unsigned long	id;
+	int	(*rfunc)(char *, char **, off_t, int, int *, void *);
+};
+
+struct fbxprocfs_rw_desc {
+	char		*name;
+	unsigned long	id;
+	int	(*rfunc)(char *, char **, off_t, int, int *, void *);
+	int	(*wfunc)(struct file *, const char *, unsigned long, void *);
+};
+
+struct fbxprocfs_client *fbxprocfs_add_client(const char *dirname,
+					      struct module *owner);
+
+int fbxprocfs_remove_client(struct fbxprocfs_client *client);
+
+
+int
+fbxprocfs_create_entries(struct fbxprocfs_client *client,
+			 const struct fbxprocfs_ro_desc *ro_desc,
+			 const struct fbxprocfs_rw_desc *rw_desc);
+
+int
+fbxprocfs_remove_entries(struct fbxprocfs_client *client,
+			 const struct fbxprocfs_ro_desc *ro_desc,
+			 const struct fbxprocfs_rw_desc *rw_desc);
+
+#endif /* FBXPROCFS_H_ */
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/include/linux/fbxserial.h	2012-11-30 16:07:20.354641726 +0100
@@ -0,0 +1,122 @@
+#ifndef FBXSERIAL_H_
+#define FBXSERIAL_H_
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+/*
+ * some part of serial may vary, we use abstract struct to store this,
+ * data content depends on type.
+ */
+#define EXTINFO_SIZE		128
+#define EXTINFO_MAX_COUNT	16
+
+/*
+ * extdev desc
+ */
+#define EXTINFO_TYPE_EXTDEV	1
+
+#define EXTDEV_TYPE_BUNDLE	1
+#define EXTDEV_TYPE_MAX		2
+
+struct fbx_serial_extinfo {
+	u32			type;
+
+	union {
+		/* extdev */
+		struct {
+			u32	type;
+			u32	model;
+			char	serial[64];
+		} extdev;
+
+		/* raw access */
+		unsigned char	data[EXTINFO_SIZE];
+	} u;
+}  __attribute__ ((packed));;
+
+
+/*
+ * master serial structure
+ */
+
+#define FBXSERIAL_VERSION	1
+
+#define FBXSERIAL_MAGIC		0x2d9521ab
+
+#define MAC_ADDR_SIZE		6
+#define RANDOM_DATA_SIZE	32
+
+/*
+ * this  is the  maximum size  we accept  to check  crc32  against, so
+ * structure may no grow larger than this
+ */
+#define FBXSERIAL_MAX_SIZE	8192
+
+struct fbx_serial {
+	u32	crc32;
+	u32	magic;
+	u32	struct_version;
+	u32	len;
+
+	/* board serial */
+	u16	type;
+	u8	version;
+	u8	manufacturer;
+	u16	year;
+	u8	week;
+	u32	number;
+	u32	flags;
+
+	/* mac address base */
+	u8	mac_addr_base[MAC_ADDR_SIZE];
+
+	/* mac address count */
+	u8	mac_count;
+
+	/* random data */
+	u8	random_data[RANDOM_DATA_SIZE];
+
+	/* last update of data (seconds since epoch) */
+	u32	last_modified;
+
+	/* count of following extinfo tag */
+	u32	extinfo_count;
+
+	/* beginning of extended info */
+	struct fbx_serial_extinfo	extinfos[EXTINFO_MAX_COUNT];
+
+} __attribute__ ((packed));
+
+
+/*
+ * default value to use in case magic is wrong (no cksum in that case)
+ */
+static inline void fbxserial_set_default(struct fbx_serial *s)
+{
+	memset(s, 0, sizeof (*s));
+	s->magic = FBXSERIAL_MAGIC;
+	s->struct_version = FBXSERIAL_VERSION;
+	s->len = sizeof (*s);
+	s->manufacturer = '_';
+	memcpy(s->mac_addr_base, "\x00\x07\xCB\x00\x00\xFD", 6);
+	s->mac_count = 1;
+}
+
+void
+fbxserialinfo_get_random(unsigned char *data, unsigned int len);
+
+void
+fbxserialinfo_get_mac_addr(unsigned char *data);
+
+int
+fbxserialinfo_read(void *data, struct fbx_serial *out);
+
+struct fbx_serial *fbxserialinfo_get(void);
+
+/*
+ * implemented in board specific code
+ */
+const struct fbx_serial *arch_get_fbxserial(void);
+
+#endif /* FBXSERIAL_H_ */
diff -Nruw linux-3.2.24-fbx/include/linux/hdmi-cec./dev.h linux-3.2.24-fbx/include/linux/hdmi-cec/dev.h
--- linux-3.2.24-fbx/include/linux/hdmi-cec./dev.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/include/linux/hdmi-cec/dev.h	2013-06-13 15:52:31.097197950 +0200
@@ -0,0 +1,30 @@
+#ifndef __HDMI_CEC_DEV_H
+#define __HDMI_CEC_DEV_H
+
+#include <linux/ioctl.h>
+#include <linux/hdmi-cec/hdmi-cec.h>
+
+#define CEC_IOCTL_BASE	'C'
+
+#define CEC_SET_LOGICAL_ADDRESS	_IOW(CEC_IOCTL_BASE, 0, int)
+#define CEC_RESET_DEVICE	_IOW(CEC_IOCTL_BASE, 3, int)
+#define CEC_GET_COUNTERS	_IOR(CEC_IOCTL_BASE, 4, struct cec_counters)
+#define CEC_SET_RX_MODE		_IOW(CEC_IOCTL_BASE, 5, enum cec_rx_mode)
+#define CEC_GET_TX_STATUS	_IOW(CEC_IOCTL_BASE, 6, struct cec_tx_status)
+#define CEC_SET_DETACHED_CONFIG	_IOW(CEC_IOCTL_BASE, 7, struct cec_detached_config)
+
+#define CEC_MAX_DEVS	(10)
+
+#ifdef __KERNEL__
+
+struct cec_adapter;
+
+int __init cec_cdev_init(void);
+void __exit cec_cdev_exit(void);
+
+int cec_create_adapter_node(struct cec_adapter *);
+void cec_remove_adapter_node(struct cec_adapter *);
+
+#endif /* __KERNEL__ */
+
+#endif /* __HDMI_CEC_DEV_H */
diff -Nruw linux-3.2.24-fbx/include/linux/hdmi-cec./hdmi-cec.h linux-3.2.24-fbx/include/linux/hdmi-cec/hdmi-cec.h
--- linux-3.2.24-fbx/include/linux/hdmi-cec./hdmi-cec.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/include/linux/hdmi-cec/hdmi-cec.h	2013-06-13 15:52:31.097197950 +0200
@@ -0,0 +1,274 @@
+/*
+ * Header for the HDMI CEC core infrastructure
+ */
+#ifndef __HDMI_CEC_H
+#define __HDMI_CEC_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+/* Common defines for HDMI CEC */
+#define CEC_BCAST_ADDR		(0x0f)
+#define CEC_ADDR_MAX		CEC_BCAST_ADDR
+
+#define CEC_MAX_MSG_LEN		(16)	/* 16 blocks */
+
+enum cec_rx_msg_flags {
+	/*
+	 * an ACK was received for this message
+	 */
+	CEC_RX_F_ACKED			= (1 << 0),
+
+	/*
+	 * message was fully received
+	 */
+	CEC_RX_F_COMPLETE		= (1 << 1),
+};
+
+/**
+ * struct cec_rx_msg - user-space exposed cec message cookie
+ * @data:	cec message payload
+ * @len:	cec message length
+ * @valid:	0 for invalid message
+ * @flags:	flag field (cec_rx_msg_flags)
+ */
+struct cec_rx_msg {
+	__u8	data[CEC_MAX_MSG_LEN];
+	__u8	len;
+	__u8	valid;
+	__u8	flags;
+
+} __attribute__((packed));
+
+enum cec_tx_status_flags {
+	/*
+	 * message was nacked at some point
+	 */
+	CEC_TX_F_NACK			= (1 << 0),
+
+	/*
+	 * abort sending because total time to send was elapsed
+	 */
+	CEC_TX_F_TIMEOUT		= (1 << 1),
+
+	/*
+	 * abort sending because maximum number of retry has passed
+	 */
+	CEC_TX_F_MAX_RETRIES		= (1 << 2),
+
+	/*
+	 * abort sending because of arbitration loss
+	 */
+	CEC_TX_F_ARBITRATION_LOST	= (1 << 3),
+
+	/*
+	 * message failed for other reason
+	 */
+	CEC_TX_F_UNKNOWN_ERROR		= (1 << 7),
+};
+
+/**
+ * struct cec_tx_msg - user-space exposed cec message cookie
+ * @expire_ms:	how long we try to send message (milliseconds)
+ * @data:	cec message payload
+ * @len:	cec message length
+ * @success:	0 => message was sent, else => failed to send message
+ * @flags:	flag field (cec_tx_msg_flags)
+ * @tries:	number of try done to send message
+ */
+struct cec_tx_msg {
+	__u16	expire_ms;
+	__u8	data[CEC_MAX_MSG_LEN];
+	__u8	len;
+	__u8	success;
+	__u8	flags;
+	__u8	tries;
+} __attribute__((packed));
+
+struct cec_tx_status {
+	__u8	sent;
+	__u8	success;
+	__u8	flags;
+	__u8	tries;
+} __attribute__((packed));
+
+#define DETACH_CFG_F_WAKEUP		(1 << 0)
+
+struct cec_detached_config {
+	__u8	phys_addr_valid;
+	__u8	phys_addr[2];
+	__u8	flags;
+} __attribute__((packed));
+
+/* Counters */
+
+/**
+ * struct cec_rx_counters - cec adpater RX counters
+ */
+struct cec_rx_counters {
+	__u8	pkts;
+	__u8	filtered_pkts;
+	__u8	valid_pkts;
+	__u8	rx_queue_full;
+	__u8	late_ack;
+	__u8	error;
+	__u8	rx_timeout_abort;
+	__u8	rx_throttled;
+};
+
+/**
+ * struct cec_tx_counters - cec adapter TX counters
+ */
+struct cec_tx_counters {
+	__u8	done;
+	__u8	fail;
+	__u8	timeout;
+	__u8	arb_loss;
+	__u8	bad_ack_timings;
+	__u8	tx_miss_early;
+	__u8	tx_miss_late;
+};
+
+/**
+ * struct cec_counters - tx and rx cec counters
+ * @rx:	struct cec_rx_counters
+ * @tx: struct cec_tx_counters
+ */
+struct cec_counters {
+	struct cec_rx_counters	rx;
+	struct cec_tx_counters	tx;
+};
+
+/**
+ * enum cec_rx_mode - cec adapter rx mode
+ * @CEC_RX_MODE_DISABLED:	RX path is disabled (default)
+ * @CEC_RX_MODE_DEFAULT:	accept only unicast traffic
+ * @CEC_RX_MODE_ACCEPT_ALL:	accept all incoming RX traffic (sniffing mode)
+ * @CEC_RX_MODE_MAX:		sentinel
+ */
+enum cec_rx_mode {
+	CEC_RX_MODE_DISABLED = 0,
+	CEC_RX_MODE_DEFAULT,
+	CEC_RX_MODE_ACCEPT_ALL,
+	CEC_RX_MODE_MAX
+};
+
+#ifdef __KERNEL__
+
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+
+struct cec_adapter;
+
+#define CEC_HW_HAS_COUNTERS	(1 << 0)	/* HW counts events */
+#define CEC_HW_HAS_RX_FILTER	(1 << 1)	/* HW has receive filter */
+
+/**
+ * struct cec_adapter_ops - cec adapter low-level operations
+ * @set_logical_address:	callback to set the logical address
+ * @send:	callback to send a cec payload
+ * @reset:	callback to reset the hardware
+ * @get_counters:	callback to get the counters (if supported by HW)
+ * @set_rx_mode:	callback to set the receive mode
+ * @attach:	callback to attach the host to the device
+ * @detach:	callbackt to detach the host from the device
+ * @set_detached_config:	callback to configure adapter when detached
+ */
+struct cec_adapter_ops {
+	int	(*set_logical_address)(struct cec_adapter *, const u8);
+	int	(*send)(struct cec_adapter *, u16, const u8 *, const u8);
+	int	(*reset)(struct cec_adapter *);
+	int	(*get_counters)(struct cec_adapter *, struct cec_counters *);
+	int	(*set_rx_mode)(struct cec_adapter *, enum cec_rx_mode);
+	int	(*attach)(struct cec_adapter *);
+	int	(*detach)(struct cec_adapter *);
+	int	(*set_detached_config)(struct cec_adapter *,
+				       const struct cec_detached_config *);
+};
+
+/**
+ * struct cec_adapter - cec adapter structure
+ * @driver_name:	driver prefix used for device naming
+ * @module:		module pointer for refcounting
+ * @ops:		struct cec_adapter_ops pointer
+ * @flags:		adapter flags bitmask
+ * @name:		adapter unique name
+ * @dev:		device structure for device/driver model interaction
+ * @lock:		adapter all-purpose mutex for exclusive locking
+ * @attached:		adapter attached to host or not
+ * @tx_pending:		true if tx is ongoing
+ * @tx_lock:		transmit lock
+ * @rx_msg_list:	receive message list head
+ * @rx_msg_list_lock:	receive message list lock
+ * @rx_msg_len:		receive message queue len
+ * @wait:		receive waitqueue (used for poll, read)
+ * @cdev:		character device node
+ */
+struct cec_adapter {
+	const char		*driver_name;
+	struct module		*module;
+	const struct cec_adapter_ops	*ops;
+	unsigned int		flags;
+	atomic_t		users;
+
+	/* unique device name, used for sysfs & chardev */
+	char			name[128];
+
+	/* associated sysfs device */
+	struct device		dev;
+
+	/* private */
+	struct mutex		lock;
+	bool			attached;
+
+	wait_queue_head_t	wait;
+
+	/* transmit message list */
+	unsigned long		tx_pending;
+	bool			last_tx_success;
+	u8			last_tx_flags;
+	u8			last_tx_tries;
+
+	/* receive message list */
+	struct list_head	rx_msg_list;
+	spinlock_t		rx_msg_list_lock;
+	unsigned int		rx_msg_len;
+
+	/* associated chardev */
+	struct cdev		cdev;
+
+	/* true when unregistering device */
+	bool			dead;
+};
+
+#define CECDEV_PRIV_ALIGN	8
+
+static inline void *cec_adapter_priv(struct cec_adapter *adapter)
+{
+	return (u8 *)adapter + ((sizeof(struct cec_adapter)
+			      + (CECDEV_PRIV_ALIGN - 1))
+			     & ~(CECDEV_PRIV_ALIGN - 1));
+}
+
+static inline struct cec_adapter *to_cec_adapter(struct device *d)
+{
+	return container_of(d, struct cec_adapter, dev);
+}
+
+struct cec_adapter *alloc_cec_adapter(size_t priv_size);
+int register_cec_adapter(struct cec_adapter *);
+void unregister_cec_adapter(struct cec_adapter *);
+void free_cec_adapter(struct cec_adapter *);
+int adapter_rx_done(struct cec_adapter *, const u8 *, const u8 len,
+		    bool valid, u8 flags);
+void adapter_tx_done(struct cec_adapter *, bool success, u8 flags, u8 tries);
+
+#endif /* __KERNEL__ */
+
+#endif /* __HDMI_CEC_H */
diff -Nruw linux-3.2.24-fbx/include/linux/hdmi-cec./Kbuild linux-3.2.24-fbx/include/linux/hdmi-cec/Kbuild
--- linux-3.2.24-fbx/include/linux/hdmi-cec./Kbuild	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/include/linux/hdmi-cec/Kbuild	2012-07-27 18:10:47.660138269 +0200
@@ -0,0 +1 @@
+header-y	+= hdmi-cec.h dev.h
diff -Nruw linux-3.2.24-fbx/include/linux/remoti./Kbuild linux-3.2.24-fbx/include/linux/remoti/Kbuild
--- linux-3.2.24-fbx/include/linux/remoti./Kbuild	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/include/linux/remoti/Kbuild	2013-06-13 15:52:31.105197946 +0200
@@ -0,0 +1 @@
+header-y	+= remoti.h
diff -Nruw linux-3.2.24-fbx/include/linux/remoti./leds.h linux-3.2.24-fbx/include/linux/remoti/leds.h
--- linux-3.2.24-fbx/include/linux/remoti./leds.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/include/linux/remoti/leds.h	2012-07-27 19:04:58.027001672 +0200
@@ -0,0 +1,11 @@
+#ifndef __REMOTI_LEDS_H
+#define __REMOTI_LEDS_H
+
+#define REMOTI_LEDS_COUNT	2
+
+struct remoti_leds_pdata {
+	unsigned num_leds;
+	const char *names[REMOTI_LEDS_COUNT];
+};
+
+#endif /* __REMOTI_LEDS_H */
diff -Nruw linux-3.2.24-fbx/include/linux/remoti./remoti.h linux-3.2.24-fbx/include/linux/remoti/remoti.h
--- linux-3.2.24-fbx/include/linux/remoti./remoti.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/include/linux/remoti/remoti.h	2013-06-13 15:52:31.105197946 +0200
@@ -0,0 +1,196 @@
+#ifndef __REMOTI_H
+#define __REMOTI_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+/*
+ * subsystem definitions
+ */
+#define NPI_SYS_RES0		0
+#define NPI_SYS_SYS		1
+#define NPI_SYS_MAC		2
+#define NPI_SYS_NWK		3
+#define NPI_SYS_AF		4
+#define NPI_SYS_ZDO		5
+#define NPI_SYS_SAPI		6
+#define NPI_SYS_UTIL		7
+#define NPI_SYS_DBG		8
+#define NPI_SYS_APP		9
+#define NPI_SYS_RCAF		10
+#define NPI_SYS_RCN		11
+#define NPI_SYS_RCN_CLI		12
+#define NPI_SYS_BOOT		13
+#define NPI_SYS_MAX		14
+#define NPI_SYS_MASK		0x1F
+
+/*
+ * type definitions
+ */
+#define NPI_POLL		0
+#define NPI_SREQ		1
+#define NPI_AREQ		2
+#define NPI_SRSP		3
+#define NPI_TYPE_MAX		4
+#define NPI_TYPE_MASK		3
+#define NPI_TYPE_SHIFT		5
+
+
+/* common error codes (see RemoTI API) */
+#define RTI_SUCCESS		0x00
+
+/*
+ * rti user message
+ */
+#define NPI_MAX_DATA_LEN	123
+
+struct rti_msg {
+	__u8	type;
+	__u8	subsys;
+	__u8	cmd;
+
+	__u8	data_len;
+	__u8	data[NPI_MAX_DATA_LEN];
+
+	__u8	custom_reply_cmd;
+	__u8	reply_cmd;
+	__u8	reply_len;
+	__u8	reply[NPI_MAX_DATA_LEN];
+};
+
+/*
+ * socket addr family on "user" device
+ */
+#ifndef PF_REMOTI
+#define PF_REMOTI			37
+#define AF_REMOTI			PF_REMOTI
+#endif
+
+struct sockaddr_rti {
+	__u32	device_id;
+};
+
+#define SOL_REMOTI			280
+#define REMOTI_REGISTER_CB		0
+
+struct rti_callback {
+	__u8	subsys;
+	__u8	cmd;
+};
+
+/*
+ * ioctl on uart device
+ */
+enum rti_dev_state {
+	RTI_DEV_S_STOPPED = 0,
+	RTI_DEV_S_BOOTING,
+	RTI_DEV_S_BOOT_FAILED,
+	RTI_DEV_S_OPERATIONAL,
+	RTI_DEV_S_STOPPING,
+	RTI_DEV_S_DEAD,
+};
+
+struct rti_dev_status {
+	__u32	dev_state;
+	__u32	fw_version;
+};
+
+struct rti_dev_stats {
+	__u64	tx_bytes;
+	__u64	tx_packets;
+
+	__u64	tx_boot_packets;
+	__u64	tx_rcaf_packets;
+	__u64	tx_util_packets;
+	__u64	tx_other_packets;
+
+
+	__u64	rx_bytes;
+	__u64	rx_packets;
+	__u64	rx_bad_sof;
+	__u64	rx_len_errors;
+	__u64	rx_fcs_errors;
+	__u64	rx_tty_errors;
+	__u64	rx_full_errors;
+	__u64	rx_subsys_errors;
+	__u64	rx_type_errors;
+	__u64	rx_no_callback;
+
+	__u64	rx_boot_packets;
+	__u64	rx_rcaf_packets;
+	__u64	rx_util_packets;
+	__u64	rx_other_packets;
+};
+
+enum {
+	RTI_BOOT_FLAGS_FORCE_UPDATE	= (1 << 0),
+};
+
+#define RTI_IOCTL_MAGIC		0xd4
+#define RTI_ATTACH_DEVICE	_IOR(RTI_IOCTL_MAGIC, 1, __u32)
+#define RTI_GET_STATUS		_IOW(RTI_IOCTL_MAGIC, 2, struct rti_dev_status)
+#define RTI_GET_STATS		_IOW(RTI_IOCTL_MAGIC, 3, struct rti_dev_stats)
+
+#define RTI_START_DEVICE	_IOR(RTI_IOCTL_MAGIC, 8, __u32)
+#define RTI_STOP_DEVICE		_IO(RTI_IOCTL_MAGIC, 9)
+
+
+#ifdef __KERNEL__
+
+/*
+ * platform data definition
+ */
+struct remoti_dev_pdata {
+	unsigned int		id;
+	unsigned int		reset_gpio;
+	unsigned int		reset_polarity;
+};
+
+/*
+ * kernel API to access remoti device
+ */
+struct rti_udev;
+
+struct rti_udev *rti_get_udevice(unsigned int id);
+
+void rti_release_udevice(struct rti_udev *udev);
+
+int rti_send_sync_msg(struct rti_udev *udev, struct rti_msg *msg);
+
+int rti_send_async_msg(struct rti_udev *udev, struct rti_msg *msg);
+
+int rti_register_cmd_callback(struct rti_udev *udev,
+			      u8 subsys, u8 cmd,
+			      void (*cb)(void *cb_priv,
+					 const struct rti_msg *msg),
+			      void *cb_priv);
+
+void rti_unregister_cmd_callback(struct rti_udev *udev, u8 subsys, u8 cmd);
+
+struct rti_kcallback {
+	__u8		subsys;
+	__u8		cmd;
+	void		(*cb)(void *cb_priv, const struct rti_msg *msg);
+};
+
+int rti_register_cmds_callback(struct rti_udev *udev,
+			       const struct rti_kcallback *cbs,
+			       size_t cb_count,
+			       void *cb_priv);
+
+void rti_unregister_cmds_callback(struct rti_udev *udev,
+				  const struct rti_kcallback *cbs,
+				  size_t cb_count);
+
+
+enum rti_udev_state {
+	RTI_UDEV_UP = 0,
+	RTI_UDEV_GOING_DOWN,
+};
+
+void rti_register_udevice_notifier(struct notifier_block *nb);
+void rti_unregister_udevice_notifier(struct notifier_block *nb);
+
+#endif /* __KERNEL__ */
+
+#endif /* __REMOTI_H */
--- /dev/null	2012-04-27 19:20:46.132017814 +0200
+++ linux-3.2.24-fbx/lib/fbxserial.c	2011-01-06 02:17:56.732113582 +0100
@@ -0,0 +1,117 @@
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/crc32.h>
+
+#include <asm/io.h>
+
+#include <linux/fbxserial.h>
+
+#define PFX "builtin-fbxserial: "
+
+static void __init
+fbxserialinfo_use_default(struct fbx_serial *serial)
+{
+	printk(KERN_WARNING PFX "warning: using default serial infos\n");
+	fbxserial_set_default(serial);
+}
+
+/*
+ * add trailing 0 for bundle string here.
+ */
+static void __init
+bundle_fixup(struct fbx_serial *serial)
+{
+	struct fbx_serial_extinfo *p;
+	int i;
+
+	for (i = 0; i < be32_to_cpu(serial->extinfo_count); i++) {
+
+		if (i >= EXTINFO_MAX_COUNT)
+			break;
+
+		p = &serial->extinfos[i];
+		if (be32_to_cpu(p->type) == EXTINFO_TYPE_EXTDEV &&
+		    be32_to_cpu(p->u.extdev.type) == EXTDEV_TYPE_BUNDLE) {
+			int size;
+
+			size = sizeof (p->u.extdev.serial);
+			p->u.extdev.serial[size - 1] = 0;
+		}
+	}
+}
+
+/*
+ * called from  arch code early  in the boot sequence.   This function
+ * returns 1  in case serial infos are  invalid/unreadable and default
+ * values have been used.
+ */
+int __init
+fbxserialinfo_read(void *data, struct fbx_serial *out)
+{
+	uint32_t sum;
+
+	/*
+	 * get partial serial data from flash/whatever.
+	 */
+	memcpy(out, data, sizeof (*out));
+
+	/* check magic first */
+	if (be32_to_cpu(out->magic) != FBXSERIAL_MAGIC) {
+		printk(KERN_NOTICE PFX "invalid magic (%08x, expected %08x), "
+			"using defaults !\n", be32_to_cpu(out->magic),
+		       FBXSERIAL_MAGIC);
+		goto out_default;
+	}
+
+	/* fetch size for which we have to check CRC */
+	if (be32_to_cpu(out->len) > FBXSERIAL_MAX_SIZE) {
+		printk(KERN_NOTICE PFX "structure size too big (%d), "
+		       "using defaults !\n", be32_to_cpu(out->len));
+		goto out_default;
+	}
+
+	/* compute and check checksum */
+	sum = crc32(0, data + 4, be32_to_cpu(out->len) - 4);
+
+	if (be32_to_cpu(out->crc32) != sum) {
+		printk(KERN_NOTICE PFX "invalid checksum (%08x, "
+		       "expected %08x), using defaults !\n", sum,
+		       be32_to_cpu(out->crc32));
+		goto out_default;
+	}
+
+	printk(KERN_INFO PFX "Found valid serial infos !\n");
+	bundle_fixup(out);
+	return 0;
+
+ out_default:
+	fbxserialinfo_use_default(out);
+	bundle_fixup(out);
+	return 1;
+}
+
+void
+fbxserialinfo_get_random(unsigned char *data, unsigned int len)
+{
+	const struct fbx_serial *s;
+
+	s = arch_get_fbxserial();
+
+	if (len > sizeof (s->random_data))
+		len = sizeof (s->random_data);
+
+	memcpy(data, s->random_data, len);
+}
+EXPORT_SYMBOL(fbxserialinfo_get_random);
+
+void
+fbxserialinfo_get_mac_addr(unsigned char *data)
+{
+	const struct fbx_serial *s;
+
+	s = arch_get_fbxserial();
+	memcpy(data, s->mac_addr_base, MAC_ADDR_SIZE);
+}
+EXPORT_SYMBOL(fbxserialinfo_get_mac_addr);
diff -Nruw linux-3.2.24-fbx/net/fbxatm./Kconfig linux-3.2.24-fbx/net/fbxatm/Kconfig
--- linux-3.2.24-fbx/net/fbxatm./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/net/fbxatm/Kconfig	2012-11-30 16:07:21.194641766 +0100
@@ -0,0 +1,28 @@
+menuconfig FBXATM
+	tristate "Freebox Asynchronous Transfer Mode (ATM)"
+
+if FBXATM
+
+config FBXATM_REMOTE
+	bool
+
+choice
+	prompt "mode"
+	default FBXATM_STACK
+
+config FBXATM_STACK
+	bool "standard"
+
+config FBXATM_REMOTE_STUB
+	bool "remote stub"
+	select FBXATM_REMOTE
+
+endchoice
+
+config FBXATM_REMOTE_DRIVER
+	tristate "remote fbxatm driver"
+	depends on FBXATM_STACK
+	select FBXATM_REMOTE
+	default n
+
+endif
diff -Nruw linux-3.2.24-fbx/net/fbxbridge./Kconfig linux-3.2.24-fbx/net/fbxbridge/Kconfig
--- linux-3.2.24-fbx/net/fbxbridge./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/net/fbxbridge/Kconfig	2012-07-27 18:10:47.908138505 +0200
@@ -0,0 +1,7 @@
+
+#
+# Freebox bridge
+#
+config FBXBRIDGE
+	tristate "Freebox Bridge"
+	depends on FREEBOX_SERIALINFO
diff -Nruw linux-3.2.24-fbx/security/fbxlsmjail./Kconfig linux-3.2.24-fbx/security/fbxlsmjail/Kconfig
--- linux-3.2.24-fbx/security/fbxlsmjail./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/security/fbxlsmjail/Kconfig	2012-07-27 19:04:58.131001775 +0200
@@ -0,0 +1,7 @@
+config SECURITY_FBXLSMJAIL
+	bool "Freebox jail Support"
+	depends on SECURITY
+	default n
+	help
+	  This selects Freebox jailing LSM.
+
diff -Nruw linux-3.2.24-fbx/security/fbxlsmjail./Makefile linux-3.2.24-fbx/security/fbxlsmjail/Makefile
--- linux-3.2.24-fbx/security/fbxlsmjail./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.2.24-fbx/security/fbxlsmjail/Makefile	2012-07-27 19:04:58.131001775 +0200
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_SECURITY_FBXLSMJAIL)	+= fbxlsmjail.o
