diff -ruw linux-3.11.10/arch/Kconfig linux-3.11.10-fbx/arch/Kconfig
--- linux-3.11.10/arch/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/Kconfig	2014-05-09 14:12:52.660546133 +0200
@@ -332,6 +332,10 @@
 	  - secure_computing return value is checked and a return value of -1
 	    results in the system call being skipped immediately.
 
+# Used by archs to tell that they support SECCOMP_FILTER_JIT
+config HAVE_SECCOMP_FILTER_JIT
+	bool
+
 config SECCOMP_FILTER
 	def_bool y
 	depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET
@@ -368,6 +372,9 @@
 config HAVE_ARCH_SOFT_DIRTY
 	bool
 
+config ARCH_THP_MOVE_PMD_ALWAYS_WITHDRAW
+	bool
+
 config HAVE_MOD_ARCH_SPECIFIC
 	bool
 	help
@@ -439,4 +446,14 @@
 config COMPAT_OLD_SIGACTION
 	bool
 
+config SECCOMP_FILTER_JIT
+	bool "enable Seccomp filter Just In Time compiler"
+	depends on HAVE_SECCOMP_FILTER_JIT && BPF_JIT && SECCOMP_FILTER
+	help
+	  Seccomp syscall filtering capabilities are normally handled
+	  by an interpreter. This option allows kernel to generate a native
+	  code when filter is loaded in memory. This should speedup
+	  syscall filtering. Note : Admin should enable this feature
+	  changing /proc/sys/net/core/bpf_jit_enable
+
 source "kernel/gcov/Kconfig"
diff -ruw linux-3.11.10/arch/x86/boot/compressed/head_32.S linux-3.11.10-fbx/arch/x86/boot/compressed/head_32.S
--- linux-3.11.10/arch/x86/boot/compressed/head_32.S	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/boot/compressed/head_32.S	2014-07-01 16:22:13.014328993 +0200
@@ -50,6 +50,13 @@
 	pushl	%eax
 	pushl	%esi
 	pushl	%ecx
+
+	call	reloc
+reloc:
+	popl	%ecx
+	subl	reloc, %ecx
+	movl	%ecx, BP_code32_start(%eax)
+
 	sub	$0x4, %esp
 
 ENTRY(efi_stub_entry)
@@ -63,12 +70,7 @@
 	hlt
 	jmp	1b
 2:
-	call	3f
-3:
-	popl	%eax
-	subl	$3b, %eax
-	subl	BP_pref_address(%esi), %eax
-	add	BP_code32_start(%esi), %eax
+	movl	BP_code32_start(%esi), %eax
 	leal	preferred_addr(%eax), %eax
 	jmp	*%eax
 
diff -ruw linux-3.11.10/arch/x86/boot/compressed/Makefile linux-3.11.10-fbx/arch/x86/boot/compressed/Makefile
--- linux-3.11.10/arch/x86/boot/compressed/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/boot/compressed/Makefile	2014-01-17 19:14:18.570220806 +0100
@@ -13,6 +13,7 @@
 cflags-$(CONFIG_X86_32) := -march=i386
 cflags-$(CONFIG_X86_64) := -mcmodel=small
 KBUILD_CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += -mno-mmx -mno-sse
 KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
 KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
 
diff -ruw linux-3.11.10/arch/x86/boot/early_serial_console.c linux-3.11.10-fbx/arch/x86/boot/early_serial_console.c
--- linux-3.11.10/arch/x86/boot/early_serial_console.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/boot/early_serial_console.c	2013-12-04 14:33:18.527478966 +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.11.10/arch/x86/boot/Makefile linux-3.11.10-fbx/arch/x86/boot/Makefile
--- linux-3.11.10/arch/x86/boot/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/boot/Makefile	2014-01-17 19:14:18.570220806 +0100
@@ -53,18 +53,18 @@
 
 # How to compile the 16-bit code.  Note we always compile for -march=i386,
 # that way we can complain to the user if the CPU is insufficient.
-KBUILD_CFLAGS	:= $(USERINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+KBUILD_CFLAGS	:= $(USERINCLUDE) -m32 -g -Os -D_SETUP -D__KERNEL__ \
 		   -DDISABLE_BRANCH_PROFILING \
 		   -Wall -Wstrict-prototypes \
 		   -march=i386 -mregparm=3 \
 		   -include $(srctree)/$(src)/code16gcc.h \
 		   -fno-strict-aliasing -fomit-frame-pointer -fno-pic \
+		   -mno-mmx -mno-sse \
 		   $(call cc-option, -ffreestanding) \
 		   $(call cc-option, -fno-toplevel-reorder,\
 			$(call cc-option, -fno-unit-at-a-time)) \
 		   $(call cc-option, -fno-stack-protector) \
 		   $(call cc-option, -mpreferred-stack-boundary=2)
-KBUILD_CFLAGS	+= $(call cc-option, -m32)
 KBUILD_AFLAGS	:= $(KBUILD_CFLAGS) -D__ASSEMBLY__
 GCOV_PROFILE := n
 
diff -ruw linux-3.11.10/arch/x86/include/asm/cpufeature.h linux-3.11.10-fbx/arch/x86/include/asm/cpufeature.h
--- linux-3.11.10/arch/x86/include/asm/cpufeature.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/include/asm/cpufeature.h	2014-07-01 16:22:13.014328993 +0200
@@ -216,9 +216,14 @@
 #define X86_FEATURE_ERMS	(9*32+ 9) /* Enhanced REP MOVSB/STOSB */
 #define X86_FEATURE_INVPCID	(9*32+10) /* Invalidate Processor Context ID */
 #define X86_FEATURE_RTM		(9*32+11) /* Restricted Transactional Memory */
+#define X86_FEATURE_MPX		(9*32+14) /* Memory Protection Extension */
+#define X86_FEATURE_AVX512F	(9*32+16) /* AVX-512 Foundation */
 #define X86_FEATURE_RDSEED	(9*32+18) /* The RDSEED instruction */
 #define X86_FEATURE_ADX		(9*32+19) /* The ADCX and ADOX instructions */
 #define X86_FEATURE_SMAP	(9*32+20) /* Supervisor Mode Access Prevention */
+#define X86_FEATURE_AVX512PF	(9*32+26) /* AVX-512 Prefetch */
+#define X86_FEATURE_AVX512ER	(9*32+27) /* AVX-512 Exponential and Reciprocal */
+#define X86_FEATURE_AVX512CD	(9*32+28) /* AVX-512 Conflict Detection */
 
 /*
  * BUG word(s)
diff -ruw linux-3.11.10/arch/x86/include/asm/fpu-internal.h linux-3.11.10-fbx/arch/x86/include/asm/fpu-internal.h
--- linux-3.11.10/arch/x86/include/asm/fpu-internal.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/include/asm/fpu-internal.h	2014-01-17 19:14:18.570220806 +0100
@@ -293,12 +293,13 @@
 	/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
 	   is pending.  Clear the x87 state here by setting it to fixed
 	   values. "m" is a random variable that should be in L1 */
-	alternative_input(
-		ASM_NOP8 ASM_NOP2,
-		"emms\n\t"		/* clear stack tags */
-		"fildl %P[addr]",	/* set F?P to defined value */
-		X86_FEATURE_FXSAVE_LEAK,
-		[addr] "m" (tsk->thread.fpu.has_fpu));
+	if (unlikely(static_cpu_has(X86_FEATURE_FXSAVE_LEAK))) {
+		asm volatile(
+			"fnclex\n\t"
+			"emms\n\t"
+			"fildl %P[addr]"	/* set F?P to defined value */
+			: : [addr] "m" (tsk->thread.fpu.has_fpu));
+	}
 
 	return fpu_restore_checking(&tsk->thread.fpu);
 }
diff -ruw linux-3.11.10/arch/x86/include/asm/pgtable.h linux-3.11.10-fbx/arch/x86/include/asm/pgtable.h
--- linux-3.11.10/arch/x86/include/asm/pgtable.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/include/asm/pgtable.h	2014-01-17 19:14:18.570220806 +0100
@@ -465,9 +465,16 @@
 }
 
 #define pte_accessible pte_accessible
-static inline int pte_accessible(pte_t a)
+static inline bool pte_accessible(struct mm_struct *mm, pte_t a)
 {
-	return pte_flags(a) & _PAGE_PRESENT;
+	if (pte_flags(a) & _PAGE_PRESENT)
+		return true;
+
+	if ((pte_flags(a) & (_PAGE_PROTNONE | _PAGE_NUMA)) &&
+			mm_tlb_flush_pending(mm))
+		return true;
+
+	return false;
 }
 
 static inline int pte_hidden(pte_t pte)
diff -ruw linux-3.11.10/arch/x86/include/asm/pgtable_types.h linux-3.11.10-fbx/arch/x86/include/asm/pgtable_types.h
--- linux-3.11.10/arch/x86/include/asm/pgtable_types.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/include/asm/pgtable_types.h	2014-05-09 14:12:52.680546134 +0200
@@ -118,7 +118,8 @@
 
 /* Set of bits not changed in pte_modify */
 #define _PAGE_CHG_MASK	(PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT |		\
-			 _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY)
+			 _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY |	\
+			 _PAGE_SOFT_DIRTY)
 #define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE)
 
 #define _PAGE_CACHE_MASK	(_PAGE_PCD | _PAGE_PWT)
diff -ruw linux-3.11.10/arch/x86/include/asm/ptrace.h linux-3.11.10-fbx/arch/x86/include/asm/ptrace.h
--- linux-3.11.10/arch/x86/include/asm/ptrace.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/include/asm/ptrace.h	2014-08-22 15:47:22.068062809 +0200
@@ -232,6 +232,22 @@
 
 #define ARCH_HAS_USER_SINGLE_STEP_INFO
 
+/*
+ * When hitting ptrace_stop(), we cannot return using SYSRET because
+ * that does not restore the full CPU state, only a minimal set.  The
+ * ptracer can change arbitrary register values, which is usually okay
+ * because the usual ptrace stops run off the signal delivery path which
+ * forces IRET; however, ptrace_event() stops happen in arbitrary places
+ * in the kernel and don't force IRET path.
+ *
+ * So force IRET path after a ptrace stop.
+ */
+#define arch_ptrace_stop_needed(code, info)				\
+({									\
+	set_thread_flag(TIF_NOTIFY_RESUME);				\
+	false;								\
+})
+
 struct user_desc;
 extern int do_get_thread_area(struct task_struct *p, int idx,
 			      struct user_desc __user *info);
diff -ruw linux-3.11.10/arch/x86/include/asm/string_32.h linux-3.11.10-fbx/arch/x86/include/asm/string_32.h
--- linux-3.11.10/arch/x86/include/asm/string_32.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/include/asm/string_32.h	2013-12-04 14:33:18.555478967 +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.11.10/arch/x86/include/asm/topology.h linux-3.11.10-fbx/arch/x86/include/asm/topology.h
--- linux-3.11.10/arch/x86/include/asm/topology.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/include/asm/topology.h	2014-07-01 16:22:13.014328993 +0200
@@ -119,9 +119,10 @@
 
 extern const struct cpumask *cpu_coregroup_mask(int cpu);
 
-#ifdef ENABLE_TOPO_DEFINES
 #define topology_physical_package_id(cpu)	(cpu_data(cpu).phys_proc_id)
 #define topology_core_id(cpu)			(cpu_data(cpu).cpu_core_id)
+
+#ifdef ENABLE_TOPO_DEFINES
 #define topology_core_cpumask(cpu)		(per_cpu(cpu_core_map, cpu))
 #define topology_thread_cpumask(cpu)		(per_cpu(cpu_sibling_map, cpu))
 
diff -ruw linux-3.11.10/arch/x86/include/uapi/asm/bootparam.h linux-3.11.10-fbx/arch/x86/include/uapi/asm/bootparam.h
--- linux-3.11.10/arch/x86/include/uapi/asm/bootparam.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/include/uapi/asm/bootparam.h	2013-12-04 14:33:18.563478967 +0100
@@ -34,6 +34,17 @@
 #include <asm/ist.h>
 #include <video/edid.h>
 
+/* setup data types */
+#define SETUP_NONE			0
+#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.11.10/arch/x86/include/uapi/asm/msr-index.h linux-3.11.10-fbx/arch/x86/include/uapi/asm/msr-index.h
--- linux-3.11.10/arch/x86/include/uapi/asm/msr-index.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/include/uapi/asm/msr-index.h	2014-05-09 14:12:52.680546134 +0200
@@ -182,6 +182,7 @@
 #define MSR_AMD64_PATCH_LOADER		0xc0010020
 #define MSR_AMD64_OSVW_ID_LENGTH	0xc0010140
 #define MSR_AMD64_OSVW_STATUS		0xc0010141
+#define MSR_AMD64_LS_CFG		0xc0011020
 #define MSR_AMD64_DC_CFG		0xc0011022
 #define MSR_AMD64_BU_CFG2		0xc001102a
 #define MSR_AMD64_IBSFETCHCTL		0xc0011030
diff -ruw linux-3.11.10/arch/x86/Kconfig linux-3.11.10-fbx/arch/x86/Kconfig
--- linux-3.11.10/arch/x86/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/Kconfig	2015-07-29 11:23:31.015266537 +0200
@@ -441,6 +441,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.11.10/arch/x86/kernel/cpu/common.c linux-3.11.10-fbx/arch/x86/kernel/cpu/common.c
--- linux-3.11.10/arch/x86/kernel/cpu/common.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/cpu/common.c	2014-05-09 14:12:52.684546134 +0200
@@ -284,8 +284,13 @@
 	raw_local_save_flags(eflags);
 	BUG_ON(eflags & X86_EFLAGS_AC);
 
-	if (cpu_has(c, X86_FEATURE_SMAP))
+	if (cpu_has(c, X86_FEATURE_SMAP)) {
+#ifdef CONFIG_X86_SMAP
 		set_in_cr4(X86_CR4_SMAP);
+#else
+		clear_in_cr4(X86_CR4_SMAP);
+#endif
+	}
 }
 
 /*
diff -ruw linux-3.11.10/arch/x86/kernel/cpu/intel.c linux-3.11.10-fbx/arch/x86/kernel/cpu/intel.c
--- linux-3.11.10/arch/x86/kernel/cpu/intel.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/cpu/intel.c	2014-05-09 14:12:52.684546134 +0200
@@ -29,6 +29,7 @@
 static void early_init_intel(struct cpuinfo_x86 *c)
 {
 	u64 misc_enable;
+	bool allow_fast_string = true;
 
 	/* Unmask CPUID levels if masked: */
 	if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
@@ -131,10 +132,11 @@
 	 * (model 2) with the same problem.
 	 */
 	if (c->x86 == 15) {
-		rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
+		allow_fast_string = false;
 
+		rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
 		if (misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING) {
-			printk(KERN_INFO "kmemcheck: Disabling fast string operations\n");
+			printk_once(KERN_INFO "kmemcheck: Disabling fast string operations\n");
 
 			misc_enable &= ~MSR_IA32_MISC_ENABLE_FAST_STRING;
 			wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
@@ -143,13 +145,28 @@
 #endif
 
 	/*
-	 * If fast string is not enabled in IA32_MISC_ENABLE for any reason,
-	 * clear the fast string and enhanced fast string CPU capabilities.
+	 * If BIOS didn't enable fast string operation, try to enable
+	 * it ourselves.  If that fails, then clear the fast string
+	 * and enhanced fast string CPU capabilities.
 	 */
 	if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
 		rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
+
+		if (allow_fast_string &&
+		    !(misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING)) {
+			misc_enable |= MSR_IA32_MISC_ENABLE_FAST_STRING;
+			wrmsrl_safe(MSR_IA32_MISC_ENABLE, misc_enable);
+
+			/* Re-read to make sure it stuck. */
+			rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
+
+			if (misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING)
+				printk_once(KERN_INFO FW_WARN "IA32_MISC_ENABLE.FAST_STRING_ENABLE was not set\n");
+		}
+
 		if (!(misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING)) {
-			printk(KERN_INFO "Disabled fast string operations\n");
+			if (allow_fast_string)
+				printk_once(KERN_INFO "Failed to enable fast string operations\n");
 			setup_clear_cpu_cap(X86_FEATURE_REP_GOOD);
 			setup_clear_cpu_cap(X86_FEATURE_ERMS);
 		}
@@ -387,7 +404,8 @@
 			set_cpu_cap(c, X86_FEATURE_PEBS);
 	}
 
-	if (c->x86 == 6 && c->x86_model == 29 && cpu_has_clflush)
+	if (c->x86 == 6 && cpu_has_clflush &&
+	    (c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47))
 		set_cpu_cap(c, X86_FEATURE_CLFLUSH_MONITOR);
 
 #ifdef CONFIG_X86_64
@@ -627,7 +645,7 @@
 		tlb_flushall_shift = 5;
 		break;
 	case 0x63a: /* Ivybridge */
-		tlb_flushall_shift = 1;
+		tlb_flushall_shift = 2;
 		break;
 	default:
 		tlb_flushall_shift = 6;
diff -ruw linux-3.11.10/arch/x86/kernel/cpu/perf_event_amd_ibs.c linux-3.11.10-fbx/arch/x86/kernel/cpu/perf_event_amd_ibs.c
--- linux-3.11.10/arch/x86/kernel/cpu/perf_event_amd_ibs.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/cpu/perf_event_amd_ibs.c	2014-05-09 14:12:52.696546134 +0200
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/ptrace.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/apic.h>
 
@@ -816,6 +817,18 @@
 	return ret;
 }
 
+static void ibs_eilvt_setup(void)
+{
+	/*
+	 * Force LVT offset assignment for family 10h: The offsets are
+	 * not assigned by the BIOS for this family, so the OS is
+	 * responsible for doing it. If the OS assignment fails, fall
+	 * back to BIOS settings and try to setup this.
+	 */
+	if (boot_cpu_data.x86 == 0x10)
+		force_ibs_eilvt_setup();
+}
+
 static inline int get_ibs_lvt_offset(void)
 {
 	u64 val;
@@ -851,6 +864,36 @@
 		setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
 }
 
+#ifdef CONFIG_PM
+
+static int perf_ibs_suspend(void)
+{
+	clear_APIC_ibs(NULL);
+	return 0;
+}
+
+static void perf_ibs_resume(void)
+{
+	ibs_eilvt_setup();
+	setup_APIC_ibs(NULL);
+}
+
+static struct syscore_ops perf_ibs_syscore_ops = {
+	.resume		= perf_ibs_resume,
+	.suspend	= perf_ibs_suspend,
+};
+
+static void perf_ibs_pm_init(void)
+{
+	register_syscore_ops(&perf_ibs_syscore_ops);
+}
+
+#else
+
+static inline void perf_ibs_pm_init(void) { }
+
+#endif
+
 static int
 perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
 {
@@ -877,18 +920,12 @@
 	if (!caps)
 		return -ENODEV;	/* ibs not supported by the cpu */
 
-	/*
-	 * Force LVT offset assignment for family 10h: The offsets are
-	 * not assigned by the BIOS for this family, so the OS is
-	 * responsible for doing it. If the OS assignment fails, fall
-	 * back to BIOS settings and try to setup this.
-	 */
-	if (boot_cpu_data.x86 == 0x10)
-		force_ibs_eilvt_setup();
+	ibs_eilvt_setup();
 
 	if (!ibs_eilvt_valid())
 		goto out;
 
+	perf_ibs_pm_init();
 	get_online_cpus();
 	ibs_caps = caps;
 	/* make ibs_caps visible to other cpus: */
diff -ruw linux-3.11.10/arch/x86/kernel/cpu/perf_event.c linux-3.11.10-fbx/arch/x86/kernel/cpu/perf_event.c
--- linux-3.11.10/arch/x86/kernel/cpu/perf_event.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/cpu/perf_event.c	2014-07-01 16:22:13.014328993 +0200
@@ -1192,6 +1192,9 @@
 	for (i = 0; i < cpuc->n_events; i++) {
 		if (event == cpuc->event_list[i]) {
 
+			if (i >= cpuc->n_events - cpuc->n_added)
+				--cpuc->n_added;
+
 			if (x86_pmu.put_event_constraints)
 				x86_pmu.put_event_constraints(cpuc, event);
 
diff -ruw linux-3.11.10/arch/x86/kernel/early_printk.c linux-3.11.10-fbx/arch/x86/kernel/early_printk.c
--- linux-3.11.10/arch/x86/kernel/early_printk.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/early_printk.c	2013-12-04 14:33:18.583478967 +0100
@@ -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.11.10/arch/x86/kernel/early-quirks.c linux-3.11.10-fbx/arch/x86/kernel/early-quirks.c
--- linux-3.11.10/arch/x86/kernel/early-quirks.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/early-quirks.c	2014-07-01 16:22:13.014328993 +0200
@@ -202,18 +202,15 @@
 	revision = read_pci_config_byte(num, slot, func, PCI_REVISION_ID);
 
 	/*
- 	 * Revision 13 of all triggering devices id in this quirk have
-	 * a problem draining interrupts when irq remapping is enabled,
-	 * and should be flagged as broken.  Additionally revisions 0x12
-	 * and 0x22 of device id 0x3405 has this problem.
+	 * Revision <= 13 of all triggering devices id in this quirk
+	 * have a problem draining interrupts when irq remapping is
+	 * enabled, and should be flagged as broken. Additionally
+	 * revision 0x22 of device id 0x3405 has this problem.
 	 */
-	if (revision == 0x13)
+	if (revision <= 0x13)
 		set_irq_remapping_broken();
-	else if ((device == 0x3405) &&
-	    ((revision == 0x12) ||
-	     (revision == 0x22)))
+	else if (device == 0x3405 && revision == 0x22)
 		set_irq_remapping_broken();
-
 }
 
 #define QFLAG_APPLY_ONCE 	0x1
diff -ruw linux-3.11.10/arch/x86/kernel/entry_32.S linux-3.11.10-fbx/arch/x86/kernel/entry_32.S
--- linux-3.11.10/arch/x86/kernel/entry_32.S	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/entry_32.S	2014-08-22 15:47:22.068062809 +0200
@@ -434,9 +434,10 @@
 	jnz sysenter_audit
 sysenter_do_call:
 	cmpl $(NR_syscalls), %eax
-	jae syscall_badsys
+	jae sysenter_badsys
 	call *sys_call_table(,%eax,4)
 	movl %eax,PT_EAX(%esp)
+sysenter_after_call:
 	LOCKDEP_SYS_EXIT
 	DISABLE_INTERRUPTS(CLBR_ANY)
 	TRACE_IRQS_OFF
@@ -554,11 +555,6 @@
 
 	CFI_RESTORE_STATE
 ldt_ss:
-	larl PT_OLDSS(%esp), %eax
-	jnz restore_nocheck
-	testl $0x00400000, %eax		# returning to 32bit stack?
-	jnz restore_nocheck		# allright, normal return
-
 #ifdef CONFIG_PARAVIRT
 	/*
 	 * The kernel can't run on a non-flat stack if paravirt mode
@@ -691,7 +687,12 @@
 
 syscall_badsys:
 	movl $-ENOSYS,PT_EAX(%esp)
-	jmp resume_userspace
+	jmp syscall_exit
+END(syscall_badsys)
+
+sysenter_badsys:
+	movl $-ENOSYS,PT_EAX(%esp)
+	jmp sysenter_after_call
 END(syscall_badsys)
 	CFI_ENDPROC
 /*
@@ -1085,7 +1086,7 @@
 	pushl $0	/* Pass NULL as regs pointer */
 	movl 4*4(%esp), %eax
 	movl 0x4(%ebp), %edx
-	leal function_trace_op, %ecx
+	movl function_trace_op, %ecx
 	subl $MCOUNT_INSN_SIZE, %eax
 
 .globl ftrace_call
@@ -1143,7 +1144,7 @@
 	movl 12*4(%esp), %eax	/* Load ip (1st parameter) */
 	subl $MCOUNT_INSN_SIZE, %eax	/* Adjust ip */
 	movl 0x4(%ebp), %edx	/* Load parent ip (2nd parameter) */
-	leal function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */
+	movl function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */
 	pushl %esp		/* Save pt_regs as 4th parameter */
 
 GLOBAL(ftrace_regs_call)
diff -ruw linux-3.11.10/arch/x86/kernel/head32.c linux-3.11.10-fbx/arch/x86/kernel/head32.c
--- linux-3.11.10/arch/x86/kernel/head32.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/head32.c	2013-12-04 14:33:18.583478967 +0100
@@ -33,6 +33,13 @@
 {
 	sanitize_boot_params(&boot_params);
 
+#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.11.10/arch/x86/kernel/head_32.S linux-3.11.10-fbx/arch/x86/kernel/head_32.S
--- linux-3.11.10/arch/x86/kernel/head_32.S	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/head_32.S	2014-07-01 16:22:13.014328993 +0200
@@ -544,6 +544,10 @@
 	/* This is global to keep gas from relaxing the jumps */
 ENTRY(early_idt_handler)
 	cld
+
+	cmpl $2,(%esp)		# X86_TRAP_NMI
+	je is_nmi		# Ignore NMI
+
 	cmpl $2,%ss:early_recursion_flag
 	je hlt_loop
 	incl %ss:early_recursion_flag
@@ -594,8 +598,9 @@
 	pop %edx
 	pop %ecx
 	pop %eax
-	addl $8,%esp		/* drop vector number and error code */
 	decl %ss:early_recursion_flag
+is_nmi:
+	addl $8,%esp		/* drop vector number and error code */
 	iret
 ENDPROC(early_idt_handler)
 
diff -ruw linux-3.11.10/arch/x86/kernel/i387.c linux-3.11.10-fbx/arch/x86/kernel/i387.c
--- linux-3.11.10/arch/x86/kernel/i387.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/i387.c	2014-07-01 16:22:13.014328993 +0200
@@ -86,11 +86,20 @@
 
 void __kernel_fpu_end(void)
 {
-	if (use_eager_fpu())
+	if (use_eager_fpu()) {
+		/*
+		 * For eager fpu, most the time, tsk_used_math() is true.
+		 * Restore the user math as we are done with the kernel usage.
+		 * At few instances during thread exit, signal handling etc,
+		 * tsk_used_math() is false. Those few places will take proper
+		 * actions, so we don't need to restore the math here.
+		 */
+		if (likely(tsk_used_math(current)))
 		math_state_restore();
-	else
+	} else {
 		stts();
 }
+}
 EXPORT_SYMBOL(__kernel_fpu_end);
 
 void unlazy_fpu(struct task_struct *tsk)
diff -ruw linux-3.11.10/arch/x86/kernel/ldt.c linux-3.11.10-fbx/arch/x86/kernel/ldt.c
--- linux-3.11.10/arch/x86/kernel/ldt.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/ldt.c	2014-07-01 16:22:13.014328993 +0200
@@ -20,6 +20,8 @@
 #include <asm/mmu_context.h>
 #include <asm/syscalls.h>
 
+int sysctl_ldt16 = 0;
+
 #ifdef CONFIG_SMP
 static void flush_ldt(void *current_mm)
 {
@@ -229,6 +231,17 @@
 		}
 	}
 
+	/*
+	 * On x86-64 we do not support 16-bit segments due to
+	 * IRET leaking the high bits of the kernel stack address.
+	 */
+#ifdef CONFIG_X86_64
+	if (!ldt_info.seg_32bit && !sysctl_ldt16) {
+		error = -EINVAL;
+		goto out_unlock;
+	}
+#endif
+
 	fill_ldt(&ldt, &ldt_info);
 	if (oldmode)
 		ldt.avl = 0;
diff -ruw linux-3.11.10/arch/x86/kernel/Makefile linux-3.11.10-fbx/arch/x86/kernel/Makefile
--- linux-3.11.10/arch/x86/kernel/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/Makefile	2013-12-04 14:33:18.563478967 +0100
@@ -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
@@ -106,6 +107,8 @@
 
 obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
 obj-$(CONFIG_TRACING)			+= tracepoint.o
+obj-$(CONFIG_FBXSERIAL)			+= fbxserial.o
+obj-y					+= fbxbootinfo.o
 
 ###
 # 64 bit specific files
diff -ruw linux-3.11.10/arch/x86/kernel/pci-dma.c linux-3.11.10-fbx/arch/x86/kernel/pci-dma.c
--- linux-3.11.10/arch/x86/kernel/pci-dma.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/pci-dma.c	2014-07-01 16:22:13.018329021 +0200
@@ -100,8 +100,10 @@
 	flag |= __GFP_ZERO;
 again:
 	page = NULL;
-	if (!(flag & GFP_ATOMIC))
+	/* CMA can be used only in the context which permits sleeping */
+	if (flag & __GFP_WAIT)
 		page = dma_alloc_from_contiguous(dev, count, get_order(size));
+	/* fallback */
 	if (!page)
 		page = alloc_pages_node(dev_to_node(dev), flag, get_order(size));
 	if (!page)
diff -ruw linux-3.11.10/arch/x86/kernel/quirks.c linux-3.11.10-fbx/arch/x86/kernel/quirks.c
--- linux-3.11.10/arch/x86/kernel/quirks.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/quirks.c	2014-07-01 16:22:13.018329021 +0200
@@ -529,7 +529,7 @@
 		return;
 
 	pci_read_config_dword(nb_ht, 0x60, &val);
-	node = val & 7;
+	node = pcibus_to_node(dev->bus) | (val & 7);
 	/*
 	 * Some hardware may return an invalid node ID,
 	 * so check it first:
diff -ruw linux-3.11.10/arch/x86/kernel/reboot.c linux-3.11.10-fbx/arch/x86/kernel/reboot.c
--- linux-3.11.10/arch/x86/kernel/reboot.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/reboot.c	2014-01-17 19:14:18.570220806 +0100
@@ -542,6 +542,10 @@
 void native_machine_shutdown(void)
 {
 	/* Stop the cpus and apics */
+#ifdef CONFIG_X86_IO_APIC
+	disable_IO_APIC();
+#endif
+
 #ifdef CONFIG_SMP
 	/*
 	 * Stop all of the others. Also disable the local irq to
@@ -554,10 +558,6 @@
 
 	lapic_shutdown();
 
-#ifdef CONFIG_X86_IO_APIC
-	disable_IO_APIC();
-#endif
-
 #ifdef CONFIG_HPET_TIMER
 	hpet_disable();
 #endif
diff -ruw linux-3.11.10/arch/x86/kernel/reboot_fixups_32.c linux-3.11.10-fbx/arch/x86/kernel/reboot_fixups_32.c
--- linux-3.11.10/arch/x86/kernel/reboot_fixups_32.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/reboot_fixups_32.c	2013-12-18 18:29:06.640968712 +0100
@@ -16,6 +16,11 @@
 
 static void cs5530a_warm_reset(struct pci_dev *dev)
 {
+	if (in_interrupt()) {
+		printk("cs5530a_warm_reset(): can't reboot: can't access "
+		       "PCI config space from IRQ.\n");
+		return ;
+	}
 	/* writing 1 to the reset control register, 0x44 causes the
 	cs5530a to perform a system warm reset */
 	pci_write_config_byte(dev, 0x44, 0x1);
@@ -57,6 +62,7 @@
 	unsigned int vendor;
 	unsigned int device;
 	void (*reboot_fixup)(struct pci_dev *);
+	struct pci_dev *dev;
 };
 
 /*
@@ -64,7 +70,7 @@
  */
 #define PCI_DEVICE_ID_INTEL_CE4100	0x0708
 
-static const struct device_fixup fixups_table[] = {
+static struct device_fixup fixups_table[] = {
 { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset },
 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, cs5536_warm_reset },
 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE, cs5530a_warm_reset },
@@ -81,22 +87,29 @@
 void mach_reboot_fixups(void)
 {
 	const struct device_fixup *cur;
-	struct pci_dev *dev;
 	int i;
 
-	/* we can be called from sysrq-B code. In such a case it is
-	 * prohibited to dig PCI */
-	if (in_interrupt())
-		return;
+	for (i = 0; i < ARRAY_SIZE(fixups_table); ++i) {
+		cur = &fixups_table[i];
+		if (cur->dev)
+			cur->reboot_fixup(cur->dev);
+	}
+}
+
+static int __init mach_reboot_fixups_init(void)
+{
+	struct pci_dev *dev;
+	struct device_fixup *cur;
+	int i;
 
 	for (i=0; i < ARRAY_SIZE(fixups_table); i++) {
-		cur = &(fixups_table[i]);
+		cur = &fixups_table[i];
 		dev = pci_get_device(cur->vendor, cur->device, NULL);
 		if (!dev)
 			continue;
 
-		cur->reboot_fixup(dev);
-		pci_dev_put(dev);
+		cur->dev = dev;
 	}
+	return 0;
 }
-
+module_init(mach_reboot_fixups_init);
diff -ruw linux-3.11.10/arch/x86/kernel/setup.c linux-3.11.10-fbx/arch/x86/kernel/setup.c
--- linux-3.11.10/arch/x86/kernel/setup.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/kernel/setup.c	2013-12-17 18:03:42.371570846 +0100
@@ -427,6 +427,8 @@
 {
 	struct setup_data *data;
 	u64 pa_data, pa_next;
+	extern void parse_fbxserial_ext(u64 phys_addr, u32 data_len);
+	extern void parse_fbxbootinfo(u64 phys_addr, u32 data_len);
 
 	pa_data = boot_params.hdr.setup_data;
 	while (pa_data) {
@@ -447,6 +449,14 @@
 		case SETUP_DTB:
 			add_dtb(pa_data);
 			break;
+#ifdef CONFIG_FBXSERIAL
+		case SETUP_FBXSERIAL_EXT:
+			parse_fbxserial_ext(pa_data, data_len);
+			break;
+#endif
+		case SETUP_FBXBOOTINFO:
+			parse_fbxbootinfo(pa_data, data_len);
+			break;
 		default:
 			break;
 		}
diff -ruw linux-3.11.10/arch/x86/Makefile linux-3.11.10-fbx/arch/x86/Makefile
--- linux-3.11.10/arch/x86/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/Makefile	2014-01-17 19:14:18.570220806 +0100
@@ -31,6 +31,9 @@
 
         KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return
 
+        # Don't autogenerate MMX or SSE instructions
+        KBUILD_CFLAGS += -mno-mmx -mno-sse
+
         # Never want PIC in a 32-bit kernel, prevent breakage with GCC built
         # with nonstandard options
         KBUILD_CFLAGS += -fno-pic
@@ -57,8 +60,11 @@
         KBUILD_AFLAGS += -m64
         KBUILD_CFLAGS += -m64
 
+        # Don't autogenerate MMX or SSE instructions
+        KBUILD_CFLAGS += -mno-mmx -mno-sse
+
 	# Use -mpreferred-stack-boundary=3 if supported.
-	KBUILD_CFLAGS += $(call cc-option,-mno-sse -mpreferred-stack-boundary=3)
+	KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3)
 
         # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
         cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
diff -ruw linux-3.11.10/arch/x86/mm/fault.c linux-3.11.10-fbx/arch/x86/mm/fault.c
--- linux-3.11.10/arch/x86/mm/fault.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/mm/fault.c	2014-05-09 14:12:52.704546134 +0200
@@ -989,6 +989,12 @@
 
 static inline bool smap_violation(int error_code, struct pt_regs *regs)
 {
+	if (!IS_ENABLED(CONFIG_X86_SMAP))
+		return false;
+
+	if (!static_cpu_has(X86_FEATURE_SMAP))
+		return false;
+
 	if (error_code & PF_USER)
 		return false;
 
@@ -1091,12 +1097,10 @@
 	if (unlikely(error_code & PF_RSVD))
 		pgtable_bad(regs, error_code, address);
 
-	if (static_cpu_has(X86_FEATURE_SMAP)) {
 		if (unlikely(smap_violation(error_code, regs))) {
 			bad_area_nosemaphore(regs, error_code, address);
 			return;
 		}
-	}
 
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
 
diff -ruw linux-3.11.10/arch/x86/mm/gup.c linux-3.11.10-fbx/arch/x86/mm/gup.c
--- linux-3.11.10/arch/x86/mm/gup.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/mm/gup.c	2014-01-17 19:14:18.574220806 +0100
@@ -83,6 +83,12 @@
 		pte_t pte = gup_get_pte(ptep);
 		struct page *page;
 
+		/* Similar to the PMD case, NUMA hinting must take slow path */
+		if (pte_numa(pte)) {
+			pte_unmap(ptep);
+			return 0;
+		}
+
 		if ((pte_flags(pte) & (mask | _PAGE_SPECIAL)) != mask) {
 			pte_unmap(ptep);
 			return 0;
@@ -167,6 +173,13 @@
 		if (pmd_none(pmd) || pmd_trans_splitting(pmd))
 			return 0;
 		if (unlikely(pmd_large(pmd))) {
+			/*
+			 * NUMA hinting faults need to be handled in the GUP
+			 * slowpath for accounting purposes and so that they
+			 * can be serialised against THP migration.
+			 */
+			if (pmd_numa(pmd))
+				return 0;
 			if (!gup_huge_pmd(pmd, addr, next, write, pages, nr))
 				return 0;
 		} else {
diff -ruw linux-3.11.10/arch/x86/mm/ioremap.c linux-3.11.10-fbx/arch/x86/mm/ioremap.c
--- linux-3.11.10/arch/x86/mm/ioremap.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/mm/ioremap.c	2014-08-22 15:47:22.072062829 +0200
@@ -50,6 +50,21 @@
 	return err;
 }
 
+static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages,
+			       void *arg)
+{
+	unsigned long i;
+
+	for (i = 0; i < nr_pages; ++i)
+		if (pfn_valid(start_pfn + i) &&
+		    !PageReserved(pfn_to_page(start_pfn + i)))
+			return 1;
+
+	WARN_ONCE(1, "ioremap on RAM pfn 0x%lx\n", start_pfn);
+
+	return 0;
+}
+
 /*
  * Remap an arbitrary physical address space into the kernel virtual
  * address space. Needed when the kernel wants to access high addresses
@@ -93,14 +108,11 @@
 	/*
 	 * Don't allow anybody to remap normal RAM that we're using..
 	 */
+	pfn      = phys_addr >> PAGE_SHIFT;
 	last_pfn = last_addr >> PAGE_SHIFT;
-	for (pfn = phys_addr >> PAGE_SHIFT; pfn <= last_pfn; pfn++) {
-		int is_ram = page_is_ram(pfn);
-
-		if (is_ram && pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn)))
+	if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL,
+				  __ioremap_check_ram) == 1)
 			return NULL;
-		WARN_ON_ONCE(is_ram);
-	}
 
 	/*
 	 * Mappings have to be page-aligned
diff -ruw linux-3.11.10/arch/x86/platform/ce4100/ce4100.c linux-3.11.10-fbx/arch/x86/platform/ce4100/ce4100.c
--- linux-3.11.10/arch/x86/platform/ce4100/ce4100.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/platform/ce4100/ce4100.c	2013-12-04 14:33:18.619478968 +0100
@@ -16,6 +16,11 @@
 #include <linux/serial_reg.h>
 #include <linux/serial_8250.h>
 #include <linux/reboot.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pstore_ram.h>
+#include <linux/sizes.h>
 
 #include <asm/ce4100.h>
 #include <asm/prom.h>
@@ -144,10 +149,96 @@
 }
 #endif
 
+
+#ifdef CONFIG_FBX6HD
+/*
+ * reserve top of RAM - 16K for crash_zone.
+ */
+#define FBX6HD_CRASHZONE_SIZE	(SZ_16K)
+#define FBX6HD_CRASHZONE_BASE  (SZ_1G - FBX6HD_CRASHZONE_SIZE)
+
+static struct ramoops_platform_data ramoops_data = {
+        .mem_size		= FBX6HD_CRASHZONE_SIZE,
+        .mem_address		= FBX6HD_CRASHZONE_BASE,
+        .record_size		= SZ_16K,
+        .dump_oops		= 1,
+	.ecc_info = {
+		.ecc_size	= 1,
+	},
+};
+
+static struct platform_device ramoops_dev = {
+        .name = "ramoops",
+        .dev = {
+                .platform_data = &ramoops_data,
+        },
+};
+
+static void __init fbx6hd_init_ramoops(void)
+{
+	platform_device_register(&ramoops_dev);
+}
+
+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;
+	}
+
+	fbx6hd_init_ramoops();
+
+	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;
@@ -166,6 +257,19 @@
 	 */
 	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;
diff -ruw linux-3.11.10/arch/x86/platform/ce4100/Makefile linux-3.11.10-fbx/arch/x86/platform/ce4100/Makefile
--- linux-3.11.10/arch/x86/platform/ce4100/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/platform/ce4100/Makefile	2013-12-04 14:33:18.619478968 +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.11.10/arch/x86/realmode/rm/Makefile linux-3.11.10-fbx/arch/x86/realmode/rm/Makefile
--- linux-3.11.10/arch/x86/realmode/rm/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/realmode/rm/Makefile	2014-01-17 19:14:18.574220806 +0100
@@ -73,6 +73,7 @@
 		   -march=i386 -mregparm=3 \
 		   -include $(srctree)/$(src)/../../boot/code16gcc.h \
 		   -fno-strict-aliasing -fomit-frame-pointer -fno-pic \
+		   -mno-mmx -mno-sse \
 		   $(call cc-option, -ffreestanding) \
 		   $(call cc-option, -fno-toplevel-reorder,\
 			$(call cc-option, -fno-unit-at-a-time)) \
diff -ruw linux-3.11.10/arch/x86/syscalls/syscall_64.tbl linux-3.11.10-fbx/arch/x86/syscalls/syscall_64.tbl
--- linux-3.11.10/arch/x86/syscalls/syscall_64.tbl	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/syscalls/syscall_64.tbl	2014-08-22 15:47:22.072062829 +0200
@@ -212,10 +212,10 @@
 203	common	sched_setaffinity	sys_sched_setaffinity
 204	common	sched_getaffinity	sys_sched_getaffinity
 205	64	set_thread_area
-206	common	io_setup		sys_io_setup
+206	64	io_setup		sys_io_setup
 207	common	io_destroy		sys_io_destroy
 208	common	io_getevents		sys_io_getevents
-209	common	io_submit		sys_io_submit
+209	64	io_submit		sys_io_submit
 210	common	io_cancel		sys_io_cancel
 211	64	get_thread_area
 212	common	lookup_dcookie		sys_lookup_dcookie
@@ -356,3 +356,5 @@
 540	x32	process_vm_writev	compat_sys_process_vm_writev
 541	x32	setsockopt		compat_sys_setsockopt
 542	x32	getsockopt		compat_sys_getsockopt
+543	x32	io_setup		compat_sys_io_setup
+544	x32	io_submit		compat_sys_io_submit
diff -ruw linux-3.11.10/arch/x86/vdso/vdso32-setup.c linux-3.11.10-fbx/arch/x86/vdso/vdso32-setup.c
--- linux-3.11.10/arch/x86/vdso/vdso32-setup.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/arch/x86/vdso/vdso32-setup.c	2014-07-01 16:22:13.022329034 +0200
@@ -41,6 +41,7 @@
 #ifdef CONFIG_X86_64
 #define vdso_enabled			sysctl_vsyscall32
 #define arch_setup_additional_pages	syscall32_setup_pages
+extern int sysctl_ldt16;
 #endif
 
 /*
@@ -379,6 +380,13 @@
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec
+	},
+	{
+		.procname	= "ldt16",
+		.data		= &sysctl_ldt16,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
 	},
 	{}
 };
diff -ruw linux-3.11.10/block/blk-cgroup.h linux-3.11.10-fbx/block/blk-cgroup.h
--- linux-3.11.10/block/blk-cgroup.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/block/blk-cgroup.h	2014-08-22 15:47:22.072062829 +0200
@@ -18,6 +18,7 @@
 #include <linux/seq_file.h>
 #include <linux/radix-tree.h>
 #include <linux/blkdev.h>
+#include <linux/atomic.h>
 
 /* Max limits for throttle policy */
 #define THROTL_IOPS_MAX		UINT_MAX
@@ -104,7 +105,7 @@
 	struct request_list		rl;
 
 	/* reference count */
-	int				refcnt;
+	atomic_t			refcnt;
 
 	/* is this blkg online? protected by both blkcg and q locks */
 	bool				online;
@@ -257,13 +258,12 @@
  * blkg_get - get a blkg reference
  * @blkg: blkg to get
  *
- * The caller should be holding queue_lock and an existing reference.
+ * The caller should be holding an existing reference.
  */
 static inline void blkg_get(struct blkcg_gq *blkg)
 {
-	lockdep_assert_held(blkg->q->queue_lock);
-	WARN_ON_ONCE(!blkg->refcnt);
-	blkg->refcnt++;
+	WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0);
+	atomic_inc(&blkg->refcnt);
 }
 
 void __blkg_release_rcu(struct rcu_head *rcu);
@@ -271,14 +271,11 @@
 /**
  * blkg_put - put a blkg reference
  * @blkg: blkg to put
- *
- * The caller should be holding queue_lock.
  */
 static inline void blkg_put(struct blkcg_gq *blkg)
 {
-	lockdep_assert_held(blkg->q->queue_lock);
-	WARN_ON_ONCE(blkg->refcnt <= 0);
-	if (!--blkg->refcnt)
+	WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0);
+	if (atomic_dec_and_test(&blkg->refcnt))
 		call_rcu(&blkg->rcu_head, __blkg_release_rcu);
 }
 
@@ -433,9 +430,9 @@
 	uint64_t v;
 
 	do {
-		start = u64_stats_fetch_begin(&stat->syncp);
+		start = u64_stats_fetch_begin_bh(&stat->syncp);
 		v = stat->cnt;
-	} while (u64_stats_fetch_retry(&stat->syncp, start));
+	} while (u64_stats_fetch_retry_bh(&stat->syncp, start));
 
 	return v;
 }
@@ -501,9 +498,9 @@
 	struct blkg_rwstat tmp;
 
 	do {
-		start = u64_stats_fetch_begin(&rwstat->syncp);
+		start = u64_stats_fetch_begin_bh(&rwstat->syncp);
 		tmp = *rwstat;
-	} while (u64_stats_fetch_retry(&rwstat->syncp, start));
+	} while (u64_stats_fetch_retry_bh(&rwstat->syncp, start));
 
 	return tmp;
 }
diff -ruw linux-3.11.10/block/blk-core.c linux-3.11.10-fbx/block/blk-core.c
--- linux-3.11.10/block/blk-core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/block/blk-core.c	2014-07-01 16:22:13.022329034 +0200
@@ -645,10 +645,12 @@
 	__set_bit(QUEUE_FLAG_BYPASS, &q->queue_flags);
 
 	if (blkcg_init_queue(q))
-		goto fail_id;
+		goto fail_bdi;
 
 	return q;
 
+fail_bdi:
+	bdi_destroy(&q->backing_dev_info);
 fail_id:
 	ida_simple_remove(&blk_queue_ida, q->id);
 fail_q:
@@ -739,9 +741,17 @@
 
 	q->sg_reserved_size = INT_MAX;
 
+	/* Protect q->elevator from elevator_change */
+	mutex_lock(&q->sysfs_lock);
+
 	/* init elevator */
-	if (elevator_init(q, NULL))
+	if (elevator_init(q, NULL)) {
+		mutex_unlock(&q->sysfs_lock);
 		return NULL;
+	}
+
+	mutex_unlock(&q->sysfs_lock);
+
 	return q;
 }
 EXPORT_SYMBOL(blk_init_allocated_queue);
@@ -2030,7 +2040,7 @@
 	}
 }
 
-static void blk_account_io_done(struct request *req)
+static void blk_account_io_done(struct request *req, int error)
 {
 	/*
 	 * Account IO completion.  flush_rq isn't accounted as a
@@ -2046,6 +2056,8 @@
 		cpu = part_stat_lock();
 		part = req->part;
 
+		if (error < 0)
+			part_stat_inc(cpu, part, io_errors[rw]);
 		part_stat_inc(cpu, part, ios[rw]);
 		part_stat_add(cpu, part, ticks[rw], duration);
 		part_round_stats(cpu, part);
@@ -2229,6 +2241,7 @@
 	if (unlikely(blk_bidi_rq(req)))
 		req->next_rq->resid_len = blk_rq_bytes(req->next_rq);
 
+	BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags));
 	blk_add_timer(req);
 }
 EXPORT_SYMBOL(blk_start_request);
@@ -2288,7 +2301,7 @@
 	if (!req->bio)
 		return false;
 
-	trace_block_rq_complete(req->q, req);
+	trace_block_rq_complete(req->q, req, nr_bytes);
 
 	/*
 	 * For fs requests, rq is just carrier of independent bio's
@@ -2448,7 +2461,7 @@
 		blk_unprep_request(req);
 
 
-	blk_account_io_done(req);
+	blk_account_io_done(req, error);
 
 	if (req->end_io)
 		req->end_io(req, error);
diff -ruw linux-3.11.10/block/blk.h linux-3.11.10-fbx/block/blk.h
--- linux-3.11.10/block/blk.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/block/blk.h	2014-05-09 14:12:52.724546134 +0200
@@ -96,7 +96,7 @@
 			q->flush_queue_delayed = 1;
 			return NULL;
 		}
-		if (unlikely(blk_queue_dying(q)) ||
+		if (unlikely(blk_queue_bypass(q)) ||
 		    !q->elevator->type->ops.elevator_dispatch_fn(q, 0))
 			return NULL;
 	}
diff -ruw linux-3.11.10/block/blk-lib.c linux-3.11.10-fbx/block/blk-lib.c
--- linux-3.11.10/block/blk-lib.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/block/blk-lib.c	2014-05-09 14:12:52.724546134 +0200
@@ -121,6 +121,14 @@
 
 		atomic_inc(&bb.done);
 		submit_bio(type, bio);
+
+		/*
+		 * We can loop for a long time in here, if someone does
+		 * full device discards (like mkfs). Be nice and allow
+		 * us to schedule out to avoid softlocking if preempt
+		 * is disabled.
+		 */
+		cond_resched();
 	}
 	blk_finish_plug(&plug);
 
diff -ruw linux-3.11.10/block/blk-settings.c linux-3.11.10-fbx/block/blk-settings.c
--- linux-3.11.10/block/blk-settings.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/block/blk-settings.c	2014-01-17 19:14:18.578220806 +0100
@@ -144,6 +144,7 @@
 	lim->discard_zeroes_data = 1;
 	lim->max_segments = USHRT_MAX;
 	lim->max_hw_sectors = UINT_MAX;
+	lim->max_segment_size = UINT_MAX;
 	lim->max_sectors = UINT_MAX;
 	lim->max_write_same_sectors = UINT_MAX;
 }
diff -ruw linux-3.11.10/block/blk-timeout.c linux-3.11.10-fbx/block/blk-timeout.c
--- linux-3.11.10/block/blk-timeout.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/block/blk-timeout.c	2014-01-17 19:14:18.578220806 +0100
@@ -91,8 +91,8 @@
 		__blk_complete_request(req);
 		break;
 	case BLK_EH_RESET_TIMER:
-		blk_clear_rq_complete(req);
 		blk_add_timer(req);
+		blk_clear_rq_complete(req);
 		break;
 	case BLK_EH_NOT_HANDLED:
 		/*
@@ -174,7 +174,6 @@
 		return;
 
 	BUG_ON(!list_empty(&req->timeout_list));
-	BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags));
 
 	/*
 	 * Some LLDs, like scsi, peek at the timeout to prevent a
diff -ruw linux-3.11.10/block/elevator.c linux-3.11.10-fbx/block/elevator.c
--- linux-3.11.10/block/elevator.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/block/elevator.c	2014-01-17 19:14:18.578220806 +0100
@@ -186,6 +186,12 @@
 	struct elevator_type *e = NULL;
 	int err;
 
+	/*
+	 * q->sysfs_lock must be held to provide mutual exclusion between
+	 * elevator_switch() and here.
+	 */
+	lockdep_assert_held(&q->sysfs_lock);
+
 	if (unlikely(q->elevator))
 		return 0;
 
@@ -959,7 +965,7 @@
 /*
  * Switch this queue to the given IO scheduler.
  */
-int elevator_change(struct request_queue *q, const char *name)
+static int __elevator_change(struct request_queue *q, const char *name)
 {
 	char elevator_name[ELV_NAME_MAX];
 	struct elevator_type *e;
@@ -981,6 +987,18 @@
 
 	return elevator_switch(q, e);
 }
+
+int elevator_change(struct request_queue *q, const char *name)
+{
+	int ret;
+
+	/* Protect q->elevator from elevator_init() */
+	mutex_lock(&q->sysfs_lock);
+	ret = __elevator_change(q, name);
+	mutex_unlock(&q->sysfs_lock);
+
+	return ret;
+}
 EXPORT_SYMBOL(elevator_change);
 
 ssize_t elv_iosched_store(struct request_queue *q, const char *name,
@@ -991,7 +1009,7 @@
 	if (!q->elevator)
 		return count;
 
-	ret = elevator_change(q, name);
+	ret = __elevator_change(q, name);
 	if (!ret)
 		return count;
 
diff -ruw linux-3.11.10/block/partition-generic.c linux-3.11.10-fbx/block/partition-generic.c
--- linux-3.11.10/block/partition-generic.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/block/partition-generic.c	2014-05-09 14:12:52.724546134 +0200
@@ -120,7 +120,7 @@
 	return sprintf(buf,
 		"%8lu %8lu %8llu %8u "
 		"%8lu %8lu %8llu %8u "
-		"%8u %8u %8u"
+		"%8u %8u %8u %8lu %lu"
 		"\n",
 		part_stat_read(p, ios[READ]),
 		part_stat_read(p, merges[READ]),
@@ -132,7 +132,9 @@
 		jiffies_to_msecs(part_stat_read(p, ticks[WRITE])),
 		part_in_flight(p),
 		jiffies_to_msecs(part_stat_read(p, io_ticks)),
-		jiffies_to_msecs(part_stat_read(p, time_in_queue)));
+		jiffies_to_msecs(part_stat_read(p, time_in_queue)),
+		part_stat_read(p, io_errors[READ]),
+		part_stat_read(p, io_errors[WRITE]));
 }
 
 ssize_t part_inflight_show(struct device *dev,
diff -ruw linux-3.11.10/crypto/algboss.c linux-3.11.10-fbx/crypto/algboss.c
--- linux-3.11.10/crypto/algboss.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/crypto/algboss.c	2013-12-04 14:33:18.663478969 +0100
@@ -221,7 +221,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.11.10/crypto/authenc.c linux-3.11.10-fbx/crypto/authenc.c
--- linux-3.11.10/crypto/authenc.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/crypto/authenc.c	2014-01-17 19:14:18.578220806 +0100
@@ -368,9 +368,10 @@
 	if (!err) {
 		struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
 		struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
-		struct ablkcipher_request *abreq = aead_request_ctx(areq);
-		u8 *iv = (u8 *)(abreq + 1) +
-			 crypto_ablkcipher_reqsize(ctx->enc);
+		struct authenc_request_ctx *areq_ctx = aead_request_ctx(areq);
+		struct ablkcipher_request *abreq = (void *)(areq_ctx->tail
+							    + ctx->reqoff);
+		u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(ctx->enc);
 
 		err = crypto_authenc_genicv(areq, iv, 0);
 	}
diff -ruw linux-3.11.10/crypto/crypto_wq.c linux-3.11.10-fbx/crypto/crypto_wq.c
--- linux-3.11.10/crypto/crypto_wq.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/crypto/crypto_wq.c	2014-07-01 16:22:13.022329034 +0200
@@ -33,7 +33,7 @@
 	destroy_workqueue(kcrypto_wq);
 }
 
-module_init(crypto_wq_init);
+subsys_initcall(crypto_wq_init);
 module_exit(crypto_wq_exit);
 
 MODULE_LICENSE("GPL");
diff -ruw linux-3.11.10/crypto/Kconfig linux-3.11.10-fbx/crypto/Kconfig
--- linux-3.11.10/crypto/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/crypto/Kconfig	2013-12-04 14:33:18.659478969 +0100
@@ -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.11.10/crypto/Makefile linux-3.11.10-fbx/crypto/Makefile
--- linux-3.11.10/crypto/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/crypto/Makefile	2013-12-04 14:33:18.659478969 +0100
@@ -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.11.10/drivers/acpi/acpica/nsrepair.c linux-3.11.10-fbx/drivers/acpi/acpica/nsrepair.c
--- linux-3.11.10/drivers/acpi/acpica/nsrepair.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/acpi/acpica/nsrepair.c	2014-07-01 16:22:13.022329034 +0200
@@ -207,13 +207,30 @@
 	 * this predefined name. Either one return value is expected, or none,
 	 * for both methods and other objects.
 	 *
-	 * Exit now if there is no return object. Warning if one was expected.
+	 * Try to fix if there was no return object. Warning if failed to fix.
 	 */
 	if (!return_object) {
 		if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
-			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+			if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
+				ACPI_WARN_PREDEFINED((AE_INFO,
+						      info->full_pathname,
+						      ACPI_WARN_ALWAYS,
+						      "Found unexpected NULL package element"));
+
+				status =
+				    acpi_ns_repair_null_element(info,
+								expected_btypes,
+								package_index,
+								return_object_ptr);
+				if (ACPI_SUCCESS(status)) {
+					return (AE_OK);	/* Repair was successful */
+				}
+			} else {
+				ACPI_WARN_PREDEFINED((AE_INFO,
+						      info->full_pathname,
 					      ACPI_WARN_ALWAYS,
 					      "Missing expected return value"));
+			}
 
 			return (AE_AML_NO_RETURN_VALUE);
 		}
diff -ruw linux-3.11.10/drivers/acpi/acpica/utstring.c linux-3.11.10-fbx/drivers/acpi/acpica/utstring.c
--- linux-3.11.10/drivers/acpi/acpica/utstring.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/acpi/acpica/utstring.c	2014-08-22 15:47:22.072062829 +0200
@@ -352,7 +352,7 @@
 	}
 
 	acpi_os_printf("\"");
-	for (i = 0; string[i] && (i < max_length); i++) {
+	for (i = 0; (i < max_length) && string[i]; i++) {
 
 		/* Escape sequences */
 
diff -ruw linux-3.11.10/drivers/acpi/acpi_processor.c linux-3.11.10-fbx/drivers/acpi/acpi_processor.c
--- linux-3.11.10/drivers/acpi/acpi_processor.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/acpi/acpi_processor.c	2014-07-01 16:22:13.022329034 +0200
@@ -403,7 +403,6 @@
 		goto err;
 
 	pr->dev = dev;
-	dev->offline = pr->flags.need_hotplug_init;
 
 	/* Trigger the processor driver's .probe() if present. */
 	if (device_attach(dev) >= 0)
diff -ruw linux-3.11.10/drivers/acpi/blacklist.c linux-3.11.10-fbx/drivers/acpi/blacklist.c
--- linux-3.11.10/drivers/acpi/blacklist.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/acpi/blacklist.c	2014-07-01 16:22:13.022329034 +0200
@@ -327,6 +327,19 @@
 		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"),
 		},
 	},
+	/*
+	 * Without this this EEEpc exports a non working WMI interface, with
+	 * this it exports a working "good old" eeepc_laptop interface, fixing
+	 * both brightness control, and rfkill not working.
+	 */
+	{
+	.callback = dmi_enable_osi_linux,
+	.ident = "Asus EEE PC 1015PX",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
+		     DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"),
+		},
+	},
 	{}
 };
 
diff -ruw linux-3.11.10/drivers/acpi/bus.c linux-3.11.10-fbx/drivers/acpi/bus.c
--- linux-3.11.10/drivers/acpi/bus.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/acpi/bus.c	2014-08-22 15:47:22.076062849 +0200
@@ -33,6 +33,7 @@
 #include <linux/proc_fs.h>
 #include <linux/acpi.h>
 #include <linux/slab.h>
+#include <linux/regulator/machine.h>
 #ifdef CONFIG_X86
 #include <asm/mpspec.h>
 #endif
@@ -56,6 +57,12 @@
 
 
 #ifdef CONFIG_X86
+#ifdef CONFIG_ACPI_CUSTOM_DSDT
+static inline int set_copy_dsdt(const struct dmi_system_id *id)
+{
+	return 0;
+}
+#else
 static int set_copy_dsdt(const struct dmi_system_id *id)
 {
 	printk(KERN_NOTICE "%s detected - "
@@ -63,6 +70,7 @@
 	acpi_gbl_copy_dsdt_locally = 1;
 	return 0;
 }
+#endif
 
 static struct dmi_system_id dsdt_dmi_table[] __initdata = {
 	/*
@@ -704,6 +712,14 @@
 		goto error0;
 	}
 
+	/*
+	 * If the system is using ACPI then we can be reasonably
+	 * confident that any regulators are managed by the firmware
+	 * so tell the regulator core it has everything it needs to
+	 * know.
+	 */
+	regulator_has_full_constraints();
+
 	return;
 
       error0:
diff -ruw linux-3.11.10/drivers/acpi/ec.c linux-3.11.10-fbx/drivers/acpi/ec.c
--- linux-3.11.10/drivers/acpi/ec.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/acpi/ec.c	2014-08-22 15:47:22.076062849 +0200
@@ -70,6 +70,8 @@
 #define ACPI_EC_DELAY		500	/* Wait 500ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
 #define ACPI_EC_MSI_UDELAY	550	/* Wait 550us for MSI EC */
+#define ACPI_EC_CLEAR_MAX	100	/* Maximum number of events to query
+					 * when trying to clear the EC */
 
 enum {
 	EC_FLAGS_QUERY_PENDING,		/* Query is pending */
@@ -79,6 +81,9 @@
 	EC_FLAGS_BLOCKED,		/* Transactions are blocked */
 };
 
+#define ACPI_EC_COMMAND_POLL		0x01 /* Available for command byte */
+#define ACPI_EC_COMMAND_COMPLETE	0x02 /* Completed last byte */
+
 /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */
 static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;
 module_param(ec_delay, uint, 0644);
@@ -114,7 +119,7 @@
 	u8 ri;
 	u8 wlen;
 	u8 rlen;
-	bool done;
+	u8 flags;
 };
 
 struct acpi_ec *boot_ec, *first_ec;
@@ -123,6 +128,7 @@
 static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
 static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
 static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
+static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
 
 /* --------------------------------------------------------------------------
                              Transaction Management
@@ -154,69 +160,83 @@
 	outb(data, ec->data_addr);
 }
 
-static int ec_transaction_done(struct acpi_ec *ec)
+static int ec_transaction_completed(struct acpi_ec *ec)
 {
 	unsigned long flags;
 	int ret = 0;
 	spin_lock_irqsave(&ec->lock, flags);
-	if (!ec->curr || ec->curr->done)
+	if (ec->curr && (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE))
 		ret = 1;
 	spin_unlock_irqrestore(&ec->lock, flags);
 	return ret;
 }
 
-static void start_transaction(struct acpi_ec *ec)
+static bool advance_transaction(struct acpi_ec *ec)
 {
-	ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0;
-	ec->curr->done = false;
-	acpi_ec_write_cmd(ec, ec->curr->command);
-}
-
-static void advance_transaction(struct acpi_ec *ec, u8 status)
-{
-	unsigned long flags;
 	struct transaction *t;
+	u8 status;
+	bool wakeup = false;
 
-	spin_lock_irqsave(&ec->lock, flags);
+	pr_debug("===== %s =====\n", in_interrupt() ? "IRQ" : "TASK");
+	status = acpi_ec_read_status(ec);
 	t = ec->curr;
 	if (!t)
-		goto unlock;
+		goto err;
+	if (t->flags & ACPI_EC_COMMAND_POLL) {
 	if (t->wlen > t->wi) {
 		if ((status & ACPI_EC_FLAG_IBF) == 0)
-			acpi_ec_write_data(ec,
-				t->wdata[t->wi++]);
+				acpi_ec_write_data(ec, t->wdata[t->wi++]);
 		else
 			goto err;
 	} else if (t->rlen > t->ri) {
 		if ((status & ACPI_EC_FLAG_OBF) == 1) {
 			t->rdata[t->ri++] = acpi_ec_read_data(ec);
-			if (t->rlen == t->ri)
-				t->done = true;
+				if (t->rlen == t->ri) {
+					t->flags |= ACPI_EC_COMMAND_COMPLETE;
+					wakeup = true;
+				}
 		} else
 			goto err;
 	} else if (t->wlen == t->wi &&
-		   (status & ACPI_EC_FLAG_IBF) == 0)
-		t->done = true;
-	goto unlock;
+			   (status & ACPI_EC_FLAG_IBF) == 0) {
+			t->flags |= ACPI_EC_COMMAND_COMPLETE;
+			wakeup = true;
+		}
+		return wakeup;
+	} else {
+		if ((status & ACPI_EC_FLAG_IBF) == 0) {
+			acpi_ec_write_cmd(ec, t->command);
+			t->flags |= ACPI_EC_COMMAND_POLL;
+		} else
+			goto err;
+		return wakeup;
+	}
 err:
 	/*
 	 * If SCI bit is set, then don't think it's a false IRQ
 	 * otherwise will take a not handled IRQ as a false one.
 	 */
-	if (in_interrupt() && !(status & ACPI_EC_FLAG_SCI))
+	if (!(status & ACPI_EC_FLAG_SCI)) {
+		if (in_interrupt() && t)
 		++t->irq_count;
+	}
+	return wakeup;
+}
 
-unlock:
-	spin_unlock_irqrestore(&ec->lock, flags);
+static void start_transaction(struct acpi_ec *ec)
+{
+	ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0;
+	ec->curr->flags = 0;
+	(void)advance_transaction(ec);
 }
 
-static int acpi_ec_sync_query(struct acpi_ec *ec);
+static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data);
 
 static int ec_check_sci_sync(struct acpi_ec *ec, u8 state)
 {
 	if (state & ACPI_EC_FLAG_SCI) {
 		if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
-			return acpi_ec_sync_query(ec);
+			return acpi_ec_sync_query(ec, NULL);
 	}
 	return 0;
 }
@@ -232,15 +252,17 @@
 			/* don't sleep with disabled interrupts */
 			if (EC_FLAGS_MSI || irqs_disabled()) {
 				udelay(ACPI_EC_MSI_UDELAY);
-				if (ec_transaction_done(ec))
+				if (ec_transaction_completed(ec))
 					return 0;
 			} else {
 				if (wait_event_timeout(ec->wait,
-						ec_transaction_done(ec),
+						ec_transaction_completed(ec),
 						msecs_to_jiffies(1)))
 					return 0;
 			}
-			advance_transaction(ec, acpi_ec_read_status(ec));
+			spin_lock_irqsave(&ec->lock, flags);
+			(void)advance_transaction(ec);
+			spin_unlock_irqrestore(&ec->lock, flags);
 		} while (time_before(jiffies, delay));
 		pr_debug(PREFIX "controller reset, restart transaction\n");
 		spin_lock_irqsave(&ec->lock, flags);
@@ -272,23 +294,6 @@
 	return ret;
 }
 
-static int ec_check_ibf0(struct acpi_ec *ec)
-{
-	u8 status = acpi_ec_read_status(ec);
-	return (status & ACPI_EC_FLAG_IBF) == 0;
-}
-
-static int ec_wait_ibf0(struct acpi_ec *ec)
-{
-	unsigned long delay = jiffies + msecs_to_jiffies(ec_delay);
-	/* interrupt wait manually if GPE mode is not active */
-	while (time_before(jiffies, delay))
-		if (wait_event_timeout(ec->wait, ec_check_ibf0(ec),
-					msecs_to_jiffies(1)))
-			return 0;
-	return -ETIME;
-}
-
 static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
 {
 	int status;
@@ -309,12 +314,6 @@
 			goto unlock;
 		}
 	}
-	if (ec_wait_ibf0(ec)) {
-		pr_err(PREFIX "input buffer is not empty, "
-				"aborting transaction\n");
-		status = -ETIME;
-		goto end;
-	}
 	pr_debug(PREFIX "transaction start (cmd=0x%02x, addr=0x%02x)\n",
 			t->command, t->wdata ? t->wdata[0] : 0);
 	/* disable GPE during transaction if storm is detected */
@@ -338,7 +337,6 @@
 		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
 	}
 	pr_debug(PREFIX "transaction end\n");
-end:
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
 unlock:
@@ -468,6 +466,27 @@
 
 EXPORT_SYMBOL(ec_get_handle);
 
+/*
+ * Process _Q events that might have accumulated in the EC.
+ * Run with locked ec mutex.
+ */
+static void acpi_ec_clear(struct acpi_ec *ec)
+{
+	int i, status;
+	u8 value = 0;
+
+	for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) {
+		status = acpi_ec_sync_query(ec, &value);
+		if (status || !value)
+			break;
+	}
+
+	if (unlikely(i == ACPI_EC_CLEAR_MAX))
+		pr_warn("Warning: Maximum of %d stale EC events cleared\n", i);
+	else
+		pr_info("%d stale EC events cleared\n", i);
+}
+
 void acpi_ec_block_transactions(void)
 {
 	struct acpi_ec *ec = first_ec;
@@ -491,6 +510,10 @@
 	mutex_lock(&ec->mutex);
 	/* Allow transactions to be carried out again */
 	clear_bit(EC_FLAGS_BLOCKED, &ec->flags);
+
+	if (EC_FLAGS_CLEAR_ON_RESUME)
+		acpi_ec_clear(ec);
+
 	mutex_unlock(&ec->mutex);
 }
 
@@ -580,13 +603,18 @@
 	kfree(handler);
 }
 
-static int acpi_ec_sync_query(struct acpi_ec *ec)
+static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data)
 {
 	u8 value = 0;
 	int status;
 	struct acpi_ec_query_handler *handler, *copy;
-	if ((status = acpi_ec_query_unlocked(ec, &value)))
+
+	status = acpi_ec_query_unlocked(ec, &value);
+	if (data)
+		*data = value;
+	if (status)
 		return status;
+
 	list_for_each_entry(handler, &ec->list, node) {
 		if (value == handler->query_bit) {
 			/* have custom handler for this bit */
@@ -609,7 +637,7 @@
 	if (!ec)
 		return;
 	mutex_lock(&ec->mutex);
-	acpi_ec_sync_query(ec);
+	acpi_ec_sync_query(ec, NULL);
 	mutex_unlock(&ec->mutex);
 }
 
@@ -628,17 +656,14 @@
 static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
 	u32 gpe_number, void *data)
 {
+	unsigned long flags;
 	struct acpi_ec *ec = data;
-	u8 status = acpi_ec_read_status(ec);
-
-	pr_debug(PREFIX "~~~> interrupt, status:0x%02x\n", status);
 
-	advance_transaction(ec, status);
-	if (ec_transaction_done(ec) &&
-	    (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
+	spin_lock_irqsave(&ec->lock, flags);
+	if (advance_transaction(ec))
 		wake_up(&ec->wait);
+	spin_unlock_irqrestore(&ec->lock, flags);
 		ec_check_sci(ec, acpi_ec_read_status(ec));
-	}
 	return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
 }
 
@@ -848,6 +873,13 @@
 
 	/* EC is fully operational, allow queries */
 	clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+
+	/* Clear stale _Q events if hardware might require that */
+	if (EC_FLAGS_CLEAR_ON_RESUME) {
+		mutex_lock(&ec->mutex);
+		acpi_ec_clear(ec);
+		mutex_unlock(&ec->mutex);
+	}
 	return ret;
 }
 
@@ -949,7 +981,31 @@
 	return 0;
 }
 
-static struct dmi_system_id __initdata ec_dmi_table[] = {
+/*
+ * On some hardware it is necessary to clear events accumulated by the EC during
+ * sleep. These ECs stop reporting GPEs until they are manually polled, if too
+ * many events are accumulated. (e.g. Samsung Series 5/9 notebooks)
+ *
+ * https://bugzilla.kernel.org/show_bug.cgi?id=44161
+ *
+ * Ideally, the EC should also be instructed NOT to accumulate events during
+ * sleep (which Windows seems to do somehow), but the interface to control this
+ * behaviour is not known at this time.
+ *
+ * Models known to be affected are Samsung 530Uxx/535Uxx/540Uxx/550Pxx/900Xxx,
+ * however it is very likely that other Samsung models are affected.
+ *
+ * On systems which don't accumulate _Q events during sleep, this extra check
+ * should be harmless.
+ */
+static int ec_clear_on_resume(const struct dmi_system_id *id)
+{
+	pr_debug("Detected system needing EC poll on resume.\n");
+	EC_FLAGS_CLEAR_ON_RESUME = 1;
+	return 0;
+}
+
+static struct dmi_system_id ec_dmi_table[] __initdata = {
 	{
 	ec_skip_dsdt_scan, "Compal JFL92", {
 	DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
@@ -992,6 +1048,9 @@
 	ec_validate_ecdt, "ASUS hardware", {
 	DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."),
 	DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL},
+	{
+	ec_clear_on_resume, "Samsung hardware", {
+	DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},
 	{},
 };
 
diff -ruw linux-3.11.10/drivers/acpi/pci_irq.c linux-3.11.10-fbx/drivers/acpi/pci_irq.c
--- linux-3.11.10/drivers/acpi/pci_irq.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/acpi/pci_irq.c	2014-07-01 16:22:13.022329034 +0200
@@ -432,6 +432,7 @@
 				 pin_name(pin));
 		}
 
+		kfree(entry);
 		return 0;
 	}
 
diff -ruw linux-3.11.10/drivers/acpi/pci_root.c linux-3.11.10-fbx/drivers/acpi/pci_root.c
--- linux-3.11.10/drivers/acpi/pci_root.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/acpi/pci_root.c	2014-01-17 19:14:18.578220806 +0100
@@ -63,6 +63,9 @@
 	.ids = root_device_ids,
 	.attach = acpi_pci_root_add,
 	.detach = acpi_pci_root_remove,
+	.hotplug = {
+		.ignore = true,
+	},
 };
 
 static DEFINE_MUTEX(osc_lock);
diff -ruw linux-3.11.10/drivers/acpi/resource.c linux-3.11.10-fbx/drivers/acpi/resource.c
--- linux-3.11.10/drivers/acpi/resource.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/acpi/resource.c	2014-07-01 16:22:13.026329050 +0200
@@ -77,18 +77,24 @@
 	switch (ares->type) {
 	case ACPI_RESOURCE_TYPE_MEMORY24:
 		memory24 = &ares->data.memory24;
+		if (!memory24->address_length)
+			return false;
 		acpi_dev_get_memresource(res, memory24->minimum,
 					 memory24->address_length,
 					 memory24->write_protect);
 		break;
 	case ACPI_RESOURCE_TYPE_MEMORY32:
 		memory32 = &ares->data.memory32;
+		if (!memory32->address_length)
+			return false;
 		acpi_dev_get_memresource(res, memory32->minimum,
 					 memory32->address_length,
 					 memory32->write_protect);
 		break;
 	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 		fixed_memory32 = &ares->data.fixed_memory32;
+		if (!fixed_memory32->address_length)
+			return false;
 		acpi_dev_get_memresource(res, fixed_memory32->address,
 					 fixed_memory32->address_length,
 					 fixed_memory32->write_protect);
@@ -144,12 +150,16 @@
 	switch (ares->type) {
 	case ACPI_RESOURCE_TYPE_IO:
 		io = &ares->data.io;
+		if (!io->address_length)
+			return false;
 		acpi_dev_get_ioresource(res, io->minimum,
 					io->address_length,
 					io->io_decode);
 		break;
 	case ACPI_RESOURCE_TYPE_FIXED_IO:
 		fixed_io = &ares->data.fixed_io;
+		if (!fixed_io->address_length)
+			return false;
 		acpi_dev_get_ioresource(res, fixed_io->address,
 					fixed_io->address_length,
 					ACPI_DECODE_10);
diff -ruw linux-3.11.10/drivers/acpi/scan.c linux-3.11.10-fbx/drivers/acpi/scan.c
--- linux-3.11.10/drivers/acpi/scan.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/acpi/scan.c	2014-01-17 19:14:18.582220806 +0100
@@ -1881,7 +1881,7 @@
 	 */
 	list_for_each_entry(hwid, &pnp.ids, list) {
 		handler = acpi_scan_match_handler(hwid->id, NULL);
-		if (handler) {
+		if (handler && !handler->hotplug.ignore) {
 			acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
 					acpi_hotplug_notify_cb, handler);
 			break;
diff -ruw linux-3.11.10/drivers/acpi/sleep.c linux-3.11.10-fbx/drivers/acpi/sleep.c
--- linux-3.11.10/drivers/acpi/sleep.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/acpi/sleep.c	2014-07-01 16:22:13.026329050 +0200
@@ -78,6 +78,17 @@
 	return 0;
 }
 
+static bool acpi_sleep_state_supported(u8 sleep_state)
+{
+	acpi_status status;
+	u8 type_a, type_b;
+
+	status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b);
+	return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware
+		|| (acpi_gbl_FADT.sleep_control.address
+			&& acpi_gbl_FADT.sleep_status.address));
+}
+
 #ifdef CONFIG_ACPI_SLEEP
 static u32 acpi_target_sleep_state = ACPI_STATE_S0;
 
@@ -602,15 +613,9 @@
 {
 	int i;
 
-	for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) {
-		acpi_status status;
-		u8 type_a, type_b;
-
-		status = acpi_get_sleep_type_data(i, &type_a, &type_b);
-		if (ACPI_SUCCESS(status)) {
+	for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++)
+		if (acpi_sleep_state_supported(i))
 			sleep_states[i] = 1;
-		}
-	}
 
 	suspend_set_ops(old_suspend_ordering ?
 		&acpi_suspend_ops_old : &acpi_suspend_ops);
@@ -741,11 +746,7 @@
 
 static void acpi_sleep_hibernate_setup(void)
 {
-	acpi_status status;
-	u8 type_a, type_b;
-
-	status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b);
-	if (ACPI_FAILURE(status))
+	if (!acpi_sleep_state_supported(ACPI_STATE_S4))
 		return;
 
 	hibernation_set_ops(old_suspend_ordering ?
@@ -794,8 +795,6 @@
 
 int __init acpi_sleep_init(void)
 {
-	acpi_status status;
-	u8 type_a, type_b;
 	char supported[ACPI_S_STATE_COUNT * 3 + 1];
 	char *pos = supported;
 	int i;
@@ -810,8 +809,7 @@
 	acpi_sleep_suspend_setup();
 	acpi_sleep_hibernate_setup();
 
-	status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
-	if (ACPI_SUCCESS(status)) {
+	if (acpi_sleep_state_supported(ACPI_STATE_S5)) {
 		sleep_states[ACPI_STATE_S5] = 1;
 		pm_power_off_prepare = acpi_power_off_prepare;
 		pm_power_off = acpi_power_off;
diff -ruw linux-3.11.10/drivers/ata/ahci.c linux-3.11.10-fbx/drivers/ata/ahci.c
--- linux-3.11.10/drivers/ata/ahci.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/ata/ahci.c	2014-08-22 15:47:22.076062849 +0200
@@ -61,6 +61,7 @@
 	/* board IDs by feature in alphabetical order */
 	board_ahci,
 	board_ahci_ign_iferr,
+	board_ahci_noncq,
 	board_ahci_nosntf,
 	board_ahci_yes_fbs,
 
@@ -119,6 +120,13 @@
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
+	[board_ahci_noncq] = {
+		AHCI_HFLAGS	(AHCI_HFLAG_NO_NCQ),
+		.flags		= AHCI_FLAG_COMMON,
+		.pio_mask	= ATA_PIO4,
+		.udma_mask	= ATA_UDMA6,
+		.port_ops	= &ahci_ops,
+	},
 	[board_ahci_nosntf] = {
 		AHCI_HFLAGS	(AHCI_HFLAG_NO_SNTF),
 		.flags		= AHCI_FLAG_COMMON,
@@ -292,6 +300,10 @@
 	{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
 	{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
 	{ PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
+	{ PCI_VDEVICE(INTEL, 0x9c83), board_ahci }, /* Wildcat Point-LP AHCI */
+	{ PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */
+	{ PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -423,14 +435,23 @@
 	  .driver_data = board_ahci_yes_fbs },			/* 88se9128 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9125),
 	  .driver_data = board_ahci_yes_fbs },			/* 88se9125 */
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_MARVELL_EXT, 0x9178,
+			 PCI_VENDOR_ID_MARVELL_EXT, 0x9170),
+	  .driver_data = board_ahci_yes_fbs },			/* 88se9170 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a),
 	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9172),
 	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192),
 	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 on some Gigabyte */
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0),
+	  .driver_data = board_ahci_yes_fbs },
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3),
 	  .driver_data = board_ahci_yes_fbs },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
+	  .driver_data = board_ahci_yes_fbs },
+	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642),
+	  .driver_data = board_ahci_yes_fbs },
 
 	/* Promise */
 	{ PCI_VDEVICE(PROMISE, 0x3f20), board_ahci },	/* PDC42819 */
@@ -441,6 +462,12 @@
 	{ PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci },	/* ASM1061 */
 	{ PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },	/* ASM1062 */
 
+	/*
+	 * Samsung SSDs found on some macbooks.  NCQ times out.
+	 * https://bugzilla.kernel.org/show_bug.cgi?id=60731
+	 */
+	{ PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq },
+
 	/* Enmotus */
 	{ PCI_DEVICE(0x1c44, 0x8000), board_ahci },
 
@@ -1146,18 +1173,18 @@
 		return rc;
 
 	for (i = 0; i < host->n_ports; i++) {
-		const char* desc;
 		struct ahci_port_priv *pp = host->ports[i]->private_data;
 
-		/* pp is NULL for dummy ports */
-		if (pp)
-			desc = pp->irq_desc;
-		else
-			desc = dev_driver_string(host->dev);
+		/* Do not receive interrupts sent by dummy ports */
+		if (!pp) {
+			disable_irq(irq + i);
+			continue;
+		}
 
-		rc = devm_request_threaded_irq(host->dev,
-			irq + i, ahci_hw_interrupt, ahci_thread_fn, IRQF_SHARED,
-			desc, host->ports[i]);
+		rc = devm_request_threaded_irq(host->dev, irq + i,
+					       ahci_hw_interrupt,
+					       ahci_thread_fn, IRQF_SHARED,
+					       pp->irq_desc, host->ports[i]);
 		if (rc)
 			goto out_free_irqs;
 	}
diff -ruw linux-3.11.10/drivers/ata/libahci.c linux-3.11.10-fbx/drivers/ata/libahci.c
--- linux-3.11.10/drivers/ata/libahci.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/ata/libahci.c	2014-01-17 19:14:18.582220806 +0100
@@ -1267,9 +1267,11 @@
 {
 	struct ata_port *ap = link->ap;
 	struct ahci_host_priv *hpriv = ap->host->private_data;
+	struct ahci_port_priv *pp = ap->private_data;
 	const char *reason = NULL;
 	unsigned long now, msecs;
 	struct ata_taskfile tf;
+	bool fbs_disabled = false;
 	int rc;
 
 	DPRINTK("ENTER\n");
@@ -1279,6 +1281,16 @@
 	if (rc && rc != -EOPNOTSUPP)
 		ata_link_warn(link, "failed to reset engine (errno=%d)\n", rc);
 
+	/*
+	 * According to AHCI-1.2 9.3.9: if FBS is enable, software shall
+	 * clear PxFBS.EN to '0' prior to issuing software reset to devices
+	 * that is attached to port multiplier.
+	 */
+	if (!ata_is_host_link(link) && pp->fbs_enabled) {
+		ahci_disable_fbs(ap);
+		fbs_disabled = true;
+	}
+
 	ata_tf_init(link->device, &tf);
 
 	/* issue the first D2H Register FIS */
@@ -1319,6 +1331,10 @@
 	} else
 		*class = ahci_dev_classify(ap);
 
+	/* re-enable FBS if disabled before */
+	if (fbs_disabled)
+		ahci_enable_fbs(ap);
+
 	DPRINTK("EXIT, class=%u\n", *class);
 	return 0;
 
diff -ruw linux-3.11.10/drivers/ata/libata-core.c linux-3.11.10-fbx/drivers/ata/libata-core.c
--- linux-3.11.10/drivers/ata/libata-core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/ata/libata-core.c	2014-07-01 16:22:13.026329050 +0200
@@ -2199,6 +2199,16 @@
 	if (rc)
 		return rc;
 
+	/* some WD SATA-1 drives have issues with LPM, turn on NOLPM for them */
+	if ((dev->horkage & ATA_HORKAGE_WD_BROKEN_LPM) &&
+	    (id[ATA_ID_SATA_CAPABILITY] & 0xe) == 0x2)
+		dev->horkage |= ATA_HORKAGE_NOLPM;
+
+	if (dev->horkage & ATA_HORKAGE_NOLPM) {
+		ata_dev_warn(dev, "LPM support broken, forcing max_power\n");
+		dev->link->ap->target_lpm_policy = ATA_LPM_MAX_POWER;
+	}
+
 	/* let ACPI work its magic */
 	rc = ata_acpi_on_devcfg(dev);
 	if (rc)
@@ -4110,6 +4120,7 @@
 	{ "TORiSAN DVD-ROM DRD-N216", NULL,	ATA_HORKAGE_MAX_SEC_128 },
 	{ "QUANTUM DAT    DAT72-000", NULL,	ATA_HORKAGE_ATAPI_MOD16_DMA },
 	{ "Slimtype DVD A  DS8A8SH", NULL,	ATA_HORKAGE_MAX_SEC_LBA48 },
+	{ "Slimtype DVD A  DS8A9SH", NULL,	ATA_HORKAGE_MAX_SEC_LBA48 },
 
 	/* Devices we expect to fail diagnostics */
 
@@ -4139,6 +4150,10 @@
 	{ "ST3320[68]13AS",	"SD1[5-9]",	ATA_HORKAGE_NONCQ |
 						ATA_HORKAGE_FIRMWARE_WARN },
 
+	/* Seagate Momentus SpinPoint M8 seem to have FPMDA_AA issues */
+	{ "ST1000LM024 HN-M101MBB", "2AR10001",	ATA_HORKAGE_BROKEN_FPDMA_AA },
+	{ "ST1000LM024 HN-M101MBB", "2BA30001",	ATA_HORKAGE_BROKEN_FPDMA_AA },
+
 	/* Blacklist entries taken from Silicon Image 3124/3132
 	   Windows driver .inf file - also several Linux problem reports */
 	{ "HTS541060G9SA00",    "MB3OC60D",     ATA_HORKAGE_NONCQ, },
@@ -4148,6 +4163,8 @@
 	/* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */
 	{ "C300-CTFDDAC128MAG",	"0001",		ATA_HORKAGE_NONCQ, },
 
+	{ "Boot ROM", 		NULL,		ATA_HORKAGE_NODMA  },
+
 	/* devices which puke on READ_NATIVE_MAX */
 	{ "HDS724040KLSA80",	"KFAOA20N",	ATA_HORKAGE_BROKEN_HPA, },
 	{ "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA },
@@ -4185,6 +4202,23 @@
 	{ "PIONEER DVD-RW  DVR-212D",	NULL,	ATA_HORKAGE_NOSETXFER },
 	{ "PIONEER DVD-RW  DVR-216D",	NULL,	ATA_HORKAGE_NOSETXFER },
 
+	/*
+	 * Some WD SATA-I drives spin up and down erratically when the link
+	 * is put into the slumber mode.  We don't have full list of the
+	 * affected devices.  Disable LPM if the device matches one of the
+	 * known prefixes and is SATA-1.  As a side effect LPM partial is
+	 * lost too.
+	 *
+	 * https://bugzilla.kernel.org/show_bug.cgi?id=57211
+	 */
+	{ "WDC WD800JD-*",		NULL,	ATA_HORKAGE_WD_BROKEN_LPM },
+	{ "WDC WD1200JD-*",		NULL,	ATA_HORKAGE_WD_BROKEN_LPM },
+	{ "WDC WD1600JD-*",		NULL,	ATA_HORKAGE_WD_BROKEN_LPM },
+	{ "WDC WD2000JD-*",		NULL,	ATA_HORKAGE_WD_BROKEN_LPM },
+	{ "WDC WD2500JD-*",		NULL,	ATA_HORKAGE_WD_BROKEN_LPM },
+	{ "WDC WD3000JD-*",		NULL,	ATA_HORKAGE_WD_BROKEN_LPM },
+	{ "WDC WD3200JD-*",		NULL,	ATA_HORKAGE_WD_BROKEN_LPM },
+
 	/* End Marker */
 	{ }
 };
@@ -4733,21 +4767,26 @@
 static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
 {
 	struct ata_queued_cmd *qc = NULL;
-	unsigned int i;
+	unsigned int i, tag;
 
 	/* no command while frozen */
 	if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
 		return NULL;
 
+	for (i = 0; i < ATA_MAX_QUEUE; i++) {
+		tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
+
 	/* the last tag is reserved for internal command. */
-	for (i = 0; i < ATA_MAX_QUEUE - 1; i++)
-		if (!test_and_set_bit(i, &ap->qc_allocated)) {
-			qc = __ata_qc_from_tag(ap, i);
+		if (tag == ATA_TAG_INTERNAL)
+			continue;
+
+		if (!test_and_set_bit(tag, &ap->qc_allocated)) {
+			qc = __ata_qc_from_tag(ap, tag);
+			qc->tag = tag;
+			ap->last_tag = tag;
 			break;
 		}
-
-	if (qc)
-		qc->tag = i;
+	}
 
 	return qc;
 }
@@ -6265,6 +6304,8 @@
 static void ata_port_detach(struct ata_port *ap)
 {
 	unsigned long flags;
+	struct ata_link *link;
+	struct ata_device *dev;
 
 	if (!ap->ops->error_handler)
 		goto skip_eh;
@@ -6284,6 +6325,13 @@
 	cancel_delayed_work_sync(&ap->hotplug_task);
 
  skip_eh:
+	/* clean up zpodd on port removal */
+	ata_for_each_link(link, ap, HOST_FIRST) {
+		ata_for_each_dev(dev, link, ALL) {
+			if (zpodd_dev_enabled(dev))
+				zpodd_exit(dev);
+		}
+	}
 	if (ap->pmp_link) {
 		int i;
 		for (i = 0; i < SATA_PMP_MAX_PORTS; i++)
@@ -6505,6 +6553,7 @@
 		{ "norst",	.lflags		= ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
 		{ "rstonce",	.lflags		= ATA_LFLAG_RST_ONCE },
 		{ "atapi_dmadir", .horkage_on	= ATA_HORKAGE_ATAPI_DMADIR },
+		{ "disable",	.horkage_on	= ATA_HORKAGE_DISABLE },
 	};
 	char *start = *cur, *p = *cur;
 	char *id, *val, *endp;
diff -ruw linux-3.11.10/drivers/ata/libata-pmp.c linux-3.11.10-fbx/drivers/ata/libata-pmp.c
--- linux-3.11.10/drivers/ata/libata-pmp.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/ata/libata-pmp.c	2014-07-01 16:22:13.026329050 +0200
@@ -447,8 +447,11 @@
 		 * otherwise.  Don't try hard to recover it.
 		 */
 		ap->pmp_link[ap->nr_pmp_links - 1].flags |= ATA_LFLAG_NO_RETRY;
-	} else if (vendor == 0x197b && devid == 0x2352) {
-		/* chip found in Thermaltake BlackX Duet, jmicron JMB350? */
+	} else if (vendor == 0x197b && (devid == 0x2352 || devid == 0x0325)) {
+		/*
+		 * 0x2352: found in Thermaltake BlackX Duet, jmicron JMB350?
+		 * 0x0325: jmicron JMB394.
+		 */
 		ata_for_each_link(link, ap, EDGE) {
 			/* SRST breaks detection and disks get misclassified
 			 * LPM disabled to avoid potential problems
diff -ruw linux-3.11.10/drivers/ata/libata-scsi.c linux-3.11.10-fbx/drivers/ata/libata-scsi.c
--- linux-3.11.10/drivers/ata/libata-scsi.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/ata/libata-scsi.c	2014-05-09 14:12:52.820546136 +0200
@@ -112,12 +112,14 @@
 	[ATA_LPM_MIN_POWER]	= "min_power",
 };
 
-static ssize_t ata_scsi_lpm_store(struct device *dev,
+static ssize_t ata_scsi_lpm_store(struct device *device,
 				  struct device_attribute *attr,
 				  const char *buf, size_t count)
 {
-	struct Scsi_Host *shost = class_to_shost(dev);
+	struct Scsi_Host *shost = class_to_shost(device);
 	struct ata_port *ap = ata_shost_to_port(shost);
+	struct ata_link *link;
+	struct ata_device *dev;
 	enum ata_lpm_policy policy;
 	unsigned long flags;
 
@@ -133,10 +135,20 @@
 		return -EINVAL;
 
 	spin_lock_irqsave(ap->lock, flags);
+
+	ata_for_each_link(link, ap, EDGE) {
+		ata_for_each_dev(dev, &ap->link, ENABLED) {
+			if (dev->horkage & ATA_HORKAGE_NOLPM) {
+				count = -EOPNOTSUPP;
+				goto out_unlock;
+			}
+		}
+	}
+
 	ap->target_lpm_policy = policy;
 	ata_port_schedule_eh(ap);
+out_unlock:
 	spin_unlock_irqrestore(ap->lock, flags);
-
 	return count;
 }
 
@@ -3613,6 +3625,7 @@
 		shost->max_lun = 1;
 		shost->max_channel = 1;
 		shost->max_cmd_len = 16;
+		shost->no_write_same = 1;
 
 		/* Schedule policy is determined by ->qc_defer()
 		 * callback and it needs to see every deferred qc.
@@ -3622,7 +3635,7 @@
 		shost->max_host_blocked = 1;
 
 		rc = scsi_add_host_with_dma(ap->scsi_host,
-						&ap->tdev, ap->host->dev);
+					    host->dev, host->dev);
 		if (rc)
 			goto err_add;
 	}
@@ -3862,6 +3875,27 @@
 		return;
 	}
 
+	/*
+	 * XXX - UGLY HACK
+	 *
+	 * The block layer suspend/resume path is fundamentally broken due
+	 * to freezable kthreads and workqueue and may deadlock if a block
+	 * device gets removed while resume is in progress.  I don't know
+	 * what the solution is short of removing freezable kthreads and
+	 * workqueues altogether.
+	 *
+	 * The following is an ugly hack to avoid kicking off device
+	 * removal while freezer is active.  This is a joke but does avoid
+	 * this particular deadlock scenario.
+	 *
+	 * https://bugzilla.kernel.org/show_bug.cgi?id=62801
+	 * http://marc.info/?l=linux-kernel&m=138695698516487
+	 */
+#ifdef CONFIG_FREEZER
+	while (pm_freezing)
+		msleep(10);
+#endif
+
 	DPRINTK("ENTER\n");
 	mutex_lock(&ap->scsi_scan_mutex);
 
diff -ruw linux-3.11.10/drivers/ata/libata-transport.c linux-3.11.10-fbx/drivers/ata/libata-transport.c
--- linux-3.11.10/drivers/ata/libata-transport.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/ata/libata-transport.c	2014-01-17 19:14:18.586220806 +0100
@@ -320,25 +320,25 @@
 /*
  * ATA link attributes
  */
+static int noop(int x) { return x; }
 
-
-#define ata_link_show_linkspeed(field)					\
+#define ata_link_show_linkspeed(field, format)			        \
 static ssize_t								\
 show_ata_link_##field(struct device *dev,				\
 		      struct device_attribute *attr, char *buf)		\
 {									\
 	struct ata_link *link = transport_class_to_link(dev);		\
 									\
-	return sprintf(buf,"%s\n", sata_spd_string(fls(link->field)));	\
+	return sprintf(buf, "%s\n", sata_spd_string(format(link->field))); \
 }
 
-#define ata_link_linkspeed_attr(field)					\
-	ata_link_show_linkspeed(field)					\
+#define ata_link_linkspeed_attr(field, format)				\
+	ata_link_show_linkspeed(field, format)				\
 static DEVICE_ATTR(field, S_IRUGO, show_ata_link_##field, NULL)
 
-ata_link_linkspeed_attr(hw_sata_spd_limit);
-ata_link_linkspeed_attr(sata_spd_limit);
-ata_link_linkspeed_attr(sata_spd);
+ata_link_linkspeed_attr(hw_sata_spd_limit, fls);
+ata_link_linkspeed_attr(sata_spd_limit, fls);
+ata_link_linkspeed_attr(sata_spd, noop);
 
 
 static DECLARE_TRANSPORT_CLASS(ata_link_class,
diff -ruw linux-3.11.10/drivers/base/dd.c linux-3.11.10-fbx/drivers/base/dd.c
--- linux-3.11.10/drivers/base/dd.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/base/dd.c	2014-07-01 16:22:13.026329050 +0200
@@ -52,6 +52,7 @@
 static LIST_HEAD(deferred_probe_pending_list);
 static LIST_HEAD(deferred_probe_active_list);
 static struct workqueue_struct *deferred_wq;
+static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
 
 /**
  * deferred_probe_work_func() - Retry probing devices in the active list.
@@ -135,6 +136,17 @@
  * This functions moves all devices from the pending list to the active
  * list and schedules the deferred probe workqueue to process them.  It
  * should be called anytime a driver is successfully bound to a device.
+ *
+ * Note, there is a race condition in multi-threaded probe. In the case where
+ * more than one device is probing at the same time, it is possible for one
+ * probe to complete successfully while another is about to defer. If the second
+ * depends on the first, then it will get put on the pending list after the
+ * trigger event has already occured and will be stuck there.
+ *
+ * The atomic 'deferred_trigger_count' is used to determine if a successful
+ * trigger has occurred in the midst of probing a driver. If the trigger count
+ * changes in the midst of a probe, then deferred processing should be triggered
+ * again.
  */
 static void driver_deferred_probe_trigger(void)
 {
@@ -147,6 +159,7 @@
 	 * into the active list so they can be retried by the workqueue
 	 */
 	mutex_lock(&deferred_probe_mutex);
+	atomic_inc(&deferred_trigger_count);
 	list_splice_tail_init(&deferred_probe_pending_list,
 			      &deferred_probe_active_list);
 	mutex_unlock(&deferred_probe_mutex);
@@ -265,6 +278,7 @@
 static int really_probe(struct device *dev, struct device_driver *drv)
 {
 	int ret = 0;
+	int local_trigger_count = atomic_read(&deferred_trigger_count);
 
 	atomic_inc(&probe_count);
 	pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
@@ -310,6 +324,9 @@
 		/* Driver requested deferred probing */
 		dev_info(dev, "Driver %s requests probe deferral\n", drv->name);
 		driver_deferred_probe_add(dev);
+		/* Did a trigger occur while probing? Need to re-trigger if yes */
+		if (local_trigger_count != atomic_read(&deferred_trigger_count))
+			driver_deferred_probe_trigger();
 	} else if (ret != -ENODEV && ret != -ENXIO) {
 		/* driver matched but the probe failed */
 		printk(KERN_WARNING
@@ -499,7 +516,7 @@
 						     BUS_NOTIFY_UNBIND_DRIVER,
 						     dev);
 
-		pm_runtime_put(dev);
+		pm_runtime_put_sync(dev);
 
 		if (dev->bus && dev->bus->remove)
 			dev->bus->remove(dev);
diff -ruw linux-3.11.10/drivers/base/firmware_class.c linux-3.11.10-fbx/drivers/base/firmware_class.c
--- linux-3.11.10/drivers/base/firmware_class.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/base/firmware_class.c	2014-07-01 16:22:13.026329050 +0200
@@ -258,7 +258,8 @@
 	"/lib/firmware/updates/" UTS_RELEASE,
 	"/lib/firmware/updates",
 	"/lib/firmware/" UTS_RELEASE,
-	"/lib/firmware"
+	"/lib/firmware",
+	"/usr/lib/hotplug/firmware"
 };
 
 /*
@@ -1532,6 +1533,7 @@
 	switch (mode) {
 	case PM_HIBERNATION_PREPARE:
 	case PM_SUSPEND_PREPARE:
+	case PM_RESTORE_PREPARE:
 		kill_requests_without_uevent();
 		device_cache_fw_images();
 		break;
diff -ruw linux-3.11.10/drivers/base/topology.c linux-3.11.10-fbx/drivers/base/topology.c
--- linux-3.11.10/drivers/base/topology.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/base/topology.c	2014-07-01 16:22:13.026329050 +0200
@@ -40,8 +40,7 @@
 static ssize_t show_##name(struct device *dev,			\
 		struct device_attribute *attr, char *buf)	\
 {								\
-	unsigned int cpu = dev->id;				\
-	return sprintf(buf, "%d\n", topology_##name(cpu));	\
+	return sprintf(buf, "%d\n", topology_##name(dev->id));	\
 }
 
 #if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \
diff -ruw linux-3.11.10/drivers/block/loop.c linux-3.11.10-fbx/drivers/block/loop.c
--- linux-3.11.10/drivers/block/loop.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/block/loop.c	2014-01-17 19:14:18.586220806 +0100
@@ -894,13 +894,6 @@
 
 	bio_list_init(&lo->lo_bio_list);
 
-	/*
-	 * set queue make_request_fn, and add limits based on lower level
-	 * device
-	 */
-	blk_queue_make_request(lo->lo_queue, loop_make_request);
-	lo->lo_queue->queuedata = lo;
-
 	if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)
 		blk_queue_flush(lo->lo_queue, REQ_FLUSH);
 
@@ -1618,6 +1611,8 @@
 	if (!lo)
 		goto out;
 
+	lo->lo_state = Lo_unbound;
+
 	/* allocate id, if @id >= 0, we're requesting that specific id */
 	if (i >= 0) {
 		err = idr_alloc(&loop_index_idr, lo, i, i + 1, GFP_KERNEL);
@@ -1633,7 +1628,13 @@
 	err = -ENOMEM;
 	lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
 	if (!lo->lo_queue)
-		goto out_free_dev;
+		goto out_free_idr;
+
+	/*
+	 * set queue make_request_fn
+	 */
+	blk_queue_make_request(lo->lo_queue, loop_make_request);
+	lo->lo_queue->queuedata = lo;
 
 	disk = lo->lo_disk = alloc_disk(1 << part_shift);
 	if (!disk)
@@ -1678,6 +1679,8 @@
 
 out_free_queue:
 	blk_cleanup_queue(lo->lo_queue);
+out_free_idr:
+	idr_remove(&loop_index_idr, i);
 out_free_dev:
 	kfree(lo);
 out:
@@ -1741,7 +1744,7 @@
 	if (err < 0)
 		err = loop_add(&lo, MINOR(dev) >> part_shift);
 	if (err < 0)
-		kobj = ERR_PTR(err);
+		kobj = NULL;
 	else
 		kobj = get_disk(lo->lo_disk);
 	mutex_unlock(&loop_index_mutex);
diff -ruw linux-3.11.10/drivers/bluetooth/ath3k.c linux-3.11.10-fbx/drivers/bluetooth/ath3k.c
--- linux-3.11.10/drivers/bluetooth/ath3k.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/bluetooth/ath3k.c	2014-07-01 16:22:13.030329072 +0200
@@ -82,6 +82,7 @@
 	{ USB_DEVICE(0x04CA, 0x3004) },
 	{ USB_DEVICE(0x04CA, 0x3005) },
 	{ USB_DEVICE(0x04CA, 0x3006) },
+	{ USB_DEVICE(0x04CA, 0x3007) },
 	{ USB_DEVICE(0x04CA, 0x3008) },
 	{ USB_DEVICE(0x13d3, 0x3362) },
 	{ USB_DEVICE(0x0CF3, 0xE004) },
@@ -124,6 +125,7 @@
 	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
diff -ruw linux-3.11.10/drivers/bluetooth/btusb.c linux-3.11.10-fbx/drivers/bluetooth/btusb.c
--- linux-3.11.10/drivers/bluetooth/btusb.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/bluetooth/btusb.c	2014-07-01 16:22:13.030329072 +0200
@@ -146,6 +146,7 @@
 	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
@@ -220,6 +221,7 @@
 
 	/* Intel Bluetooth device */
 	{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
+	{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
 
 	{ }	/* Terminating entry */
 };
diff -ruw linux-3.11.10/drivers/char/Kconfig linux-3.11.10-fbx/drivers/char/Kconfig
--- linux-3.11.10/drivers/char/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/char/Kconfig	2013-12-04 14:33:18.807478971 +0100
@@ -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 SGI_SNSC
 	bool "SGI Altix system controller communication support"
 	depends on (IA64_SGI_SN2 || IA64_GENERIC)
diff -ruw linux-3.11.10/drivers/char/mem.c linux-3.11.10-fbx/drivers/char/mem.c
--- linux-3.11.10/drivers/char/mem.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/char/mem.c	2013-12-04 14:33:18.823478971 +0100
@@ -356,6 +356,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_DEVKMEM
 /*
  * This function reads the *virtual* memory as seen by the kernel.
@@ -730,6 +740,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
@@ -801,6 +818,14 @@
 	.write		= write_full,
 };
 
+#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 const struct memdev {
 	const char *name;
 	umode_t mode;
@@ -822,6 +847,9 @@
 #ifdef CONFIG_PRINTK
 	[11] = { "kmsg", 0644, &kmsg_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.11.10/drivers/cpufreq/Makefile linux-3.11.10-fbx/drivers/cpufreq/Makefile
--- linux-3.11.10/drivers/cpufreq/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/cpufreq/Makefile	2014-08-22 15:47:22.080062869 +0200
@@ -50,7 +50,7 @@
 # LITTLE drivers, so that it is probed last.
 obj-$(CONFIG_ARM_DT_BL_CPUFREQ)		+= arm_big_little_dt.o
 
-obj-$(CONFIG_ARCH_DAVINCI_DA850)	+= davinci-cpufreq.o
+obj-$(CONFIG_ARCH_DAVINCI)		+= davinci-cpufreq.o
 obj-$(CONFIG_UX500_SOC_DB8500)		+= dbx500-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS_CPUFREQ)	+= exynos-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ)	+= exynos4210-cpufreq.o
diff -ruw linux-3.11.10/drivers/cpuidle/cpuidle.c linux-3.11.10-fbx/drivers/cpuidle/cpuidle.c
--- linux-3.11.10/drivers/cpuidle/cpuidle.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/cpuidle/cpuidle.c	2014-01-17 19:14:18.590220806 +0100
@@ -434,7 +434,7 @@
 {
 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
 
-	if (dev->registered == 0)
+	if (!dev || dev->registered == 0)
 		return;
 
 	cpuidle_pause_and_lock();
diff -ruw linux-3.11.10/drivers/cpuidle/driver.c linux-3.11.10-fbx/drivers/cpuidle/driver.c
--- linux-3.11.10/drivers/cpuidle/driver.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/cpuidle/driver.c	2014-07-01 16:22:13.034329100 +0200
@@ -331,6 +331,7 @@
 	spin_lock(&cpuidle_driver_lock);
 
 	drv = cpuidle_get_driver();
+	if (drv)
 	drv->refcnt++;
 
 	spin_unlock(&cpuidle_driver_lock);
diff -ruw linux-3.11.10/drivers/dma/Kconfig linux-3.11.10-fbx/drivers/dma/Kconfig
--- linux-3.11.10/drivers/dma/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/dma/Kconfig	2014-01-17 19:14:18.590220806 +0100
@@ -321,6 +321,7 @@
 	bool "Network: TCP receive copy offload"
 	depends on DMA_ENGINE && NET
 	default (INTEL_IOATDMA || FSL_DMA)
+	depends on BROKEN
 	help
 	  This enables the use of DMA engines in the network stack to
 	  offload receive copy-to-user operations, freeing CPU cycles.
diff -ruw linux-3.11.10/drivers/gpu/drm/i915/i915_reg.h linux-3.11.10-fbx/drivers/gpu/drm/i915/i915_reg.h
--- linux-3.11.10/drivers/gpu/drm/i915/i915_reg.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/gpu/drm/i915/i915_reg.h	2014-05-09 14:12:52.864546136 +0200
@@ -1865,9 +1865,13 @@
  * Please check the detailed lore in the commit message for for experimental
  * evidence.
  */
-#define   PORTD_HOTPLUG_LIVE_STATUS               (1 << 29)
-#define   PORTC_HOTPLUG_LIVE_STATUS               (1 << 28)
-#define   PORTB_HOTPLUG_LIVE_STATUS               (1 << 27)
+#define   PORTD_HOTPLUG_LIVE_STATUS_G4X		(1 << 29)
+#define   PORTC_HOTPLUG_LIVE_STATUS_G4X		(1 << 28)
+#define   PORTB_HOTPLUG_LIVE_STATUS_G4X		(1 << 27)
+/* VLV DP/HDMI bits again match Bspec */
+#define   PORTD_HOTPLUG_LIVE_STATUS_VLV		(1 << 27)
+#define   PORTC_HOTPLUG_LIVE_STATUS_VLV		(1 << 28)
+#define   PORTB_HOTPLUG_LIVE_STATUS_VLV		(1 << 29)
 #define   PORTD_HOTPLUG_INT_STATUS		(3 << 21)
 #define   PORTC_HOTPLUG_INT_STATUS		(3 << 19)
 #define   PORTB_HOTPLUG_INT_STATUS		(3 << 17)
diff -ruw linux-3.11.10/drivers/gpu/drm/shmobile/Kconfig linux-3.11.10-fbx/drivers/gpu/drm/shmobile/Kconfig
--- linux-3.11.10/drivers/gpu/drm/shmobile/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/gpu/drm/shmobile/Kconfig	2014-01-17 19:14:18.610220807 +0100
@@ -1,6 +1,7 @@
 config DRM_SHMOBILE
 	tristate "DRM Support for SH Mobile"
 	depends on DRM && (ARM || SUPERH)
+	select BACKLIGHT_CLASS_DEVICE
 	select DRM_KMS_HELPER
 	select DRM_KMS_CMA_HELPER
 	select DRM_GEM_CMA_HELPER
diff -ruw linux-3.11.10/drivers/hid/hid-apple.c linux-3.11.10-fbx/drivers/hid/hid-apple.c
--- linux-3.11.10/drivers/hid/hid-apple.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hid/hid-apple.c	2014-01-17 19:14:18.610220807 +0100
@@ -46,6 +46,12 @@
 MODULE_PARM_DESC(iso_layout, "Enable/Disable hardcoded ISO-layout of the keyboard. "
 		"(0 = disabled, [1] = enabled)");
 
+static unsigned int swap_opt_cmd = 0;
+module_param(swap_opt_cmd, uint, 0644);
+MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") keys. "
+		"(For people who want to keep Windows PC keyboard muscle memory. "
+		"[0] = as-is, Mac layout. 1 = swapped, Windows layout.)");
+
 struct apple_sc {
 	unsigned long quirks;
 	unsigned int fn_on;
@@ -150,6 +156,14 @@
 	{ }
 };
 
+static const struct apple_key_translation swapped_option_cmd_keys[] = {
+	{ KEY_LEFTALT,	KEY_LEFTMETA },
+	{ KEY_LEFTMETA,	KEY_LEFTALT },
+	{ KEY_RIGHTALT,	KEY_RIGHTMETA },
+	{ KEY_RIGHTMETA,KEY_RIGHTALT },
+	{ }
+};
+
 static const struct apple_key_translation *apple_find_translation(
 		const struct apple_key_translation *table, u16 from)
 {
@@ -242,6 +256,14 @@
 		}
 	}
 
+	if (swap_opt_cmd) {
+		trans = apple_find_translation(swapped_option_cmd_keys, usage->code);
+		if (trans) {
+			input_event(input, usage->type, trans->to, value);
+			return 1;
+		}
+	}
+
 	return 0;
 }
 
diff -ruw linux-3.11.10/drivers/hid/hid-core.c linux-3.11.10-fbx/drivers/hid/hid-core.c
--- linux-3.11.10/drivers/hid/hid-core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hid/hid-core.c	2014-12-10 16:03:44.162385155 +0100
@@ -796,7 +796,17 @@
 	 * ->numbered being checked, which may not always be the case when
 	 * drivers go to access report values.
 	 */
+	if (id == 0) {
+		/*
+		 * Validating on id 0 means we should examine the first
+		 * report in the list.
+		 */
+		report = list_entry(
+				hid->report_enum[type].report_list.next,
+				struct hid_report, list);
+	} else {
 	report = hid->report_enum[type].report_id_hash[id];
+	}
 	if (!report) {
 		hid_err(hid, "missing %s %u\n", hid_report_names[type], id);
 		return NULL;
@@ -1562,6 +1572,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0xf705) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
@@ -1673,6 +1684,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
@@ -1680,6 +1692,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_MANTICORE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GX_IMPERATOR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
@@ -1711,6 +1724,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
@@ -1758,12 +1772,14 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
 #if IS_ENABLED(CONFIG_HID_ROCCAT)
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKUFX) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE_OPTICAL) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEXTD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
@@ -1773,6 +1789,8 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS2_TOUCH, USB_DEVICE_ID_SIS9200_TOUCH) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS2_TOUCH, USB_DEVICE_ID_SIS817_TOUCH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
@@ -1829,6 +1847,7 @@
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO2, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
+	{ HID_BLUETOOTH_DEVICE(0x10eb, 0x0023) },
 	{ }
 };
 
@@ -2330,15 +2349,6 @@
 				hdev->type == HID_TYPE_USBNONE)
 			return true;
 		break;
-	case USB_VENDOR_ID_DWAV:
-		/* These are handled by usbtouchscreen. hdev->type is probably
-		 * HID_TYPE_USBNONE, but we say !HID_TYPE_USBMOUSE to match
-		 * usbtouchscreen. */
-		if ((hdev->product == USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER ||
-		     hdev->product == USB_DEVICE_ID_DWAV_TOUCHCONTROLLER) &&
-		    hdev->type != HID_TYPE_USBMOUSE)
-			return true;
-		break;
 	case USB_VENDOR_ID_VELLEMAN:
 		/* These are not HID devices.  They are handled by comedi. */
 		if ((hdev->product >= USB_DEVICE_ID_VELLEMAN_K8055_FIRST &&
diff -ruw linux-3.11.10/drivers/hid/hid-dr.c linux-3.11.10-fbx/drivers/hid/hid-dr.c
--- linux-3.11.10/drivers/hid/hid-dr.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hid/hid-dr.c	2013-12-04 14:33:19.091478975 +0100
@@ -234,6 +234,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)
 {
@@ -244,6 +313,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;
 }
@@ -268,6 +343,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.11.10/drivers/hid/hid-ids.h linux-3.11.10-fbx/drivers/hid/hid-ids.h
--- linux-3.11.10/drivers/hid/hid-ids.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hid/hid-ids.h	2014-07-01 16:22:13.062329230 +0200
@@ -332,6 +332,11 @@
 #define USB_VENDOR_ID_GENERAL_TOUCH	0x0dfc
 #define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003
 #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS 0x0100
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0101 0x0101
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0102 0x0102
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0106 0x0106
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
 
 #define USB_VENDOR_ID_GLAB		0x06c2
 #define USB_DEVICE_ID_4_PHIDGETSERVO_30	0x0038
@@ -448,8 +453,9 @@
 
 #define USB_VENDOR_ID_HOLTEK_ALT		0x04d9
 #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD	0xa055
-#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067	0xa067
 #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A	0xa04a
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067	0xa067
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072	0xa072
 #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081	0xa081
 
 #define USB_VENDOR_ID_IMATION		0x0718
@@ -483,6 +489,7 @@
 #define USB_VENDOR_ID_KYE		0x0458
 #define USB_DEVICE_ID_KYE_ERGO_525V	0x0087
 #define USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE	0x0138
+#define USB_DEVICE_ID_GENIUS_MANTICORE	0x0153
 #define USB_DEVICE_ID_GENIUS_GX_IMPERATOR	0x4018
 #define USB_DEVICE_ID_KYE_GPEN_560	0x5003
 #define USB_DEVICE_ID_KYE_EASYPEN_I405X	0x5010
@@ -571,6 +578,7 @@
 #define USB_DEVICE_ID_DINOVO_EDGE	0xc714
 #define USB_DEVICE_ID_DINOVO_MINI	0xc71f
 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2	0xca03
+#define USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL	0xca04
 
 #define USB_VENDOR_ID_LUMIO		0x202e
 #define USB_DEVICE_ID_CRYSTALTOUCH	0x0006
@@ -745,6 +753,10 @@
 #define USB_VENDOR_ID_SIGMATEL		0x066F
 #define USB_DEVICE_ID_SIGMATEL_STMP3780	0x3780
 
+#define USB_VENDOR_ID_SIS2_TOUCH	0x0457
+#define USB_DEVICE_ID_SIS9200_TOUCH	0x9200
+#define USB_DEVICE_ID_SIS817_TOUCH	0x0817
+
 #define USB_VENDOR_ID_SKYCABLE			0x1223
 #define	USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER	0x3F07
 
@@ -793,6 +805,11 @@
 #define USB_DEVICE_ID_SYNAPTICS_COMP_TP	0x0009
 #define USB_DEVICE_ID_SYNAPTICS_WTP	0x0010
 #define USB_DEVICE_ID_SYNAPTICS_DPAD	0x0013
+#define USB_DEVICE_ID_SYNAPTICS_LTS1	0x0af8
+#define USB_DEVICE_ID_SYNAPTICS_LTS2	0x1d10
+#define USB_DEVICE_ID_SYNAPTICS_HD	0x0ac3
+#define USB_DEVICE_ID_SYNAPTICS_QUAD_HD	0x1ac3
+#define USB_DEVICE_ID_SYNAPTICS_TP_V103	0x5710
 
 #define USB_VENDOR_ID_THINGM		0x27b8
 #define USB_DEVICE_ID_BLINK1		0x01ed
@@ -886,6 +903,9 @@
 #define USB_DEVICE_ID_SUPER_DUAL_BOX_PRO 0x8802
 #define USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO 0x8804
 
+#define USB_VENDOR_ID_WISTRON		0x0fb8
+#define USB_DEVICE_ID_WISTRON_OPTICAL_TOUCH		0x1109
+
 #define USB_VENDOR_ID_X_TENSIONS               0x1ae7
 #define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE    0x9001
 
@@ -917,4 +937,7 @@
 #define USB_VENDOR_ID_PRIMAX	0x0461
 #define USB_DEVICE_ID_PRIMAX_KEYBOARD	0x4e05
 
+#define USB_VENDOR_ID_SIS	0x0457
+#define USB_DEVICE_ID_SIS_TS	0x1013
+
 #endif
diff -ruw linux-3.11.10/drivers/hid/hid-kye.c linux-3.11.10-fbx/drivers/hid/hid-kye.c
--- linux-3.11.10/drivers/hid/hid-kye.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hid/hid-kye.c	2014-01-17 19:14:18.614220807 +0100
@@ -342,6 +342,10 @@
 		rdesc = kye_consumer_control_fixup(hdev, rdesc, rsize, 83,
 					"Genius Gx Imperator Keyboard");
 		break;
+	case USB_DEVICE_ID_GENIUS_MANTICORE:
+		rdesc = kye_consumer_control_fixup(hdev, rdesc, rsize, 104,
+					"Genius Manticore Keyboard");
+		break;
 	}
 	return rdesc;
 }
@@ -439,6 +443,8 @@
 				USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
 				USB_DEVICE_ID_GENIUS_GX_IMPERATOR) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
+				USB_DEVICE_ID_GENIUS_MANTICORE) },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, kye_devices);
diff -ruw linux-3.11.10/drivers/hid/hid-lg.c linux-3.11.10-fbx/drivers/hid/hid-lg.c
--- linux-3.11.10/drivers/hid/hid-lg.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hid/hid-lg.c	2014-01-17 19:14:18.614220807 +0100
@@ -45,7 +45,9 @@
 /* Size of the original descriptors of the Driving Force (and Pro) wheels */
 #define DF_RDESC_ORIG_SIZE	130
 #define DFP_RDESC_ORIG_SIZE	97
+#define FV_RDESC_ORIG_SIZE	130
 #define MOMO_RDESC_ORIG_SIZE	87
+#define MOMO2_RDESC_ORIG_SIZE	87
 
 /* Fixed report descriptors for Logitech Driving Force (and Pro)
  * wheel controllers
@@ -170,6 +172,73 @@
 0xC0                /*  End Collection                          */
 };
 
+static __u8 fv_rdesc_fixed[] = {
+0x05, 0x01,         /*  Usage Page (Desktop),                   */
+0x09, 0x04,         /*  Usage (Joystik),                        */
+0xA1, 0x01,         /*  Collection (Application),               */
+0xA1, 0x02,         /*      Collection (Logical),               */
+0x95, 0x01,         /*          Report Count (1),               */
+0x75, 0x0A,         /*          Report Size (10),               */
+0x15, 0x00,         /*          Logical Minimum (0),            */
+0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),         */
+0x35, 0x00,         /*          Physical Minimum (0),           */
+0x46, 0xFF, 0x03,   /*          Physical Maximum (1023),        */
+0x09, 0x30,         /*          Usage (X),                      */
+0x81, 0x02,         /*          Input (Variable),               */
+0x95, 0x0C,         /*          Report Count (12),              */
+0x75, 0x01,         /*          Report Size (1),                */
+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),               */
+0x95, 0x02,         /*          Report Count (2),               */
+0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),             */
+0x09, 0x01,         /*          Usage (01h),                    */
+0x81, 0x02,         /*          Input (Variable),               */
+0x09, 0x02,         /*          Usage (02h),                    */
+0x26, 0xFF, 0x00,   /*          Logical Maximum (255),          */
+0x46, 0xFF, 0x00,   /*          Physical Maximum (255),         */
+0x95, 0x01,         /*          Report Count (1),               */
+0x75, 0x08,         /*          Report Size (8),                */
+0x81, 0x02,         /*          Input (Variable),               */
+0x05, 0x01,         /*          Usage Page (Desktop),           */
+0x25, 0x07,         /*          Logical Maximum (7),            */
+0x46, 0x3B, 0x01,   /*          Physical Maximum (315),         */
+0x75, 0x04,         /*          Report Size (4),                */
+0x65, 0x14,         /*          Unit (Degrees),                 */
+0x09, 0x39,         /*          Usage (Hat Switch),             */
+0x81, 0x42,         /*          Input (Variable, Null State),   */
+0x75, 0x01,         /*          Report Size (1),                */
+0x95, 0x04,         /*          Report Count (4),               */
+0x65, 0x00,         /*          Unit,                           */
+0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),             */
+0x09, 0x01,         /*          Usage (01h),                    */
+0x25, 0x01,         /*          Logical Maximum (1),            */
+0x45, 0x01,         /*          Physical Maximum (1),           */
+0x81, 0x02,         /*          Input (Variable),               */
+0x05, 0x01,         /*          Usage Page (Desktop),           */
+0x95, 0x01,         /*          Report Count (1),               */
+0x75, 0x08,         /*          Report Size (8),                */
+0x26, 0xFF, 0x00,   /*          Logical Maximum (255),          */
+0x46, 0xFF, 0x00,   /*          Physical Maximum (255),         */
+0x09, 0x31,         /*          Usage (Y),                      */
+0x81, 0x02,         /*          Input (Variable),               */
+0x09, 0x32,         /*          Usage (Z),                      */
+0x81, 0x02,         /*          Input (Variable),               */
+0xC0,               /*      End Collection,                     */
+0xA1, 0x02,         /*      Collection (Logical),               */
+0x26, 0xFF, 0x00,   /*          Logical Maximum (255),          */
+0x46, 0xFF, 0x00,   /*          Physical Maximum (255),         */
+0x95, 0x07,         /*          Report Count (7),               */
+0x75, 0x08,         /*          Report Size (8),                */
+0x09, 0x03,         /*          Usage (03h),                    */
+0x91, 0x02,         /*          Output (Variable),              */
+0xC0,               /*      End Collection,                     */
+0xC0                /*  End Collection                          */
+};
+
 static __u8 momo_rdesc_fixed[] = {
 0x05, 0x01,         /*  Usage Page (Desktop),               */
 0x09, 0x04,         /*  Usage (Joystik),                    */
@@ -216,6 +285,54 @@
 0xC0                /*  End Collection                      */
 };
 
+static __u8 momo2_rdesc_fixed[] = {
+0x05, 0x01,         /*  Usage Page (Desktop),               */
+0x09, 0x04,         /*  Usage (Joystik),                    */
+0xA1, 0x01,         /*  Collection (Application),           */
+0xA1, 0x02,         /*      Collection (Logical),           */
+0x95, 0x01,         /*          Report Count (1),           */
+0x75, 0x0A,         /*          Report Size (10),           */
+0x15, 0x00,         /*          Logical Minimum (0),        */
+0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
+0x35, 0x00,         /*          Physical Minimum (0),       */
+0x46, 0xFF, 0x03,   /*          Physical Maximum (1023),    */
+0x09, 0x30,         /*          Usage (X),                  */
+0x81, 0x02,         /*          Input (Variable),           */
+0x95, 0x0A,         /*          Report Count (10),          */
+0x75, 0x01,         /*          Report Size (1),            */
+0x25, 0x01,         /*          Logical Maximum (1),        */
+0x45, 0x01,         /*          Physical Maximum (1),       */
+0x05, 0x09,         /*          Usage Page (Button),        */
+0x19, 0x01,         /*          Usage Minimum (01h),        */
+0x29, 0x0A,         /*          Usage Maximum (0Ah),        */
+0x81, 0x02,         /*          Input (Variable),           */
+0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
+0x09, 0x00,         /*          Usage (00h),                */
+0x95, 0x04,         /*          Report Count (4),           */
+0x81, 0x02,         /*          Input (Variable),           */
+0x95, 0x01,         /*          Report Count (1),           */
+0x75, 0x08,         /*          Report Size (8),            */
+0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
+0x46, 0xFF, 0x00,   /*          Physical Maximum (255),     */
+0x09, 0x01,         /*          Usage (01h),                */
+0x81, 0x02,         /*          Input (Variable),           */
+0x05, 0x01,         /*          Usage Page (Desktop),       */
+0x09, 0x31,         /*          Usage (Y),                  */
+0x81, 0x02,         /*          Input (Variable),           */
+0x09, 0x32,         /*          Usage (Z),                  */
+0x81, 0x02,         /*          Input (Variable),           */
+0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
+0x09, 0x00,         /*          Usage (00h),                */
+0x81, 0x02,         /*          Input (Variable),           */
+0xC0,               /*      End Collection,                 */
+0xA1, 0x02,         /*      Collection (Logical),           */
+0x09, 0x02,         /*          Usage (02h),                */
+0x95, 0x07,         /*          Report Count (7),           */
+0x91, 0x02,         /*          Output (Variable),          */
+0xC0,               /*      End Collection,                 */
+0xC0                /*  End Collection                      */
+};
+
 /*
  * Certain Logitech keyboards send in report #3 keys which are far
  * above the logical maximum described in descriptor. This extends
@@ -275,6 +392,24 @@
 		}
 		break;
 
+	case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2:
+		if (*rsize == MOMO2_RDESC_ORIG_SIZE) {
+			hid_info(hdev,
+				"fixing up Logitech Momo Racing Force (Black) report descriptor\n");
+			rdesc = momo2_rdesc_fixed;
+			*rsize = sizeof(momo2_rdesc_fixed);
+		}
+		break;
+
+	case USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL:
+		if (*rsize == FV_RDESC_ORIG_SIZE) {
+			hid_info(hdev,
+				"fixing up Logitech Formula Vibration report descriptor\n");
+			rdesc = fv_rdesc_fixed;
+			*rsize = sizeof(fv_rdesc_fixed);
+		}
+		break;
+
 	case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
 		if (*rsize == DFP_RDESC_ORIG_SIZE) {
 			hid_info(hdev,
@@ -492,6 +627,7 @@
 		case USB_DEVICE_ID_LOGITECH_G27_WHEEL:
 		case USB_DEVICE_ID_LOGITECH_WII_WHEEL:
 		case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2:
+		case USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL:
 			field->application = HID_GD_MULTIAXIS;
 			break;
 		default:
@@ -639,6 +775,8 @@
 		.driver_data = LG_NOGET | LG_FF4 },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2),
 		.driver_data = LG_FF4 },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL),
+		.driver_data = LG_FF2 },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
 		.driver_data = LG_FF4 },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL),
diff -ruw linux-3.11.10/drivers/hid/Kconfig linux-3.11.10-fbx/drivers/hid/Kconfig
--- linux-3.11.10/drivers/hid/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hid/Kconfig	2014-12-10 16:03:44.162385155 +0100
@@ -242,6 +242,7 @@
 	  - Tracer Sniper TRM-503 / NOVA Gaming Slider X200 /
 	    Zalman ZM-GM1
 	  - SHARKOON DarkGlider Gaming mouse
+	  - LEETGION Hellion Gaming Mouse
 
 config HOLTEK_FF
 	bool "Holtek On Line Grip force feedback support"
@@ -287,6 +288,10 @@
 	---help---
 	Support for Waltop tablets.
 
+config HID_FBX_REMOTE_AUDIO
+	tristate "Freebox BLE remote audio driver"
+	depends on HID && SND_PCM
+
 config HID_GYRATION
 	tristate "Gyration remote control"
 	depends on HID
@@ -369,12 +374,14 @@
 	  force feedback.
 
 config LOGIRUMBLEPAD2_FF
-	bool "Logitech RumblePad/Rumblepad 2 force feedback support"
+	bool "Logitech force feedback support (variant 2)"
 	depends on HID_LOGITECH
 	select INPUT_FF_MEMLESS
 	help
-	  Say Y here if you want to enable force feedback support for Logitech
-	  RumblePad and Rumblepad 2 devices.
+	  Say Y here if you want to enable force feedback support for:
+	  - Logitech RumblePad
+	  - Logitech Rumblepad 2
+	  - Logitech Formula Vibration Feedback Wheel
 
 config LOGIG940_FF
 	bool "Logitech Flight System G940 force feedback support"
@@ -453,9 +460,11 @@
 	  - Pixcir dual touch panels
 	  - Quanta panels
 	  - eGalax dual-touch panels, including the Joojoo and Wetab tablets
+	  - SiS multitouch panels
 	  - Stantum multitouch panels
 	  - Touch International Panels
 	  - Unitec Panels
+	  - Wistron optical touch panels
 	  - XAT optical touch panels
 	  - Xiroku optical touch panels
 	  - Zytronic touch panels
diff -ruw linux-3.11.10/drivers/hid/Makefile linux-3.11.10-fbx/drivers/hid/Makefile
--- linux-3.11.10/drivers/hid/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hid/Makefile	2014-12-10 16:03:44.162385155 +0100
@@ -47,6 +47,7 @@
 obj-$(CONFIG_HID_ELECOM)	+= hid-elecom.o
 obj-$(CONFIG_HID_ELO)		+= hid-elo.o
 obj-$(CONFIG_HID_EZKEY)		+= hid-ezkey.o
+obj-$(CONFIG_HID_FBX_REMOTE_AUDIO)	+= hid-fbx-remote-audio.o
 obj-$(CONFIG_HID_GYRATION)	+= hid-gyration.o
 obj-$(CONFIG_HID_HOLTEK)	+= hid-holtek-kbd.o
 obj-$(CONFIG_HID_HOLTEK)	+= hid-holtek-mouse.o
diff -ruw linux-3.11.10/drivers/hid/uhid.c linux-3.11.10-fbx/drivers/hid/uhid.c
--- linux-3.11.10/drivers/hid/uhid.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hid/uhid.c	2014-01-17 19:14:18.614220807 +0100
@@ -312,7 +312,7 @@
 			 */
 			struct uhid_create_req_compat *compat;
 
-			compat = kmalloc(sizeof(*compat), GFP_KERNEL);
+			compat = kzalloc(sizeof(*compat), GFP_KERNEL);
 			if (!compat)
 				return -ENOMEM;
 
diff -ruw linux-3.11.10/drivers/hid/usbhid/hid-quirks.c linux-3.11.10-fbx/drivers/hid/usbhid/hid-quirks.c
--- linux-3.11.10/drivers/hid/usbhid/hid-quirks.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hid/usbhid/hid-quirks.c	2014-07-01 16:22:13.062329230 +0200
@@ -84,6 +84,8 @@
 	{ USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_SIS2_TOUCH, USB_DEVICE_ID_SIS9200_TOUCH, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_SIS2_TOUCH, USB_DEVICE_ID_SIS817_TOUCH, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET },
@@ -110,6 +112,12 @@
 	{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
+	{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS1, HID_QUIRK_NO_INIT_REPORTS },
+	{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2, HID_QUIRK_NO_INIT_REPORTS },
+	{ USB_VENDOR_ID_SIS, USB_DEVICE_ID_SIS_TS, HID_QUIRK_NO_INIT_REPORTS },
+	{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS },
+	{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD, HID_QUIRK_NO_INIT_REPORTS },
+	{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103, HID_QUIRK_NO_INIT_REPORTS },
 
 	{ 0, 0 }
 };
diff -ruw linux-3.11.10/drivers/hwmon/adt7475.c linux-3.11.10-fbx/drivers/hwmon/adt7475.c
--- linux-3.11.10/drivers/hwmon/adt7475.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hwmon/adt7475.c	2013-12-04 14:33:19.111478976 +0100
@@ -124,7 +124,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 */
 
@@ -278,6 +290,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);
 
@@ -846,7 +861,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.11.10/drivers/hwmon/coretemp.c linux-3.11.10-fbx/drivers/hwmon/coretemp.c
--- linux-3.11.10/drivers/hwmon/coretemp.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hwmon/coretemp.c	2014-05-09 14:12:52.900546137 +0200
@@ -52,7 +52,7 @@
 
 #define BASE_SYSFS_ATTR_NO	2	/* Sysfs Base attr no for coretemp */
 #define NUM_REAL_CORES		32	/* Number of Real cores per cpu */
-#define CORETEMP_NAME_LENGTH	17	/* String Length of attrs */
+#define CORETEMP_NAME_LENGTH	19	/* String Length of attrs */
 #define MAX_CORE_ATTRS		4	/* Maximum no of basic attrs */
 #define TOTAL_ATTRS		(MAX_CORE_ATTRS + 1)
 #define MAX_CORE_DATA		(NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
diff -ruw linux-3.11.10/drivers/hwmon/Kconfig linux-3.11.10-fbx/drivers/hwmon/Kconfig
--- linux-3.11.10/drivers/hwmon/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hwmon/Kconfig	2014-07-01 16:22:13.062329230 +0200
@@ -959,7 +959,7 @@
 
 config SENSORS_NTC_THERMISTOR
 	tristate "NTC thermistor support"
-	depends on (!OF && !IIO) || (OF && IIO)
+	depends on !OF || IIO=n || IIO
 	help
 	  This driver supports NTC thermistors sensor reading and its
 	  interpretation. The driver can also monitor the temperature and
@@ -1543,6 +1543,10 @@
         help
           Support for the A/D converter on MC13783 and MC13892 PMIC.
 
+config SENSORS_KIRKWOOD_CORETEMP
+	tristate "Kirkwood core temperature censor"
+	depends on ARCH_KIRKWOOD
+
 if ACPI
 
 comment "ACPI drivers"
diff -ruw linux-3.11.10/drivers/hwmon/lm85.c linux-3.11.10-fbx/drivers/hwmon/lm85.c
--- linux-3.11.10/drivers/hwmon/lm85.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hwmon/lm85.c	2013-12-04 14:33:19.119478976 +0100
@@ -207,11 +207,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)
@@ -219,7 +219,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;
@@ -227,7 +227,7 @@
 
 static int FREQ_FROM_REG(const int *map, u8 reg)
 {
-	return map[reg & 0x07];
+	return map[reg & 0x0f];
 }
 
 /*
@@ -1013,7 +1013,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;
@@ -1049,7 +1049,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;
 }
@@ -1240,8 +1240,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)) {
@@ -1667,7 +1687,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.11.10/drivers/hwmon/Makefile linux-3.11.10-fbx/drivers/hwmon/Makefile
--- linux-3.11.10/drivers/hwmon/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/hwmon/Makefile	2013-12-04 14:33:19.107478976 +0100
@@ -141,6 +141,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.11.10/drivers/i2c/busses/i2c-pxa.c linux-3.11.10-fbx/drivers/i2c/busses/i2c-pxa.c
--- linux-3.11.10/drivers/i2c/busses/i2c-pxa.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/i2c/busses/i2c-pxa.c	2014-05-09 14:12:52.904546137 +0200
@@ -793,6 +793,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);
diff -ruw linux-3.11.10/drivers/i2c/busses/i2c-pxa-pci.c linux-3.11.10-fbx/drivers/i2c/busses/i2c-pxa-pci.c
--- linux-3.11.10/drivers/i2c/busses/i2c-pxa-pci.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/i2c/busses/i2c-pxa-pci.c	2013-12-04 14:33:19.147478976 +0100
@@ -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.11.10/drivers/i2c/busses/Kconfig linux-3.11.10-fbx/drivers/i2c/busses/Kconfig
--- linux-3.11.10/drivers/i2c/busses/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/i2c/busses/Kconfig	2014-07-01 16:22:13.062329230 +0200
@@ -109,6 +109,8 @@
 	    Avoton (SOC)
 	    Wellsburg (PCH)
 	    Coleto Creek (PCH)
+	    Wildcat Point-LP (PCH)
+	    BayTrail (SOC)
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-i801.
@@ -375,7 +377,7 @@
 
 config I2C_CPM
 	tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
-	depends on (CPM1 || CPM2) && OF_I2C
+	depends on CPM1 || CPM2
 	help
 	  This supports the use of the I2C interface on Freescale
 	  processors with CPM1 or CPM2.
@@ -922,6 +924,10 @@
 	help
 	  Supports the SiByte SOC on-chip I2C interfaces (2 channels).
 
+config I2C_WP3
+	tristate "Wintegra WP3 I2C controll"
+	depends on WINTEGRA_WINPATH3
+
 config SCx200_I2C
 	tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)"
 	depends on SCx200_GPIO
diff -ruw linux-3.11.10/drivers/i2c/busses/Makefile linux-3.11.10-fbx/drivers/i2c/busses/Makefile
--- linux-3.11.10/drivers/i2c/busses/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/i2c/busses/Makefile	2013-12-04 14:33:19.139478976 +0100
@@ -76,6 +76,7 @@
 obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
 obj-$(CONFIG_I2C_XLR)		+= i2c-xlr.o
 obj-$(CONFIG_I2C_RCAR)		+= i2c-rcar.o
+obj-$(CONFIG_I2C_WP3)		+= i2c-wp3.o
 
 # External I2C/SMBus adapter drivers
 obj-$(CONFIG_I2C_DIOLAN_U2C)	+= i2c-diolan-u2c.o
diff -ruw linux-3.11.10/drivers/ide/Kconfig linux-3.11.10-fbx/drivers/ide/Kconfig
--- linux-3.11.10/drivers/ide/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/ide/Kconfig	2013-12-04 14:33:19.155478976 +0100
@@ -690,6 +690,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.11.10/drivers/ide/Makefile linux-3.11.10-fbx/drivers/ide/Makefile
--- linux-3.11.10/drivers/ide/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/ide/Makefile	2013-12-04 14:33:19.155478976 +0100
@@ -116,3 +116,4 @@
 
 obj-$(CONFIG_BLK_DEV_IDE_TX4938)	+= tx4938ide.o
 obj-$(CONFIG_BLK_DEV_IDE_TX4939)	+= tx4939ide.o
+obj-$(CONFIG_BLK_DEV_IDE_TANGO2)	+= tango2ide.o
diff -ruw linux-3.11.10/drivers/idle/intel_idle.c linux-3.11.10-fbx/drivers/idle/intel_idle.c
--- linux-3.11.10/drivers/idle/intel_idle.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/idle/intel_idle.c	2014-01-17 19:14:18.618220807 +0100
@@ -361,6 +361,9 @@
 
 	if (!current_set_polling_and_test()) {
 
+		if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR))
+			clflush((void *)&current_thread_info()->flags);
+
 		__monitor((void *)&current_thread_info()->flags, 0, 0);
 		smp_mb();
 		if (!need_resched())
diff -ruw linux-3.11.10/drivers/iio/gyro/Kconfig linux-3.11.10-fbx/drivers/iio/gyro/Kconfig
--- linux-3.11.10/drivers/iio/gyro/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/iio/gyro/Kconfig	2014-07-01 16:22:13.062329230 +0200
@@ -56,7 +56,7 @@
 	select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
 	help
 	  Say yes here to build support for STMicroelectronics gyroscopes:
-	  L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330.
+	  L3G4200D, LSM330DL, L3GD20, LSM330DLC, L3G4IS, LSM330.
 
 	  This driver can also be built as a module. If so, will be created
 	  these modules:
diff -ruw linux-3.11.10/drivers/input/evdev.c linux-3.11.10-fbx/drivers/input/evdev.c
--- linux-3.11.10/drivers/input/evdev.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/input/evdev.c	2014-01-17 19:14:18.622220807 +0100
@@ -18,6 +18,8 @@
 #include <linux/poll.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/input/mt.h>
@@ -365,6 +367,10 @@
 	mutex_unlock(&evdev->mutex);
 
 	evdev_detach_client(evdev, client);
+
+	if (is_vmalloc_addr(client))
+		vfree(client);
+	else
 	kfree(client);
 
 	evdev_close_device(evdev);
@@ -385,12 +391,14 @@
 {
 	struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev);
 	unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev);
+	unsigned int size = sizeof(struct evdev_client) +
+					bufsize * sizeof(struct input_event);
 	struct evdev_client *client;
 	int error;
 
-	client = kzalloc(sizeof(struct evdev_client) +
-				bufsize * sizeof(struct input_event),
-			 GFP_KERNEL);
+	client = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
+	if (!client)
+		client = vzalloc(size);
 	if (!client)
 		return -ENOMEM;
 
diff -ruw linux-3.11.10/drivers/input/input.c linux-3.11.10-fbx/drivers/input/input.c
--- linux-3.11.10/drivers/input/input.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/input/input.c	2014-01-17 19:14:18.622220807 +0100
@@ -1866,6 +1866,10 @@
 		break;
 
 	case EV_ABS:
+		input_alloc_absinfo(dev);
+		if (!dev->absinfo)
+			return;
+
 		__set_bit(code, dev->absbit);
 		break;
 
diff -ruw linux-3.11.10/drivers/input/Kconfig linux-3.11.10-fbx/drivers/input/Kconfig
--- linux-3.11.10/drivers/input/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/input/Kconfig	2014-01-17 19:14:18.622220807 +0100
@@ -80,7 +80,7 @@
 comment "Userland interfaces"
 
 config INPUT_MOUSEDEV
-	tristate "Mouse interface" if EXPERT
+	tristate "Mouse interface"
 	default y
 	help
 	  Say Y here if you want your mouse to be accessible as char devices
diff -ruw linux-3.11.10/drivers/input/keyboard/Kconfig linux-3.11.10-fbx/drivers/input/keyboard/Kconfig
--- linux-3.11.10/drivers/input/keyboard/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/input/keyboard/Kconfig	2014-01-17 19:14:18.622220807 +0100
@@ -2,7 +2,7 @@
 # Input core configuration
 #
 menuconfig INPUT_KEYBOARD
-	bool "Keyboards" if EXPERT || !X86
+	bool "Keyboards"
 	default y
 	help
 	  Say Y here, and a list of supported keyboards will be displayed.
@@ -67,7 +67,7 @@
 	  module will be called atakbd.
 
 config KEYBOARD_ATKBD
-	tristate "AT keyboard" if EXPERT || !X86
+	tristate "AT keyboard"
 	default y
 	select SERIO
 	select SERIO_LIBPS2
diff -ruw linux-3.11.10/drivers/input/misc/Kconfig linux-3.11.10-fbx/drivers/input/misc/Kconfig
--- linux-3.11.10/drivers/input/misc/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/input/misc/Kconfig	2013-12-04 14:33:19.259478978 +0100
@@ -647,4 +647,9 @@
 
 	  If unsure, say N.
 
+config INPUT_SMSC_CAP1066
+	tristate "SMSC CAP1066 capacitive sensor driver"
+	select I2C
+	select INPUT_POLLDEV
+
 endif
diff -ruw linux-3.11.10/drivers/input/misc/Makefile linux-3.11.10-fbx/drivers/input/misc/Makefile
--- linux-3.11.10/drivers/input/misc/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/input/misc/Makefile	2013-12-04 14:33:19.259478978 +0100
@@ -61,3 +61,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.11.10/drivers/input/serio/Kconfig linux-3.11.10-fbx/drivers/input/serio/Kconfig
--- linux-3.11.10/drivers/input/serio/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/input/serio/Kconfig	2014-01-17 19:14:18.622220807 +0100
@@ -2,7 +2,7 @@
 # Input core configuration
 #
 config SERIO
-	tristate "Serial I/O support" if EXPERT || !X86
+	tristate "Serial I/O support"
 	default y
 	help
 	  Say Yes here if you have any input device that uses serial I/O to
@@ -19,7 +19,7 @@
 if SERIO
 
 config SERIO_I8042
-	tristate "i8042 PC Keyboard controller" if EXPERT || !X86
+	tristate "i8042 PC Keyboard controller"
 	default y
 	depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \
 		   (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !S390 && \
@@ -170,7 +170,7 @@
 	  module will be called maceps2.
 
 config SERIO_LIBPS2
-	tristate "PS/2 driver library" if EXPERT
+	tristate "PS/2 driver library"
 	depends on SERIO_I8042 || SERIO_I8042=n
 	help
 	  Say Y here if you are using a driver for device connected
diff -ruw linux-3.11.10/drivers/Kconfig linux-3.11.10-fbx/drivers/Kconfig
--- linux-3.11.10/drivers/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/Kconfig	2013-12-04 14:33:18.691478969 +0100
@@ -6,8 +6,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"
@@ -62,6 +66,10 @@
 
 source "drivers/gpio/Kconfig"
 
+source "drivers/fbxgpio/Kconfig"
+
+source "drivers/fbxjtag/Kconfig"
+
 source "drivers/w1/Kconfig"
 
 source "drivers/power/Kconfig"
@@ -70,6 +78,8 @@
 
 source "drivers/thermal/Kconfig"
 
+source "drivers/fbxwatchdog/Kconfig"
+
 source "drivers/watchdog/Kconfig"
 
 source "drivers/ssb/Kconfig"
@@ -98,6 +108,8 @@
 
 source "drivers/leds/Kconfig"
 
+source "drivers/fbxpanel/Kconfig"
+
 source "drivers/accessibility/Kconfig"
 
 source "drivers/infiniband/Kconfig"
diff -ruw linux-3.11.10/drivers/Makefile linux-3.11.10-fbx/drivers/Makefile
--- linux-3.11.10/drivers/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/Makefile	2013-12-04 14:33:18.691478969 +0100
@@ -12,6 +12,8 @@
 obj-y				+= pinctrl/
 obj-y				+= gpio/
 obj-y				+= pwm/
+obj-$(CONFIG_FREEBOX_GPIO)	+= fbxgpio/
+obj-$(CONFIG_FREEBOX_JTAG)	+= fbxjtag/
 obj-$(CONFIG_PCI)		+= pci/
 obj-$(CONFIG_PARISC)		+= parisc/
 obj-$(CONFIG_RAPIDIO)		+= rapidio/
@@ -73,6 +75,9 @@
 obj-$(CONFIG_VFIO)		+= vfio/
 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/
@@ -98,6 +103,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_MD)		+= md/
 obj-$(CONFIG_BT)		+= bluetooth/
@@ -111,6 +117,7 @@
 obj-y				+= 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.11.10/drivers/md/Kconfig linux-3.11.10-fbx/drivers/md/Kconfig
--- linux-3.11.10/drivers/md/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/md/Kconfig	2014-05-09 14:12:52.948546138 +0200
@@ -176,8 +176,12 @@
 
 source "drivers/md/bcache/Kconfig"
 
+config BLK_DEV_DM_BUILTIN
+	boolean
+
 config BLK_DEV_DM
 	tristate "Device mapper support"
+	select BLK_DEV_DM_BUILTIN
 	---help---
 	  Device-mapper is a low level volume manager.  It works by allowing
 	  people to specify mappings for ranges of logical sectors.  Various
diff -ruw linux-3.11.10/drivers/md/Makefile linux-3.11.10-fbx/drivers/md/Makefile
--- linux-3.11.10/drivers/md/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/md/Makefile	2014-05-09 14:12:52.948546138 +0200
@@ -32,6 +32,7 @@
 obj-$(CONFIG_BCACHE)		+= bcache/
 obj-$(CONFIG_BLK_DEV_MD)	+= md-mod.o
 obj-$(CONFIG_BLK_DEV_DM)	+= dm-mod.o
+obj-$(CONFIG_BLK_DEV_DM_BUILTIN) += dm-builtin.o
 obj-$(CONFIG_DM_BUFIO)		+= dm-bufio.o
 obj-$(CONFIG_DM_BIO_PRISON)	+= dm-bio-prison.o
 obj-$(CONFIG_DM_CRYPT)		+= dm-crypt.o
diff -ruw linux-3.11.10/drivers/media/dvb-core/dvb_frontend.c linux-3.11.10-fbx/drivers/media/dvb-core/dvb_frontend.c
--- linux-3.11.10/drivers/media/dvb-core/dvb_frontend.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/dvb-core/dvb_frontend.c	2013-12-04 14:33:19.403478980 +0100
@@ -758,6 +758,7 @@
 
 	fepriv->exit = DVB_FE_NORMAL_EXIT;
 	mb();
+	wake_up_all(&fepriv->events.wait_queue);
 
 	if (!fepriv->thread)
 		return;
@@ -2407,6 +2408,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.11.10/drivers/media/dvb-core/dvb-usb-ids.h linux-3.11.10-fbx/drivers/media/dvb-core/dvb-usb-ids.h
--- linux-3.11.10/drivers/media/dvb-core/dvb-usb-ids.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/dvb-core/dvb-usb-ids.h	2014-08-22 15:47:22.096062948 +0200
@@ -105,6 +105,7 @@
 #define USB_PID_DELOCK_USB2_DVBT			0xb803
 #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
@@ -239,6 +240,7 @@
 #define USB_PID_AVERMEDIA_A835B_4835			0x4835
 #define USB_PID_AVERMEDIA_1867				0x1867
 #define USB_PID_AVERMEDIA_A867				0xa867
+#define USB_PID_AVERMEDIA_H335				0x0335
 #define USB_PID_AVERMEDIA_TWINSTAR			0x0825
 #define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
 #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM	0x3009
@@ -256,6 +258,7 @@
 #define USB_PID_TERRATEC_T5				0x10a1
 #define USB_PID_NOXON_DAB_STICK				0x00b3
 #define USB_PID_NOXON_DAB_STICK_REV2			0x00e0
+#define USB_PID_NOXON_DAB_STICK_REV3			0x00b4
 #define USB_PID_PINNACLE_EXPRESSCARD_320CX		0x022e
 #define USB_PID_PINNACLE_PCTV2000E			0x022c
 #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH		0x0228
@@ -317,6 +320,7 @@
 #define USB_PID_WINFAST_DTV_DONGLE_H			0x60f6
 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2		0x6f01
 #define USB_PID_WINFAST_DTV_DONGLE_GOLD			0x6029
+#define USB_PID_WINFAST_DTV_DONGLE_MINID		0x6f0f
 #define USB_PID_GENPIX_8PSK_REV_1_COLD			0x0200
 #define USB_PID_GENPIX_8PSK_REV_1_WARM			0x0201
 #define USB_PID_GENPIX_8PSK_REV_2			0x0202
@@ -358,6 +362,7 @@
 #define USB_PID_FRIIO_WHITE				0x0001
 #define USB_PID_TVWAY_PLUS				0x0002
 #define USB_PID_SVEON_STV20				0xe39d
+#define USB_PID_SVEON_STV20_RTL2832U			0xd39d
 #define USB_PID_SVEON_STV22				0xe401
 #define USB_PID_SVEON_STV22_IT9137			0xe411
 #define USB_PID_AZUREWAVE_AZ6027			0x3275
@@ -369,4 +374,7 @@
 #define USB_PID_TECHNISAT_USB2_DVB_S2			0x0500
 #define USB_PID_CPYTO_REDI_PC50A			0xa803
 #define USB_PID_CTVDIGDUAL_V2				0xe410
+#define USB_PID_PCTV_2002E                              0x025c
+#define USB_PID_PCTV_2002E_SE                           0x025d
+#define USB_PID_SVEON_STV27                             0xd3af
 #endif
diff -ruw linux-3.11.10/drivers/media/dvb-frontends/af9033.c linux-3.11.10-fbx/drivers/media/dvb-frontends/af9033.c
--- linux-3.11.10/drivers/media/dvb-frontends/af9033.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/dvb-frontends/af9033.c	2014-07-25 17:33:32.878726283 +0200
@@ -21,6 +21,9 @@
 
 #include "af9033_priv.h"
 
+/* Max transfer size done by I2C transfer functions */
+#define MAX_XFER_SIZE  64
+
 struct af9033_state {
 	struct i2c_adapter *i2c;
 	struct dvb_frontend fe;
@@ -40,16 +43,23 @@
 		int len)
 {
 	int ret;
-	u8 buf[3 + len];
+	u8 buf[MAX_XFER_SIZE];
 	struct i2c_msg msg[1] = {
 		{
 			.addr = state->cfg.i2c_addr,
 			.flags = 0,
-			.len = sizeof(buf),
+			.len = 3 + len,
 			.buf = buf,
 		}
 	};
 
+	if (3 + len > sizeof(buf)) {
+		dev_warn(&state->i2c->dev,
+			 "%s: i2c wr reg=%04x: len=%d is too big!\n",
+			 KBUILD_MODNAME, reg, len);
+		return -EINVAL;
+	}
+
 	buf[0] = (reg >> 16) & 0xff;
 	buf[1] = (reg >>  8) & 0xff;
 	buf[2] = (reg >>  0) & 0xff;
@@ -160,11 +170,18 @@
 static int af9033_wr_reg_val_tab(struct af9033_state *state,
 		const struct reg_val *tab, int tab_len)
 {
+#define MAX_TAB_LEN 212
 	int ret, i, j;
-	u8 buf[tab_len];
+	u8 buf[1 + MAX_TAB_LEN];
 
 	dev_dbg(&state->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
 
+	if (tab_len > sizeof(buf)) {
+		dev_warn(&state->i2c->dev, "%s: tab len %d is too big\n",
+				KBUILD_MODNAME, tab_len);
+		return -EINVAL;
+	}
+
 	for (i = 0, j = 0; i < tab_len; i++) {
 		buf[j] = tab[i].val;
 
@@ -257,6 +274,22 @@
 		{ 0x800045, state->cfg.adc_multiplier, 0xff },
 	};
 
+	/* power up tuner - for performance */
+	switch (state->cfg.tuner) {
+	case AF9033_TUNER_IT9135_38:
+	case AF9033_TUNER_IT9135_51:
+	case AF9033_TUNER_IT9135_52:
+	case AF9033_TUNER_IT9135_60:
+	case AF9033_TUNER_IT9135_61:
+	case AF9033_TUNER_IT9135_62:
+		ret = af9033_wr_reg(state, 0x80ec40, 0x1);
+		ret |= af9033_wr_reg(state, 0x80fba8, 0x0);
+		ret |= af9033_wr_reg(state, 0x80ec57, 0x0);
+		ret |= af9033_wr_reg(state, 0x80ec58, 0x0);
+		if (ret < 0)
+			goto err;
+	}
+
 	/* program clock control */
 	clock_cw = af9033_div(state, state->cfg.clock, 1000000ul, 19ul);
 	buf[0] = (clock_cw >>  0) & 0xff;
@@ -423,6 +456,8 @@
 	case AF9033_TUNER_IT9135_61:
 	case AF9033_TUNER_IT9135_62:
 		ret = af9033_wr_reg(state, 0x800000, 0x01);
+		ret |= af9033_wr_reg(state, 0x00d827, 0x00);
+		ret |= af9033_wr_reg(state, 0x00d829, 0x00);
 		if (ret < 0)
 			goto err;
 	}
diff -ruw linux-3.11.10/drivers/media/dvb-frontends/af9033_priv.h linux-3.11.10-fbx/drivers/media/dvb-frontends/af9033_priv.h
--- linux-3.11.10/drivers/media/dvb-frontends/af9033_priv.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/dvb-frontends/af9033_priv.h	2014-07-25 17:33:32.878726283 +0200
@@ -1418,7 +1418,7 @@
 	{ 0x800068, 0x0a },
 	{ 0x80006a, 0x03 },
 	{ 0x800070, 0x0a },
-	{ 0x800071, 0x05 },
+	{ 0x800071, 0x0a },
 	{ 0x800072, 0x02 },
 	{ 0x800075, 0x8c },
 	{ 0x800076, 0x8c },
@@ -1484,7 +1484,6 @@
 	{ 0x800104, 0x02 },
 	{ 0x800105, 0xbe },
 	{ 0x800106, 0x00 },
-	{ 0x800109, 0x02 },
 	{ 0x800115, 0x0a },
 	{ 0x800116, 0x03 },
 	{ 0x80011a, 0xbe },
@@ -1510,7 +1509,6 @@
 	{ 0x80014b, 0x8c },
 	{ 0x80014d, 0xac },
 	{ 0x80014e, 0xc6 },
-	{ 0x80014f, 0x03 },
 	{ 0x800151, 0x1e },
 	{ 0x800153, 0xbc },
 	{ 0x800178, 0x09 },
@@ -1522,9 +1520,10 @@
 	{ 0x80018d, 0x5f },
 	{ 0x80018f, 0xa0 },
 	{ 0x800190, 0x5a },
-	{ 0x80ed02, 0xff },
-	{ 0x80ee42, 0xff },
-	{ 0x80ee82, 0xff },
+	{ 0x800191, 0x00 },
+	{ 0x80ed02, 0x40 },
+	{ 0x80ee42, 0x40 },
+	{ 0x80ee82, 0x40 },
 	{ 0x80f000, 0x0f },
 	{ 0x80f01f, 0x8c },
 	{ 0x80f020, 0x00 },
@@ -1699,7 +1698,6 @@
 	{ 0x800104, 0x02 },
 	{ 0x800105, 0xc8 },
 	{ 0x800106, 0x00 },
-	{ 0x800109, 0x02 },
 	{ 0x800115, 0x0a },
 	{ 0x800116, 0x03 },
 	{ 0x80011a, 0xc6 },
@@ -1725,7 +1723,6 @@
 	{ 0x80014b, 0x8c },
 	{ 0x80014d, 0xa8 },
 	{ 0x80014e, 0xc6 },
-	{ 0x80014f, 0x03 },
 	{ 0x800151, 0x28 },
 	{ 0x800153, 0xcc },
 	{ 0x800178, 0x09 },
@@ -1737,9 +1734,10 @@
 	{ 0x80018d, 0x5f },
 	{ 0x80018f, 0xfb },
 	{ 0x800190, 0x5c },
-	{ 0x80ed02, 0xff },
-	{ 0x80ee42, 0xff },
-	{ 0x80ee82, 0xff },
+	{ 0x800191, 0x00 },
+	{ 0x80ed02, 0x40 },
+	{ 0x80ee42, 0x40 },
+	{ 0x80ee82, 0x40 },
 	{ 0x80f000, 0x0f },
 	{ 0x80f01f, 0x8c },
 	{ 0x80f020, 0x00 },
diff -ruw linux-3.11.10/drivers/media/platform/Kconfig linux-3.11.10-fbx/drivers/media/platform/Kconfig
--- linux-3.11.10/drivers/media/platform/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/platform/Kconfig	2013-12-04 14:33:19.519478982 +0100
@@ -124,6 +124,7 @@
 source "drivers/media/platform/soc_camera/Kconfig"
 source "drivers/media/platform/exynos4-is/Kconfig"
 source "drivers/media/platform/s5p-tv/Kconfig"
+source "drivers/media/platform/tango2/Kconfig"
 
 endif # V4L_PLATFORM_DRIVERS
 
diff -ruw linux-3.11.10/drivers/media/platform/Makefile linux-3.11.10-fbx/drivers/media/platform/Makefile
--- linux-3.11.10/drivers/media/platform/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/platform/Makefile	2013-12-04 14:33:19.519478982 +0100
@@ -46,6 +46,8 @@
 
 obj-$(CONFIG_SOC_CAMERA)		+= soc_camera/
 
+obj-$(CONFIG_DVB_TANGO2)		+= tango2/
+
 obj-y	+= davinci/
 
 obj-$(CONFIG_ARCH_OMAP)	+= omap/
diff -ruw linux-3.11.10/drivers/media/rc/ir-rc6-decoder.c linux-3.11.10-fbx/drivers/media/rc/ir-rc6-decoder.c
--- linux-3.11.10/drivers/media/rc/ir-rc6-decoder.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/rc/ir-rc6-decoder.c	2013-12-04 14:33:19.571478983 +0100
@@ -248,10 +248,10 @@
 					(scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) {
 				/* MCE RC */
 				toggle = (scancode & RC6_6A_MCE_TOGGLE_MASK) ? 1 : 0;
-				scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
 			} else {
 				toggle = 0;
 			}
+			scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
 			IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n",
 				   scancode, toggle);
 			break;
diff -ruw linux-3.11.10/drivers/media/rc/keymaps/Makefile linux-3.11.10-fbx/drivers/media/rc/keymaps/Makefile
--- linux-3.11.10/drivers/media/rc/keymaps/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/rc/keymaps/Makefile	2013-12-04 14:33:19.571478983 +0100
@@ -78,6 +78,7 @@
 			rc-pv951.o \
 			rc-hauppauge.o \
 			rc-rc6-mce.o \
+			rc-rc6-freebox.o \
 			rc-real-audio-220-32-keys.o \
 			rc-reddo.o \
 			rc-snapstream-firefly.o \
diff -ruw linux-3.11.10/drivers/media/rc/mceusb.c linux-3.11.10-fbx/drivers/media/rc/mceusb.c
--- linux-3.11.10/drivers/media/rc/mceusb.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/rc/mceusb.c	2013-12-04 14:33:19.579478983 +0100
@@ -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[] = {
@@ -361,7 +367,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 },
 	/* Formosa Industrial Computing */
 	{ USB_DEVICE(VENDOR_FORMOSA, 0xe042) },
 	/* Fintek eHome Infrared Transceiver (HP branded) */
@@ -932,7 +939,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;
@@ -1208,7 +1215,7 @@
 	rc->priv = ir;
 	rc->driver_type = RC_DRIVER_IR_RAW;
 	rc->allowed_protos = RC_BIT_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.11.10/drivers/media/tuners/tuner_it913x.c linux-3.11.10-fbx/drivers/media/tuners/tuner_it913x.c
--- linux-3.11.10/drivers/media/tuners/tuner_it913x.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/tuners/tuner_it913x.c	2014-07-25 17:33:32.878726283 +0200
@@ -200,12 +200,6 @@
 		}
 	}
 
-	/* Power Up Tuner - common all versions */
-	ret = it913x_wr_reg(state, PRO_DMOD, 0xec40, 0x1);
-	ret |= it913x_wr_reg(state, PRO_DMOD, 0xfba8, 0x0);
-	ret |= it913x_wr_reg(state, PRO_DMOD, 0xec57, 0x0);
-	ret |= it913x_wr_reg(state, PRO_DMOD, 0xec58, 0x0);
-
 	return it913x_wr_reg(state, PRO_DMOD, 0xed81, val);
 }
 
diff -ruw linux-3.11.10/drivers/media/usb/dvb-usb/dib0700_devices.c linux-3.11.10-fbx/drivers/media/usb/dvb-usb/dib0700_devices.c
--- linux-3.11.10/drivers/media/usb/dvb-usb/dib0700_devices.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/usb/dvb-usb/dib0700_devices.c	2014-08-22 15:47:22.096062948 +0200
@@ -3589,6 +3589,9 @@
 	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE7790P) },
 	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE8096P) },
 /* 80 */{ USB_DEVICE(USB_VID_ELGATO,	USB_PID_ELGATO_EYETV_DTT_2) },
+	{ USB_DEVICE(USB_VID_PCTV,      USB_PID_PCTV_2002E) },
+	{ USB_DEVICE(USB_VID_PCTV,      USB_PID_PCTV_2002E_SE) },
+	{ USB_DEVICE(USB_VID_DIBCOM,	USB_PID_DIBCOM_HOOK_DEFAULT_STK7770P) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -3993,12 +3996,20 @@
 			}
 		},
 
-		.num_device_descs = 1,
+		.num_device_descs = 3,
 		.devices = {
 			{   "Hauppauge Nova-TD Stick (52009)",
 				{ &dib0700_usb_id_table[35], NULL },
 				{ NULL },
 			},
+			{   "PCTV 2002e",
+				{ &dib0700_usb_id_table[81], NULL },
+				{ NULL },
+			},
+			{   "PCTV 2002e SE",
+				{ &dib0700_usb_id_table[82], NULL },
+				{ NULL },
+			},
 		},
 
 		.rc.core = {
@@ -4320,6 +4331,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[83], NULL },
+				{ NULL },
+			},
+		},
+
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
 		.num_adapters = 1,
 		.adapter = {
 			{
diff -ruw linux-3.11.10/drivers/media/usb/dvb-usb/dvb-usb-dvb.c linux-3.11.10-fbx/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
--- linux-3.11.10/drivers/media/usb/dvb-usb/dvb-usb-dvb.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/usb/dvb-usb/dvb-usb-dvb.c	2013-12-04 14:33:19.607478984 +0100
@@ -249,6 +249,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);
@@ -261,10 +265,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.11.10/drivers/media/usb/dvb-usb/dvb-usb.h linux-3.11.10-fbx/drivers/media/usb/dvb-usb/dvb-usb.h
--- linux-3.11.10/drivers/media/usb/dvb-usb/dvb-usb.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/usb/dvb-usb/dvb-usb.h	2013-12-04 14:33:19.607478984 +0100
@@ -294,7 +294,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.11.10/drivers/media/usb/dvb-usb-v2/af9035.c linux-3.11.10-fbx/drivers/media/usb/dvb-usb-v2/af9035.c
--- linux-3.11.10/drivers/media/usb/dvb-usb-v2/af9035.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/usb/dvb-usb-v2/af9035.c	2014-07-25 17:33:32.878726283 +0200
@@ -21,6 +21,9 @@
 
 #include "af9035.h"
 
+/* Max transfer size done by I2C transfer functions */
+#define MAX_XFER_SIZE  64
+
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 static u16 af9035_checksum(const u8 *buf, size_t len)
@@ -126,9 +129,15 @@
 /* write multiple registers */
 static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
 {
-	u8 wbuf[6 + len];
+	u8 wbuf[MAX_XFER_SIZE];
 	u8 mbox = (reg >> 16) & 0xff;
-	struct usb_req req = { CMD_MEM_WR, mbox, sizeof(wbuf), wbuf, 0, NULL };
+	struct usb_req req = { CMD_MEM_WR, mbox, 6 + len, wbuf, 0, NULL };
+
+	if (6 + len > sizeof(wbuf)) {
+		dev_warn(&d->udev->dev, "%s: i2c wr: len=%d is too big!\n",
+			 KBUILD_MODNAME, len);
+		return -EOPNOTSUPP;
+	}
 
 	wbuf[0] = len;
 	wbuf[1] = 2;
@@ -228,9 +237,17 @@
 					msg[1].len);
 		} else {
 			/* I2C */
-			u8 buf[5 + msg[0].len];
-			struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
+			u8 buf[MAX_XFER_SIZE];
+			struct usb_req req = { CMD_I2C_RD, 0, 5 + msg[0].len,
 					buf, msg[1].len, msg[1].buf };
+
+			if (5 + msg[0].len > sizeof(buf)) {
+				dev_warn(&d->udev->dev,
+					 "%s: i2c xfer: len=%d is too big!\n",
+					 KBUILD_MODNAME, msg[0].len);
+				ret = -EOPNOTSUPP;
+				goto unlock;
+			}
 			req.mbox |= ((msg[0].addr & 0x80)  >>  3);
 			buf[0] = msg[1].len;
 			buf[1] = msg[0].addr << 1;
@@ -257,9 +274,17 @@
 					msg[0].len - 3);
 		} else {
 			/* I2C */
-			u8 buf[5 + msg[0].len];
-			struct usb_req req = { CMD_I2C_WR, 0, sizeof(buf), buf,
-					0, NULL };
+			u8 buf[MAX_XFER_SIZE];
+			struct usb_req req = { CMD_I2C_WR, 0, 5 + msg[0].len,
+					buf, 0, NULL };
+
+			if (5 + msg[0].len > sizeof(buf)) {
+				dev_warn(&d->udev->dev,
+					 "%s: i2c xfer: len=%d is too big!\n",
+					 KBUILD_MODNAME, msg[0].len);
+				ret = -EOPNOTSUPP;
+				goto unlock;
+			}
 			req.mbox |= ((msg[0].addr & 0x80)  >>  3);
 			buf[0] = msg[0].len;
 			buf[1] = msg[0].addr << 1;
@@ -296,6 +321,7 @@
 		ret = -EOPNOTSUPP;
 	}
 
+unlock:
 	mutex_unlock(&d->i2c_mutex);
 
 	if (ret < 0)
@@ -572,6 +598,8 @@
 	if (ret < 0)
 		goto err;
 
+	msleep(30);
+
 	/* firmware loaded, request boot */
 	req.cmd = CMD_FW_BOOT;
 	ret = af9035_ctrl_msg(d, &req);
@@ -591,6 +619,15 @@
 		goto err;
 	}
 
+	/* tuner RF initial */
+	if (state->chip_type == 0x9135) {
+		ret = af9035_wr_reg(d, 0x80ec4c, 0x68);
+		if (ret < 0)
+			goto err;
+
+		msleep(30);
+	}
+
 	dev_info(&d->udev->dev, "%s: firmware version=%d.%d.%d.%d",
 			KBUILD_MODNAME, rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
 
@@ -1502,15 +1539,37 @@
 	{ DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa,
 		&af9035_props, "TerraTec Cinergy T Stick (rev. 2)", NULL) },
 	/* IT9135 devices */
-#if 0
-	{ DVB_USB_DEVICE(0x048d, 0x9135,
-		&af9035_props, "IT9135 reference design", NULL) },
-	{ DVB_USB_DEVICE(0x048d, 0x9006,
-		&af9035_props, "IT9135 reference design", NULL) },
-#endif
+	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135,
+		&af9035_props, "ITE 9135 Generic", RC_MAP_IT913X_V1) },
+	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005,
+		&af9035_props, "ITE 9135(9005) Generic", RC_MAP_IT913X_V2) },
+	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006,
+		&af9035_props, "ITE 9135(9006) Generic", RC_MAP_IT913X_V1) },
+	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_1835,
+		&af9035_props, "Avermedia A835B(1835)", RC_MAP_IT913X_V2) },
+	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_2835,
+		&af9035_props, "Avermedia A835B(2835)", RC_MAP_IT913X_V2) },
+	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_3835,
+		&af9035_props, "Avermedia A835B(3835)", RC_MAP_IT913X_V2) },
+	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_4835,
+		&af9035_props, "Avermedia A835B(4835)",	RC_MAP_IT913X_V2) },
+	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_H335,
+		&af9035_props, "Avermedia H335", RC_MAP_IT913X_V2) },
+	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09,
+		&af9035_props, "Kworld UB499-2T T09", RC_MAP_IT913X_V1) },
+	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137,
+		&af9035_props, "Sveon STV22 Dual DVB-T HDTV",
+							RC_MAP_IT913X_V1) },
+	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2,
+		&af9035_props, "Digital Dual TV Receiver CTVDIGDUAL_V2",
+							RC_MAP_IT913X_V1) },
 	/* XXX: that same ID [0ccd:0099] is used by af9015 driver too */
 	{ DVB_USB_DEVICE(USB_VID_TERRATEC, 0x0099,
 		&af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", NULL) },
+	{ DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a05,
+		&af9035_props, "Leadtek WinFast DTV Dongle Dual", NULL) },
+	{ DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xf900,
+		&af9035_props, "Hauppauge WinTV-MiniStick 2", NULL) },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, af9035_id_table);
diff -ruw linux-3.11.10/drivers/mfd/Kconfig linux-3.11.10-fbx/drivers/mfd/Kconfig
--- linux-3.11.10/drivers/mfd/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/mfd/Kconfig	2014-07-01 16:22:13.082329339 +0200
@@ -1145,8 +1145,6 @@
 	  core support for the WM8994, in order to use the actual
 	  functionaltiy of the device other drivers must be enabled.
 
-endmenu
-endif
 
 menu "Multimedia Capabilities Port drivers"
 	depends on ARCH_SA1100
@@ -1178,3 +1176,6 @@
 	help
 	  Platform configuration infrastructure for the ARM Ltd.
 	  Versatile Express.
+
+endmenu
+endif
diff -ruw linux-3.11.10/drivers/misc/Kconfig linux-3.11.10-fbx/drivers/misc/Kconfig
--- linux-3.11.10/drivers/misc/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/Kconfig	2013-12-04 14:33:19.699478985 +0100
@@ -4,6 +4,9 @@
 
 menu "Misc devices"
 
+config WINTEGRA_MMAP
+	bool "wintegra mmap driver"
+
 config SENSORS_LIS3LV02D
 	tristate
 	depends on INPUT
@@ -440,6 +443,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
@@ -537,4 +552,7 @@
 source "drivers/misc/altera-stapl/Kconfig"
 source "drivers/misc/mei/Kconfig"
 source "drivers/misc/vmw_vmci/Kconfig"
+source "drivers/misc/remoti/Kconfig"
+source "drivers/misc/hdmi-cec/Kconfig"
+
 endmenu
diff -ruw linux-3.11.10/drivers/misc/Makefile linux-3.11.10-fbx/drivers/misc/Makefile
--- linux-3.11.10/drivers/misc/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/Makefile	2013-12-04 14:33:19.699478985 +0100
@@ -2,6 +2,7 @@
 # Makefile for misc devices that really don't fit anywhere else.
 #
 
+obj-$(CONFIG_WINTEGRA_MMAP)	+= wintegra_mmap.o
 obj-$(CONFIG_IBM_ASM)		+= ibmasm/
 obj-$(CONFIG_AD525X_DPOT)	+= ad525x_dpot.o
 obj-$(CONFIG_AD525X_DPOT_I2C)	+= ad525x_dpot-i2c.o
@@ -26,6 +27,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
@@ -53,3 +55,5 @@
 obj-$(CONFIG_VMWARE_VMCI)	+= vmw_vmci/
 obj-$(CONFIG_LATTICE_ECP3_CONFIG)	+= lattice-ecp3-config.o
 obj-$(CONFIG_SRAM)		+= sram.o
+obj-y				+= remoti/
+obj-y				+= hdmi-cec/
diff -ruw linux-3.11.10/drivers/mtd/Kconfig linux-3.11.10-fbx/drivers/mtd/Kconfig
--- linux-3.11.10/drivers/mtd/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/mtd/Kconfig	2013-12-04 14:33:19.739478986 +0100
@@ -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---
@@ -155,6 +158,17 @@
 	  This provides partitions parser for devices based on BCM47xx
 	  boards.
 
+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_BLKDEVS
diff -ruw linux-3.11.10/drivers/mtd/Makefile linux-3.11.10-fbx/drivers/mtd/Makefile
--- linux-3.11.10/drivers/mtd/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/mtd/Makefile	2013-12-04 14:33:19.739478986 +0100
@@ -13,6 +13,7 @@
 obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
 obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63xxpart.o
 obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o
+obj-$(CONFIG_MTD_FBX6HD_PARTS)	+= fbx6hd-mtdparts.o
 
 # 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o
diff -ruw linux-3.11.10/drivers/mtd/mtdchar.c linux-3.11.10-fbx/drivers/mtd/mtdchar.c
--- linux-3.11.10/drivers/mtd/mtdchar.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/mtd/mtdchar.c	2013-12-04 14:33:19.751478986 +0100
@@ -215,6 +215,7 @@
 		{
 			struct mtd_oob_ops ops;
 
+			memset(&ops, 0, sizeof (ops));
 			ops.mode = MTD_OPS_RAW;
 			ops.datbuf = kbuf;
 			ops.oobbuf = NULL;
@@ -309,6 +310,7 @@
 		{
 			struct mtd_oob_ops ops;
 
+			memset(&ops, 0, sizeof (ops));
 			ops.mode = MTD_OPS_RAW;
 			ops.datbuf = kbuf;
 			ops.oobbuf = NULL;
@@ -707,6 +709,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.11.10/drivers/mtd/mtdcore.c linux-3.11.10-fbx/drivers/mtd/mtdcore.c
--- linux-3.11.10/drivers/mtd/mtdcore.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/mtd/mtdcore.c	2013-12-04 14:33:19.755478986 +0100
@@ -285,6 +285,33 @@
 		   mtd_bitflip_threshold_show,
 		   mtd_bitflip_threshold_store);
 
+static ssize_t mtd_nand_type_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_get_drvdata(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_get_drvdata(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_get_drvdata(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,
@@ -297,6 +324,9 @@
 	&dev_attr_name.attr,
 	&dev_attr_ecc_strength.attr,
 	&dev_attr_bitflip_threshold.attr,
+	&dev_attr_nand_type.attr,
+	&dev_attr_nand_manufacturer.attr,
+	&dev_attr_onfi_version.attr,
 	NULL,
 };
 
diff -ruw linux-3.11.10/drivers/mtd/mtdpart.c linux-3.11.10-fbx/drivers/mtd/mtdpart.c
--- linux-3.11.10/drivers/mtd/mtdpart.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/mtd/mtdpart.c	2013-12-04 14:33:19.755478986 +0100
@@ -366,6 +366,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.11.10/drivers/mtd/nand/Kconfig linux-3.11.10-fbx/drivers/mtd/nand/Kconfig
--- linux-3.11.10/drivers/mtd/nand/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/mtd/nand/Kconfig	2013-12-04 14:33:19.755478986 +0100
@@ -41,6 +41,15 @@
 	tristate
 	default n
 
+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_DENALI
         tristate "Support Denali NAND controller"
         help
@@ -544,4 +553,9 @@
 	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
 	  to the External Bus Unit (EBU).
 
+config MTD_NAND_DENALI_FBX
+	tristate "NAND Denali controller support"
+	depends on MTD_NAND && PCI
+	default n
+
 endif # MTD_NAND
diff -ruw linux-3.11.10/drivers/mtd/nand/Makefile linux-3.11.10-fbx/drivers/mtd/nand/Makefile
--- linux-3.11.10/drivers/mtd/nand/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/mtd/nand/Makefile	2013-12-04 14:33:19.755478986 +0100
@@ -50,5 +50,6 @@
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
 obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
 obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
+obj-$(CONFIG_MTD_NAND_DENALI_FBX)	+= denali_nand.o
 
 nand-objs := nand_base.o nand_bbt.o
diff -ruw linux-3.11.10/drivers/mtd/nand/nand_base.c linux-3.11.10-fbx/drivers/mtd/nand/nand_base.c
--- linux-3.11.10/drivers/mtd/nand/nand_base.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/mtd/nand/nand_base.c	2014-01-17 19:14:18.650220807 +0100
@@ -2594,6 +2594,7 @@
 
 	while (len) {
 		/* Check 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",
@@ -2601,6 +2602,7 @@
 			instr->state = MTD_ERASE_FAILED;
 			goto erase_exit;
 		}
+#endif
 
 		/*
 		 * Invalidate the page cache, if we erase the block which
@@ -2904,10 +2906,21 @@
 	sanitize_string(p->model, sizeof(p->model));
 	if (!mtd->name)
 		mtd->name = p->model;
+
 	mtd->writesize = le32_to_cpu(p->byte_per_page);
-	mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
+
+	/*
+	 * pages_per_block and blocks_per_lun may not be a power-of-2 size
+	 * (don't ask me who thought of this...). MTD assumes that these
+	 * dimensions will be power-of-2, so just truncate the remaining area.
+	 */
+	mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
+	mtd->erasesize *= mtd->writesize;
+
 	mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
-	chip->chipsize = le32_to_cpu(p->blocks_per_lun);
+
+	/* See erasesize comment */
+	chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
 	chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
 	*busw = 0;
 	if (le16_to_cpu(p->features) & 1)
@@ -3193,6 +3206,8 @@
 {
 	int i, maf_idx;
 	u8 id_data[8];
+	int ret;
+	char onfi_version[5];
 
 	/* Select the device */
 	chip->select_chip(mtd, 0);
@@ -3330,7 +3345,38 @@
 		chip->onfi_version ? chip->onfi_params.model : type->name,
 		(int)(chip->chipsize >> 20), mtd->writesize, mtd->oobsize);
 
+	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);
 }
 
 /**
@@ -3350,6 +3396,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;
@@ -3364,7 +3411,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;
 	}
 
 	chip->select_chip(mtd, -1);
@@ -3392,6 +3440,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);
 
@@ -3533,9 +3591,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;
@@ -3649,7 +3711,8 @@
 	chip->pagebuf = -1;
 
 	/* Large page NAND with SOFT_ECC should support subpage reads */
-	if ((chip->ecc.mode == NAND_ECC_SOFT) && (chip->page_shift > 9))
+	if ((chip->ecc.mode == NAND_ECC_SOFT) && (chip->page_shift > 9) &&
+	    !(chip->options & NAND_NO_RNDOUT))
 		chip->options |= NAND_SUBPAGE_READ;
 
 	/* Fill in remaining MTD driver data */
diff -ruw linux-3.11.10/drivers/net/ethernet/intel/e1000/e1000.h linux-3.11.10-fbx/drivers/net/ethernet/intel/e1000/e1000.h
--- linux-3.11.10/drivers/net/ethernet/intel/e1000/e1000.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/net/ethernet/intel/e1000/e1000.h	2013-12-04 14:33:19.907478988 +0100
@@ -225,6 +225,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;
@@ -313,6 +314,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.11.10/drivers/net/ethernet/intel/e1000/e1000_main.c linux-3.11.10-fbx/drivers/net/ethernet/intel/e1000/e1000_main.c
--- linux-3.11.10/drivers/net/ethernet/intel/e1000/e1000_main.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/net/ethernet/intel/e1000/e1000_main.c	2013-12-04 14:33:19.911478988 +0100
@@ -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
 
 char e1000_driver_name[] = "e1000";
 static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
@@ -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");
@@ -1119,6 +1133,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);
 
@@ -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 */
@@ -2389,6 +2413,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) {
@@ -2398,6 +2442,7 @@
 			link_active = true;
 		}
 		break;
+#endif
 	case e1000_media_type_fiber:
 		e1000_check_for_link(hw);
 		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
@@ -3727,11 +3772,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.11.10/drivers/net/ethernet/Kconfig linux-3.11.10-fbx/drivers/net/ethernet/Kconfig
--- linux-3.11.10/drivers/net/ethernet/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/net/ethernet/Kconfig	2013-12-04 14:33:19.803478987 +0100
@@ -149,6 +149,7 @@
 	  will be called s6gmac.
 
 source "drivers/net/ethernet/seeq/Kconfig"
+source "drivers/net/ethernet/sigma/Kconfig"
 source "drivers/net/ethernet/silan/Kconfig"
 source "drivers/net/ethernet/sis/Kconfig"
 source "drivers/net/ethernet/sfc/Kconfig"
@@ -163,6 +164,7 @@
 source "drivers/net/ethernet/tundra/Kconfig"
 source "drivers/net/ethernet/via/Kconfig"
 source "drivers/net/ethernet/wiznet/Kconfig"
+source "drivers/net/ethernet/wintegra/Kconfig"
 source "drivers/net/ethernet/xilinx/Kconfig"
 source "drivers/net/ethernet/xircom/Kconfig"
 
diff -ruw linux-3.11.10/drivers/net/ethernet/Makefile linux-3.11.10-fbx/drivers/net/ethernet/Makefile
--- linux-3.11.10/drivers/net/ethernet/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/net/ethernet/Makefile	2013-12-04 14:33:19.803478987 +0100
@@ -61,6 +61,7 @@
 obj-$(CONFIG_S6GMAC) += s6gmac.o
 obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/
 obj-$(CONFIG_NET_VENDOR_SILAN) += silan/
+obj-$(CONFIG_NET_VENDOR_SIGMA) += sigma/
 obj-$(CONFIG_NET_VENDOR_SIS) += sis/
 obj-$(CONFIG_SFC) += sfc/
 obj-$(CONFIG_NET_VENDOR_SGI) += sgi/
@@ -74,5 +75,6 @@
 obj-$(CONFIG_NET_VENDOR_TUNDRA) += tundra/
 obj-$(CONFIG_NET_VENDOR_VIA) += via/
 obj-$(CONFIG_NET_VENDOR_WIZNET) += wiznet/
+obj-$(CONFIG_NET_VENDOR_WINTEGRA) += wintegra/
 obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/
 obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/
diff -ruw linux-3.11.10/drivers/net/ethernet/marvell/Kconfig linux-3.11.10-fbx/drivers/net/ethernet/marvell/Kconfig
--- linux-3.11.10/drivers/net/ethernet/marvell/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/net/ethernet/marvell/Kconfig	2013-12-04 14:33:19.939478989 +0100
@@ -23,6 +23,7 @@
 	depends on (MV64X60 || PPC32 || PLAT_ORION) && INET
 	select PHYLIB
 	select MVMDIO
+	select MII
 	---help---
 	  This driver supports the gigabit ethernet MACs in the
 	  Marvell Discovery PPC/MIPS chipset family (MV643XX) and
diff -ruw linux-3.11.10/drivers/net/Kconfig linux-3.11.10-fbx/drivers/net/Kconfig
--- linux-3.11.10/drivers/net/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/net/Kconfig	2013-12-04 14:33:19.775478986 +0100
@@ -362,4 +362,18 @@
 
 source "drivers/net/hyperv/Kconfig"
 
+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.11.10/drivers/net/wireless/ath/ath10k/Kconfig linux-3.11.10-fbx/drivers/net/wireless/ath/ath10k/Kconfig
--- linux-3.11.10/drivers/net/wireless/ath/ath10k/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/net/wireless/ath/ath10k/Kconfig	2013-12-17 18:03:42.675570851 +0100
@@ -37,3 +37,10 @@
 	---help---
 	  Select this to ath10k use tracing infrastructure.
 
+config ATH10K_DFS_CERTIFIED
+	bool "Atheros DFS support for certified platforms"
+	depends on ATH10K && CFG80211_CERTIFICATION_ONUS
+	default n
+	---help---
+	  This option enables DFS support for initiating radiation on
+	  ath10k.
diff -ruw linux-3.11.10/drivers/net/wireless/ath/ath9k/Makefile linux-3.11.10-fbx/drivers/net/wireless/ath/ath9k/Makefile
--- linux-3.11.10/drivers/net/wireless/ath/ath9k/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/net/wireless/ath/ath9k/Makefile	2013-12-17 18:03:42.691570851 +0100
@@ -14,9 +14,7 @@
 ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
 ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
 ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += \
-		dfs.o \
-		dfs_pattern_detector.o \
-		dfs_pri_detector.o
+		dfs.o
 ath9k-$(CONFIG_PM_SLEEP) += wow.o
 
 obj-$(CONFIG_ATH9K) += ath9k.o
diff -ruw linux-3.11.10/drivers/net/wireless/ath/Makefile linux-3.11.10-fbx/drivers/net/wireless/ath/Makefile
--- linux-3.11.10/drivers/net/wireless/ath/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/net/wireless/ath/Makefile	2013-12-17 18:03:42.675570851 +0100
@@ -11,7 +11,9 @@
 ath-objs :=	main.o \
 		regd.o \
 		hw.o \
-		key.o
+		key.o \
+		dfs_pattern_detector.o \
+		dfs_pri_detector.o
 
 ath-$(CONFIG_ATH_DEBUG) += debug.o
 ccflags-y += -D__CHECK_ENDIAN__
diff -ruw linux-3.11.10/drivers/net/wireless/Kconfig linux-3.11.10-fbx/drivers/net/wireless/Kconfig
--- linux-3.11.10/drivers/net/wireless/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/net/wireless/Kconfig	2013-12-04 14:33:20.087478991 +0100
@@ -264,6 +264,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.11.10/drivers/net/wireless/Makefile linux-3.11.10-fbx/drivers/net/wireless/Makefile
--- linux-3.11.10/drivers/net/wireless/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/net/wireless/Makefile	2013-12-04 14:33:20.087478991 +0100
@@ -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_IWLEGACY)	+= iwlegacy/
diff -ruw linux-3.11.10/drivers/of/address.c linux-3.11.10-fbx/drivers/of/address.c
--- linux-3.11.10/drivers/of/address.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/of/address.c	2014-05-09 14:12:53.180546141 +0200
@@ -69,14 +69,6 @@
 		 (unsigned long long)cp, (unsigned long long)s,
 		 (unsigned long long)da);
 
-	/*
-	 * If the number of address cells is larger than 2 we assume the
-	 * mapping doesn't specify a physical address. Rather, the address
-	 * specifies an identifier that must match exactly.
-	 */
-	if (na > 2 && memcmp(range, addr, na * 4) != 0)
-		return OF_BAD_ADDR;
-
 	if (da < cp || da >= (cp + s))
 		return OF_BAD_ADDR;
 	return da - cp;
@@ -107,11 +99,12 @@
 static int of_bus_pci_match(struct device_node *np)
 {
 	/*
+ 	 * "pciex" is PCI Express
 	 * "vci" is for the /chaos bridge on 1st-gen PCI powermacs
 	 * "ht" is hypertransport
 	 */
-	return !strcmp(np->type, "pci") || !strcmp(np->type, "vci") ||
-		!strcmp(np->type, "ht");
+	return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex") ||
+		!strcmp(np->type, "vci") || !strcmp(np->type, "ht");
 }
 
 static void of_bus_pci_count_cells(struct device_node *np,
diff -ruw linux-3.11.10/drivers/pci/pci.c linux-3.11.10-fbx/drivers/pci/pci.c
--- linux-3.11.10/drivers/pci/pci.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/pci/pci.c	2014-08-22 15:47:22.104062988 +0200
@@ -1119,6 +1119,8 @@
 static int do_pci_enable_device(struct pci_dev *dev, int bars)
 {
 	int err;
+	u16 cmd;
+	u8 pin;
 
 	err = pci_set_power_state(dev, PCI_D0);
 	if (err < 0 && err != -EIO)
@@ -1128,6 +1130,17 @@
 		return err;
 	pci_fixup_device(pci_fixup_enable, dev);
 
+	if (dev->msi_enabled || dev->msix_enabled)
+		return 0;
+
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	if (pin) {
+		pci_read_config_word(dev, PCI_COMMAND, &cmd);
+		if (cmd & PCI_COMMAND_INTX_DISABLE)
+			pci_write_config_word(dev, PCI_COMMAND,
+					      cmd & ~PCI_COMMAND_INTX_DISABLE);
+	}
+
 	return 0;
 }
 
@@ -3656,7 +3669,7 @@
 	u16 cmd;
 	int rc;
 
-	WARN_ON((flags & PCI_VGA_STATE_CHANGE_DECODES) & (command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)));
+	WARN_ON((flags & PCI_VGA_STATE_CHANGE_DECODES) && (command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)));
 
 	/* ARCH specific VGA enables */
 	rc = pci_set_vga_state_arch(dev, decode, command_bits, flags);
diff -ruw linux-3.11.10/drivers/pci/pci-driver.c linux-3.11.10-fbx/drivers/pci/pci-driver.c
--- linux-3.11.10/drivers/pci/pci-driver.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/pci/pci-driver.c	2014-01-17 19:14:18.694220808 +0100
@@ -19,6 +19,7 @@
 #include <linux/cpu.h>
 #include <linux/pm_runtime.h>
 #include <linux/suspend.h>
+#include <linux/kexec.h>
 #include "pci.h"
 
 struct pci_dynid {
@@ -388,12 +389,17 @@
 	pci_msi_shutdown(pci_dev);
 	pci_msix_shutdown(pci_dev);
 
+#ifdef CONFIG_KEXEC
 	/*
-	 * Turn off Bus Master bit on the device to tell it to not
-	 * continue to do DMA. Don't touch devices in D3cold or unknown states.
+	 * If this is a kexec reboot, turn off Bus Master bit on the
+	 * device to tell it to not continue to do DMA. Don't touch
+	 * devices in D3cold or unknown states.
+	 * If it is not a kexec reboot, firmware will hit the PCI
+	 * devices with big hammer and stop their DMA any way.
 	 */
-	if (pci_dev->current_state <= PCI_D3hot)
+	if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot))
 		pci_clear_master(pci_dev);
+#endif
 }
 
 #ifdef CONFIG_PM
diff -ruw linux-3.11.10/drivers/pci/quirks.c linux-3.11.10-fbx/drivers/pci/quirks.c
--- linux-3.11.10/drivers/pci/quirks.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/pci/quirks.c	2014-08-22 15:47:22.104062988 +0200
@@ -2635,6 +2635,8 @@
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0020, quirk_hotplug_bridge);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PI7C9X20303SL,
+			 quirk_hotplug_bridge);
 
 /*
  * This is a quirk for the Ricoh MMC controller found as a part of
@@ -2953,6 +2955,7 @@
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq);
 
 /*
  * Some devices may pass our check in pci_intx_mask_supported if
diff -ruw linux-3.11.10/drivers/platform/Kconfig linux-3.11.10-fbx/drivers/platform/Kconfig
--- linux-3.11.10/drivers/platform/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/platform/Kconfig	2013-12-04 14:33:20.395478996 +0100
@@ -5,3 +5,10 @@
 source "drivers/platform/goldfish/Kconfig"
 endif
 
+if TANGO2
+source "drivers/platform/tango2/Kconfig"
+endif
+
+if X86_INTEL_CE
+source "drivers/platform/intelce/Kconfig"
+endif
diff -ruw linux-3.11.10/drivers/platform/Makefile linux-3.11.10-fbx/drivers/platform/Makefile
--- linux-3.11.10/drivers/platform/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/platform/Makefile	2013-12-04 14:33:20.395478996 +0100
@@ -5,3 +5,5 @@
 obj-$(CONFIG_X86)		+= x86/
 obj-$(CONFIG_OLPC)		+= olpc/
 obj-$(CONFIG_GOLDFISH)		+= goldfish/
+obj-$(CONFIG_TANGO2)		+= tango2/
+obj-$(CONFIG_X86_INTEL_CE)	+= intelce/
diff -ruw linux-3.11.10/drivers/pnp/pnpacpi/rsparser.c linux-3.11.10-fbx/drivers/pnp/pnpacpi/rsparser.c
--- linux-3.11.10/drivers/pnp/pnpacpi/rsparser.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/pnp/pnpacpi/rsparser.c	2014-07-01 16:22:13.114329497 +0200
@@ -183,9 +183,7 @@
 	struct resource r = {0};
 	int i, flags;
 
-	if (acpi_dev_resource_memory(res, &r)
-	    || acpi_dev_resource_io(res, &r)
-	    || acpi_dev_resource_address_space(res, &r)
+	if (acpi_dev_resource_address_space(res, &r)
 	    || acpi_dev_resource_ext_address_space(res, &r)) {
 		pnp_add_resource(dev, &r);
 		return AE_OK;
@@ -217,6 +215,17 @@
 	}
 
 	switch (res->type) {
+	case ACPI_RESOURCE_TYPE_MEMORY24:
+	case ACPI_RESOURCE_TYPE_MEMORY32:
+	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+		if (acpi_dev_resource_memory(res, &r))
+			pnp_add_resource(dev, &r);
+		break;
+	case ACPI_RESOURCE_TYPE_IO:
+	case ACPI_RESOURCE_TYPE_FIXED_IO:
+		if (acpi_dev_resource_io(res, &r))
+			pnp_add_resource(dev, &r);
+		break;
 	case ACPI_RESOURCE_TYPE_DMA:
 		dma = &res->data.dma;
 		if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
diff -ruw linux-3.11.10/drivers/scsi/hosts.c linux-3.11.10-fbx/drivers/scsi/hosts.c
--- linux-3.11.10/drivers/scsi/hosts.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/scsi/hosts.c	2014-01-17 19:14:18.702220808 +0100
@@ -388,6 +388,7 @@
 	shost->unchecked_isa_dma = sht->unchecked_isa_dma;
 	shost->use_clustering = sht->use_clustering;
 	shost->ordered_tag = sht->ordered_tag;
+	shost->no_write_same = sht->no_write_same;
 
 	if (sht->supported_mode == MODE_UNKNOWN)
 		/* means we didn't set it ... default to INITIATOR */
diff -ruw linux-3.11.10/drivers/scsi/scsi_error.c linux-3.11.10-fbx/drivers/scsi/scsi_error.c
--- linux-3.11.10/drivers/scsi/scsi_error.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/scsi/scsi_error.c	2014-08-22 15:47:22.104062988 +0200
@@ -933,6 +933,15 @@
 		    SCSI_SENSE_VALID(scmd))
 			continue;
 
+		if (status_byte(scmd->result) != CHECK_CONDITION)
+			/*
+			 * don't request sense if there's no check condition
+			 * status because the error we're processing isn't one
+			 * that has a sense code (and some devices get
+			 * confused by sense requests out of the blue)
+			 */
+			continue;
+
 		SCSI_LOG_ERROR_RECOVERY(2, scmd_printk(KERN_INFO, scmd,
 						  "%s: requesting sense\n",
 						  current->comm));
diff -ruw linux-3.11.10/drivers/scsi/scsi_scan.c linux-3.11.10-fbx/drivers/scsi/scsi_scan.c
--- linux-3.11.10/drivers/scsi/scsi_scan.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/scsi/scsi_scan.c	2014-07-01 16:22:13.126329546 +0200
@@ -320,6 +320,7 @@
 	struct Scsi_Host *shost = dev_to_shost(dev->parent);
 	unsigned long flags;
 
+	starget->state = STARGET_DEL;
 	transport_destroy_device(dev);
 	spin_lock_irqsave(shost->host_lock, flags);
 	if (shost->hostt->target_destroy)
@@ -371,6 +372,37 @@
 }
 
 /**
+ * scsi_target_reap_ref_release - remove target from visibility
+ * @kref: the reap_ref in the target being released
+ *
+ * Called on last put of reap_ref, which is the indication that no device
+ * under this target is visible anymore, so render the target invisible in
+ * sysfs.  Note: we have to be in user context here because the target reaps
+ * should be done in places where the scsi device visibility is being removed.
+ */
+static void scsi_target_reap_ref_release(struct kref *kref)
+{
+	struct scsi_target *starget
+		= container_of(kref, struct scsi_target, reap_ref);
+
+	/*
+	 * if we get here and the target is still in the CREATED state that
+	 * means it was allocated but never made visible (because a scan
+	 * turned up no LUNs), so don't call device_del() on it.
+	 */
+	if (starget->state != STARGET_CREATED) {
+		transport_remove_device(&starget->dev);
+		device_del(&starget->dev);
+	}
+	scsi_target_destroy(starget);
+}
+
+static void scsi_target_reap_ref_put(struct scsi_target *starget)
+{
+	kref_put(&starget->reap_ref, scsi_target_reap_ref_release);
+}
+
+/**
  * scsi_alloc_target - allocate a new or find an existing target
  * @parent:	parent of the target (need not be a scsi host)
  * @channel:	target channel number (zero if no channels)
@@ -392,7 +424,7 @@
 		+ shost->transportt->target_size;
 	struct scsi_target *starget;
 	struct scsi_target *found_target;
-	int error;
+	int error, ref_got;
 
 	starget = kzalloc(size, GFP_KERNEL);
 	if (!starget) {
@@ -401,7 +433,7 @@
 	}
 	dev = &starget->dev;
 	device_initialize(dev);
-	starget->reap_ref = 1;
+	kref_init(&starget->reap_ref);
 	dev->parent = get_device(parent);
 	dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
 	dev->bus = &scsi_bus_type;
@@ -441,29 +473,36 @@
 	return starget;
 
  found:
-	found_target->reap_ref++;
+	/*
+	 * release routine already fired if kref is zero, so if we can still
+	 * take the reference, the target must be alive.  If we can't, it must
+	 * be dying and we need to wait for a new target
+	 */
+	ref_got = kref_get_unless_zero(&found_target->reap_ref);
+
 	spin_unlock_irqrestore(shost->host_lock, flags);
-	if (found_target->state != STARGET_DEL) {
+	if (ref_got) {
 		put_device(dev);
 		return found_target;
 	}
-	/* Unfortunately, we found a dying target; need to
-	 * wait until it's dead before we can get a new one */
+	/*
+	 * Unfortunately, we found a dying target; need to wait until it's
+	 * dead before we can get a new one.  There is an anomaly here.  We
+	 * *should* call scsi_target_reap() to balance the kref_get() of the
+	 * reap_ref above.  However, since the target being released, it's
+	 * already invisible and the reap_ref is irrelevant.  If we call
+	 * scsi_target_reap() we might spuriously do another device_del() on
+	 * an already invisible target.
+	 */
 	put_device(&found_target->dev);
-	flush_scheduled_work();
+	/*
+	 * length of time is irrelevant here, we just want to yield the CPU
+	 * for a tick to avoid busy waiting for the target to die.
+	 */
+	msleep(1);
 	goto retry;
 }
 
-static void scsi_target_reap_usercontext(struct work_struct *work)
-{
-	struct scsi_target *starget =
-		container_of(work, struct scsi_target, ew.work);
-
-	transport_remove_device(&starget->dev);
-	device_del(&starget->dev);
-	scsi_target_destroy(starget);
-}
-
 /**
  * scsi_target_reap - check to see if target is in use and destroy if not
  * @starget: target to be checked
@@ -474,28 +513,13 @@
  */
 void scsi_target_reap(struct scsi_target *starget)
 {
-	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-	unsigned long flags;
-	enum scsi_target_state state;
-	int empty = 0;
-
-	spin_lock_irqsave(shost->host_lock, flags);
-	state = starget->state;
-	if (--starget->reap_ref == 0 && list_empty(&starget->devices)) {
-		empty = 1;
-		starget->state = STARGET_DEL;
-	}
-	spin_unlock_irqrestore(shost->host_lock, flags);
-
-	if (!empty)
-		return;
-
-	BUG_ON(state == STARGET_DEL);
-	if (state == STARGET_CREATED)
-		scsi_target_destroy(starget);
-	else
-		execute_in_process_context(scsi_target_reap_usercontext,
-					   &starget->ew);
+	/*
+	 * serious problem if this triggers: STARGET_DEL is only set in the if
+	 * the reap_ref drops to zero, so we're trying to do another final put
+	 * on an already released kref
+	 */
+	BUG_ON(starget->state == STARGET_DEL);
+	scsi_target_reap_ref_put(starget);
 }
 
 /**
@@ -1532,6 +1556,10 @@
 	}
 	mutex_unlock(&shost->scan_mutex);
 	scsi_autopm_put_target(starget);
+	/*
+	 * paired with scsi_alloc_target().  Target will be destroyed unless
+	 * scsi_probe_and_add_lun made an underlying device visible
+	 */
 	scsi_target_reap(starget);
 	put_device(&starget->dev);
 
@@ -1612,8 +1640,10 @@
 
  out_reap:
 	scsi_autopm_put_target(starget);
-	/* now determine if the target has any children at all
-	 * and if not, nuke it */
+	/*
+	 * paired with scsi_alloc_target(): determine if the target has
+	 * any children at all and if not, nuke it
+	 */
 	scsi_target_reap(starget);
 
 	put_device(&starget->dev);
diff -ruw linux-3.11.10/drivers/scsi/scsi_sysfs.c linux-3.11.10-fbx/drivers/scsi/scsi_sysfs.c
--- linux-3.11.10/drivers/scsi/scsi_sysfs.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/scsi/scsi_sysfs.c	2014-07-01 16:22:13.126329546 +0200
@@ -332,17 +332,14 @@
 {
 	struct scsi_device *sdev;
 	struct device *parent;
-	struct scsi_target *starget;
 	struct list_head *this, *tmp;
 	unsigned long flags;
 
 	sdev = container_of(work, struct scsi_device, ew.work);
 
 	parent = sdev->sdev_gendev.parent;
-	starget = to_scsi_target(parent);
 
 	spin_lock_irqsave(sdev->host->host_lock, flags);
-	starget->reap_ref++;
 	list_del(&sdev->siblings);
 	list_del(&sdev->same_target_siblings);
 	list_del(&sdev->starved_entry);
@@ -362,8 +359,6 @@
 	/* NULL queue means the device can't be used */
 	sdev->request_queue = NULL;
 
-	scsi_target_reap(scsi_target(sdev));
-
 	kfree(sdev->inquiry);
 	kfree(sdev);
 
@@ -1008,6 +1003,13 @@
 		sdev->host->hostt->slave_destroy(sdev);
 	transport_destroy_device(dev);
 
+	/*
+	 * Paired with the kref_get() in scsi_sysfs_initialize().  We have
+	 * remoed sysfs visibility from the device, so make the target
+	 * invisible if this was the last device underneath it.
+	 */
+	scsi_target_reap(scsi_target(sdev));
+
 	put_device(dev);
 }
 
@@ -1070,7 +1072,7 @@
 			continue;
 		if (starget->dev.parent == dev || &starget->dev == dev) {
 			/* assuming new targets arrive at the end */
-			starget->reap_ref++;
+			kref_get(&starget->reap_ref);
 			spin_unlock_irqrestore(shost->host_lock, flags);
 			if (last)
 				scsi_target_reap(last);
@@ -1154,6 +1156,12 @@
 	list_add_tail(&sdev->same_target_siblings, &starget->devices);
 	list_add_tail(&sdev->siblings, &shost->__devices);
 	spin_unlock_irqrestore(shost->host_lock, flags);
+	/*
+	 * device can now only be removed via __scsi_remove_device() so hold
+	 * the target.  Target will be held in CREATED state until something
+	 * beneath it becomes visible (in which case it moves to RUNNING)
+	 */
+	kref_get(&starget->reap_ref);
 }
 
 int scsi_is_sdev_device(const struct device *dev)
diff -ruw linux-3.11.10/drivers/scsi/sd.c linux-3.11.10-fbx/drivers/scsi/sd.c
--- linux-3.11.10/drivers/scsi/sd.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/scsi/sd.c	2014-05-09 14:12:53.184546142 +0200
@@ -2637,14 +2637,23 @@
 {
 	struct scsi_device *sdev = sdkp->device;
 
+	if (sdev->host->no_write_same) {
+		sdev->no_write_same = 1;
+
+		return;
+	}
+
 	if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY) < 0) {
+		/* too large values might cause issues with arcmsr */
+		int vpd_buf_len = 64;
+
 		sdev->no_report_opcodes = 1;
 
 		/* Disable WRITE SAME if REPORT SUPPORTED OPERATION
 		 * CODES is unsupported and the device has an ATA
 		 * Information VPD page (SAT).
 		 */
-		if (!scsi_get_vpd_page(sdev, 0x89, buffer, SD_BUF_SIZE))
+		if (!scsi_get_vpd_page(sdev, 0x89, buffer, vpd_buf_len))
 			sdev->no_write_same = 1;
 	}
 
diff -ruw linux-3.11.10/drivers/spi/Kconfig linux-3.11.10-fbx/drivers/spi/Kconfig
--- linux-3.11.10/drivers/spi/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/spi/Kconfig	2013-12-04 14:33:20.699479001 +0100
@@ -327,6 +327,12 @@
 	def_bool y
 	depends on SPI_PXA2XX && !SPI_PXA2XX_PXADMA
 
+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 || PCI || ACPI) && GENERIC_HARDIRQS
diff -ruw linux-3.11.10/drivers/spi/Makefile linux-3.11.10-fbx/drivers/spi/Makefile
--- linux-3.11.10/drivers/spi/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/spi/Makefile	2013-12-04 14:33:20.699479001 +0100
@@ -47,6 +47,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
 spi-pxa2xx-platform-objs		:= spi-pxa2xx.o
diff -ruw linux-3.11.10/drivers/staging/tidspbridge/Kconfig linux-3.11.10-fbx/drivers/staging/tidspbridge/Kconfig
--- linux-3.11.10/drivers/staging/tidspbridge/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/staging/tidspbridge/Kconfig	2014-01-17 19:14:18.718220808 +0100
@@ -4,7 +4,7 @@
 
 menuconfig TIDSPBRIDGE
 	tristate "DSP Bridge driver"
-	depends on ARCH_OMAP3 && !ARCH_MULTIPLATFORM
+	depends on ARCH_OMAP3 && !ARCH_MULTIPLATFORM && BROKEN
 	select MAILBOX
 	select OMAP2PLUS_MBOX
 	help
diff -ruw linux-3.11.10/drivers/thermal/thermal_core.c linux-3.11.10-fbx/drivers/thermal/thermal_core.c
--- linux-3.11.10/drivers/thermal/thermal_core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/thermal/thermal_core.c	2014-08-22 15:47:22.112063027 +0200
@@ -971,6 +971,12 @@
 	return NULL;
 }
 
+static bool thermal_zone_crit_temp_valid(struct thermal_zone_device *tz)
+{
+	unsigned long temp;
+	return tz->ops->get_crit_temp && !tz->ops->get_crit_temp(tz, &temp);
+}
+
 static int
 thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
 {
@@ -1021,9 +1027,7 @@
 	if (result)
 		goto free_temp_mem;
 
-	if (tz->ops->get_crit_temp) {
-		unsigned long temperature;
-		if (!tz->ops->get_crit_temp(tz, &temperature)) {
+	if (thermal_zone_crit_temp_valid(tz)) {
 			snprintf(temp->temp_crit.name,
 				 sizeof(temp->temp_crit.name),
 				"temp%d_crit", hwmon->count);
@@ -1036,7 +1040,6 @@
 			if (result)
 				goto unregister_input;
 		}
-	}
 
 	mutex_lock(&thermal_list_lock);
 	if (new_hwmon_device)
@@ -1083,7 +1086,7 @@
 	}
 
 	device_remove_file(hwmon->device, &temp->temp_input.attr);
-	if (tz->ops->get_crit_temp)
+	if (thermal_zone_crit_temp_valid(tz))
 		device_remove_file(hwmon->device, &temp->temp_crit.attr);
 
 	mutex_lock(&thermal_list_lock);
diff -ruw linux-3.11.10/drivers/tty/n_tty.c linux-3.11.10-fbx/drivers/tty/n_tty.c
--- linux-3.11.10/drivers/tty/n_tty.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/tty/n_tty.c	2014-07-01 16:22:13.134329598 +0200
@@ -2066,8 +2066,12 @@
 			if (tty->ops->flush_chars)
 				tty->ops->flush_chars(tty);
 		} else {
+			struct n_tty_data *ldata = tty->disc_data;
+
 			while (nr > 0) {
+				mutex_lock(&ldata->output_lock);
 				c = tty->ops->write(tty, b, nr);
+				mutex_unlock(&ldata->output_lock);
 				if (c < 0) {
 					retval = c;
 					goto break_out;
diff -ruw linux-3.11.10/drivers/tty/serial/8250/8250_core.c linux-3.11.10-fbx/drivers/tty/serial/8250/8250_core.c
--- linux-3.11.10/drivers/tty/serial/8250/8250_core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/tty/serial/8250/8250_core.c	2014-07-01 16:22:13.134329598 +0200
@@ -42,6 +42,12 @@
 #include <linux/sunserialcore.h>
 #endif
 
+#ifdef CONFIG_TANGO2
+#include <asm/mach-tango2/tango2_gbus.h>
+
+extern unsigned long em8xxx_sys_frequency;
+#endif
+
 #include <asm/io.h>
 #include <asm/irq.h>
 
@@ -325,20 +331,30 @@
 	},
 };
 
+
 /* Uart divisor latch read */
 static int default_serial_dl_read(struct uart_8250_port *up)
 {
+#ifndef CONFIG_TANGO2
 	return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8;
+#else
+	BUG();
+	return 0;
+#endif
 }
 
 /* Uart divisor latch write */
 static void default_serial_dl_write(struct uart_8250_port *up, int value)
 {
+#ifndef CONFIG_TANGO2
 	serial_out(up, UART_DLL, value & 0xff);
 	serial_out(up, UART_DLM, value >> 8 & 0xff);
+#else
+	BUG();
+#endif
 }
 
-#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X)
+#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) || defined(CONFIG_WINTEGRA_WINPATH3)
 
 /* Au1x00/RT288x UART hardware has a weird register layout */
 static const u8 au_io_in_map[] = {
@@ -400,14 +416,44 @@
 
 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 = 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 = offset << p->regshift;
 	writeb(value, p->membase + offset);
+#endif
 }
 
 static void mem32_serial_out(struct uart_port *p, int offset, int value)
@@ -461,7 +507,7 @@
 		p->serial_out = mem32_serial_out;
 		break;
 
-#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X)
+#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) || defined(CONFIG_WINTEGRA_WINPATH3)
 	case UPIO_AU:
 		p->serial_in = au_serial_in;
 		p->serial_out = au_serial_out;
@@ -555,7 +601,7 @@
 	 */
 	if ((p->port.type == PORT_XR17V35X) ||
 	   (p->port.type == PORT_XR17D15X)) {
-		serial_out(p, UART_EXAR_SLEEP, 0xff);
+		serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0);
 		return;
 	}
 
@@ -650,7 +696,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_in(up, UART_LCR);
@@ -661,8 +711,14 @@
 		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
 	serial_out(up, UART_MCR, UART_MCR_LOOP);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+#ifdef CONFIG_TANGO2
+	old_dll = serial_in(up, UART_DL) & 0xff;
+	old_dlm = serial_in(up, UART_DL) >> 8;
+	serial_out(up, UART_DL, 0x01);
+#else
 	old_dl = serial_dl_read(up);
 	serial_dl_write(up, 0x0001);
+#endif
 	serial_out(up, UART_LCR, 0x03);
 	for (count = 0; count < 256; count++)
 		serial_out(up, UART_TX, count);
@@ -673,7 +729,11 @@
 	serial_out(up, UART_FCR, old_fcr);
 	serial_out(up, UART_MCR, old_mcr);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+#ifdef CONFIG_TANGO2
+	serial_out(up, UART_DL, (old_dlm << 8) | old_dll);
+#else
 	serial_dl_write(up, old_dl);
+#endif
 	serial_out(up, UART_LCR, old_lcr);
 
 	return count;
@@ -692,6 +752,16 @@
 	old_lcr = serial_in(p, UART_LCR);
 	serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A);
 
+#ifdef CONFIG_TANGO2
+	old_dll = serial_in(p, UART_DL) & 0xff;
+	old_dlm = serial_in(p, UART_DL) >> 8;
+
+	serial_out(p, UART_DL, 0);
+
+	id = serial_in(p, UART_DL);
+
+	serial_out(p, UART_DL, (old_dlm << 8) | old_dll);
+#else
 	old_dll = serial_in(p, UART_DLL);
 	old_dlm = serial_in(p, UART_DLM);
 
@@ -702,6 +772,7 @@
 
 	serial_out(p, UART_DLL, old_dll);
 	serial_out(p, UART_DLM, old_dlm);
+#endif
 	serial_out(p, UART_LCR, old_lcr);
 
 	return id;
@@ -941,11 +1012,19 @@
 
 			serial_out(up, UART_LCR, 0xE0);
 
+#ifdef CONFIG_TANGO2
+			quot = serial_in(up, UART_DL);
+#else
 			quot = serial_dl_read(up);
+#endif
 			quot <<= 3;
 
 			if (ns16550a_goto_highspeed(up))
+#ifdef CONFIG_TANGO2
+				serial_out(up, UART_DL, quot);
+#else
 				serial_dl_write(up, quot);
+#endif
 
 			serial_out(up, UART_LCR, 0);
 
@@ -1520,7 +1599,7 @@
 			status = serial8250_rx_chars(up, status);
 	}
 	serial8250_modem_status(up);
-	if (status & UART_LSR_THRE)
+	if (!up->dma && (status & UART_LSR_THRE))
 		serial8250_tx_chars(up);
 
 	spin_unlock_irqrestore(&port->lock, flags);
@@ -2430,7 +2509,11 @@
 	else
 		serial_port_out(port, UART_LCR, cval | UART_LCR_DLAB);
 
+#ifdef CONFIG_TANGO2
+	serial_out(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
@@ -2670,6 +2753,10 @@
 	if (port->type == PORT_16550A && port->iotype == UPIO_AU)
 		up->bugs |= UART_BUG_NOMSR;
 
+	/* HW bugs may trigger IRQ while IIR == NO_INT */
+	if (port->type == PORT_TEGRA)
+		up->bugs |= UART_BUG_NOMSR;
+
 	if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
 		autoconfig_irq(up);
 
diff -ruw linux-3.11.10/drivers/tty/serial/8250/8250_early.c linux-3.11.10-fbx/drivers/tty/serial/8250/8250_early.c
--- linux-3.11.10/drivers/tty/serial/8250/8250_early.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/tty/serial/8250/8250_early.c	2013-12-04 14:33:21.099479007 +0100
@@ -121,8 +121,13 @@
 
 	lcr = serial8250_early_in(port, UART_LCR);
 	serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
+#ifdef CONFIG_TANGO2
+	dll = serial8250_early_in(port, UART_DL) & 0xff;
+	dlm = serial8250_early_in(port, UART_DL) >> 8;
+#else
 	dll = serial8250_early_in(port, UART_DLL);
 	dlm = serial8250_early_in(port, UART_DLM);
+#endif
 	serial8250_early_out(port, UART_LCR, lcr);
 
 	quot = (dlm << 8) | dll;
@@ -143,8 +148,12 @@
 	divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud);
 	c = serial8250_early_in(port, UART_LCR);
 	serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB);
+#ifdef CONFIG_TANGO2
+	serial8250_early_out(port, UART_DL, divisor & 0xffff);
+#else
 	serial8250_early_out(port, UART_DLL, divisor & 0xff);
 	serial8250_early_out(port, UART_DLM, (divisor >> 8) & 0xff);
+#endif
 	serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB);
 }
 
diff -ruw linux-3.11.10/drivers/tty/serial/8250/8250_pci.c linux-3.11.10-fbx/drivers/tty/serial/8250/8250_pci.c
--- linux-3.11.10/drivers/tty/serial/8250/8250_pci.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/tty/serial/8250/8250_pci.c	2014-05-09 14:12:53.204546142 +0200
@@ -1260,10 +1260,10 @@
 		unsigned long base = pci_resource_start(dev, 0);
 		if (base) {
 			u32 tmp;
-			outl(inl(base + 0x38), base + 0x38);
+			outl(inl(base + 0x38) | 0x00002000, base + 0x38);
 			tmp = inl(base + 0x3c);
 			outl(tmp | 0x01000000, base + 0x3c);
-			outl(tmp, base + 0x3c);
+			outl(tmp &= ~0x01000000, base + 0x3c);
 		}
 	}
 	return 0;
@@ -1545,6 +1545,7 @@
 #define PCI_DEVICE_ID_TITAN_800E	0xA014
 #define PCI_DEVICE_ID_TITAN_200EI	0xA016
 #define PCI_DEVICE_ID_TITAN_200EISI	0xA017
+#define PCI_DEVICE_ID_TITAN_200V3	0xA306
 #define PCI_DEVICE_ID_TITAN_400V3	0xA310
 #define PCI_DEVICE_ID_TITAN_410V3	0xA312
 #define PCI_DEVICE_ID_TITAN_800V3	0xA314
@@ -4139,6 +4140,9 @@
 	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_oxsemi_2_4000000 },
+	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200V3,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_2_921600 },
 	{	PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400V3,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_b0_4_921600 },
diff -ruw linux-3.11.10/drivers/tty/tty_io.c linux-3.11.10-fbx/drivers/tty/tty_io.c
--- linux-3.11.10/drivers/tty/tty_io.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/tty/tty_io.c	2014-07-01 16:22:13.134329598 +0200
@@ -1267,12 +1267,13 @@
  *
  *	Locking: None
  */
-static void tty_line_name(struct tty_driver *driver, int index, char *p)
+static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p)
 {
 	if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE)
-		strcpy(p, driver->name);
+		return sprintf(p, "%s", driver->name);
 	else
-		sprintf(p, "%s%d", driver->name, index + driver->name_base);
+		return sprintf(p, "%s%d", driver->name,
+			       index + driver->name_base);
 }
 
 /**
@@ -3539,9 +3540,19 @@
 		if (i >= ARRAY_SIZE(cs))
 			break;
 	}
-	while (i--)
-		count += sprintf(buf + count, "%s%d%c",
-				 cs[i]->name, cs[i]->index, i ? ' ':'\n');
+	while (i--) {
+		int index = cs[i]->index;
+		struct tty_driver *drv = cs[i]->device(cs[i], &index);
+
+		/* don't resolve tty0 as some programs depend on it */
+		if (drv && (cs[i]->index > 0 || drv->major != TTY_MAJOR))
+			count += tty_line_name(drv, index, buf + count);
+		else
+			count += sprintf(buf + count, "%s%d",
+					 cs[i]->name, cs[i]->index);
+
+		count += sprintf(buf + count, "%c", i ? ' ':'\n');
+	}
 	console_unlock();
 
 	return count;
diff -ruw linux-3.11.10/drivers/tty/vt/vt.c linux-3.11.10-fbx/drivers/tty/vt/vt.c
--- linux-3.11.10/drivers/tty/vt/vt.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/tty/vt/vt.c	2014-05-09 14:12:53.208546142 +0200
@@ -1164,6 +1164,8 @@
 			scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
 				    vc->vc_screenbuf_size >> 1);
 			set_origin(vc);
+			if (CON_IS_VISIBLE(vc))
+				update_screen(vc);
 			/* fall through */
 		case 2: /* erase whole display */
 			count = vc->vc_cols * vc->vc_rows;
diff -ruw linux-3.11.10/drivers/usb/core/config.c linux-3.11.10-fbx/drivers/usb/core/config.c
--- linux-3.11.10/drivers/usb/core/config.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/core/config.c	2014-07-01 16:22:13.134329598 +0200
@@ -651,10 +651,6 @@
  *
  * hub-only!! ... and only in reset path, or usb_new_device()
  * (used by real hubs and virtual root hubs)
- *
- * NOTE: if this is a WUSB device and is not authorized, we skip the
- *       whole thing. A non-authorized USB device has no
- *       configurations.
  */
 int usb_get_configuration(struct usb_device *dev)
 {
@@ -666,8 +662,6 @@
 	struct usb_config_descriptor *desc;
 
 	cfgno = 0;
-	if (dev->authorized == 0)	/* Not really an error */
-		goto out_not_authorized;
 	result = -ENOMEM;
 	if (ncfg > USB_MAXCONFIG) {
 		dev_warn(ddev, "too many configurations: %d, "
@@ -724,6 +718,10 @@
 			result = -ENOMEM;
 			goto err;
 		}
+
+		if (dev->quirks & USB_QUIRK_DELAY_INIT)
+			msleep(100);
+
 		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
 		    bigbuffer, length);
 		if (result < 0) {
@@ -751,7 +749,6 @@
 
 err:
 	kfree(desc);
-out_not_authorized:
 	dev->descriptor.bNumConfigurations = cfgno;
 err2:
 	if (result == -ENOMEM)
diff -ruw linux-3.11.10/drivers/usb/core/driver.c linux-3.11.10-fbx/drivers/usb/core/driver.c
--- linux-3.11.10/drivers/usb/core/driver.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/core/driver.c	2014-07-01 16:22:13.138329612 +0200
@@ -953,8 +953,7 @@
  * it doesn't support pre_reset/post_reset/reset_resume or
  * because it doesn't support suspend/resume.
  *
- * The caller must hold @intf's device's lock, but not its pm_mutex
- * and not @intf->dev.sem.
+ * The caller must hold @intf's device's lock, but not @intf's lock.
  */
 void usb_forced_unbind_intf(struct usb_interface *intf)
 {
@@ -967,16 +966,37 @@
 	intf->needs_binding = 1;
 }
 
+/*
+ * Unbind drivers for @udev's marked interfaces.  These interfaces have
+ * the needs_binding flag set, for example by usb_resume_interface().
+ *
+ * The caller must hold @udev's device lock.
+ */
+static void unbind_marked_interfaces(struct usb_device *udev)
+{
+	struct usb_host_config	*config;
+	int			i;
+	struct usb_interface	*intf;
+
+	config = udev->actconfig;
+	if (config) {
+		for (i = 0; i < config->desc.bNumInterfaces; ++i) {
+			intf = config->interface[i];
+			if (intf->dev.driver && intf->needs_binding)
+				usb_forced_unbind_intf(intf);
+		}
+	}
+}
+
 /* Delayed forced unbinding of a USB interface driver and scan
  * for rebinding.
  *
- * The caller must hold @intf's device's lock, but not its pm_mutex
- * and not @intf->dev.sem.
+ * The caller must hold @intf's device's lock, but not @intf's lock.
  *
  * Note: Rebinds will be skipped if a system sleep transition is in
  * progress and the PM "complete" callback hasn't occurred yet.
  */
-void usb_rebind_intf(struct usb_interface *intf)
+static void usb_rebind_intf(struct usb_interface *intf)
 {
 	int rc;
 
@@ -993,68 +1013,66 @@
 	}
 }
 
-#ifdef CONFIG_PM
-
-/* Unbind drivers for @udev's interfaces that don't support suspend/resume
- * There is no check for reset_resume here because it can be determined
- * only during resume whether reset_resume is needed.
+/*
+ * Rebind drivers to @udev's marked interfaces.  These interfaces have
+ * the needs_binding flag set.
  *
  * The caller must hold @udev's device lock.
  */
-static void unbind_no_pm_drivers_interfaces(struct usb_device *udev)
+static void rebind_marked_interfaces(struct usb_device *udev)
 {
 	struct usb_host_config	*config;
 	int			i;
 	struct usb_interface	*intf;
-	struct usb_driver	*drv;
 
 	config = udev->actconfig;
 	if (config) {
 		for (i = 0; i < config->desc.bNumInterfaces; ++i) {
 			intf = config->interface[i];
-
-			if (intf->dev.driver) {
-				drv = to_usb_driver(intf->dev.driver);
-				if (!drv->suspend || !drv->resume)
-					usb_forced_unbind_intf(intf);
-			}
+			if (intf->needs_binding)
+				usb_rebind_intf(intf);
 		}
 	}
 }
 
-/* Unbind drivers for @udev's interfaces that failed to support reset-resume.
- * These interfaces have the needs_binding flag set by usb_resume_interface().
+/*
+ * Unbind all of @udev's marked interfaces and then rebind all of them.
+ * This ordering is necessary because some drivers claim several interfaces
+ * when they are first probed.
  *
  * The caller must hold @udev's device lock.
  */
-static void unbind_no_reset_resume_drivers_interfaces(struct usb_device *udev)
+void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev)
 {
-	struct usb_host_config	*config;
-	int			i;
-	struct usb_interface	*intf;
-
-	config = udev->actconfig;
-	if (config) {
-		for (i = 0; i < config->desc.bNumInterfaces; ++i) {
-			intf = config->interface[i];
-			if (intf->dev.driver && intf->needs_binding)
-				usb_forced_unbind_intf(intf);
-		}
-	}
+	unbind_marked_interfaces(udev);
+	rebind_marked_interfaces(udev);
 }
 
-static void do_rebind_interfaces(struct usb_device *udev)
+#ifdef CONFIG_PM
+
+/* Unbind drivers for @udev's interfaces that don't support suspend/resume
+ * There is no check for reset_resume here because it can be determined
+ * only during resume whether reset_resume is needed.
+ *
+ * The caller must hold @udev's device lock.
+ */
+static void unbind_no_pm_drivers_interfaces(struct usb_device *udev)
 {
 	struct usb_host_config	*config;
 	int			i;
 	struct usb_interface	*intf;
+	struct usb_driver	*drv;
 
 	config = udev->actconfig;
 	if (config) {
 		for (i = 0; i < config->desc.bNumInterfaces; ++i) {
 			intf = config->interface[i];
-			if (intf->needs_binding)
-				usb_rebind_intf(intf);
+
+			if (intf->dev.driver) {
+				drv = to_usb_driver(intf->dev.driver);
+				if (!drv->suspend || !drv->resume)
+					usb_forced_unbind_intf(intf);
+			}
 		}
 	}
 }
@@ -1379,7 +1397,7 @@
 	 * whose needs_binding flag is set
 	 */
 	if (udev->state != USB_STATE_NOTATTACHED)
-		do_rebind_interfaces(udev);
+		rebind_marked_interfaces(udev);
 	return 0;
 }
 
@@ -1401,7 +1419,7 @@
 		pm_runtime_disable(dev);
 		pm_runtime_set_active(dev);
 		pm_runtime_enable(dev);
-		unbind_no_reset_resume_drivers_interfaces(udev);
+		unbind_marked_interfaces(udev);
 	}
 
 	/* Avoid PM error messages for devices disconnected while suspended
@@ -1736,10 +1754,13 @@
 	if (status == -EAGAIN || status == -EBUSY)
 		usb_mark_last_busy(udev);
 
-	/* The PM core reacts badly unless the return code is 0,
-	 * -EAGAIN, or -EBUSY, so always return -EBUSY on an error.
+	/*
+	 * The PM core reacts badly unless the return code is 0,
+	 * -EAGAIN, or -EBUSY, so always return -EBUSY on an error
+	 * (except for root hubs, because they don't suspend through
+	 * an upstream port like other USB devices).
 	 */
-	if (status != 0)
+	if (status != 0 && udev->parent)
 		return -EBUSY;
 	return status;
 }
@@ -1774,6 +1795,9 @@
 	struct usb_hcd *hcd = bus_to_hcd(udev->bus);
 	int ret = -EPERM;
 
+	if (enable && !udev->usb2_hw_lpm_allowed)
+		return 0;
+
 	if (hcd->driver->set_usb2_hw_lpm) {
 		ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable);
 		if (!ret)
diff -ruw linux-3.11.10/drivers/usb/core/hcd.c linux-3.11.10-fbx/drivers/usb/core/hcd.c
--- linux-3.11.10/drivers/usb/core/hcd.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/core/hcd.c	2014-05-09 14:12:53.324546144 +0200
@@ -1035,7 +1035,6 @@
 					dev_name(&usb_dev->dev), retval);
 			return retval;
 		}
-		usb_dev->lpm_capable = usb_device_supports_lpm(usb_dev);
 	}
 
 	retval = usb_new_device (usb_dev);
diff -ruw linux-3.11.10/drivers/usb/core/hcd-pci.c linux-3.11.10-fbx/drivers/usb/core/hcd-pci.c
--- linux-3.11.10/drivers/usb/core/hcd-pci.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/core/hcd-pci.c	2014-07-01 16:22:13.138329612 +0200
@@ -75,7 +75,7 @@
 				PCI_SLOT(companion->devfn) != slot)
 			continue;
 		companion_hcd = pci_get_drvdata(companion);
-		if (!companion_hcd)
+		if (!companion_hcd || !companion_hcd->self.root_hub)
 			continue;
 		fn(pdev, hcd, companion, companion_hcd);
 	}
diff -ruw linux-3.11.10/drivers/usb/core/hub.c linux-3.11.10-fbx/drivers/usb/core/hub.c
--- linux-3.11.10/drivers/usb/core/hub.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/core/hub.c	2014-07-01 16:22:13.138329612 +0200
@@ -135,7 +135,7 @@
 	return usb_get_intfdata(hdev->actconfig->interface[0]);
 }
 
-int usb_device_supports_lpm(struct usb_device *udev)
+static int usb_device_supports_lpm(struct usb_device *udev)
 {
 	/* USB 2.1 (and greater) devices indicate LPM support through
 	 * their USB 2.0 Extended Capabilities BOS descriptor.
@@ -156,11 +156,6 @@
 				"Power management will be impacted.\n");
 		return 0;
 	}
-
-	/* udev is root hub */
-	if (!udev->parent)
-		return 1;
-
 	if (udev->parent->lpm_capable)
 		return 1;
 
@@ -1129,6 +1124,11 @@
 			usb_clear_port_feature(hub->hdev, port1,
 					USB_PORT_FEAT_C_ENABLE);
 		}
+		if (portchange & USB_PORT_STAT_C_RESET) {
+			need_debounce_delay = true;
+			usb_clear_port_feature(hub->hdev, port1,
+					USB_PORT_FEAT_C_RESET);
+		}
 		if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
 				hub_is_superspeed(hub->hdev)) {
 			need_debounce_delay = true;
@@ -1600,7 +1600,7 @@
 {
 	struct usb_hub *hub = usb_get_intfdata(intf);
 	struct usb_device *hdev = interface_to_usbdev(intf);
-	int i;
+	int port1;
 
 	/* Take the hub off the event list and don't let it be added again */
 	spin_lock_irq(&hub_event_lock);
@@ -1615,11 +1615,15 @@
 	hub->error = 0;
 	hub_quiesce(hub, HUB_DISCONNECT);
 
+	/* Avoid races with recursively_mark_NOTATTACHED() */
+	spin_lock_irq(&device_state_lock);
+	port1 = hdev->maxchild;
+	hdev->maxchild = 0;
 	usb_set_intfdata (intf, NULL);
+	spin_unlock_irq(&device_state_lock);
 
-	for (i = 0; i < hdev->maxchild; i++)
-		usb_hub_remove_port_device(hub, i + 1);
-	hub->hdev->maxchild = 0;
+	for (; port1 > 0; --port1)
+		usb_hub_remove_port_device(hub, port1);
 
 	if (hub->hdev->speed == USB_SPEED_HIGH)
 		highspeed_hubs--;
@@ -1679,8 +1683,19 @@
 	 */
 	pm_runtime_set_autosuspend_delay(&hdev->dev, 0);
 
-	/* Hubs have proper suspend/resume support. */
+	/*
+	 * Hubs have proper suspend/resume support, except for root hubs
+	 * where the controller driver doesn't have bus_suspend and
+	 * bus_resume methods.
+	 */
+	if (hdev->parent) {		/* normal device */
 	usb_enable_autosuspend(hdev);
+	} else {			/* root hub */
+		const struct hc_driver *drv = bus_to_hcd(hdev->bus)->driver;
+
+		if (drv->bus_suspend && drv->bus_resume)
+			usb_enable_autosuspend(hdev);
+	}
 
 	if (hdev->level == MAX_TOPO_LEVEL) {
 		dev_err(&intf->dev,
@@ -2224,18 +2239,13 @@
 			return err;
 		}
 	}
-	if (udev->wusb == 1 && udev->authorized == 0) {
-		udev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
-		udev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
-		udev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
-	}
-	else {
+
 		/* read the standard strings and cache them if present */
 		udev->product = usb_cache_string(udev, udev->descriptor.iProduct);
 		udev->manufacturer = usb_cache_string(udev,
 						      udev->descriptor.iManufacturer);
 		udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
-	}
+
 	err = usb_enumerate_device_otg(udev);
 	if (err < 0)
 		return err;
@@ -2414,16 +2424,6 @@
 	usb_dev->authorized = 0;
 	usb_set_configuration(usb_dev, -1);
 
-	kfree(usb_dev->product);
-	usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
-	kfree(usb_dev->manufacturer);
-	usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
-	kfree(usb_dev->serial);
-	usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
-
-	usb_destroy_configuration(usb_dev);
-	usb_dev->descriptor.bNumConfigurations = 0;
-
 out_unauthorized:
 	usb_unlock_device(usb_dev);
 	return 0;
@@ -2451,17 +2451,7 @@
 		goto error_device_descriptor;
 	}
 
-	kfree(usb_dev->product);
-	usb_dev->product = NULL;
-	kfree(usb_dev->manufacturer);
-	usb_dev->manufacturer = NULL;
-	kfree(usb_dev->serial);
-	usb_dev->serial = NULL;
-
 	usb_dev->authorized = 1;
-	result = usb_enumerate_device(usb_dev);
-	if (result < 0)
-		goto error_enumerate;
 	/* Choose and set the configuration.  This registers the interfaces
 	 * with the driver core and lets interface drivers bind to them.
 	 */
@@ -2477,7 +2467,6 @@
 	}
 	dev_info(&usb_dev->dev, "authorized to connect\n");
 
-error_enumerate:
 error_device_descriptor:
 	usb_autosuspend_device(usb_dev);
 error_autoresume:
@@ -3952,6 +3941,32 @@
 	return retval;
 }
 
+/*
+ * There are reports of USB 3.0 devices that say they support USB 2.0 Link PM
+ * when they're plugged into a USB 2.0 port, but they don't work when LPM is
+ * enabled.
+ *
+ * Only enable USB 2.0 Link PM if the port is internal (hardwired), or the
+ * device says it supports the new USB 2.0 Link PM errata by setting the BESL
+ * support bit in the BOS descriptor.
+ */
+static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev)
+{
+	int connect_type;
+
+	if (!udev->usb2_hw_lpm_capable)
+		return;
+
+	connect_type = usb_get_hub_port_connect_type(udev->parent,
+			udev->portnum);
+
+	if ((udev->bos->ext_cap->bmAttributes & USB_BESL_SUPPORT) ||
+			connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
+		udev->usb2_hw_lpm_allowed = 1;
+		usb_set_usb2_hardware_lpm(udev, 1);
+	}
+}
+
 /* Reset device, (re)assign address, get device descriptor.
  * Device connection must be stable, no more debouncing needed.
  * Returns device in USB_STATE_ADDRESS, except on error.
@@ -4245,6 +4260,7 @@
 	/* notify HCD that we have a device connected and addressed */
 	if (hcd->driver->update_device)
 		hcd->driver->update_device(hcd, udev);
+	hub_set_initial_usb2_lpm_policy(udev);
 fail:
 	if (retval) {
 		hub_port_disable(hub, port1, 0);
@@ -4805,8 +4821,9 @@
 					hub->ports[i - 1]->child;
 
 				dev_dbg(hub_dev, "warm reset port %d\n", i);
-				if (!udev || !(portstatus &
-						USB_PORT_STAT_CONNECTION)) {
+				if (!udev ||
+				    !(portstatus & USB_PORT_STAT_CONNECTION) ||
+				    udev->state == USB_STATE_NOTATTACHED) {
 					status = hub_port_reset(hub, i,
 							NULL, HUB_BH_RESET_TIME,
 							true);
@@ -5079,6 +5096,12 @@
 	}
 	parent_hub = usb_hub_to_struct_hub(parent_hdev);
 
+	/* Disable USB2 hardware LPM.
+	 * It will be re-enabled by the enumeration process.
+	 */
+	if (udev->usb2_hw_lpm_enabled == 1)
+		usb_set_usb2_hardware_lpm(udev, 0);
+
 	/* Disable LPM and LTM while we reset the device and reinstall the alt
 	 * settings.  Device-initiated LPM settings, and system exit latency
 	 * settings are cleared when the device is reset, so we have to set
@@ -5183,6 +5206,7 @@
 
 done:
 	/* Now that the alt settings are re-installed, enable LTM and LPM. */
+	usb_set_usb2_hardware_lpm(udev, 1);
 	usb_unlocked_enable_lpm(udev);
 	usb_enable_ltm(udev);
 	return 0;
@@ -5275,10 +5299,11 @@
 				else if (cintf->condition ==
 						USB_INTERFACE_BOUND)
 					rebind = 1;
+				if (rebind)
+					cintf->needs_binding = 1;
 			}
-			if (ret == 0 && rebind)
-				usb_rebind_intf(cintf);
 		}
+		usb_unbind_and_rebind_marked_interfaces(udev);
 	}
 
 	usb_autosuspend_device(udev);
diff -ruw linux-3.11.10/drivers/usb/core/quirks.c linux-3.11.10-fbx/drivers/usb/core/quirks.c
--- linux-3.11.10/drivers/usb/core/quirks.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/core/quirks.c	2014-07-01 16:22:13.138329612 +0200
@@ -46,6 +46,10 @@
 	/* Microsoft LifeCam-VX700 v2.0 */
 	{ USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Logitech HD Pro Webcams C920 and C930e */
+	{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
+	{ USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT },
+
 	/* Logitech Quickcam Fusion */
 	{ USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
 
diff -ruw linux-3.11.10/drivers/usb/core/sysfs.c linux-3.11.10-fbx/drivers/usb/core/sysfs.c
--- linux-3.11.10/drivers/usb/core/sysfs.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/core/sysfs.c	2014-01-17 19:14:18.726220809 +0100
@@ -463,7 +463,7 @@
 	struct usb_device *udev = to_usb_device(dev);
 	const char *p;
 
-	if (udev->usb2_hw_lpm_enabled == 1)
+	if (udev->usb2_hw_lpm_allowed == 1)
 		p = "enabled";
 	else
 		p = "disabled";
@@ -483,8 +483,10 @@
 
 	ret = strtobool(buf, &value);
 
-	if (!ret)
+	if (!ret) {
+		udev->usb2_hw_lpm_allowed = value;
 		ret = usb_set_usb2_hardware_lpm(udev, value);
+	}
 
 	usb_unlock_device(udev);
 
diff -ruw linux-3.11.10/drivers/usb/core/usb.h linux-3.11.10-fbx/drivers/usb/core/usb.h
--- linux-3.11.10/drivers/usb/core/usb.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/core/usb.h	2014-07-01 16:22:13.138329612 +0200
@@ -35,7 +35,6 @@
 		unsigned int size);
 extern int usb_get_bos_descriptor(struct usb_device *dev);
 extern void usb_release_bos_descriptor(struct usb_device *dev);
-extern int usb_device_supports_lpm(struct usb_device *udev);
 extern char *usb_cache_string(struct usb_device *udev, int index);
 extern int usb_set_configuration(struct usb_device *dev, int configuration);
 extern int usb_choose_configuration(struct usb_device *udev);
@@ -56,7 +55,7 @@
 extern int usb_match_device(struct usb_device *dev,
 			    const struct usb_device_id *id);
 extern void usb_forced_unbind_intf(struct usb_interface *intf);
-extern void usb_rebind_intf(struct usb_interface *intf);
+extern void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev);
 
 extern int usb_hub_claim_port(struct usb_device *hdev, unsigned port,
 		struct dev_state *owner);
diff -ruw linux-3.11.10/drivers/usb/gadget/Kconfig linux-3.11.10-fbx/drivers/usb/gadget/Kconfig
--- linux-3.11.10/drivers/usb/gadget/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/gadget/Kconfig	2013-12-04 14:33:21.147479008 +0100
@@ -173,7 +173,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_FSL_MPH_DR_OF if OF
 	help
 	   Some of Freescale PowerPC and i.MX processors have a High Speed
diff -ruw linux-3.11.10/drivers/usb/gadget/Makefile linux-3.11.10-fbx/drivers/usb/gadget/Makefile
--- linux-3.11.10/drivers/usb/gadget/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/gadget/Makefile	2013-12-04 14:33:21.147479008 +0100
@@ -23,6 +23,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.11.10/drivers/usb/host/ehci.h linux-3.11.10-fbx/drivers/usb/host/ehci.h
--- linux-3.11.10/drivers/usb/host/ehci.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/host/ehci.h	2014-05-09 14:12:53.468546146 +0200
@@ -200,6 +200,7 @@
 	unsigned		has_synopsys_hc_bug:1; /* Synopsys HC */
 	unsigned		frame_index_bug:1; /* MosChip (AKA NetMos) */
 	unsigned		need_oc_pp_cycle:1; /* MPC834X port power */
+	unsigned		imx28_write_fix:1; /* For Freescale i.MX28 */
 
 	/* required for usb32 quirk */
 	#define OHCI_CTRL_HCFS          (3 << 6)
@@ -675,6 +676,18 @@
 #endif
 }
 
+#ifdef CONFIG_SOC_IMX28
+static inline void imx28_ehci_writel(const unsigned int val,
+		volatile __u32 __iomem *addr)
+{
+	__asm__ ("swp %0, %0, [%1]" : : "r"(val), "r"(addr));
+}
+#else
+static inline void imx28_ehci_writel(const unsigned int val,
+		volatile __u32 __iomem *addr)
+{
+}
+#endif
 static inline void ehci_writel(const struct ehci_hcd *ehci,
 		const unsigned int val, __u32 __iomem *regs)
 {
@@ -683,6 +696,9 @@
 		writel_be(val, regs) :
 		writel(val, regs);
 #else
+	if (ehci->imx28_write_fix)
+		imx28_ehci_writel(val, regs);
+	else
 	writel(val, regs);
 #endif
 }
diff -ruw linux-3.11.10/drivers/usb/host/ehci-hcd.c linux-3.11.10-fbx/drivers/usb/host/ehci-hcd.c
--- linux-3.11.10/drivers/usb/host/ehci-hcd.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/host/ehci-hcd.c	2014-07-01 16:22:13.142329627 +0200
@@ -689,8 +689,15 @@
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
 	u32			status, masked_status, pcd_status = 0, cmd;
 	int			bh;
+	unsigned long		flags;
 
-	spin_lock (&ehci->lock);
+	/*
+	 * For threadirqs option we use spin_lock_irqsave() variant to prevent
+	 * deadlock with ehci hrtimer callback, because hrtimer callbacks run
+	 * in interrupt context even when threadirqs is specified. We can go
+	 * back to spin_lock() variant when hrtimer callbacks become threaded.
+	 */
+	spin_lock_irqsave(&ehci->lock, flags);
 
 	status = ehci_readl(ehci, &ehci->regs->status);
 
@@ -708,7 +715,7 @@
 
 	/* Shared IRQ? */
 	if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
-		spin_unlock(&ehci->lock);
+		spin_unlock_irqrestore(&ehci->lock, flags);
 		return IRQ_NONE;
 	}
 
@@ -826,7 +833,7 @@
 
 	if (bh)
 		ehci_work (ehci);
-	spin_unlock (&ehci->lock);
+	spin_unlock_irqrestore(&ehci->lock, flags);
 	if (pcd_status)
 		usb_hcd_poll_rh_status(hcd);
 	return IRQ_HANDLED;
@@ -1284,6 +1291,16 @@
 #define	PLATFORM_DRIVER		ehci_hcd_sead3_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
+
 static int __init ehci_hcd_init(void)
 {
 	int retval = 0;
diff -ruw linux-3.11.10/drivers/usb/host/Kconfig linux-3.11.10-fbx/drivers/usb/host/Kconfig
--- linux-3.11.10/drivers/usb/host/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/host/Kconfig	2013-12-04 14:33:21.175479009 +0100
@@ -130,6 +130,14 @@
 		support both high speed and full speed devices, or high speed
 		devices only.
 
+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 PPC on-chip EHCI USB controller"
 	depends on FSL_SOC
@@ -373,6 +381,15 @@
 
 if USB_OHCI_HCD
 
+config USB_OHCI_BCM63XX
+	bool "Support for Broadcom 63xx on-chip OHCI USB controller"
+	depends on 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 ARCH_OMAP1
diff -ruw linux-3.11.10/drivers/usb/host/pci-quirks.c linux-3.11.10-fbx/drivers/usb/host/pci-quirks.c
--- linux-3.11.10/drivers/usb/host/pci-quirks.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/host/pci-quirks.c	2014-08-22 15:47:22.112063027 +0200
@@ -568,6 +568,14 @@
 			DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"),
 		},
 	},
+	{
+		/* HASEE E200 */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "HASEE"),
+			DMI_MATCH(DMI_BOARD_NAME, "E210"),
+			DMI_MATCH(DMI_BIOS_VERSION, "6.00"),
+		},
+	},
 	{ }
 };
 
@@ -577,9 +585,14 @@
 {
 	int try_handoff = 1, tried_handoff = 0;
 
-	/* The Pegatron Lucid tablet sporadically waits for 98 seconds trying
-	 * the handoff on its unused controller.  Skip it. */
-	if (pdev->vendor == 0x8086 && pdev->device == 0x283a) {
+	/*
+	 * The Pegatron Lucid tablet sporadically waits for 98 seconds trying
+	 * the handoff on its unused controller.  Skip it.
+	 *
+	 * The HASEE E200 hangs when the semaphore is set (bugzilla #77021).
+	 */
+	if (pdev->vendor == 0x8086 && (pdev->device == 0x283a ||
+			pdev->device == 0x27cc)) {
 		if (dmi_check_system(ehci_dmi_nohandoff_table))
 			try_handoff = 0;
 	}
diff -ruw linux-3.11.10/drivers/usb/storage/Kconfig linux-3.11.10-fbx/drivers/usb/storage/Kconfig
--- linux-3.11.10/drivers/usb/storage/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/storage/Kconfig	2014-05-09 14:12:53.596546148 +0200
@@ -18,7 +18,9 @@
 
 	  This option depends on 'SCSI' support being enabled, but you
 	  probably also need 'SCSI device support: SCSI disk support'
-	  (BLK_DEV_SD) for most USB storage devices.
+	  (BLK_DEV_SD) for most USB storage devices.  Some devices also
+	  will require 'Probe all LUNs on each SCSI device'
+	  (SCSI_MULTI_LUN).
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called usb-storage.
diff -ruw linux-3.11.10/drivers/usb/storage/scsiglue.c linux-3.11.10-fbx/drivers/usb/storage/scsiglue.c
--- linux-3.11.10/drivers/usb/storage/scsiglue.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/storage/scsiglue.c	2014-05-09 14:12:53.660546149 +0200
@@ -78,6 +78,8 @@
 
 static int slave_alloc (struct scsi_device *sdev)
 {
+	struct us_data *us = host_to_us(sdev->host);
+
 	/*
 	 * Set the INQUIRY transfer length to 36.  We don't use any of
 	 * the extra data and many devices choke if asked for more or
@@ -102,6 +104,10 @@
 	 */
 	blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
 
+	/* Tell the SCSI layer if we know there is more than one LUN */
+	if (us->protocol == USB_PR_BULK && us->max_lun > 0)
+		sdev->sdev_bflags |= BLIST_FORCELUN;
+
 	return 0;
 }
 
diff -ruw linux-3.11.10/drivers/usb/storage/unusual_cypress.h linux-3.11.10-fbx/drivers/usb/storage/unusual_cypress.h
--- linux-3.11.10/drivers/usb/storage/unusual_cypress.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/storage/unusual_cypress.h	2014-05-09 14:12:53.724546150 +0200
@@ -31,7 +31,7 @@
 		"Cypress ISD-300LP",
 		USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0),
 
-UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x0219,
+UNUSUAL_DEV( 0x14cd, 0x6116, 0x0160, 0x0160,
 		"Super Top",
 		"USB 2.0  SATA BRIDGE",
 		USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0),
diff -ruw linux-3.11.10/drivers/usb/storage/unusual_devs.h linux-3.11.10-fbx/drivers/usb/storage/unusual_devs.h
--- linux-3.11.10/drivers/usb/storage/unusual_devs.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/storage/unusual_devs.h	2014-07-01 16:22:13.150329675 +0200
@@ -234,6 +234,27 @@
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_MAX_SECTORS_64 ),
 
+/* Reported by Daniele Forsi <dforsi@gmail.com> */
+UNUSUAL_DEV(  0x0421, 0x04b9, 0x0350, 0x0350,
+		"Nokia",
+		"5300",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_MAX_SECTORS_64 ),
+
+/* Patch submitted by Victor A. Santos <victoraur.santos@gmail.com> */
+UNUSUAL_DEV(  0x0421, 0x05af, 0x0742, 0x0742,
+		"Nokia",
+		"305",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_MAX_SECTORS_64),
+
+/* Patch submitted by Mikhail Zolotaryov <lebon@lebon.org.ua> */
+UNUSUAL_DEV(  0x0421, 0x06aa, 0x1110, 0x1110,
+		"Nokia",
+		"502",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_MAX_SECTORS_64 ),
+
 #ifdef NO_SDDR09
 UNUSUAL_DEV(  0x0436, 0x0005, 0x0100, 0x0100,
 		"Microtech",
@@ -1448,6 +1469,13 @@
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY ),
 
+/* Reported by Moritz Moeller-Herrmann <moritz-kernel@moeller-herrmann.de> */
+UNUSUAL_DEV(  0x0fca, 0x8004, 0x0201, 0x0201,
+		"Research In Motion",
+		"BlackBerry Bold 9000",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_MAX_SECTORS_64 ),
+
 /* Reported by Michael Stattmann <michael@stattmann.com> */
 UNUSUAL_DEV(  0x0fce, 0xd008, 0x0000, 0x0000,
 		"Sony Ericsson",
diff -ruw linux-3.11.10/drivers/usb/storage/usb.c linux-3.11.10-fbx/drivers/usb/storage/usb.c
--- linux-3.11.10/drivers/usb/storage/usb.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/usb/storage/usb.c	2013-12-04 14:33:21.243479010 +0100
@@ -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.11.10/drivers/video/Kconfig linux-3.11.10-fbx/drivers/video/Kconfig
--- linux-3.11.10/drivers/video/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/video/Kconfig	2013-12-04 14:33:21.255479010 +0100
@@ -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.11.10/drivers/video/Makefile linux-3.11.10-fbx/drivers/video/Makefile
--- linux-3.11.10/drivers/video/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/drivers/video/Makefile	2013-12-04 14:33:21.255479010 +0100
@@ -34,6 +34,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.11.10/firmware/Makefile linux-3.11.10-fbx/firmware/Makefile
--- linux-3.11.10/firmware/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/firmware/Makefile	2013-12-04 14:33:21.699479017 +0100
@@ -65,6 +65,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-1.fw \
+				mwl8k/fmimage_8366_ap-3.fw
+
+fw-shipped-$(CONFIG_MWL8K_MFG) += mwl8k/mfg_fmimage_8764.fw mwl8k/mfg_fmimage_8366.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 \
@@ -249,3 +254,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.11.10/fs/aio.c linux-3.11.10-fbx/fs/aio.c
--- linux-3.11.10/fs/aio.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/aio.c	2014-08-22 15:47:22.124063087 +0200
@@ -312,7 +312,6 @@
 
 		avail = (head <= ctx->tail ? ctx->tail : ctx->nr_events) - head;
 
-		atomic_sub(avail, &ctx->reqs_active);
 		head += avail;
 		head %= ctx->nr_events;
 	}
@@ -425,10 +424,12 @@
  *	when the processes owning a context have all exited to encourage
  *	the rapid destruction of the kioctx.
  */
-static void kill_ioctx(struct kioctx *ctx)
+static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx)
 {
 	if (!atomic_xchg(&ctx->dead, 1)) {
+		spin_lock(&mm->ioctx_lock);
 		hlist_del_rcu(&ctx->list);
+		spin_unlock(&mm->ioctx_lock);
 
 		/*
 		 * It'd be more correct to do this in free_ioctx(), after all
@@ -496,7 +497,7 @@
 		 */
 		ctx->mmap_size = 0;
 
-		kill_ioctx(ctx);
+		kill_ioctx(mm, ctx);
 	}
 }
 
@@ -678,6 +679,7 @@
 put_rq:
 	/* everything turned out well, dispose of the aiocb. */
 	aio_put_req(iocb);
+	atomic_dec(&ctx->reqs_active);
 
 	/*
 	 * We have to order our ring_info tail store above and test
@@ -717,6 +719,8 @@
 	if (head == ctx->tail)
 		goto out;
 
+	head %= ctx->nr_events;
+
 	while (ret < nr) {
 		long avail;
 		struct io_event *ev;
@@ -755,8 +759,6 @@
 	flush_dcache_page(ctx->ring_pages[0]);
 
 	pr_debug("%li  h%u t%u\n", ret, head, ctx->tail);
-
-	atomic_sub(ret, &ctx->reqs_active);
 out:
 	mutex_unlock(&ctx->ring_lock);
 
@@ -854,7 +856,7 @@
 	if (!IS_ERR(ioctx)) {
 		ret = put_user(ioctx->user_id, ctxp);
 		if (ret)
-			kill_ioctx(ioctx);
+			kill_ioctx(current->mm, ioctx);
 		put_ioctx(ioctx);
 	}
 
@@ -872,7 +874,7 @@
 {
 	struct kioctx *ioctx = lookup_ioctx(ctx);
 	if (likely(NULL != ioctx)) {
-		kill_ioctx(ioctx);
+		kill_ioctx(current->mm, ioctx);
 		put_ioctx(ioctx);
 		return 0;
 	}
diff -ruw linux-3.11.10/fs/attr.c linux-3.11.10-fbx/fs/attr.c
--- linux-3.11.10/fs/attr.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/attr.c	2014-07-01 16:22:13.150329675 +0200
@@ -50,14 +50,14 @@
 	if ((ia_valid & ATTR_UID) &&
 	    (!uid_eq(current_fsuid(), inode->i_uid) ||
 	     !uid_eq(attr->ia_uid, inode->i_uid)) &&
-	    !inode_capable(inode, CAP_CHOWN))
+	    !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
 		return -EPERM;
 
 	/* Make sure caller can chgrp. */
 	if ((ia_valid & ATTR_GID) &&
 	    (!uid_eq(current_fsuid(), inode->i_uid) ||
 	    (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) &&
-	    !inode_capable(inode, CAP_CHOWN))
+	    !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
 		return -EPERM;
 
 	/* Make sure a caller can chmod. */
@@ -67,7 +67,7 @@
 		/* Also check the setgid bit! */
 		if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
 				inode->i_gid) &&
-		    !inode_capable(inode, CAP_FSETID))
+		    !capable_wrt_inode_uidgid(inode, CAP_FSETID))
 			attr->ia_mode &= ~S_ISGID;
 	}
 
@@ -160,7 +160,7 @@
 		umode_t mode = attr->ia_mode;
 
 		if (!in_group_p(inode->i_gid) &&
-		    !inode_capable(inode, CAP_FSETID))
+		    !capable_wrt_inode_uidgid(inode, CAP_FSETID))
 			mode &= ~S_ISGID;
 		inode->i_mode = mode;
 	}
@@ -182,11 +182,6 @@
 			return -EPERM;
 	}
 
-	if ((ia_valid & ATTR_SIZE) && IS_I_VERSION(inode)) {
-		if (attr->ia_size != inode->i_size)
-			inode_inc_iversion(inode);
-	}
-
 	if ((ia_valid & ATTR_MODE)) {
 		umode_t amode = attr->ia_mode;
 		/* Flag setting protected by i_mutex */
diff -ruw linux-3.11.10/fs/buffer.c linux-3.11.10-fbx/fs/buffer.c
--- linux-3.11.10/fs/buffer.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/buffer.c	2014-05-09 14:12:54.232546158 +0200
@@ -654,14 +654,16 @@
 static void __set_page_dirty(struct page *page,
 		struct address_space *mapping, int warn)
 {
-	spin_lock_irq(&mapping->tree_lock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&mapping->tree_lock, flags);
 	if (page->mapping) {	/* Race with truncate? */
 		WARN_ON_ONCE(warn && !PageUptodate(page));
 		account_page_dirtied(page, mapping);
 		radix_tree_tag_set(&mapping->page_tree,
 				page_index(page), PAGECACHE_TAG_DIRTY);
 	}
-	spin_unlock_irq(&mapping->tree_lock);
+	spin_unlock_irqrestore(&mapping->tree_lock, flags);
 	__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
 }
 
diff -ruw linux-3.11.10/fs/coredump.c linux-3.11.10-fbx/fs/coredump.c
--- linux-3.11.10/fs/coredump.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/coredump.c	2014-07-01 16:22:13.154329688 +0200
@@ -74,10 +74,15 @@
 static int cn_vprintf(struct core_name *cn, const char *fmt, va_list arg)
 {
 	int free, need;
+	va_list arg_copy;
 
 again:
 	free = cn->size - cn->used;
-	need = vsnprintf(cn->corename + cn->used, free, fmt, arg);
+
+	va_copy(arg_copy, arg);
+	need = vsnprintf(cn->corename + cn->used, free, fmt, arg_copy);
+	va_end(arg_copy);
+
 	if (need < free) {
 		cn->used += need;
 		return 0;
diff -ruw linux-3.11.10/fs/dcache.c linux-3.11.10-fbx/fs/dcache.c
--- linux-3.11.10/fs/dcache.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/dcache.c	2014-05-09 14:12:54.236546158 +0200
@@ -2675,8 +2675,13 @@
 	 * thus don't need to be hashed.  They also don't need a name until a
 	 * user wants to identify the object in /proc/pid/fd/.  The little hack
 	 * below allows us to generate a name for these objects on demand:
+	 *
+	 * Some pseudo inodes are mountable.  When they are mounted
+	 * path->dentry == path->mnt->mnt_root.  In that case don't call d_dname
+	 * and instead have d_path return the mounted path.
 	 */
-	if (path->dentry->d_op && path->dentry->d_op->d_dname)
+	if (path->dentry->d_op && path->dentry->d_op->d_dname &&
+	    (!IS_ROOT(path->dentry) || path->dentry != path->mnt->mnt_root))
 		return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
 
 	get_fs_root(current->fs, &root);
diff -ruw linux-3.11.10/fs/devpts/inode.c linux-3.11.10-fbx/fs/devpts/inode.c
--- linux-3.11.10/fs/devpts/inode.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/devpts/inode.c	2014-01-17 19:14:18.754220809 +0100
@@ -498,6 +498,7 @@
 {
 	struct pts_fs_info *fsi = DEVPTS_SB(sb);
 
+	ida_destroy(&fsi->allocated_ptys);
 	kfree(fsi);
 	kill_litter_super(sb);
 }
diff -ruw linux-3.11.10/fs/exec.c linux-3.11.10-fbx/fs/exec.c
--- linux-3.11.10/fs/exec.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/exec.c	2014-07-01 16:22:13.158329705 +0200
@@ -655,10 +655,10 @@
 	unsigned long rlim_stack;
 
 #ifdef CONFIG_STACK_GROWSUP
-	/* Limit stack size to 1GB */
+	/* Limit stack size */
 	stack_base = rlimit_max(RLIMIT_STACK);
-	if (stack_base > (1 << 30))
-		stack_base = 1 << 30;
+	if (stack_base > STACK_SIZE_MAX)
+		stack_base = STACK_SIZE_MAX;
 
 	/* Make sure we didn't let the argument array grow too large. */
 	if (vma->vm_end - vma->vm_start > stack_base)
@@ -1467,6 +1467,23 @@
 	int retval;
 
 	/*
+	 * handle current->exec_mode:
+	 * - if unlimited, then nothing to do.
+	 * - if once, then set it to denied and continue (next execve
+	 *   after this one will fail).
+	 * - if denied, then effectively fail the execve call with EPERM.
+	 */
+	switch (current->exec_mode) {
+	case EXEC_MODE_UNLIMITED:
+		break;
+	case EXEC_MODE_ONCE:
+		current->exec_mode = EXEC_MODE_DENIED;
+		break;
+	case EXEC_MODE_DENIED:
+		return -EPERM;
+	}
+
+	/*
 	 * We move the actual failure in case of RLIMIT_NPROC excess from
 	 * set*uid() to execve() because too many poorly written programs
 	 * don't check setuid() return code.  Here we additionally recheck
diff -ruw linux-3.11.10/fs/ext2/super.c linux-3.11.10-fbx/fs/ext2/super.c
--- linux-3.11.10/fs/ext2/super.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext2/super.c	2014-01-17 19:14:18.754220809 +0100
@@ -1493,6 +1493,7 @@
 				sb->s_blocksize - offset : towrite;
 
 		tmp_bh.b_state = 0;
+		tmp_bh.b_size = sb->s_blocksize;
 		err = ext2_get_block(inode, blk, &tmp_bh, 1);
 		if (err < 0)
 			goto out;
diff -ruw linux-3.11.10/fs/ext4/ext4.h linux-3.11.10-fbx/fs/ext4/ext4.h
--- linux-3.11.10/fs/ext4/ext4.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/ext4.h	2014-08-22 15:47:22.128063107 +0200
@@ -270,6 +270,16 @@
 /* Translate # of blks to # of clusters */
 #define EXT4_NUM_B2C(sbi, blks)	(((blks) + (sbi)->s_cluster_ratio - 1) >> \
 				 (sbi)->s_cluster_bits)
+/* Mask out the low bits to get the starting block of the cluster */
+#define EXT4_PBLK_CMASK(s, pblk) ((pblk) &				\
+				  ~((ext4_fsblk_t) (s)->s_cluster_ratio - 1))
+#define EXT4_LBLK_CMASK(s, lblk) ((lblk) &				\
+				  ~((ext4_lblk_t) (s)->s_cluster_ratio - 1))
+/* Get the cluster offset */
+#define EXT4_PBLK_COFF(s, pblk) ((pblk) &				\
+				 ((ext4_fsblk_t) (s)->s_cluster_ratio - 1))
+#define EXT4_LBLK_COFF(s, lblk) ((lblk) &				\
+				 ((ext4_lblk_t) (s)->s_cluster_ratio - 1))
 
 /*
  * Structure of a blocks group descriptor
@@ -749,6 +759,8 @@
 	if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime))		       \
 		(einode)->xtime.tv_sec = 				       \
 			(signed)le32_to_cpu((raw_inode)->xtime);	       \
+	else								       \
+		(einode)->xtime.tv_sec = 0;				       \
 	if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra))	       \
 		ext4_decode_extra_time(&(einode)->xtime,		       \
 				       raw_inode->xtime ## _extra);	       \
@@ -2721,7 +2733,8 @@
 extern int ext4_bio_write_page(struct ext4_io_submit *io,
 			       struct page *page,
 			       int len,
-			       struct writeback_control *wbc);
+			       struct writeback_control *wbc,
+			       bool keep_towrite);
 
 /* mmp.c */
 extern int ext4_multi_mount_protect(struct super_block *, ext4_fsblk_t);
diff -ruw linux-3.11.10/fs/ext4/ext4_jbd2.c linux-3.11.10-fbx/fs/ext4/ext4_jbd2.c
--- linux-3.11.10/fs/ext4/ext4_jbd2.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/ext4_jbd2.c	2014-01-17 19:14:18.754220809 +0100
@@ -259,6 +259,15 @@
 		if (WARN_ON_ONCE(err)) {
 			ext4_journal_abort_handle(where, line, __func__, bh,
 						  handle, err);
+			ext4_error_inode(inode, where, line,
+					 bh->b_blocknr,
+					 "journal_dirty_metadata failed: "
+					 "handle type %u started at line %u, "
+					 "credits %u/%u, errcode %d",
+					 handle->h_type,
+					 handle->h_line_no,
+					 handle->h_requested_credits,
+					 handle->h_buffer_credits, err);
 		}
 	} else {
 		if (inode)
diff -ruw linux-3.11.10/fs/ext4/extents.c linux-3.11.10-fbx/fs/ext4/extents.c
--- linux-3.11.10/fs/ext4/extents.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/extents.c	2014-07-01 16:22:13.158329705 +0200
@@ -360,8 +360,10 @@
 {
 	ext4_fsblk_t block = ext4_ext_pblock(ext);
 	int len = ext4_ext_get_actual_len(ext);
+	ext4_lblk_t lblock = le32_to_cpu(ext->ee_block);
+	ext4_lblk_t last = lblock + len - 1;
 
-	if (len == 0)
+	if (lblock > last)
 		return 0;
 	return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len);
 }
@@ -387,11 +389,26 @@
 	if (depth == 0) {
 		/* leaf entries */
 		struct ext4_extent *ext = EXT_FIRST_EXTENT(eh);
+		struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
+		ext4_fsblk_t pblock = 0;
+		ext4_lblk_t lblock = 0;
+		ext4_lblk_t prev = 0;
+		int len = 0;
 		while (entries) {
 			if (!ext4_valid_extent(inode, ext))
 				return 0;
+
+			/* Check for overlapping extents */
+			lblock = le32_to_cpu(ext->ee_block);
+			len = ext4_ext_get_actual_len(ext);
+			if ((lblock <= prev) && prev) {
+				pblock = ext4_ext_pblock(ext);
+				es->s_last_error_block = cpu_to_le64(pblock);
+				return 0;
+			}
 			ext++;
 			entries--;
+			prev = lblock + len - 1;
 		}
 	} else {
 		struct ext4_extent_idx *ext_idx = EXT_FIRST_INDEX(eh);
@@ -1755,8 +1772,7 @@
 	depth = ext_depth(inode);
 	if (!path[depth].p_ext)
 		goto out;
-	b2 = le32_to_cpu(path[depth].p_ext->ee_block);
-	b2 &= ~(sbi->s_cluster_ratio - 1);
+	b2 = EXT4_LBLK_CMASK(sbi, le32_to_cpu(path[depth].p_ext->ee_block));
 
 	/*
 	 * get the next allocated block if the extent in the path
@@ -1766,7 +1782,7 @@
 		b2 = ext4_ext_next_allocated_block(path);
 		if (b2 == EXT_MAX_BLOCKS)
 			goto out;
-		b2 &= ~(sbi->s_cluster_ratio - 1);
+		b2 = EXT4_LBLK_CMASK(sbi, b2);
 	}
 
 	/* check for wrap through zero on extent logical start block*/
@@ -2446,7 +2462,7 @@
 		 * extent, we have to mark the cluster as used (store negative
 		 * cluster number in partial_cluster).
 		 */
-		unaligned = pblk & (sbi->s_cluster_ratio - 1);
+		unaligned = EXT4_PBLK_COFF(sbi, pblk);
 		if (unaligned && (ee_len == num) &&
 		    (*partial_cluster != -((long long)EXT4_B2C(sbi, pblk))))
 			*partial_cluster = EXT4_B2C(sbi, pblk);
@@ -2511,6 +2527,27 @@
 	ex_ee_block = le32_to_cpu(ex->ee_block);
 	ex_ee_len = ext4_ext_get_actual_len(ex);
 
+	/*
+	 * If we're starting with an extent other than the last one in the
+	 * node, we need to see if it shares a cluster with the extent to
+	 * the right (towards the end of the file). If its leftmost cluster
+	 * is this extent's rightmost cluster and it is not cluster aligned,
+	 * we'll mark it as a partial that is not to be deallocated.
+	 */
+
+	if (ex != EXT_LAST_EXTENT(eh)) {
+		ext4_fsblk_t current_pblk, right_pblk;
+		long long current_cluster, right_cluster;
+
+		current_pblk = ext4_ext_pblock(ex) + ex_ee_len - 1;
+		current_cluster = (long long)EXT4_B2C(sbi, current_pblk);
+		right_pblk = ext4_ext_pblock(ex + 1);
+		right_cluster = (long long)EXT4_B2C(sbi, right_pblk);
+		if (current_cluster == right_cluster &&
+			EXT4_PBLK_COFF(sbi, right_pblk))
+			*partial_cluster = -right_cluster;
+	}
+
 	trace_ext4_ext_rm_leaf(inode, start, ex, *partial_cluster);
 
 	while (ex >= EXT_FIRST_EXTENT(eh) &&
@@ -2540,7 +2577,7 @@
 			 * accidentally freeing it later on
 			 */
 			pblk = ext4_ext_pblock(ex);
-			if (pblk & (sbi->s_cluster_ratio - 1))
+			if (EXT4_PBLK_COFF(sbi, pblk))
 				*partial_cluster =
 					-((long long)EXT4_B2C(sbi, pblk));
 			ex--;
@@ -2636,10 +2673,15 @@
 		err = ext4_ext_correct_indexes(handle, inode, path);
 
 	/*
-	 * Free the partial cluster only if the current extent does not
-	 * reference it. Otherwise we might free used cluster.
+	 * If there's a partial cluster and at least one extent remains in
+	 * the leaf, free the partial cluster if it isn't shared with the
+	 * current extent.  If there's a partial cluster and no extents
+	 * remain in the leaf, it can't be freed here.  It can only be
+	 * freed when it's possible to determine if it's not shared with
+	 * any other extent - when the next leaf is processed or when space
+	 * removal is complete.
 	 */
-	if (*partial_cluster > 0 &&
+	if (*partial_cluster > 0 && eh->eh_entries &&
 	    (EXT4_B2C(sbi, ext4_ext_pblock(ex) + ex_ee_len - 1) !=
 	     *partial_cluster)) {
 		int flags = get_default_free_blocks_flags(inode);
@@ -3680,7 +3722,7 @@
 {
 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
 	ext4_lblk_t lblk_start, lblk_end;
-	lblk_start = lblk & (~(sbi->s_cluster_ratio - 1));
+	lblk_start = EXT4_LBLK_CMASK(sbi, lblk);
 	lblk_end = lblk_start + sbi->s_cluster_ratio - 1;
 
 	return ext4_find_delalloc_range(inode, lblk_start, lblk_end);
@@ -3739,9 +3781,9 @@
 	trace_ext4_get_reserved_cluster_alloc(inode, lblk_start, num_blks);
 
 	/* Check towards left side */
-	c_offset = lblk_start & (sbi->s_cluster_ratio - 1);
+	c_offset = EXT4_LBLK_COFF(sbi, lblk_start);
 	if (c_offset) {
-		lblk_from = lblk_start & (~(sbi->s_cluster_ratio - 1));
+		lblk_from = EXT4_LBLK_CMASK(sbi, lblk_start);
 		lblk_to = lblk_from + c_offset - 1;
 
 		if (ext4_find_delalloc_range(inode, lblk_from, lblk_to))
@@ -3749,7 +3791,7 @@
 	}
 
 	/* Now check towards right. */
-	c_offset = (lblk_start + num_blks) & (sbi->s_cluster_ratio - 1);
+	c_offset = EXT4_LBLK_COFF(sbi, lblk_start + num_blks);
 	if (allocated_clusters && c_offset) {
 		lblk_from = lblk_start + num_blks;
 		lblk_to = lblk_from + (sbi->s_cluster_ratio - c_offset) - 1;
@@ -3817,6 +3859,7 @@
 		} else
 			err = ret;
 		map->m_flags |= EXT4_MAP_MAPPED;
+		map->m_pblk = newblock;
 		if (allocated > map->m_len)
 			allocated = map->m_len;
 		map->m_len = allocated;
@@ -3957,7 +4000,7 @@
 				     struct ext4_ext_path *path)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
-	ext4_lblk_t c_offset = map->m_lblk & (sbi->s_cluster_ratio-1);
+	ext4_lblk_t c_offset = EXT4_LBLK_COFF(sbi, map->m_lblk);
 	ext4_lblk_t ex_cluster_start, ex_cluster_end;
 	ext4_lblk_t rr_cluster_start;
 	ext4_lblk_t ee_block = le32_to_cpu(ex->ee_block);
@@ -3975,8 +4018,7 @@
 	    (rr_cluster_start == ex_cluster_start)) {
 		if (rr_cluster_start == ex_cluster_end)
 			ee_start += ee_len - 1;
-		map->m_pblk = (ee_start & ~(sbi->s_cluster_ratio - 1)) +
-			c_offset;
+		map->m_pblk = EXT4_PBLK_CMASK(sbi, ee_start) + c_offset;
 		map->m_len = min(map->m_len,
 				 (unsigned) sbi->s_cluster_ratio - c_offset);
 		/*
@@ -4039,7 +4081,7 @@
 	struct ext4_extent newex, *ex, *ex2;
 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
 	ext4_fsblk_t newblock = 0;
-	int free_on_err = 0, err = 0, depth;
+	int free_on_err = 0, err = 0, depth, ret;
 	unsigned int allocated = 0, offset = 0;
 	unsigned int allocated_clusters = 0;
 	struct ext4_allocation_request ar;
@@ -4100,9 +4142,13 @@
 			if (!ext4_ext_is_uninitialized(ex))
 				goto out;
 
-			allocated = ext4_ext_handle_uninitialized_extents(
+			ret = ext4_ext_handle_uninitialized_extents(
 				handle, inode, map, path, flags,
 				allocated, newblock);
+			if (ret < 0)
+				err = ret;
+			else
+				allocated = ret;
 			goto out3;
 		}
 	}
@@ -4130,7 +4176,7 @@
 	 */
 	map->m_flags &= ~EXT4_MAP_FROM_CLUSTER;
 	newex.ee_block = cpu_to_le32(map->m_lblk);
-	cluster_offset = map->m_lblk & (sbi->s_cluster_ratio-1);
+	cluster_offset = EXT4_LBLK_COFF(sbi, map->m_lblk);
 
 	/*
 	 * If we are doing bigalloc, check to see if the extent returned
@@ -4198,7 +4244,7 @@
 	 * needed so that future calls to get_implied_cluster_alloc()
 	 * work correctly.
 	 */
-	offset = map->m_lblk & (sbi->s_cluster_ratio - 1);
+	offset = EXT4_LBLK_COFF(sbi, map->m_lblk);
 	ar.len = EXT4_NUM_B2C(sbi, offset+allocated);
 	ar.goal -= offset;
 	ar.logical -= offset;
diff -ruw linux-3.11.10/fs/ext4/file.c linux-3.11.10-fbx/fs/ext4/file.c
--- linux-3.11.10/fs/ext4/file.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/file.c	2014-07-01 16:22:13.158329705 +0200
@@ -82,7 +82,7 @@
 	size_t count = iov_length(iov, nr_segs);
 	loff_t final_size = pos + count;
 
-	if (pos >= inode->i_size)
+	if (pos >= i_size_read(inode))
 		return 0;
 
 	if ((pos & blockmask) || (final_size & blockmask))
diff -ruw linux-3.11.10/fs/ext4/ialloc.c linux-3.11.10-fbx/fs/ext4/ialloc.c
--- linux-3.11.10/fs/ext4/ialloc.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/ialloc.c	2014-08-22 15:47:22.128063107 +0200
@@ -781,6 +781,13 @@
 		goto out;
 	}
 
+	BUFFER_TRACE(group_desc_bh, "get_write_access");
+	err = ext4_journal_get_write_access(handle, group_desc_bh);
+	if (err) {
+		ext4_std_error(sb, err);
+		goto out;
+	}
+
 	/* We may have to initialize the block bitmap if it isn't already */
 	if (ext4_has_group_desc_csum(sb) &&
 	    gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
@@ -817,13 +824,6 @@
 		}
 	}
 
-	BUFFER_TRACE(group_desc_bh, "get_write_access");
-	err = ext4_journal_get_write_access(handle, group_desc_bh);
-	if (err) {
-		ext4_std_error(sb, err);
-		goto out;
-	}
-
 	/* Update the relevant bg descriptor fields */
 	if (ext4_has_group_desc_csum(sb)) {
 		int free;
diff -ruw linux-3.11.10/fs/ext4/indirect.c linux-3.11.10-fbx/fs/ext4/indirect.c
--- linux-3.11.10/fs/ext4/indirect.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/indirect.c	2014-08-22 15:47:22.128063107 +0200
@@ -390,7 +390,13 @@
 	return 0;
 failed:
 	for (; i >= 0; i--) {
-		if (i != indirect_blks && branch[i].bh)
+		/*
+		 * We want to ext4_forget() only freshly allocated indirect
+		 * blocks.  Buffer for new_blocks[i-1] is at branch[i].bh and
+		 * buffer at branch[0].bh is indirect block / inode already
+		 * existing before ext4_alloc_branch() was called.
+		 */
+		if (i > 0 && i != indirect_blks && branch[i].bh)
 			ext4_forget(handle, 1, inode, branch[i].bh,
 				    branch[i].bh->b_blocknr);
 		ext4_free_blocks(handle, inode, NULL, new_blocks[i],
@@ -1313,16 +1319,24 @@
 		blk = *i_data;
 		if (level > 0) {
 			ext4_lblk_t first2;
+			ext4_lblk_t count2;
+
 			bh = sb_bread(inode->i_sb, le32_to_cpu(blk));
 			if (!bh) {
 				EXT4_ERROR_INODE_BLOCK(inode, le32_to_cpu(blk),
 						       "Read failure");
 				return -EIO;
 			}
-			first2 = (first > offset) ? first - offset : 0;
+			if (first > offset) {
+				first2 = first - offset;
+				count2 = count;
+			} else {
+				first2 = 0;
+				count2 = count - (offset - first);
+			}
 			ret = free_hole_blocks(handle, inode, bh,
 					       (__le32 *)bh->b_data, level - 1,
-					       first2, count - offset,
+					       first2, count2,
 					       inode->i_sb->s_blocksize >> 2);
 			if (ret) {
 				brelse(bh);
diff -ruw linux-3.11.10/fs/ext4/inline.c linux-3.11.10-fbx/fs/ext4/inline.c
--- linux-3.11.10/fs/ext4/inline.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/inline.c	2014-05-09 14:12:54.236546158 +0200
@@ -1925,9 +1925,11 @@
 		}
 
 		/* Clear the content within i_blocks. */
-		if (i_size < EXT4_MIN_INLINE_DATA_SIZE)
-			memset(ext4_raw_inode(&is.iloc)->i_block + i_size, 0,
+		if (i_size < EXT4_MIN_INLINE_DATA_SIZE) {
+			void *p = (void *) ext4_raw_inode(&is.iloc)->i_block;
+			memset(p + i_size, 0,
 					EXT4_MIN_INLINE_DATA_SIZE - i_size);
+		}
 
 		EXT4_I(inode)->i_inline_size = i_size <
 					EXT4_MIN_INLINE_DATA_SIZE ?
diff -ruw linux-3.11.10/fs/ext4/inode.c linux-3.11.10-fbx/fs/ext4/inode.c
--- linux-3.11.10/fs/ext4/inode.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/inode.c	2014-08-22 15:47:22.132063127 +0200
@@ -38,6 +38,7 @@
 #include <linux/slab.h>
 #include <linux/ratelimit.h>
 #include <linux/aio.h>
+#include <linux/bitops.h>
 
 #include "ext4_jbd2.h"
 #include "xattr.h"
@@ -1201,7 +1202,6 @@
  */
 static int ext4_da_reserve_metadata(struct inode *inode, ext4_lblk_t lblock)
 {
-	int retries = 0;
 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
 	struct ext4_inode_info *ei = EXT4_I(inode);
 	unsigned int md_needed;
@@ -1213,7 +1213,6 @@
 	 * in order to allocate nrblocks
 	 * worse case is one extent per block
 	 */
-repeat:
 	spin_lock(&ei->i_block_reservation_lock);
 	/*
 	 * ext4_calc_metadata_amount() has side effects, which we have
@@ -1233,10 +1232,6 @@
 		ei->i_da_metadata_calc_len = save_len;
 		ei->i_da_metadata_calc_last_lblock = save_last_lblock;
 		spin_unlock(&ei->i_block_reservation_lock);
-		if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
-			cond_resched();
-			goto repeat;
-		}
 		return -ENOSPC;
 	}
 	ei->i_reserved_meta_blocks += md_needed;
@@ -1250,7 +1245,6 @@
  */
 static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock)
 {
-	int retries = 0;
 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
 	struct ext4_inode_info *ei = EXT4_I(inode);
 	unsigned int md_needed;
@@ -1272,7 +1266,6 @@
 	 * in order to allocate nrblocks
 	 * worse case is one extent per block
 	 */
-repeat:
 	spin_lock(&ei->i_block_reservation_lock);
 	/*
 	 * ext4_calc_metadata_amount() has side effects, which we have
@@ -1292,10 +1285,6 @@
 		ei->i_da_metadata_calc_len = save_len;
 		ei->i_da_metadata_calc_last_lblock = save_last_lblock;
 		spin_unlock(&ei->i_block_reservation_lock);
-		if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
-			cond_resched();
-			goto repeat;
-		}
 		dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1));
 		return -ENOSPC;
 	}
@@ -1837,6 +1826,7 @@
 	struct buffer_head *page_bufs = NULL;
 	struct inode *inode = page->mapping->host;
 	struct ext4_io_submit io_submit;
+	bool keep_towrite = false;
 
 	trace_ext4_writepage(page);
 	size = i_size_read(inode);
@@ -1867,6 +1857,7 @@
 			unlock_page(page);
 			return 0;
 		}
+		keep_towrite = true;
 	}
 
 	if (PageChecked(page) && ext4_should_journal_data(inode))
@@ -1883,7 +1874,7 @@
 		unlock_page(page);
 		return -ENOMEM;
 	}
-	ret = ext4_bio_write_page(&io_submit, page, len, wbc);
+	ret = ext4_bio_write_page(&io_submit, page, len, wbc, keep_towrite);
 	ext4_io_submit(&io_submit);
 	/* Drop io_end reference we got from init */
 	ext4_put_io_end_defer(io_submit.io_end);
@@ -1902,7 +1893,7 @@
 	else
 		len = PAGE_CACHE_SIZE;
 	clear_page_dirty_for_io(page);
-	err = ext4_bio_write_page(&mpd->io_submit, page, len, mpd->wbc);
+	err = ext4_bio_write_page(&mpd->io_submit, page, len, mpd->wbc, false);
 	if (!err)
 		mpd->wbc->nr_to_write--;
 	mpd->first_page++;
@@ -3949,18 +3940,20 @@
 void ext4_set_inode_flags(struct inode *inode)
 {
 	unsigned int flags = EXT4_I(inode)->i_flags;
+	unsigned int new_fl = 0;
 
-	inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
 	if (flags & EXT4_SYNC_FL)
-		inode->i_flags |= S_SYNC;
+		new_fl |= S_SYNC;
 	if (flags & EXT4_APPEND_FL)
-		inode->i_flags |= S_APPEND;
+		new_fl |= S_APPEND;
 	if (flags & EXT4_IMMUTABLE_FL)
-		inode->i_flags |= S_IMMUTABLE;
+		new_fl |= S_IMMUTABLE;
 	if (flags & EXT4_NOATIME_FL)
-		inode->i_flags |= S_NOATIME;
+		new_fl |= S_NOATIME;
 	if (flags & EXT4_DIRSYNC_FL)
-		inode->i_flags |= S_DIRSYNC;
+		new_fl |= S_DIRSYNC;
+	set_mask_bits(&inode->i_flags,
+		      S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC, new_fl);
 }
 
 /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
@@ -4610,6 +4603,10 @@
 			if (attr->ia_size > sbi->s_bitmap_maxbytes)
 				return -EFBIG;
 		}
+
+		if (IS_I_VERSION(inode) && attr->ia_size != inode->i_size)
+			inode_inc_iversion(inode);
+
 		if (S_ISREG(inode->i_mode) &&
 		    (attr->ia_size < inode->i_size)) {
 			if (ext4_should_order_data(inode)) {
diff -ruw linux-3.11.10/fs/ext4/ioctl.c linux-3.11.10-fbx/fs/ext4/ioctl.c
--- linux-3.11.10/fs/ext4/ioctl.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/ioctl.c	2014-07-01 16:22:13.158329705 +0200
@@ -145,7 +145,7 @@
 	handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
 	if (IS_ERR(handle)) {
 		err = -EINVAL;
-		goto swap_boot_out;
+		goto journal_err_out;
 	}
 
 	/* Protect extent tree against block allocations via delalloc */
@@ -203,6 +203,7 @@
 
 	ext4_double_up_write_data_sem(inode, inode_bl);
 
+journal_err_out:
 	ext4_inode_resume_unlocked_dio(inode);
 	ext4_inode_resume_unlocked_dio(inode_bl);
 
diff -ruw linux-3.11.10/fs/ext4/mballoc.c linux-3.11.10-fbx/fs/ext4/mballoc.c
--- linux-3.11.10/fs/ext4/mballoc.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/mballoc.c	2014-08-22 15:47:22.132063127 +0200
@@ -3117,7 +3117,7 @@
 	}
 	BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&
 			start > ac->ac_o_ex.fe_logical);
-	BUG_ON(size <= 0 || size > EXT4_CLUSTERS_PER_GROUP(ac->ac_sb));
+	BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
 
 	/* now prepare goal request */
 
@@ -3424,6 +3424,9 @@
 {
 	struct ext4_prealloc_space *pa;
 	pa = container_of(head, struct ext4_prealloc_space, u.pa_rcu);
+
+	BUG_ON(atomic_read(&pa->pa_count));
+	BUG_ON(pa->pa_deleted == 0);
 	kmem_cache_free(ext4_pspace_cachep, pa);
 }
 
@@ -3437,11 +3440,13 @@
 	ext4_group_t grp;
 	ext4_fsblk_t grp_blk;
 
-	if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0)
-		return;
-
 	/* in this short window concurrent discard can set pa_deleted */
 	spin_lock(&pa->pa_lock);
+	if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) {
+		spin_unlock(&pa->pa_lock);
+		return;
+	}
+
 	if (pa->pa_deleted == 1) {
 		spin_unlock(&pa->pa_lock);
 		return;
@@ -4103,7 +4108,7 @@
 	ext4_get_group_no_and_offset(sb, goal, &group, &block);
 
 	/* set up allocation goals */
-	ac->ac_b_ex.fe_logical = ar->logical & ~(sbi->s_cluster_ratio - 1);
+	ac->ac_b_ex.fe_logical = EXT4_LBLK_CMASK(sbi, ar->logical);
 	ac->ac_status = AC_STATUS_CONTINUE;
 	ac->ac_sb = sb;
 	ac->ac_inode = ar->inode;
@@ -4644,7 +4649,7 @@
 	 * blocks at the beginning or the end unless we are explicitly
 	 * requested to avoid doing so.
 	 */
-	overflow = block & (sbi->s_cluster_ratio - 1);
+	overflow = EXT4_PBLK_COFF(sbi, block);
 	if (overflow) {
 		if (flags & EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER) {
 			overflow = sbi->s_cluster_ratio - overflow;
@@ -4658,7 +4663,7 @@
 			count += overflow;
 		}
 	}
-	overflow = count & (sbi->s_cluster_ratio - 1);
+	overflow = EXT4_LBLK_COFF(sbi, count);
 	if (overflow) {
 		if (flags & EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER) {
 			if (count > overflow)
@@ -4771,8 +4776,8 @@
 					 " group:%d block:%d count:%lu failed"
 					 " with %d", block_group, bit, count,
 					 err);
-		}
-
+		} else
+			EXT4_MB_GRP_CLEAR_TRIMMED(e4b.bd_info);
 
 		ext4_lock_group(sb, block_group);
 		mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
diff -ruw linux-3.11.10/fs/ext4/page-io.c linux-3.11.10-fbx/fs/ext4/page-io.c
--- linux-3.11.10/fs/ext4/page-io.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/page-io.c	2014-08-22 15:47:22.132063127 +0200
@@ -323,13 +323,14 @@
 	if (error) {
 		struct inode *inode = io_end->inode;
 
-		ext4_warning(inode->i_sb, "I/O error writing to inode %lu "
+		ext4_warning(inode->i_sb, "I/O error %d writing to inode %lu "
 			     "(offset %llu size %ld starting block %llu)",
-			     inode->i_ino,
+			     error, inode->i_ino,
 			     (unsigned long long) io_end->offset,
 			     (long) io_end->size,
 			     (unsigned long long)
 			     bi_sector >> (inode->i_blkbits - 9));
+		mapping_set_error(inode->i_mapping, error);
 	}
 
 	if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
@@ -415,7 +416,8 @@
 int ext4_bio_write_page(struct ext4_io_submit *io,
 			struct page *page,
 			int len,
-			struct writeback_control *wbc)
+			struct writeback_control *wbc,
+			bool keep_towrite)
 {
 	struct inode *inode = page->mapping->host;
 	unsigned block_start, blocksize;
@@ -428,10 +430,24 @@
 	BUG_ON(!PageLocked(page));
 	BUG_ON(PageWriteback(page));
 
+	if (keep_towrite)
+		set_page_writeback_keepwrite(page);
+	else
 	set_page_writeback(page);
 	ClearPageError(page);
 
 	/*
+	 * Comments copied from block_write_full_page_endio:
+	 *
+	 * The page straddles i_size.  It must be zeroed out on each and every
+	 * writepage invocation because it may be mmapped.  "A file is mapped
+	 * in multiples of the page size.  For a file that is not a multiple of
+	 * the page size, the remaining memory is zeroed when mapped, and
+	 * writes to that region are not written out to the file."
+	 */
+	if (len < PAGE_CACHE_SIZE)
+		zero_user_segment(page, len, PAGE_CACHE_SIZE);
+	/*
 	 * In the first loop we prepare and mark buffers to submit. We have to
 	 * mark all buffers in the page before submitting so that
 	 * end_page_writeback() cannot be called from ext4_bio_end_io() when IO
@@ -442,19 +458,6 @@
 	do {
 		block_start = bh_offset(bh);
 		if (block_start >= len) {
-			/*
-			 * Comments copied from block_write_full_page_endio:
-			 *
-			 * The page straddles i_size.  It must be zeroed out on
-			 * each and every writepage invocation because it may
-			 * be mmapped.  "A file is mapped in multiples of the
-			 * page size.  For a file that is not a multiple of
-			 * the  page size, the remaining memory is zeroed when
-			 * mapped, and writes to that region are not written
-			 * out to the file."
-			 */
-			zero_user_segment(page, block_start,
-					  block_start + blocksize);
 			clear_buffer_dirty(bh);
 			set_buffer_uptodate(bh);
 			continue;
diff -ruw linux-3.11.10/fs/ext4/resize.c linux-3.11.10-fbx/fs/ext4/resize.c
--- linux-3.11.10/fs/ext4/resize.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/resize.c	2014-07-01 16:22:13.158329705 +0200
@@ -243,6 +243,7 @@
 	ext4_group_t group;
 	ext4_group_t last_group;
 	unsigned overhead;
+	__u16 uninit_mask = (flexbg_size > 1) ? ~EXT4_BG_BLOCK_UNINIT : ~0;
 
 	BUG_ON(flex_gd->count == 0 || group_data == NULL);
 
@@ -266,7 +267,7 @@
 	src_group++;
 	for (; src_group <= last_group; src_group++) {
 		overhead = ext4_group_overhead_blocks(sb, src_group);
-		if (overhead != 0)
+		if (overhead == 0)
 			last_blk += group_data[src_group - group].blocks_count;
 		else
 			break;
@@ -280,8 +281,7 @@
 		group = ext4_get_group_number(sb, start_blk - 1);
 		group -= group_data[0].group;
 		group_data[group].free_blocks_count--;
-		if (flexbg_size > 1)
-			flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
+		flex_gd->bg_flags[group] &= uninit_mask;
 	}
 
 	/* Allocate inode bitmaps */
@@ -292,22 +292,30 @@
 		group = ext4_get_group_number(sb, start_blk - 1);
 		group -= group_data[0].group;
 		group_data[group].free_blocks_count--;
-		if (flexbg_size > 1)
-			flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
+		flex_gd->bg_flags[group] &= uninit_mask;
 	}
 
 	/* Allocate inode tables */
 	for (; it_index < flex_gd->count; it_index++) {
-		if (start_blk + EXT4_SB(sb)->s_itb_per_group > last_blk)
+		unsigned int itb = EXT4_SB(sb)->s_itb_per_group;
+		ext4_fsblk_t next_group_start;
+
+		if (start_blk + itb > last_blk)
 			goto next_group;
 		group_data[it_index].inode_table = start_blk;
-		group = ext4_get_group_number(sb, start_blk - 1);
+		group = ext4_get_group_number(sb, start_blk);
+		next_group_start = ext4_group_first_block_no(sb, group + 1);
 		group -= group_data[0].group;
-		group_data[group].free_blocks_count -=
-					EXT4_SB(sb)->s_itb_per_group;
-		if (flexbg_size > 1)
-			flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
 
+		if (start_blk + itb > next_group_start) {
+			flex_gd->bg_flags[group + 1] &= uninit_mask;
+			overhead = start_blk + itb - next_group_start;
+			group_data[group + 1].free_blocks_count -= overhead;
+			itb -= overhead;
+		}
+
+		group_data[group].free_blocks_count -= itb;
+		flex_gd->bg_flags[group] &= uninit_mask;
 		start_blk += EXT4_SB(sb)->s_itb_per_group;
 	}
 
@@ -401,7 +409,7 @@
 		start = ext4_group_first_block_no(sb, group);
 		group -= flex_gd->groups[0].group;
 
-		count2 = sb->s_blocksize * 8 - (block - start);
+		count2 = EXT4_BLOCKS_PER_GROUP(sb) - (block - start);
 		if (count2 > count)
 			count2 = count;
 
@@ -620,7 +628,7 @@
 			if (err)
 				goto out;
 			count = group_table_count[j];
-			start = group_data[i].block_bitmap;
+			start = (&group_data[i].block_bitmap)[j];
 			block = start;
 		}
 
diff -ruw linux-3.11.10/fs/ext4/super.c linux-3.11.10-fbx/fs/ext4/super.c
--- linux-3.11.10/fs/ext4/super.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/super.c	2014-08-22 15:47:22.132063127 +0200
@@ -775,7 +775,7 @@
 	}
 
 	ext4_es_unregister_shrinker(sbi);
-	del_timer(&sbi->s_err_report);
+	del_timer_sync(&sbi->s_err_report);
 	ext4_release_system_zone(sb);
 	ext4_mb_release(sb);
 	ext4_ext_release(sb);
@@ -1501,8 +1501,6 @@
 			arg = JBD2_DEFAULT_MAX_COMMIT_AGE;
 		sbi->s_commit_interval = HZ * arg;
 	} else if (token == Opt_max_batch_time) {
-		if (arg == 0)
-			arg = EXT4_DEF_MAX_BATCH_TIME;
 		sbi->s_max_batch_time = arg;
 	} else if (token == Opt_min_batch_time) {
 		sbi->s_min_batch_time = arg;
@@ -2725,10 +2723,11 @@
 	es = sbi->s_es;
 
 	if (es->s_error_count)
-		ext4_msg(sb, KERN_NOTICE, "error count: %u",
+		/* fsck newer than v1.41.13 is needed to clean this condition. */
+		ext4_msg(sb, KERN_NOTICE, "error count since last fsck: %u",
 			 le32_to_cpu(es->s_error_count));
 	if (es->s_first_error_time) {
-		printk(KERN_NOTICE "EXT4-fs (%s): initial error at %u: %.*s:%d",
+		printk(KERN_NOTICE "EXT4-fs (%s): initial error at time %u: %.*s:%d",
 		       sb->s_id, le32_to_cpu(es->s_first_error_time),
 		       (int) sizeof(es->s_first_error_func),
 		       es->s_first_error_func,
@@ -2742,7 +2741,7 @@
 		printk("\n");
 	}
 	if (es->s_last_error_time) {
-		printk(KERN_NOTICE "EXT4-fs (%s): last error at %u: %.*s:%d",
+		printk(KERN_NOTICE "EXT4-fs (%s): last error at time %u: %.*s:%d",
 		       sb->s_id, le32_to_cpu(es->s_last_error_time),
 		       (int) sizeof(es->s_last_error_func),
 		       es->s_last_error_func,
@@ -3251,11 +3250,19 @@
 }
 
 
-static ext4_fsblk_t ext4_calculate_resv_clusters(struct ext4_sb_info *sbi)
+static ext4_fsblk_t ext4_calculate_resv_clusters(struct super_block *sb)
 {
 	ext4_fsblk_t resv_clusters;
 
 	/*
+	 * There's no need to reserve anything when we aren't using extents.
+	 * The space estimates are exact, there are no unwritten extents,
+	 * hole punching doesn't need new metadata... This is needed especially
+	 * to keep ext2/3 backward compatibility.
+	 */
+	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
+		return 0;
+	/*
 	 * By default we reserve 2% or 4096 clusters, whichever is smaller.
 	 * This should cover the situations where we can not afford to run
 	 * out of space like for example punch hole, or converting
@@ -3263,7 +3270,8 @@
 	 * allocation would require 1, or 2 blocks, higher numbers are
 	 * very rare.
 	 */
-	resv_clusters = ext4_blocks_count(sbi->s_es) >> sbi->s_cluster_bits;
+	resv_clusters = ext4_blocks_count(EXT4_SB(sb)->s_es) >>
+			EXT4_SB(sb)->s_cluster_bits;
 
 	do_div(resv_clusters, 50);
 	resv_clusters = min_t(ext4_fsblk_t, resv_clusters, 4096);
@@ -3621,17 +3629,23 @@
 	for (i = 0; i < 4; i++)
 		sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
 	sbi->s_def_hash_version = es->s_def_hash_version;
+	if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
 	i = le32_to_cpu(es->s_flags);
 	if (i & EXT2_FLAGS_UNSIGNED_HASH)
 		sbi->s_hash_unsigned = 3;
 	else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
 #ifdef __CHAR_UNSIGNED__
-		es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
+			if (!(sb->s_flags & MS_RDONLY))
+				es->s_flags |=
+					cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
 		sbi->s_hash_unsigned = 3;
 #else
-		es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
+			if (!(sb->s_flags & MS_RDONLY))
+				es->s_flags |=
+					cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
 #endif
 	}
+	}
 
 	/* Handle clustersize */
 	clustersize = BLOCK_SIZE << le32_to_cpu(es->s_log_cluster_size);
@@ -4014,10 +4028,10 @@
 			 "available");
 	}
 
-	err = ext4_reserve_clusters(sbi, ext4_calculate_resv_clusters(sbi));
+	err = ext4_reserve_clusters(sbi, ext4_calculate_resv_clusters(sb));
 	if (err) {
 		ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
-			 "reserved pool", ext4_calculate_resv_clusters(sbi));
+			 "reserved pool", ext4_calculate_resv_clusters(sb));
 		goto failed_mount4a;
 	}
 
@@ -4124,7 +4138,7 @@
 	}
 failed_mount3:
 	ext4_es_unregister_shrinker(sbi);
-	del_timer(&sbi->s_err_report);
+	del_timer_sync(&sbi->s_err_report);
 	if (sbi->s_flex_groups)
 		ext4_kvfree(sbi->s_flex_groups);
 	percpu_counter_destroy(&sbi->s_freeclusters_counter);
diff -ruw linux-3.11.10/fs/ext4/xattr.c linux-3.11.10-fbx/fs/ext4/xattr.c
--- linux-3.11.10/fs/ext4/xattr.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ext4/xattr.c	2014-07-01 16:22:13.162329728 +0200
@@ -517,8 +517,8 @@
 }
 
 /*
- * Release the xattr block BH: If the reference count is > 1, decrement
- * it; otherwise free the block.
+ * Release the xattr block BH: If the reference count is > 1, decrement it;
+ * otherwise free the block.
  */
 static void
 ext4_xattr_release_block(handle_t *handle, struct inode *inode,
@@ -538,16 +538,31 @@
 		if (ce)
 			mb_cache_entry_free(ce);
 		get_bh(bh);
+		unlock_buffer(bh);
 		ext4_free_blocks(handle, inode, bh, 0, 1,
 				 EXT4_FREE_BLOCKS_METADATA |
 				 EXT4_FREE_BLOCKS_FORGET);
-		unlock_buffer(bh);
 	} else {
 		le32_add_cpu(&BHDR(bh)->h_refcount, -1);
 		if (ce)
 			mb_cache_entry_release(ce);
+		/*
+		 * Beware of this ugliness: Releasing of xattr block references
+		 * from different inodes can race and so we have to protect
+		 * from a race where someone else frees the block (and releases
+		 * its journal_head) before we are done dirtying the buffer. In
+		 * nojournal mode this race is harmless and we actually cannot
+		 * call ext4_handle_dirty_xattr_block() with locked buffer as
+		 * that function can call sync_dirty_buffer() so for that case
+		 * we handle the dirtying after unlocking the buffer.
+		 */
+		if (ext4_handle_valid(handle))
+			error = ext4_handle_dirty_xattr_block(handle, inode,
+							      bh);
 		unlock_buffer(bh);
-		error = ext4_handle_dirty_xattr_block(handle, inode, bh);
+		if (!ext4_handle_valid(handle))
+			error = ext4_handle_dirty_xattr_block(handle, inode,
+							      bh);
 		if (IS_SYNC(inode))
 			ext4_handle_sync(handle);
 		dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1));
@@ -1352,6 +1367,7 @@
 					new_extra_isize = s_min_extra_isize;
 					kfree(is); is = NULL;
 					kfree(bs); bs = NULL;
+					brelse(bh);
 					goto retry;
 				}
 				error = -1;
diff -ruw linux-3.11.10/fs/file.c linux-3.11.10-fbx/fs/file.c
--- linux-3.11.10/fs/file.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/file.c	2014-05-09 14:12:54.244546158 +0200
@@ -34,7 +34,7 @@
 	 * vmalloc() if the allocation size will be considered "large" by the VM.
 	 */
 	if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) {
-		void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN);
+		void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY);
 		if (data != NULL)
 			return data;
 	}
diff -ruw linux-3.11.10/fs/file_table.c linux-3.11.10-fbx/fs/file_table.c
--- linux-3.11.10/fs/file_table.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/file_table.c	2014-07-01 16:22:13.162329728 +0200
@@ -211,10 +211,10 @@
 	struct dentry *dentry = file->f_path.dentry;
 	struct inode *inode = dentry->d_inode;
 
-	put_write_access(inode);
-
 	if (special_file(inode->i_mode))
 		return;
+
+	put_write_access(inode);
 	if (file_check_writeable(file) != 0)
 		return;
 	__mnt_drop_write(mnt);
diff -ruw linux-3.11.10/fs/fs-writeback.c linux-3.11.10-fbx/fs/fs-writeback.c
--- linux-3.11.10/fs/fs-writeback.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/fs-writeback.c	2014-07-01 16:22:13.162329728 +0200
@@ -88,16 +88,29 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/writeback.h>
 
+static void bdi_wakeup_thread(struct backing_dev_info *bdi)
+{
+	spin_lock_bh(&bdi->wb_lock);
+	if (test_bit(BDI_registered, &bdi->state))
+		mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
+	spin_unlock_bh(&bdi->wb_lock);
+}
+
 static void bdi_queue_work(struct backing_dev_info *bdi,
 			   struct wb_writeback_work *work)
 {
 	trace_writeback_queue(bdi, work);
 
 	spin_lock_bh(&bdi->wb_lock);
+	if (!test_bit(BDI_registered, &bdi->state)) {
+		if (work->done)
+			complete(work->done);
+		goto out_unlock;
+	}
 	list_add_tail(&work->list, &bdi->work_list);
-	spin_unlock_bh(&bdi->wb_lock);
-
 	mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
+out_unlock:
+	spin_unlock_bh(&bdi->wb_lock);
 }
 
 static void
@@ -113,7 +126,7 @@
 	work = kzalloc(sizeof(*work), GFP_ATOMIC);
 	if (!work) {
 		trace_writeback_nowork(bdi);
-		mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
+		bdi_wakeup_thread(bdi);
 		return;
 	}
 
@@ -160,7 +173,7 @@
 	 * writeback as soon as there is no other work to do.
 	 */
 	trace_writeback_wake_background(bdi);
-	mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
+	bdi_wakeup_thread(bdi);
 }
 
 /*
@@ -508,13 +521,16 @@
 	}
 	WARN_ON(inode->i_state & I_SYNC);
 	/*
-	 * Skip inode if it is clean. We don't want to mess with writeback
-	 * lists in this function since flusher thread may be doing for example
-	 * sync in parallel and if we move the inode, it could get skipped. So
-	 * here we make sure inode is on some writeback list and leave it there
-	 * unless we have completely cleaned the inode.
-	 */
-	if (!(inode->i_state & I_DIRTY))
+	 * Skip inode if it is clean and we have no outstanding writeback in
+	 * WB_SYNC_ALL mode. We don't want to mess with writeback lists in this
+	 * function since flusher thread may be doing for example sync in
+	 * parallel and if we move the inode, it could get skipped. So here we
+	 * make sure inode is on some writeback list and leave it there unless
+	 * we have completely cleaned the inode.
+	 */
+	if (!(inode->i_state & I_DIRTY) &&
+	    (wbc->sync_mode != WB_SYNC_ALL ||
+	     !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK)))
 		goto out;
 	inode->i_state |= I_SYNC;
 	spin_unlock(&inode->i_lock);
@@ -1011,7 +1027,7 @@
 	current->flags |= PF_SWAPWRITE;
 
 	if (likely(!current_is_workqueue_rescuer() ||
-		   list_empty(&bdi->bdi_list))) {
+		   !test_bit(BDI_registered, &bdi->state))) {
 		/*
 		 * The normal path.  Keep writing back @bdi until its
 		 * work_list is empty.  Note that this path is also taken
@@ -1033,10 +1049,10 @@
 		trace_writeback_pages_written(pages_written);
 	}
 
-	if (!list_empty(&bdi->work_list) ||
-	    (wb_has_dirty_io(wb) && dirty_writeback_interval))
-		queue_delayed_work(bdi_wq, &wb->dwork,
-			msecs_to_jiffies(dirty_writeback_interval * 10));
+	if (!list_empty(&bdi->work_list))
+		mod_delayed_work(bdi_wq, &wb->dwork, 0);
+	else if (wb_has_dirty_io(wb) && dirty_writeback_interval)
+		bdi_wakeup_thread_delayed(bdi);
 
 	current->flags &= ~PF_SWAPWRITE;
 }
diff -ruw linux-3.11.10/fs/fuse/dev.c linux-3.11.10-fbx/fs/fuse/dev.c
--- linux-3.11.10/fs/fuse/dev.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/fuse/dev.c	2014-05-09 14:12:54.304546159 +0200
@@ -1296,22 +1296,6 @@
 	return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs));
 }
 
-static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe,
-				   struct pipe_buffer *buf)
-{
-	return 1;
-}
-
-static const struct pipe_buf_operations fuse_dev_pipe_buf_ops = {
-	.can_merge = 0,
-	.map = generic_pipe_buf_map,
-	.unmap = generic_pipe_buf_unmap,
-	.confirm = generic_pipe_buf_confirm,
-	.release = generic_pipe_buf_release,
-	.steal = fuse_dev_pipe_buf_steal,
-	.get = generic_pipe_buf_get,
-};
-
 static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
 				    struct pipe_inode_info *pipe,
 				    size_t len, unsigned int flags)
@@ -1358,7 +1342,11 @@
 		buf->page = bufs[page_nr].page;
 		buf->offset = bufs[page_nr].offset;
 		buf->len = bufs[page_nr].len;
-		buf->ops = &fuse_dev_pipe_buf_ops;
+		/*
+		 * Need to be careful about this.  Having buf->ops in module
+		 * code can Oops if the buffer persists after module unload.
+		 */
+		buf->ops = &nosteal_pipe_buf_ops;
 
 		pipe->nrbufs++;
 		page_nr++;
diff -ruw linux-3.11.10/fs/hfsplus/btree.c linux-3.11.10-fbx/fs/hfsplus/btree.c
--- linux-3.11.10/fs/hfsplus/btree.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/hfsplus/btree.c	2014-06-25 11:22:30.385677444 +0200
@@ -15,6 +15,118 @@
 #include "hfsplus_fs.h"
 #include "hfsplus_raw.h"
 
+/*
+ * Initial source code of clump size calculation is gotten
+ * from http://opensource.apple.com/tarballs/diskdev_cmds/
+ */
+#define CLUMP_ENTRIES	15
+
+static short clumptbl[CLUMP_ENTRIES * 3] = {
+/*
+ *	    Volume	Attributes	 Catalog	 Extents
+ *	     Size	Clump (MB)	Clump (MB)	Clump (MB)
+ */
+	/*   1GB */	  4,		  4,		 4,
+	/*   2GB */	  6,		  6,		 4,
+	/*   4GB */	  8,		  8,		 4,
+	/*   8GB */	 11,		 11,		 5,
+	/*
+	 * For volumes 16GB and larger, we want to make sure that a full OS
+	 * install won't require fragmentation of the Catalog or Attributes
+	 * B-trees.  We do this by making the clump sizes sufficiently large,
+	 * and by leaving a gap after the B-trees for them to grow into.
+	 *
+	 * For SnowLeopard 10A298, a FullNetInstall with all packages selected
+	 * results in:
+	 * Catalog B-tree Header
+	 *	nodeSize:          8192
+	 *	totalNodes:       31616
+	 *	freeNodes:         1978
+	 * (used = 231.55 MB)
+	 * Attributes B-tree Header
+	 *	nodeSize:          8192
+	 *	totalNodes:       63232
+	 *	freeNodes:          958
+	 * (used = 486.52 MB)
+	 *
+	 * We also want Time Machine backup volumes to have a sufficiently
+	 * large clump size to reduce fragmentation.
+	 *
+	 * The series of numbers for Catalog and Attribute form a geometric
+	 * series. For Catalog (16GB to 512GB), each term is 8**(1/5) times
+	 * the previous term.  For Attributes (16GB to 512GB), each term is
+	 * 4**(1/5) times the previous term.  For 1TB to 16TB, each term is
+	 * 2**(1/5) times the previous term.
+	 */
+	/*  16GB */	 64,		 32,		 5,
+	/*  32GB */	 84,		 49,		 6,
+	/*  64GB */	111,		 74,		 7,
+	/* 128GB */	147,		111,		 8,
+	/* 256GB */	194,		169,		 9,
+	/* 512GB */	256,		256,		11,
+	/*   1TB */	294,		294,		14,
+	/*   2TB */	338,		338,		16,
+	/*   4TB */	388,		388,		20,
+	/*   8TB */	446,		446,		25,
+	/*  16TB */	512,		512,		32
+};
+
+u32 hfsplus_calc_btree_clump_size(u32 block_size, u32 node_size,
+					u64 sectors, int file_id)
+{
+	u32 mod = max(node_size, block_size);
+	u32 clump_size;
+	int column;
+	int i;
+
+	/* Figure out which column of the above table to use for this file. */
+	switch (file_id) {
+	case HFSPLUS_ATTR_CNID:
+		column = 0;
+		break;
+	case HFSPLUS_CAT_CNID:
+		column = 1;
+		break;
+	default:
+		column = 2;
+		break;
+	}
+
+	/*
+	 * The default clump size is 0.8% of the volume size. And
+	 * it must also be a multiple of the node and block size.
+	 */
+	if (sectors < 0x200000) {
+		clump_size = sectors << 2;	/*  0.8 %  */
+		if (clump_size < (8 * node_size))
+			clump_size = 8 * node_size;
+	} else {
+		/* turn exponent into table index... */
+		for (i = 0, sectors = sectors >> 22;
+		     sectors && (i < CLUMP_ENTRIES - 1);
+		     ++i, sectors = sectors >> 1) {
+			/* empty body */
+		}
+
+		clump_size = clumptbl[column + (i) * 3] * 1024 * 1024;
+	}
+
+	/*
+	 * Round the clump size to a multiple of node and block size.
+	 * NOTE: This rounds down.
+	 */
+	clump_size /= mod;
+	clump_size *= mod;
+
+	/*
+	 * Rounding down could have rounded down to 0 if the block size was
+	 * greater than the clump size.  If so, just use one block or node.
+	 */
+	if (clump_size == 0)
+		clump_size = mod;
+
+	return clump_size;
+}
 
 /* Get a reference to a B*Tree and do some initial checks */
 struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id)
diff -ruw linux-3.11.10/fs/hfsplus/hfsplus_fs.h linux-3.11.10-fbx/fs/hfsplus/hfsplus_fs.h
--- linux-3.11.10/fs/hfsplus/hfsplus_fs.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/hfsplus/hfsplus_fs.h	2014-06-25 11:22:30.385677444 +0200
@@ -126,6 +126,14 @@
 #define HFS_BNODE_DELETED	4
 
 /*
+ * Attributes file states
+ */
+#define HFSPLUS_EMPTY_ATTR_TREE		0
+#define HFSPLUS_CREATING_ATTR_TREE	1
+#define HFSPLUS_VALID_ATTR_TREE		2
+#define HFSPLUS_FAILED_ATTR_TREE	3
+
+/*
  * HFS+ superblock info (built from Volume Header on disk)
  */
 
@@ -140,6 +148,7 @@
 	struct hfs_btree *ext_tree;
 	struct hfs_btree *cat_tree;
 	struct hfs_btree *attr_tree;
+	atomic_t attr_tree_state;
 	struct inode *alloc_file;
 	struct inode *hidden_dir;
 	struct nls_table *nls;
@@ -188,6 +197,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)
 {
@@ -379,6 +389,7 @@
 int hfsplus_block_free(struct super_block *, u32, u32);
 
 /* btree.c */
+u32 hfsplus_calc_btree_clump_size(u32, u32, u64, int);
 struct hfs_btree *hfs_btree_open(struct super_block *, u32);
 void hfs_btree_close(struct hfs_btree *);
 int hfs_btree_write(struct hfs_btree *);
diff -ruw linux-3.11.10/fs/hfsplus/hfsplus_raw.h linux-3.11.10-fbx/fs/hfsplus/hfsplus_raw.h
--- linux-3.11.10/fs/hfsplus/hfsplus_raw.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/hfsplus/hfsplus_raw.h	2014-06-25 11:22:30.385677444 +0200
@@ -187,6 +187,9 @@
 /* HFS+ BTree misc info */
 #define HFSPLUS_TREE_HEAD 0
 #define HFSPLUS_NODE_MXSZ 32768
+#define HFSPLUS_ATTR_TREE_NODE_SIZE		8192
+#define HFSPLUS_BTREE_HDR_NODE_RECS_COUNT	3
+#define HFSPLUS_BTREE_HDR_USER_BYTES		128
 
 /* Some special File ID numbers (stolen from hfs.h) */
 #define HFSPLUS_POR_CNID		1	/* Parent Of the Root */
diff -ruw linux-3.11.10/fs/hfsplus/inode.c linux-3.11.10-fbx/fs/hfsplus/inode.c
--- linux-3.11.10/fs/hfsplus/inode.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/hfsplus/inode.c	2013-12-04 14:33:23.019479038 +0100
@@ -244,11 +244,13 @@
 	mode = be16_to_cpu(perms->mode);
 
 	i_uid_write(inode, be32_to_cpu(perms->owner));
-	if (!i_uid_read(inode) && !mode)
+	if ((!i_uid_read(inode) && !mode) ||
+	    test_bit(HFSPLUS_SB_NOOWNERS, &sbi->flags))
 		inode->i_uid = sbi->uid;
 
 	i_gid_write(inode, be32_to_cpu(perms->group));
-	if (!i_gid_read(inode) && !mode)
+	if ((!i_gid_read(inode) && !mode) ||
+	    test_bit(HFSPLUS_SB_NOOWNERS, &sbi->flags))
 		inode->i_gid = sbi->gid;
 
 	if (dir) {
@@ -301,12 +303,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);
@@ -410,8 +416,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.11.10/fs/hfsplus/options.c linux-3.11.10-fbx/fs/hfsplus/options.c
--- linux-3.11.10/fs/hfsplus/options.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/hfsplus/options.c	2013-12-04 14:33:23.019479038 +0100
@@ -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 }
 };
 
@@ -196,6 +197,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;
 		}
@@ -235,5 +239,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.11.10/fs/hfsplus/super.c linux-3.11.10-fbx/fs/hfsplus/super.c
--- linux-3.11.10/fs/hfsplus/super.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/hfsplus/super.c	2014-06-25 11:22:30.385677444 +0200
@@ -474,12 +474,14 @@
 		pr_err("failed to load catalog file\n");
 		goto out_close_ext_tree;
 	}
+	atomic_set(&sbi->attr_tree_state, HFSPLUS_EMPTY_ATTR_TREE);
 	if (vhdr->attr_file.total_blocks != 0) {
 		sbi->attr_tree = hfs_btree_open(sb, HFSPLUS_ATTR_CNID);
 		if (!sbi->attr_tree) {
 			pr_err("failed to load attributes file\n");
 			goto out_close_cat_tree;
 		}
+		atomic_set(&sbi->attr_tree_state, HFSPLUS_VALID_ATTR_TREE);
 	}
 	sb->s_xattr = hfsplus_xattr_handlers;
 
diff -ruw linux-3.11.10/fs/hfsplus/xattr.c linux-3.11.10-fbx/fs/hfsplus/xattr.c
--- linux-3.11.10/fs/hfsplus/xattr.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/hfsplus/xattr.c	2014-06-25 11:22:30.385677444 +0200
@@ -75,6 +75,208 @@
 	return 0;
 }
 
+static void hfsplus_init_header_node(struct inode *attr_file,
+					u32 clump_size,
+					char *buf, size_t node_size)
+{
+	struct hfs_bnode_desc *desc;
+	struct hfs_btree_header_rec *head;
+	u16 offset;
+	__be16 *rec_offsets;
+	u32 hdr_node_map_rec_bits;
+	char *bmp;
+	u32 used_nodes;
+	u32 used_bmp_bytes;
+
+	hfs_dbg(ATTR_MOD, "init_hdr_attr_file: clump %u, node_size %zu\n",
+				clump_size, node_size);
+
+	/* The end of the node contains list of record offsets */
+	rec_offsets = (__be16 *)(buf + node_size);
+
+	desc = (struct hfs_bnode_desc *)buf;
+	desc->type = HFS_NODE_HEADER;
+	desc->num_recs = cpu_to_be16(HFSPLUS_BTREE_HDR_NODE_RECS_COUNT);
+	offset = sizeof(struct hfs_bnode_desc);
+	*--rec_offsets = cpu_to_be16(offset);
+
+	head = (struct hfs_btree_header_rec *)(buf + offset);
+	head->node_size = cpu_to_be16(node_size);
+	head->node_count = cpu_to_be32(i_size_read(attr_file) / node_size);
+	head->free_nodes = cpu_to_be32(be32_to_cpu(head->node_count) - 1);
+	head->clump_size = cpu_to_be32(clump_size);
+	head->attributes |= cpu_to_be32(HFS_TREE_BIGKEYS | HFS_TREE_VARIDXKEYS);
+	head->max_key_len = cpu_to_be16(HFSPLUS_ATTR_KEYLEN - sizeof(u16));
+	offset += sizeof(struct hfs_btree_header_rec);
+	*--rec_offsets = cpu_to_be16(offset);
+	offset += HFSPLUS_BTREE_HDR_USER_BYTES;
+	*--rec_offsets = cpu_to_be16(offset);
+
+	hdr_node_map_rec_bits = 8 * (node_size - offset - (4 * sizeof(u16)));
+	if (be32_to_cpu(head->node_count) > hdr_node_map_rec_bits) {
+		u32 map_node_bits;
+		u32 map_nodes;
+
+		desc->next = cpu_to_be32(be32_to_cpu(head->leaf_tail) + 1);
+		map_node_bits = 8 * (node_size - sizeof(struct hfs_bnode_desc) -
+					(2 * sizeof(u16)) - 2);
+		map_nodes = (be32_to_cpu(head->node_count) -
+				hdr_node_map_rec_bits +
+				(map_node_bits - 1)) / map_node_bits;
+		be32_add_cpu(&head->free_nodes, 0 - map_nodes);
+	}
+
+	bmp = buf + offset;
+	used_nodes =
+		be32_to_cpu(head->node_count) - be32_to_cpu(head->free_nodes);
+	used_bmp_bytes = used_nodes / 8;
+	if (used_bmp_bytes) {
+		memset(bmp, 0xFF, used_bmp_bytes);
+		bmp += used_bmp_bytes;
+		used_nodes %= 8;
+	}
+	*bmp = ~(0xFF >> used_nodes);
+	offset += hdr_node_map_rec_bits / 8;
+	*--rec_offsets = cpu_to_be16(offset);
+}
+
+static int hfsplus_create_attributes_file(struct super_block *sb)
+{
+	int err = 0;
+	struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
+	struct inode *attr_file;
+	struct hfsplus_inode_info *hip;
+	u32 clump_size;
+	u16 node_size = HFSPLUS_ATTR_TREE_NODE_SIZE;
+	char *buf;
+	int index, written;
+	struct address_space *mapping;
+	struct page *page;
+	int old_state = HFSPLUS_EMPTY_ATTR_TREE;
+
+	hfs_dbg(ATTR_MOD, "create_attr_file: ino %d\n", HFSPLUS_ATTR_CNID);
+
+check_attr_tree_state_again:
+	switch (atomic_read(&sbi->attr_tree_state)) {
+	case HFSPLUS_EMPTY_ATTR_TREE:
+		if (old_state != atomic_cmpxchg(&sbi->attr_tree_state,
+						old_state,
+						HFSPLUS_CREATING_ATTR_TREE))
+			goto check_attr_tree_state_again;
+		break;
+	case HFSPLUS_CREATING_ATTR_TREE:
+		/*
+		 * This state means that another thread is in process
+		 * of AttributesFile creation. Theoretically, it is
+		 * possible to be here. But really __setxattr() method
+		 * first of all calls hfs_find_init() for lookup in
+		 * B-tree of CatalogFile. This method locks mutex of
+		 * CatalogFile's B-tree. As a result, if some thread
+		 * is inside AttributedFile creation operation then
+		 * another threads will be waiting unlocking of
+		 * CatalogFile's B-tree's mutex. However, if code will
+		 * change then we will return error code (-EAGAIN) from
+		 * here. Really, it means that first try to set of xattr
+		 * fails with error but second attempt will have success.
+		 */
+		return -EAGAIN;
+	case HFSPLUS_VALID_ATTR_TREE:
+		return 0;
+	case HFSPLUS_FAILED_ATTR_TREE:
+		return -EOPNOTSUPP;
+	default:
+		BUG();
+	}
+
+	attr_file = hfsplus_iget(sb, HFSPLUS_ATTR_CNID);
+	if (IS_ERR(attr_file)) {
+		pr_err("failed to load attributes file\n");
+		return PTR_ERR(attr_file);
+	}
+
+	BUG_ON(i_size_read(attr_file) != 0);
+
+	hip = HFSPLUS_I(attr_file);
+
+	clump_size = hfsplus_calc_btree_clump_size(sb->s_blocksize,
+						    node_size,
+						    sbi->sect_count,
+						    HFSPLUS_ATTR_CNID);
+
+	mutex_lock(&hip->extents_lock);
+	hip->clump_blocks = clump_size >> sbi->alloc_blksz_shift;
+	mutex_unlock(&hip->extents_lock);
+
+	if (sbi->free_blocks <= (hip->clump_blocks << 1)) {
+		err = -ENOSPC;
+		goto end_attr_file_creation;
+	}
+
+	while (hip->alloc_blocks < hip->clump_blocks) {
+		err = hfsplus_file_extend(attr_file);
+		if (unlikely(err)) {
+			pr_err("failed to extend attributes file\n");
+			goto end_attr_file_creation;
+		}
+		hip->phys_size = attr_file->i_size =
+			(loff_t)hip->alloc_blocks << sbi->alloc_blksz_shift;
+		hip->fs_blocks = hip->alloc_blocks << sbi->fs_shift;
+		inode_set_bytes(attr_file, attr_file->i_size);
+	}
+
+	buf = kzalloc(node_size, GFP_NOFS);
+	if (!buf) {
+		pr_err("failed to allocate memory for header node\n");
+		err = -ENOMEM;
+		goto end_attr_file_creation;
+	}
+
+	hfsplus_init_header_node(attr_file, clump_size, buf, node_size);
+
+	mapping = attr_file->i_mapping;
+
+	index = 0;
+	written = 0;
+	for (; written < node_size; index++, written += PAGE_CACHE_SIZE) {
+		void *kaddr;
+
+		page = read_mapping_page(mapping, index, NULL);
+		if (IS_ERR(page)) {
+			err = PTR_ERR(page);
+			goto failed_header_node_init;
+		}
+
+		kaddr = kmap_atomic(page);
+		memcpy(kaddr, buf + written,
+			min_t(size_t, PAGE_CACHE_SIZE, node_size - written));
+		kunmap_atomic(kaddr);
+
+		set_page_dirty(page);
+		page_cache_release(page);
+	}
+
+	hfsplus_mark_inode_dirty(attr_file, HFSPLUS_I_ATTR_DIRTY);
+
+	sbi->attr_tree = hfs_btree_open(sb, HFSPLUS_ATTR_CNID);
+	if (!sbi->attr_tree)
+		pr_err("failed to load attributes file\n");
+
+failed_header_node_init:
+	kfree(buf);
+
+end_attr_file_creation:
+	iput(attr_file);
+
+	if (!err)
+		atomic_set(&sbi->attr_tree_state, HFSPLUS_VALID_ATTR_TREE);
+	else if (err == -ENOSPC)
+		atomic_set(&sbi->attr_tree_state, HFSPLUS_EMPTY_ATTR_TREE);
+	else
+		atomic_set(&sbi->attr_tree_state, HFSPLUS_FAILED_ATTR_TREE);
+
+	return err;
+}
+
 int __hfsplus_setxattr(struct inode *inode, const char *name,
 			const void *value, size_t size, int flags)
 {
@@ -159,7 +361,8 @@
 	}
 
 	if (!HFSPLUS_SB(inode->i_sb)->attr_tree) {
-		err = -EOPNOTSUPP;
+		err = hfsplus_create_attributes_file(inode->i_sb);
+		if (unlikely(err))
 		goto end_setxattr;
 	}
 
diff -ruw linux-3.11.10/fs/inode.c linux-3.11.10-fbx/fs/inode.c
--- linux-3.11.10/fs/inode.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/inode.c	2014-07-01 16:22:13.162329728 +0200
@@ -1839,14 +1839,18 @@
  * inode_owner_or_capable - check current task permissions to inode
  * @inode: inode being checked
  *
- * Return true if current either has CAP_FOWNER to the inode, or
- * owns the file.
+ * Return true if current either has CAP_FOWNER in a namespace with the
+ * inode owner uid mapped, or owns the file.
  */
 bool inode_owner_or_capable(const struct inode *inode)
 {
+	struct user_namespace *ns;
+
 	if (uid_eq(current_fsuid(), inode->i_uid))
 		return true;
-	if (inode_capable(inode, CAP_FOWNER))
+
+	ns = current_user_ns();
+	if (ns_capable(ns, CAP_FOWNER) && kuid_has_mapping(ns, inode->i_uid))
 		return true;
 	return false;
 }
diff -ruw linux-3.11.10/fs/jbd2/transaction.c linux-3.11.10-fbx/fs/jbd2/transaction.c
--- linux-3.11.10/fs/jbd2/transaction.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/jbd2/transaction.c	2014-08-22 15:47:22.132063127 +0200
@@ -514,11 +514,13 @@
 	 * similarly constrained call sites
 	 */
 	ret = start_this_handle(journal, handle, GFP_NOFS);
-	if (ret < 0)
+	if (ret < 0) {
 		jbd2_journal_free_reserved(handle);
+		return ret;
+	}
 	handle->h_type = type;
 	handle->h_line_no = line_no;
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(jbd2_journal_start_reserved);
 
@@ -1290,7 +1292,10 @@
 		 * once a transaction -bzzz
 		 */
 		jh->b_modified = 1;
-		J_ASSERT_JH(jh, handle->h_buffer_credits > 0);
+		if (handle->h_buffer_credits <= 0) {
+			ret = -ENOSPC;
+			goto out_unlock_bh;
+		}
 		handle->h_buffer_credits--;
 	}
 
@@ -1373,7 +1378,6 @@
 	jbd2_journal_put_journal_head(jh);
 out:
 	JBUFFER_TRACE(jh, "exit");
-	WARN_ON(ret);	/* All errors are bugs, so dump the stack */
 	return ret;
 }
 
@@ -1586,9 +1590,12 @@
 	 * to perform a synchronous write.  We do this to detect the
 	 * case where a single process is doing a stream of sync
 	 * writes.  No point in waiting for joiners in that case.
+	 *
+	 * Setting max_batch_time to 0 disables this completely.
 	 */
 	pid = current->pid;
-	if (handle->h_sync && journal->j_last_sync_writer != pid) {
+	if (handle->h_sync && journal->j_last_sync_writer != pid &&
+	    journal->j_max_batch_time) {
 		u64 commit_time, trans_time;
 
 		journal->j_last_sync_writer = pid;
diff -ruw linux-3.11.10/fs/Kconfig linux-3.11.10-fbx/fs/Kconfig
--- linux-3.11.10/fs/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/Kconfig	2013-12-04 14:33:22.007479022 +0100
@@ -93,6 +93,7 @@
 
 source "fs/fat/Kconfig"
 source "fs/ntfs/Kconfig"
+source "fs/exfat/Kconfig"
 
 endmenu
 endif # BLOCK
@@ -166,6 +167,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.11.10/fs/lockd/svc.c linux-3.11.10-fbx/fs/lockd/svc.c
--- linux-3.11.10/fs/lockd/svc.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/lockd/svc.c	2014-07-01 16:22:13.162329728 +0200
@@ -235,6 +235,7 @@
 	if (warned++ == 0)
 		printk(KERN_WARNING
 			"lockd_up: makesock failed, error=%d\n", err);
+	svc_shutdown_net(serv, net);
 	return err;
 }
 
diff -ruw linux-3.11.10/fs/lockd/svclock.c linux-3.11.10-fbx/fs/lockd/svclock.c
--- linux-3.11.10/fs/lockd/svclock.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/lockd/svclock.c	2014-05-09 14:12:54.304546159 +0200
@@ -779,6 +779,7 @@
 	struct nlm_file		*file = block->b_file;
 	struct nlm_lock		*lock = &block->b_call->a_args.lock;
 	int			error;
+	loff_t			fl_start, fl_end;
 
 	dprintk("lockd: grant blocked lock %p\n", block);
 
@@ -796,9 +797,16 @@
 	}
 
 	/* Try the lock operation again */
+	/* vfs_lock_file() can mangle fl_start and fl_end, but we need
+	 * them unchanged for the GRANT_MSG
+	 */
 	lock->fl.fl_flags |= FL_SLEEP;
+	fl_start = lock->fl.fl_start;
+	fl_end = lock->fl.fl_end;
 	error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
 	lock->fl.fl_flags &= ~FL_SLEEP;
+	lock->fl.fl_start = fl_start;
+	lock->fl.fl_end = fl_end;
 
 	switch (error) {
 	case 0:
diff -ruw linux-3.11.10/fs/locks.c linux-3.11.10-fbx/fs/locks.c
--- linux-3.11.10/fs/locks.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/locks.c	2014-07-01 16:22:13.162329728 +0200
@@ -1359,11 +1359,10 @@
 
 restart:
 	break_time = flock->fl_break_time;
-	if (break_time != 0) {
+	if (break_time != 0)
 		break_time -= jiffies;
 		if (break_time == 0)
 			break_time++;
-	}
 	locks_insert_block(flock, new_fl);
 	spin_unlock(&inode->i_lock);
 	error = wait_event_interruptible_timeout(new_fl->fl_wait,
diff -ruw linux-3.11.10/fs/Makefile linux-3.11.10-fbx/fs/Makefile
--- linux-3.11.10/fs/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/Makefile	2013-12-04 14:33:22.007479022 +0100
@@ -126,3 +126,4 @@
 obj-$(CONFIG_CEPH_FS)		+= ceph/
 obj-$(CONFIG_PSTORE)		+= pstore/
 obj-$(CONFIG_EFIVAR_FS)		+= efivarfs/
+obj-$(CONFIG_EXFAT_FS)		+= exfat/
diff -ruw linux-3.11.10/fs/mount.h linux-3.11.10-fbx/fs/mount.h
--- linux-3.11.10/fs/mount.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/mount.h	2014-05-09 14:12:54.304546159 +0200
@@ -73,7 +73,7 @@
 static inline int is_mounted(struct vfsmount *mnt)
 {
 	/* neither detached nor internal? */
-	return !IS_ERR_OR_NULL(real_mount(mnt));
+	return !IS_ERR_OR_NULL(real_mount(mnt)->mnt_ns);
 }
 
 extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
diff -ruw linux-3.11.10/fs/namei.c linux-3.11.10-fbx/fs/namei.c
--- linux-3.11.10/fs/namei.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/namei.c	2014-07-01 16:22:13.166329756 +0200
@@ -321,10 +321,11 @@
 
 	if (S_ISDIR(inode->i_mode)) {
 		/* DACs are overridable for directories */
-		if (inode_capable(inode, CAP_DAC_OVERRIDE))
+		if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
 			return 0;
 		if (!(mask & MAY_WRITE))
-			if (inode_capable(inode, CAP_DAC_READ_SEARCH))
+			if (capable_wrt_inode_uidgid(inode,
+						     CAP_DAC_READ_SEARCH))
 				return 0;
 		return -EACCES;
 	}
@@ -334,7 +335,7 @@
 	 * at least one exec bit set.
 	 */
 	if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
-		if (inode_capable(inode, CAP_DAC_OVERRIDE))
+		if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
 			return 0;
 
 	/*
@@ -342,7 +343,7 @@
 	 */
 	mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
 	if (mask == MAY_READ)
-		if (inode_capable(inode, CAP_DAC_READ_SEARCH))
+		if (capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
 			return 0;
 
 	return -EACCES;
@@ -2198,7 +2199,7 @@
 		return 0;
 	if (uid_eq(dir->i_uid, fsuid))
 		return 0;
-	return !inode_capable(inode, CAP_FOWNER);
+	return !capable_wrt_inode_uidgid(inode, CAP_FOWNER);
 }
 
 /*
@@ -2262,6 +2263,7 @@
  */
 static inline int may_create(struct inode *dir, struct dentry *child)
 {
+	audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE);
 	if (child->d_inode)
 		return -EEXIST;
 	if (IS_DEADDIR(dir))
@@ -3707,6 +3709,7 @@
 out_dput:
 	done_path_create(&new_path, new_dentry);
 	if (retry_estale(error, how)) {
+		path_put(&old_path);
 		how |= LOOKUP_REVAL;
 		goto retry;
 	}
diff -ruw linux-3.11.10/fs/namespace.c linux-3.11.10-fbx/fs/namespace.c
--- linux-3.11.10/fs/namespace.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/namespace.c	2013-12-04 14:33:23.051479038 +0100
@@ -1650,7 +1650,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.11.10/fs/nfs/delegation.c linux-3.11.10-fbx/fs/nfs/delegation.c
--- linux-3.11.10/fs/nfs/delegation.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/nfs/delegation.c	2014-07-01 16:22:13.166329756 +0200
@@ -656,16 +656,19 @@
 
 	rcu_read_lock();
 	delegation = rcu_dereference(NFS_I(inode)->delegation);
+	if (delegation == NULL)
+		goto out_enoent;
 
-	if (!clp->cl_mvops->match_stateid(&delegation->stateid, stateid)) {
-		rcu_read_unlock();
-		return -ENOENT;
-	}
+	if (!clp->cl_mvops->match_stateid(&delegation->stateid, stateid))
+		goto out_enoent;
 	nfs_mark_return_delegation(server, delegation);
 	rcu_read_unlock();
 
 	nfs_delegation_run_state_manager(clp);
 	return 0;
+out_enoent:
+	rcu_read_unlock();
+	return -ENOENT;
 }
 
 static struct inode *
diff -ruw linux-3.11.10/fs/nfs/dir.c linux-3.11.10-fbx/fs/nfs/dir.c
--- linux-3.11.10/fs/nfs/dir.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/nfs/dir.c	2014-05-09 14:12:54.304546159 +0200
@@ -1813,6 +1813,11 @@
 							GFP_KERNEL)) {
 		SetPageUptodate(page);
 		unlock_page(page);
+		/*
+		 * add_to_page_cache_lru() grabs an extra page refcount.
+		 * Drop it here to avoid leaking this page later.
+		 */
+		page_cache_release(page);
 	} else
 		__free_page(page);
 
diff -ruw linux-3.11.10/fs/nfs/dns_resolve.c linux-3.11.10-fbx/fs/nfs/dns_resolve.c
--- linux-3.11.10/fs/nfs/dns_resolve.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/nfs/dns_resolve.c	2014-07-01 16:22:13.166329756 +0200
@@ -46,7 +46,9 @@
 #include <linux/sunrpc/cache.h>
 #include <linux/sunrpc/svcauth.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
+#include <linux/nfs_fs.h>
 
+#include "nfs4_fs.h"
 #include "dns_resolve.h"
 #include "cache_lib.h"
 #include "netns.h"
diff -ruw linux-3.11.10/fs/nfs/inode.c linux-3.11.10-fbx/fs/nfs/inode.c
--- linux-3.11.10/fs/nfs/inode.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/nfs/inode.c	2014-08-22 15:47:22.132063127 +0200
@@ -163,17 +163,16 @@
 	if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) {
 		nfs_fscache_invalidate(inode);
 		nfsi->cache_validity |= NFS_INO_INVALID_ATTR
-					| NFS_INO_INVALID_LABEL
 					| NFS_INO_INVALID_DATA
 					| NFS_INO_INVALID_ACCESS
 					| NFS_INO_INVALID_ACL
 					| NFS_INO_REVAL_PAGECACHE;
 	} else
 		nfsi->cache_validity |= NFS_INO_INVALID_ATTR
-					| NFS_INO_INVALID_LABEL
 					| NFS_INO_INVALID_ACCESS
 					| NFS_INO_INVALID_ACL
 					| NFS_INO_REVAL_PAGECACHE;
+	nfs_zap_label_cache_locked(nfsi);
 }
 
 void nfs_zap_caches(struct inode *inode)
@@ -265,6 +264,13 @@
 }
 
 #ifdef CONFIG_NFS_V4_SECURITY_LABEL
+static void nfs_clear_label_invalid(struct inode *inode)
+{
+	spin_lock(&inode->i_lock);
+	NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_LABEL;
+	spin_unlock(&inode->i_lock);
+}
+
 void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
 					struct nfs4_label *label)
 {
@@ -288,6 +294,7 @@
 					__func__,
 					(char *)label->label,
 					label->len, error);
+		nfs_clear_label_invalid(inode);
 	}
 }
 
@@ -1478,18 +1485,20 @@
 			inode->i_version = fattr->change_attr;
 		}
 	} else if (server->caps & NFS_CAP_CHANGE_ATTR)
-		invalid |= save_cache_validity;
+		nfsi->cache_validity |= save_cache_validity;
 
 	if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
 		memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
 	} else if (server->caps & NFS_CAP_MTIME)
-		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
 				| NFS_INO_REVAL_FORCED);
 
 	if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
 		memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
 	} else if (server->caps & NFS_CAP_CTIME)
-		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
 				| NFS_INO_REVAL_FORCED);
 
 	/* Check if our cached file size is stale */
@@ -1512,7 +1521,8 @@
 					(long long)new_isize);
 		}
 	} else
-		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
 				| NFS_INO_REVAL_PAGECACHE
 				| NFS_INO_REVAL_FORCED);
 
@@ -1520,7 +1530,8 @@
 	if (fattr->valid & NFS_ATTR_FATTR_ATIME)
 		memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
 	else if (server->caps & NFS_CAP_ATIME)
-		invalid |= save_cache_validity & (NFS_INO_INVALID_ATIME
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATIME
 				| NFS_INO_REVAL_FORCED);
 
 	if (fattr->valid & NFS_ATTR_FATTR_MODE) {
@@ -1531,7 +1542,8 @@
 			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
 		}
 	} else if (server->caps & NFS_CAP_MODE)
-		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
 				| NFS_INO_INVALID_ACCESS
 				| NFS_INO_INVALID_ACL
 				| NFS_INO_REVAL_FORCED);
@@ -1542,7 +1554,8 @@
 			inode->i_uid = fattr->uid;
 		}
 	} else if (server->caps & NFS_CAP_OWNER)
-		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
 				| NFS_INO_INVALID_ACCESS
 				| NFS_INO_INVALID_ACL
 				| NFS_INO_REVAL_FORCED);
@@ -1553,7 +1566,8 @@
 			inode->i_gid = fattr->gid;
 		}
 	} else if (server->caps & NFS_CAP_OWNER_GROUP)
-		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
 				| NFS_INO_INVALID_ACCESS
 				| NFS_INO_INVALID_ACL
 				| NFS_INO_REVAL_FORCED);
@@ -1566,7 +1580,8 @@
 			set_nlink(inode, fattr->nlink);
 		}
 	} else if (server->caps & NFS_CAP_NLINK)
-		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
 				| NFS_INO_REVAL_FORCED);
 
 	if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
@@ -1579,7 +1594,7 @@
 		inode->i_blocks = fattr->du.nfs2.blocks;
 
 	/* Update attrtimeo value if we're out of the unstable period */
-	if (invalid & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) {
+	if (invalid & NFS_INO_INVALID_ATTR) {
 		nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
 		nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
 		nfsi->attrtimeo_timestamp = now;
@@ -1592,7 +1607,6 @@
 		}
 	}
 	invalid &= ~NFS_INO_INVALID_ATTR;
-	invalid &= ~NFS_INO_INVALID_LABEL;
 	/* Don't invalidate the data if we were to blame */
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
 				|| S_ISLNK(inode->i_mode)))
diff -ruw linux-3.11.10/fs/nfs/internal.h linux-3.11.10-fbx/fs/nfs/internal.h
--- linux-3.11.10/fs/nfs/internal.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/nfs/internal.h	2014-07-01 16:22:13.166329756 +0200
@@ -263,6 +263,30 @@
 extern struct rpc_procinfo nfs4_procedures[];
 #endif
 
+#ifdef CONFIG_NFS_V4_SECURITY_LABEL
+extern struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags);
+static inline void nfs4_label_free(struct nfs4_label *label)
+{
+	if (label) {
+		kfree(label->label);
+		kfree(label);
+	}
+	return;
+}
+
+static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
+{
+	if (nfs_server_capable(&nfsi->vfs_inode, NFS_CAP_SECURITY_LABEL))
+		nfsi->cache_validity |= NFS_INO_INVALID_LABEL;
+}
+#else
+static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
+static inline void nfs4_label_free(void *label) {}
+static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
+{
+}
+#endif /* CONFIG_NFS_V4_SECURITY_LABEL */
+
 /* proc.c */
 void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
 extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
diff -ruw linux-3.11.10/fs/nfs/nfs4client.c linux-3.11.10-fbx/fs/nfs/nfs4client.c
--- linux-3.11.10/fs/nfs/nfs4client.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/nfs/nfs4client.c	2014-05-09 14:12:54.304546159 +0200
@@ -245,13 +245,11 @@
 	error = nfs4_discover_server_trunking(clp, &old);
 	if (error < 0)
 		goto error;
-	nfs_put_client(clp);
-	if (clp != old) {
-		clp->cl_preserve_clid = true;
-		clp = old;
-	}
 
-	return clp;
+	if (clp != old)
+		clp->cl_preserve_clid = true;
+	nfs_put_client(clp);
+	return old;
 
 error:
 	nfs_mark_client_ready(clp, error);
@@ -329,9 +327,10 @@
 			prev = pos;
 
 			status = nfs_wait_client_init_complete(pos);
-			spin_lock(&nn->nfs_client_lock);
 			if (status < 0)
-				continue;
+				goto out;
+			status = -NFS4ERR_STALE_CLIENTID;
+			spin_lock(&nn->nfs_client_lock);
 		}
 		if (pos->cl_cons_state != NFS_CS_READY)
 			continue;
@@ -469,7 +468,8 @@
 			}
 			spin_lock(&nn->nfs_client_lock);
 			if (status < 0)
-				continue;
+				break;
+			status = -NFS4ERR_STALE_CLIENTID;
 		}
 		if (pos->cl_cons_state != NFS_CS_READY)
 			continue;
diff -ruw linux-3.11.10/fs/nfs/nfs4_fs.h linux-3.11.10-fbx/fs/nfs/nfs4_fs.h
--- linux-3.11.10/fs/nfs/nfs4_fs.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/nfs/nfs4_fs.h	2014-07-01 16:22:13.166329756 +0200
@@ -9,6 +9,14 @@
 #ifndef __LINUX_FS_NFS_NFS4_FS_H
 #define __LINUX_FS_NFS_NFS4_FS_H
 
+#if defined(CONFIG_NFS_V4_2)
+#define NFS4_MAX_MINOR_VERSION 2
+#elif defined(CONFIG_NFS_V4_1)
+#define NFS4_MAX_MINOR_VERSION 1
+#else
+#define NFS4_MAX_MINOR_VERSION 0
+#endif
+
 #if IS_ENABLED(CONFIG_NFS_V4)
 
 #define NFS4_MAX_LOOP_ON_RECOVER (10)
diff -ruw linux-3.11.10/fs/nfs/nfs4proc.c linux-3.11.10-fbx/fs/nfs/nfs4proc.c
--- linux-3.11.10/fs/nfs/nfs4proc.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/nfs/nfs4proc.c	2014-07-01 16:22:13.166329756 +0200
@@ -976,6 +976,7 @@
 	dput(p->dentry);
 	nfs_sb_deactive(sb);
 	nfs_fattr_free_names(&p->f_attr);
+	kfree(p->f_attr.mdsthreshold);
 	kfree(p);
 }
 
@@ -1231,20 +1232,13 @@
 	int ret;
 
 	if (!data->rpc_done) {
+		if (data->rpc_status) {
 		ret = data->rpc_status;
 		goto err;
 	}
-
-	ret = -ESTALE;
-	if (!(data->f_attr.valid & NFS_ATTR_FATTR_TYPE) ||
-	    !(data->f_attr.valid & NFS_ATTR_FATTR_FILEID) ||
-	    !(data->f_attr.valid & NFS_ATTR_FATTR_CHANGE))
-		goto err;
-
-	ret = -ENOMEM;
-	state = nfs4_get_open_state(inode, data->owner);
-	if (state == NULL)
-		goto err;
+		/* cached opens have already been processed */
+		goto update;
+	}
 
 	ret = nfs_refresh_inode(inode, &data->f_attr);
 	if (ret)
@@ -1254,8 +1248,10 @@
 
 	if (data->o_res.delegation_type != 0)
 		nfs4_opendata_check_deleg(data, state);
+update:
 	update_open_stateid(state, &data->o_res.stateid, NULL,
 			    data->o_arg.fmode);
+	atomic_inc(&state->count);
 
 	return state;
 err:
@@ -2131,10 +2127,12 @@
 		}
 	}
 
-	if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) {
+	if (server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) {
+		if (!opendata->f_attr.mdsthreshold) {
 		opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
 		if (!opendata->f_attr.mdsthreshold)
 			goto err_free_label;
+		}
 		opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];
 	}
 	if (dentry->d_inode != NULL)
@@ -2160,11 +2158,10 @@
 		}
 	}
 
-	if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server))
+	if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) {
 		*ctx_th = opendata->f_attr.mdsthreshold;
-	else
-		kfree(opendata->f_attr.mdsthreshold);
 	opendata->f_attr.mdsthreshold = NULL;
+	}
 
 	nfs4_label_free(olabel);
 
@@ -2174,7 +2171,6 @@
 err_free_label:
 	nfs4_label_free(olabel);
 err_opendata_put:
-	kfree(opendata->f_attr.mdsthreshold);
 	nfs4_opendata_put(opendata);
 err_put_state_owner:
 	nfs4_put_state_owner(sp);
@@ -3830,8 +3826,9 @@
 {
 	nfs4_stateid current_stateid;
 
-	if (nfs4_set_rw_stateid(&current_stateid, ctx, l_ctx, fmode))
-		return false;
+	/* If the current stateid represents a lost lock, then exit */
+	if (nfs4_set_rw_stateid(&current_stateid, ctx, l_ctx, fmode) == -EIO)
+		return true;
 	return nfs4_stateid_match(stateid, &current_stateid);
 }
 
@@ -4414,7 +4411,7 @@
 	struct nfs4_label label = {0, 0, buflen, buf};
 
 	u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL };
-	struct nfs4_getattr_arg args = {
+	struct nfs4_getattr_arg arg = {
 		.fh		= NFS_FH(inode),
 		.bitmask	= bitmask,
 	};
@@ -4425,14 +4422,14 @@
 	};
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_GETATTR],
-		.rpc_argp	= &args,
+		.rpc_argp	= &arg,
 		.rpc_resp	= &res,
 	};
 	int ret;
 
 	nfs_fattr_init(&fattr);
 
-	ret = rpc_call_sync(server->client, &msg, 0);
+	ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 0);
 	if (ret)
 		return ret;
 	if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL))
@@ -4468,7 +4465,7 @@
 	struct iattr sattr = {0};
 	struct nfs_server *server = NFS_SERVER(inode);
 	const u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL };
-	struct nfs_setattrargs args = {
+	struct nfs_setattrargs arg = {
 		.fh             = NFS_FH(inode),
 		.iap            = &sattr,
 		.server		= server,
@@ -4482,14 +4479,14 @@
 	};
 	struct rpc_message msg = {
 		.rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_SETATTR],
-		.rpc_argp       = &args,
+		.rpc_argp       = &arg,
 		.rpc_resp       = &res,
 	};
 	int status;
 
-	nfs4_stateid_copy(&args.stateid, &zero_stateid);
+	nfs4_stateid_copy(&arg.stateid, &zero_stateid);
 
-	status = rpc_call_sync(server->client, &msg, 0);
+	status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
 	if (status)
 		dprintk("%s failed: %d\n", __func__, status);
 
@@ -4594,8 +4591,7 @@
 			dprintk("%s ERROR %d, Reset session\n", __func__,
 				task->tk_status);
 			nfs4_schedule_session_recovery(clp->cl_session, task->tk_status);
-			task->tk_status = 0;
-			return -EAGAIN;
+			goto wait_on_recovery;
 #endif /* CONFIG_NFS_V4_1 */
 		case -NFS4ERR_DELAY:
 			nfs_inc_server_stats(server, NFSIOS_DELAY);
@@ -4773,11 +4769,17 @@
 		return;
 
 	switch (task->tk_status) {
-	case -NFS4ERR_STALE_STATEID:
-	case -NFS4ERR_EXPIRED:
 	case 0:
 		renew_lease(data->res.server, data->timestamp);
 		break;
+	case -NFS4ERR_ADMIN_REVOKED:
+	case -NFS4ERR_DELEG_REVOKED:
+	case -NFS4ERR_BAD_STATEID:
+	case -NFS4ERR_OLD_STATEID:
+	case -NFS4ERR_STALE_STATEID:
+	case -NFS4ERR_EXPIRED:
+		task->tk_status = 0;
+		break;
 	default:
 		if (nfs4_async_handle_error(task, data->res.server, NULL) ==
 				-EAGAIN) {
@@ -4939,6 +4941,7 @@
 			status = 0;
 	}
 	request->fl_ops->fl_release_private(request);
+	request->fl_ops = NULL;
 out:
 	return status;
 }
@@ -6650,9 +6653,9 @@
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct pnfs_layout_hdr *lo;
 	struct nfs4_state *state = NULL;
-	unsigned long timeo, giveup;
+	unsigned long timeo, now, giveup;
 
-	dprintk("--> %s\n", __func__);
+	dprintk("--> %s tk_status => %d\n", __func__, -task->tk_status);
 
 	if (!nfs41_sequence_done(task, &lgp->res.seq_res))
 		goto out;
@@ -6660,12 +6663,38 @@
 	switch (task->tk_status) {
 	case 0:
 		goto out;
+	/*
+	 * NFS4ERR_LAYOUTTRYLATER is a conflict with another client
+	 * (or clients) writing to the same RAID stripe
+	 */
 	case -NFS4ERR_LAYOUTTRYLATER:
+	/*
+	 * NFS4ERR_RECALLCONFLICT is when conflict with self (must recall
+	 * existing layout before getting a new one).
+	 */
 	case -NFS4ERR_RECALLCONFLICT:
 		timeo = rpc_get_timeout(task->tk_client);
 		giveup = lgp->args.timestamp + timeo;
-		if (time_after(giveup, jiffies))
-			task->tk_status = -NFS4ERR_DELAY;
+		now = jiffies;
+		if (time_after(giveup, now)) {
+			unsigned long delay;
+
+			/* Delay for:
+			 * - Not less then NFS4_POLL_RETRY_MIN.
+			 * - One last time a jiffie before we give up
+			 * - exponential backoff (time_now minus start_attempt)
+			 */
+			delay = max_t(unsigned long, NFS4_POLL_RETRY_MIN,
+				    min((giveup - now - 1),
+					now - lgp->args.timestamp));
+
+			dprintk("%s: NFS4ERR_RECALLCONFLICT waiting %lu\n",
+				__func__, delay);
+			rpc_delay(task, delay);
+			task->tk_status = 0;
+			rpc_restart_call_prepare(task);
+			goto out; /* Do not call nfs4_async_handle_error() */
+		}
 		break;
 	case -NFS4ERR_EXPIRED:
 	case -NFS4ERR_BAD_STATEID:
@@ -7108,7 +7137,7 @@
 		switch (err) {
 		case 0:
 		case -NFS4ERR_WRONGSEC:
-		case -NFS4ERR_NOTSUPP:
+		case -ENOTSUPP:
 			goto out;
 		default:
 			err = nfs4_handle_exception(server, err, &exception);
@@ -7140,7 +7169,7 @@
 	 * Fall back on "guess and check" method if
 	 * the server doesn't support SECINFO_NO_NAME
 	 */
-	if (err == -NFS4ERR_WRONGSEC || err == -NFS4ERR_NOTSUPP) {
+	if (err == -NFS4ERR_WRONGSEC || err == -ENOTSUPP) {
 		err = nfs4_find_root_sec(server, fhandle, info);
 		goto out_freepage;
 	}
diff -ruw linux-3.11.10/fs/nfs/nfs4xdr.c linux-3.11.10-fbx/fs/nfs/nfs4xdr.c
--- linux-3.11.10/fs/nfs/nfs4xdr.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/nfs/nfs4xdr.c	2014-05-09 14:12:54.308546159 +0200
@@ -3050,7 +3050,8 @@
 	return -EIO;
 }
 
-static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
+static bool __decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected,
+		int *nfs_retval)
 {
 	__be32 *p;
 	uint32_t opnum;
@@ -3060,19 +3061,32 @@
 	if (unlikely(!p))
 		goto out_overflow;
 	opnum = be32_to_cpup(p++);
-	if (opnum != expected) {
+	if (unlikely(opnum != expected))
+		goto out_bad_operation;
+	nfserr = be32_to_cpup(p);
+	if (nfserr == NFS_OK)
+		*nfs_retval = 0;
+	else
+		*nfs_retval = nfs4_stat_to_errno(nfserr);
+	return true;
+out_bad_operation:
 		dprintk("nfs: Server returned operation"
 			" %d but we issued a request for %d\n",
 				opnum, expected);
-		return -EIO;
-	}
-	nfserr = be32_to_cpup(p);
-	if (nfserr != NFS_OK)
-		return nfs4_stat_to_errno(nfserr);
-	return 0;
+	*nfs_retval = -EREMOTEIO;
+	return false;
 out_overflow:
 	print_overflow_msg(__func__, xdr);
-	return -EIO;
+	*nfs_retval = -EIO;
+	return false;
+}
+
+static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
+{
+	int retval;
+
+	__decode_op_hdr(xdr, expected, &retval);
+	return retval;
 }
 
 /* Dummy routine */
@@ -4954,10 +4968,11 @@
 	uint32_t savewords, bmlen, i;
 	int status;
 
-	status = decode_op_hdr(xdr, OP_OPEN);
-	if (status != -EIO)
+	if (!__decode_op_hdr(xdr, OP_OPEN, &status))
+		return status;
 		nfs_increment_open_seqid(status, res->seqid);
-	if (!status)
+	if (status)
+		return status;
 		status = decode_stateid(xdr, &res->stateid);
 	if (unlikely(status))
 		return status;
diff -ruw linux-3.11.10/fs/nfs/super.c linux-3.11.10-fbx/fs/nfs/super.c
--- linux-3.11.10/fs/nfs/super.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/nfs/super.c	2014-08-22 15:47:22.136063146 +0200
@@ -2178,6 +2178,7 @@
 	data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ;
 	data->nfs_server.port = nfss->port;
 	data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen;
+	data->net = current->nsproxy->net_ns;
 	memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
 		data->nfs_server.addrlen);
 
diff -ruw linux-3.11.10/fs/nfs/write.c linux-3.11.10-fbx/fs/nfs/write.c
--- linux-3.11.10/fs/nfs/write.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/nfs/write.c	2014-05-09 14:12:54.308546159 +0200
@@ -893,19 +893,20 @@
  * extend the write to cover the entire page in order to avoid fragmentation
  * inefficiencies.
  *
- * If the file is opened for synchronous writes or if we have a write delegation
- * from the server then we can just skip the rest of the checks.
+ * If the file is opened for synchronous writes then we can just skip the rest
+ * of the checks.
  */
 static int nfs_can_extend_write(struct file *file, struct page *page, struct inode *inode)
 {
 	if (file->f_flags & O_DSYNC)
 		return 0;
+	if (!nfs_write_pageuptodate(page, inode))
+		return 0;
 	if (NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE))
 		return 1;
-	if (nfs_write_pageuptodate(page, inode) && (inode->i_flock == NULL ||
-			(inode->i_flock->fl_start == 0 &&
+	if (inode->i_flock == NULL || (inode->i_flock->fl_start == 0 &&
 			inode->i_flock->fl_end == OFFSET_MAX &&
-			inode->i_flock->fl_type != F_RDLCK)))
+			inode->i_flock->fl_type != F_RDLCK))
 		return 1;
 	return 0;
 }
diff -ruw linux-3.11.10/fs/notify/fanotify/fanotify_user.c linux-3.11.10-fbx/fs/notify/fanotify/fanotify_user.c
--- linux-3.11.10/fs/notify/fanotify/fanotify_user.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/notify/fanotify/fanotify_user.c	2014-05-09 14:12:54.308546159 +0200
@@ -888,9 +888,9 @@
 {
 	return sys_fanotify_mark(fanotify_fd, flags,
 #ifdef __BIG_ENDIAN
-				((__u64)mask1 << 32) | mask0,
-#else
 				((__u64)mask0 << 32) | mask1,
+#else
+				((__u64)mask1 << 32) | mask0,
 #endif
 				 dfd, pathname);
 }
diff -ruw linux-3.11.10/fs/open.c linux-3.11.10-fbx/fs/open.c
--- linux-3.11.10/fs/open.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/open.c	2014-07-01 16:22:13.174329786 +0200
@@ -628,23 +628,12 @@
 static inline int __get_file_write_access(struct inode *inode,
 					  struct vfsmount *mnt)
 {
-	int error;
-	error = get_write_access(inode);
+	int error = get_write_access(inode);
 	if (error)
 		return error;
-	/*
-	 * Do not take mount writer counts on
-	 * special files since no writes to
-	 * the mount itself will occur.
-	 */
-	if (!special_file(inode->i_mode)) {
-		/*
-		 * Balanced in __fput()
-		 */
 		error = __mnt_want_write(mnt);
 		if (error)
 			put_write_access(inode);
-	}
 	return error;
 }
 
@@ -677,11 +666,10 @@
 
 	path_get(&f->f_path);
 	inode = f->f_inode = f->f_path.dentry->d_inode;
-	if (f->f_mode & FMODE_WRITE) {
+	if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
 		error = __get_file_write_access(inode, f->f_path.mnt);
 		if (error)
 			goto cleanup_file;
-		if (!special_file(inode->i_mode))
 			file_take_write(f);
 	}
 
@@ -723,7 +711,6 @@
 	fops_put(f->f_op);
 	file_sb_list_del(f);
 	if (f->f_mode & FMODE_WRITE) {
-		put_write_access(inode);
 		if (!special_file(inode->i_mode)) {
 			/*
 			 * We don't consider this a real
@@ -731,6 +718,7 @@
 			 * because it all happenend right
 			 * here, so just reset the state.
 			 */
+			put_write_access(inode);
 			file_reset_write(f);
 			__mnt_drop_write(f->f_path.mnt);
 		}
diff -ruw linux-3.11.10/fs/pipe.c linux-3.11.10-fbx/fs/pipe.c
--- linux-3.11.10/fs/pipe.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/pipe.c	2014-01-17 19:14:18.766220809 +0100
@@ -726,11 +726,25 @@
 	return mask;
 }
 
+static void put_pipe_info(struct inode *inode, struct pipe_inode_info *pipe)
+{
+	int kill = 0;
+
+	spin_lock(&inode->i_lock);
+	if (!--pipe->files) {
+		inode->i_pipe = NULL;
+		kill = 1;
+	}
+	spin_unlock(&inode->i_lock);
+
+	if (kill)
+		free_pipe_info(pipe);
+}
+
 static int
 pipe_release(struct inode *inode, struct file *file)
 {
-	struct pipe_inode_info *pipe = inode->i_pipe;
-	int kill = 0;
+	struct pipe_inode_info *pipe = file->private_data;
 
 	__pipe_lock(pipe);
 	if (file->f_mode & FMODE_READ)
@@ -743,17 +757,9 @@
 		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
 		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
 	}
-	spin_lock(&inode->i_lock);
-	if (!--pipe->files) {
-		inode->i_pipe = NULL;
-		kill = 1;
-	}
-	spin_unlock(&inode->i_lock);
 	__pipe_unlock(pipe);
 
-	if (kill)
-		free_pipe_info(pipe);
-
+	put_pipe_info(inode, pipe);
 	return 0;
 }
 
@@ -1014,7 +1020,6 @@
 {
 	struct pipe_inode_info *pipe;
 	bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC;
-	int kill = 0;
 	int ret;
 
 	filp->f_version = 0;
@@ -1130,15 +1135,9 @@
 	goto err;
 
 err:
-	spin_lock(&inode->i_lock);
-	if (!--pipe->files) {
-		inode->i_pipe = NULL;
-		kill = 1;
-	}
-	spin_unlock(&inode->i_lock);
 	__pipe_unlock(pipe);
-	if (kill)
-		free_pipe_info(pipe);
+
+	put_pipe_info(inode, pipe);
 	return ret;
 }
 
diff -ruw linux-3.11.10/fs/posix_acl.c linux-3.11.10-fbx/fs/posix_acl.c
--- linux-3.11.10/fs/posix_acl.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/posix_acl.c	2014-07-01 16:22:13.174329786 +0200
@@ -158,6 +158,12 @@
 	umode_t mode = 0;
 	int not_equiv = 0;
 
+	/*
+	 * A null ACL can always be presented as mode bits.
+	 */
+	if (!acl)
+		return 0;
+
 	FOREACH_ACL_ENTRY(pa, acl, pe) {
 		switch (pa->e_tag) {
 			case ACL_USER_OBJ:
diff -ruw linux-3.11.10/fs/proc/array.c linux-3.11.10-fbx/fs/proc/array.c
--- linux-3.11.10/fs/proc/array.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/proc/array.c	2013-12-04 14:33:23.647479048 +0100
@@ -160,6 +160,21 @@
 	return *p;
 }
 
+static const char *const task_exec_mode_array[] = {
+	"0 (Denied)",
+	"1 (Once)",
+	"2 (Unlimited)",
+};
+
+static inline const char *get_task_exec_mode(struct task_struct *tsk)
+{
+	unsigned int exec_mode = tsk->exec_mode;
+
+	if (exec_mode > EXEC_MODE_UNLIMITED)
+		return "? (Invalid)";
+	return task_exec_mode_array[exec_mode];
+}
+
 static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
 				struct pid *pid, struct task_struct *p)
 {
@@ -353,6 +368,12 @@
 			p->nivcsw);
 }
 
+static inline void task_exec_mode(struct seq_file *m,
+				  struct task_struct *p)
+{
+	seq_printf(m, "Exec mode: %s\n", get_task_exec_mode(p));
+}
+
 static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
 {
 	seq_puts(m, "Cpus_allowed:\t");
@@ -381,6 +402,7 @@
 	task_cpus_allowed(m, task);
 	cpuset_task_status_allowed(m, task);
 	task_context_switch_counts(m, task);
+	task_exec_mode(m, task);
 	return 0;
 }
 
diff -ruw linux-3.11.10/fs/proc/base.c linux-3.11.10-fbx/fs/proc/base.c
--- linux-3.11.10/fs/proc/base.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/proc/base.c	2014-07-01 16:22:13.174329786 +0200
@@ -1813,6 +1813,7 @@
 	if (rc)
 		goto out_mmput;
 
+	rc = -ENOENT;
 	down_read(&mm->mmap_sem);
 	vma = find_exact_vma(mm, vm_start, vm_end);
 	if (vma && vma->vm_file) {
diff -ruw linux-3.11.10/fs/proc/proc_devtree.c linux-3.11.10-fbx/fs/proc/proc_devtree.c
--- linux-3.11.10/fs/proc/proc_devtree.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/proc/proc_devtree.c	2014-07-01 16:22:13.174329786 +0200
@@ -235,6 +235,7 @@
 		return;
 	root = of_find_node_by_path("/");
 	if (root == NULL) {
+		remove_proc_entry("device-tree", NULL);
 		pr_debug("/proc/device-tree: can't find root\n");
 		return;
 	}
diff -ruw linux-3.11.10/fs/proc/stat.c linux-3.11.10-fbx/fs/proc/stat.c
--- linux-3.11.10/fs/proc/stat.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/proc/stat.c	2014-08-22 15:47:22.136063146 +0200
@@ -184,29 +184,11 @@
 
 static int stat_open(struct inode *inode, struct file *file)
 {
-	size_t size = 1024 + 128 * num_possible_cpus();
-	char *buf;
-	struct seq_file *m;
-	int res;
+	size_t size = 1024 + 128 * num_online_cpus();
 
 	/* minimum size to display an interrupt count : 2 bytes */
 	size += 2 * nr_irqs;
-
-	/* don't ask for more than the kmalloc() max size */
-	if (size > KMALLOC_MAX_SIZE)
-		size = KMALLOC_MAX_SIZE;
-	buf = kmalloc(size, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-
-	res = single_open(file, show_stat, NULL);
-	if (!res) {
-		m = file->private_data;
-		m->buf = buf;
-		m->size = ksize(buf);
-	} else
-		kfree(buf);
-	return res;
+	return single_open_size(file, show_stat, NULL, size);
 }
 
 static const struct file_operations proc_stat_operations = {
diff -ruw linux-3.11.10/fs/pstore/ram.c linux-3.11.10-fbx/fs/pstore/ram.c
--- linux-3.11.10/fs/pstore/ram.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/pstore/ram.c	2013-12-04 14:33:23.655479048 +0100
@@ -400,11 +400,11 @@
 		goto fail_out;
 	}
 
-	if (!is_power_of_2(pdata->record_size))
+	if (pdata->record_size && !is_power_of_2(pdata->record_size))
 		pdata->record_size = rounddown_pow_of_two(pdata->record_size);
-	if (!is_power_of_2(pdata->console_size))
+	if (pdata->console_size && !is_power_of_2(pdata->console_size))
 		pdata->console_size = rounddown_pow_of_two(pdata->console_size);
-	if (!is_power_of_2(pdata->ftrace_size))
+	if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size))
 		pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
 
 	cxt->dump_read_cnt = 0;
diff -ruw linux-3.11.10/fs/ramfs/file-mmu.c linux-3.11.10-fbx/fs/ramfs/file-mmu.c
--- linux-3.11.10/fs/ramfs/file-mmu.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ramfs/file-mmu.c	2013-12-04 14:33:23.659479048 +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.11.10/fs/ramfs/inode.c linux-3.11.10-fbx/fs/ramfs/inode.c
--- linux-3.11.10/fs/ramfs/inode.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ramfs/inode.c	2013-12-04 14:33:23.715479049 +0100
@@ -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, umode_t 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,
@@ -229,6 +261,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);
 	sb->s_root = d_make_root(inode);
@@ -268,6 +303,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);
@@ -282,9 +327,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.11.10/fs/ramfs/internal.h linux-3.11.10-fbx/fs/ramfs/internal.h
--- linux-3.11.10/fs/ramfs/internal.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ramfs/internal.h	2013-12-04 14:33:23.715479049 +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.11.10/fs/ramfs/Makefile linux-3.11.10-fbx/fs/ramfs/Makefile
--- linux-3.11.10/fs/ramfs/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ramfs/Makefile	2010-02-25 15:41:09.970055615 +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.11.10/fs/read_write.c linux-3.11.10-fbx/fs/read_write.c
--- linux-3.11.10/fs/read_write.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/read_write.c	2014-05-09 14:12:54.308546159 +0200
@@ -980,9 +980,9 @@
 	return ret;
 }
 
-COMPAT_SYSCALL_DEFINE3(readv, unsigned long, fd,
+COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
 		const struct compat_iovec __user *,vec,
-		unsigned long, vlen)
+		compat_ulong_t, vlen)
 {
 	struct fd f = fdget(fd);
 	ssize_t ret;
@@ -1017,9 +1017,9 @@
 	return ret;
 }
 
-COMPAT_SYSCALL_DEFINE5(preadv, unsigned long, fd,
+COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd,
 		const struct compat_iovec __user *,vec,
-		unsigned long, vlen, u32, pos_low, u32, pos_high)
+		compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
 {
 	loff_t pos = ((loff_t)pos_high << 32) | pos_low;
 	return compat_sys_preadv64(fd, vec, vlen, pos);
@@ -1047,9 +1047,9 @@
 	return ret;
 }
 
-COMPAT_SYSCALL_DEFINE3(writev, unsigned long, fd,
+COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
 		const struct compat_iovec __user *, vec,
-		unsigned long, vlen)
+		compat_ulong_t, vlen)
 {
 	struct fd f = fdget(fd);
 	ssize_t ret;
@@ -1084,9 +1084,9 @@
 	return ret;
 }
 
-COMPAT_SYSCALL_DEFINE5(pwritev, unsigned long, fd,
+COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
 		const struct compat_iovec __user *,vec,
-		unsigned long, vlen, u32, pos_low, u32, pos_high)
+		compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
 {
 	loff_t pos = ((loff_t)pos_high << 32) | pos_low;
 	return compat_sys_pwritev64(fd, vec, vlen, pos);
diff -ruw linux-3.11.10/fs/splice.c linux-3.11.10-fbx/fs/splice.c
--- linux-3.11.10/fs/splice.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/splice.c	2014-05-09 14:12:54.308546159 +0200
@@ -555,6 +555,24 @@
 	.get = generic_pipe_buf_get,
 };
 
+static int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe,
+				    struct pipe_buffer *buf)
+{
+	return 1;
+}
+
+/* Pipe buffer operations for a socket and similar. */
+const struct pipe_buf_operations nosteal_pipe_buf_ops = {
+	.can_merge = 0,
+	.map = generic_pipe_buf_map,
+	.unmap = generic_pipe_buf_unmap,
+	.confirm = generic_pipe_buf_confirm,
+	.release = generic_pipe_buf_release,
+	.steal = generic_pipe_buf_nosteal,
+	.get = generic_pipe_buf_get,
+};
+EXPORT_SYMBOL(nosteal_pipe_buf_ops);
+
 static ssize_t kernel_readv(struct file *file, const struct iovec *vec,
 			    unsigned long vlen, loff_t offset)
 {
diff -ruw linux-3.11.10/fs/squashfs/Kconfig linux-3.11.10-fbx/fs/squashfs/Kconfig
--- linux-3.11.10/fs/squashfs/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/squashfs/Kconfig	2014-05-09 14:12:54.308546159 +0200
@@ -25,6 +25,78 @@
 
 	  If unsure, say N.
 
+choice
+	prompt "File decompression options"
+	depends on SQUASHFS
+	help
+	  Squashfs now supports two options for decompressing file
+	  data.  Traditionally Squashfs has decompressed into an
+	  intermediate buffer and then memcopied it into the page cache.
+	  Squashfs now supports the ability to decompress directly into
+	  the page cache.
+
+	  If unsure, select "Decompress file data into an intermediate buffer"
+
+config SQUASHFS_FILE_CACHE
+	bool "Decompress file data into an intermediate buffer"
+	help
+	  Decompress file data into an intermediate buffer and then
+	  memcopy it into the page cache.
+
+config SQUASHFS_FILE_DIRECT
+	bool "Decompress files directly into the page cache"
+	help
+	  Directly decompress file data into the page cache.
+	  Doing so can significantly improve performance because
+	  it eliminates a memcpy and it also removes the lock contention
+	  on the single buffer.
+
+endchoice
+
+choice
+	prompt "Decompressor parallelisation options"
+	depends on SQUASHFS
+	help
+	  Squashfs now supports three parallelisation options for
+	  decompression.  Each one exhibits various trade-offs between
+	  decompression performance and CPU and memory usage.
+
+	  If in doubt, select "Single threaded compression"
+
+config SQUASHFS_DECOMP_SINGLE
+	bool "Single threaded compression"
+	help
+	  Traditionally Squashfs has used single-threaded decompression.
+	  Only one block (data or metadata) can be decompressed at any
+	  one time.  This limits CPU and memory usage to a minimum.
+
+config SQUASHFS_DECOMP_MULTI
+	bool "Use multiple decompressors for parallel I/O"
+	help
+	  By default Squashfs uses a single decompressor but it gives
+	  poor performance on parallel I/O workloads when using multiple CPU
+	  machines due to waiting on decompressor availability.
+
+	  If you have a parallel I/O workload and your system has enough memory,
+	  using this option may improve overall I/O performance.
+
+	  This decompressor implementation uses up to two parallel
+	  decompressors per core.  It dynamically allocates decompressors
+	  on a demand basis.
+
+config SQUASHFS_DECOMP_MULTI_PERCPU
+	bool "Use percpu multiple decompressors for parallel I/O"
+	help
+	  By default Squashfs uses a single decompressor but it gives
+	  poor performance on parallel I/O workloads when using multiple CPU
+	  machines due to waiting on decompressor availability.
+
+	  This decompressor implementation uses a maximum of one
+	  decompressor per core.  It uses percpu variables to ensure
+	  decompression is load-balanced across the cores.
+
+endchoice
+
 config SQUASHFS_XATTR
 	bool "Squashfs XATTR support"
 	depends on SQUASHFS
diff -ruw linux-3.11.10/fs/squashfs/Makefile linux-3.11.10-fbx/fs/squashfs/Makefile
--- linux-3.11.10/fs/squashfs/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/squashfs/Makefile	2014-05-09 14:12:54.308546159 +0200
@@ -5,6 +5,11 @@
 obj-$(CONFIG_SQUASHFS) += squashfs.o
 squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
 squashfs-y += namei.o super.o symlink.o decompressor.o
+squashfs-$(CONFIG_SQUASHFS_FILE_CACHE) += file_cache.o
+squashfs-$(CONFIG_SQUASHFS_FILE_DIRECT) += file_direct.o page_actor.o
+squashfs-$(CONFIG_SQUASHFS_DECOMP_SINGLE) += decompressor_single.o
+squashfs-$(CONFIG_SQUASHFS_DECOMP_MULTI) += decompressor_multi.o
+squashfs-$(CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU) += decompressor_multi_percpu.o
 squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o
 squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o
 squashfs-$(CONFIG_SQUASHFS_XZ) += xz_wrapper.o
diff -ruw linux-3.11.10/fs/ubifs/file.c linux-3.11.10-fbx/fs/ubifs/file.c
--- linux-3.11.10/fs/ubifs/file.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ubifs/file.c	2014-08-22 15:47:22.136063146 +0200
@@ -1525,8 +1525,7 @@
 	}
 
 	wait_for_stable_page(page);
-	unlock_page(page);
-	return 0;
+	return VM_FAULT_LOCKED;
 
 out_unlock:
 	unlock_page(page);
diff -ruw linux-3.11.10/fs/ubifs/shrinker.c linux-3.11.10-fbx/fs/ubifs/shrinker.c
--- linux-3.11.10/fs/ubifs/shrinker.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/ubifs/shrinker.c	2014-08-22 15:47:22.136063146 +0200
@@ -128,7 +128,6 @@
 			freed = ubifs_destroy_tnc_subtree(znode);
 			atomic_long_sub(freed, &ubifs_clean_zn_cnt);
 			atomic_long_sub(freed, &c->clean_zn_cnt);
-			ubifs_assert(atomic_long_read(&c->clean_zn_cnt) >= 0);
 			total_freed += freed;
 			znode = zprev;
 		}
diff -ruw linux-3.11.10/fs/xattr_acl.c linux-3.11.10-fbx/fs/xattr_acl.c
--- linux-3.11.10/fs/xattr_acl.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/xattr_acl.c	2014-07-01 16:22:13.174329786 +0200
@@ -146,7 +146,7 @@
 		   void *buffer, size_t size)
 {
 	posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer;
-	posix_acl_xattr_entry *ext_entry = ext_acl->a_entries;
+	posix_acl_xattr_entry *ext_entry;
 	int real_size, n;
 
 	real_size = posix_acl_xattr_size(acl->a_count);
@@ -155,6 +155,7 @@
 	if (real_size > size)
 		return -ERANGE;
 	
+	ext_entry = ext_acl->a_entries;
 	ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
 
 	for (n=0; n < acl->a_count; n++, ext_entry++) {
diff -ruw linux-3.11.10/fs/xfs/xfs_buf.c linux-3.11.10-fbx/fs/xfs/xfs_buf.c
--- linux-3.11.10/fs/xfs/xfs_buf.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/xfs/xfs_buf.c	2013-12-04 14:33:23.991479053 +0100
@@ -431,6 +431,37 @@
 	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 (!xfs_buf_is_vmapped(bp))
+		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.
  */
@@ -459,6 +490,7 @@
 		if (!bp->b_addr)
 			return -ENOMEM;
 		bp->b_addr += bp->b_offset;
+		cache_flush_buf(bp);
 	}
 
 	return 0;
@@ -1296,6 +1328,7 @@
 		if (nbytes > size)
 			nbytes = size;
 
+		cache_flush_buf_page(bp, page_index);
 		rbytes = bio_add_page(bio, bp->b_pages[page_index], nbytes,
 				      offset);
 		if (rbytes < nbytes)
diff -ruw linux-3.11.10/fs/xfs/xfs_da_btree.c linux-3.11.10-fbx/fs/xfs/xfs_da_btree.c
--- linux-3.11.10/fs/xfs/xfs_da_btree.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/xfs/xfs_da_btree.c	2014-07-01 16:22:13.174329786 +0200
@@ -1334,7 +1334,7 @@
 		node = blk->bp->b_addr;
 		xfs_da3_node_hdr_from_disk(&nodehdr, node);
 		btree = xfs_da3_node_tree_p(node);
-		if (be32_to_cpu(btree->hashval) == lasthash)
+		if (be32_to_cpu(btree[blk->index].hashval) == lasthash)
 			break;
 		blk->hashval = lasthash;
 		btree[blk->index].hashval = cpu_to_be32(lasthash);
diff -ruw linux-3.11.10/fs/xfs/xfs_dir2_block.c linux-3.11.10-fbx/fs/xfs/xfs_dir2_block.c
--- linux-3.11.10/fs/xfs/xfs_dir2_block.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/xfs/xfs_dir2_block.c	2013-12-04 14:33:23.991479053 +0100
@@ -37,6 +37,7 @@
 #include "xfs_error.h"
 #include "xfs_trace.h"
 #include "xfs_cksum.h"
+#include "xfs_icache.h"
 
 /*
  * Local function prototypes.
@@ -614,6 +615,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.
@@ -638,6 +642,14 @@
 		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;
+
 		ctx->pos = cook & 0x7fffffff;
 		/*
 		 * If it didn't fit, set the final offset to here & return.
diff -ruw linux-3.11.10/fs/xfs/xfs_dir2_leaf.c linux-3.11.10-fbx/fs/xfs/xfs_dir2_leaf.c
--- linux-3.11.10/fs/xfs/xfs_dir2_leaf.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/xfs/xfs_dir2_leaf.c	2013-12-04 14:33:23.991479053 +0100
@@ -36,6 +36,7 @@
 #include "xfs_trace.h"
 #include "xfs_buf_item.h"
 #include "xfs_cksum.h"
+#include "xfs_icache.h"
 
 /*
  * Local function declarations.
@@ -1358,6 +1359,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.
@@ -1445,6 +1449,14 @@
 		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;
+
 		ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
 		if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
 			    be64_to_cpu(dep->inumber), DT_UNKNOWN))
diff -ruw linux-3.11.10/fs/xfs/xfs_dir2_sf.c linux-3.11.10-fbx/fs/xfs/xfs_dir2_sf.c
--- linux-3.11.10/fs/xfs/xfs_dir2_sf.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/xfs/xfs_dir2_sf.c	2013-12-04 14:33:23.995479053 +0100
@@ -33,6 +33,7 @@
 #include "xfs_dir2_format.h"
 #include "xfs_dir2_priv.h"
 #include "xfs_trace.h"
+#include "xfs_icache.h"
 
 /*
  * Prototypes for internal functions.
@@ -838,6 +839,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));
 
@@ -847,6 +851,13 @@
 		}
 
 		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;
+
 		ctx->pos = off & 0x7fffffff;
 		if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen,
 			    ino, DT_UNKNOWN))
diff -ruw linux-3.11.10/fs/xfs/xfs_fsops.c linux-3.11.10-fbx/fs/xfs/xfs_fsops.c
--- linux-3.11.10/fs/xfs/xfs_fsops.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/xfs/xfs_fsops.c	2014-01-17 19:14:18.766220809 +0100
@@ -216,6 +216,8 @@
 	 */
 	nfree = 0;
 	for (agno = nagcount - 1; agno >= oagcount; agno--, new -= agsize) {
+		__be32	*agfl_bno;
+
 		/*
 		 * AG freespace header block
 		 */
@@ -275,8 +277,10 @@
 			agfl->agfl_seqno = cpu_to_be32(agno);
 			uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_uuid);
 		}
+
+		agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, bp);
 		for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
-			agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
+			agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
 
 		error = xfs_bwrite(bp);
 		xfs_buf_relse(bp);
diff -ruw linux-3.11.10/fs/xfs/xfs_ioctl.c linux-3.11.10-fbx/fs/xfs/xfs_ioctl.c
--- linux-3.11.10/fs/xfs/xfs_ioctl.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/xfs/xfs_ioctl.c	2014-01-17 19:14:18.766220809 +0100
@@ -409,7 +409,8 @@
 		return -XFS_ERROR(EPERM);
 	if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
 		return -XFS_ERROR(EFAULT);
-	if (al_hreq.buflen > XATTR_LIST_MAX)
+	if (al_hreq.buflen < sizeof(struct attrlist) ||
+	    al_hreq.buflen > XATTR_LIST_MAX)
 		return -XFS_ERROR(EINVAL);
 
 	/*
@@ -1612,6 +1613,12 @@
 	case XFS_IOC_FREE_EOFBLOCKS: {
 		struct xfs_eofblocks eofb;
 
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		if (mp->m_flags & XFS_MOUNT_RDONLY)
+			return -XFS_ERROR(EROFS);
+
 		if (copy_from_user(&eofb, arg, sizeof(eofb)))
 			return -XFS_ERROR(EFAULT);
 
diff -ruw linux-3.11.10/fs/xfs/xfs_mount.c linux-3.11.10-fbx/fs/xfs/xfs_mount.c
--- linux-3.11.10/fs/xfs/xfs_mount.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/fs/xfs/xfs_mount.c	2014-01-17 19:14:18.770220809 +0100
@@ -749,6 +749,11 @@
  * single bit error could clear the feature bit and unused parts of the
  * superblock are supposed to be zero. Hence a non-null crc field indicates that
  * we've potentially lost a feature bit and we should check it anyway.
+ *
+ * However, past bugs (i.e. in growfs) left non-zeroed regions beyond the
+ * last field in V4 secondary superblocks.  So for secondary superblocks,
+ * we are more forgiving, and ignore CRC failures if the primary doesn't
+ * indicate that the fs version is V5.
  */
 static void
 xfs_sb_read_verify(
@@ -769,10 +774,14 @@
 
 		if (!xfs_verify_cksum(bp->b_addr, be16_to_cpu(dsb->sb_sectsize),
 				      offsetof(struct xfs_sb, sb_crc))) {
+			/* Only fail bad secondaries on a known V5 filesystem */
+			if (bp->b_bn != XFS_SB_DADDR &&
+			    xfs_sb_version_hascrc(&mp->m_sb)) {
 			error = EFSCORRUPTED;
 			goto out_error;
 		}
 	}
+	}
 	error = xfs_sb_verify(bp, true);
 
 out_error:
diff -ruw linux-3.11.10/include/acpi/acpi_bus.h linux-3.11.10-fbx/include/acpi/acpi_bus.h
--- linux-3.11.10/include/acpi/acpi_bus.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/acpi/acpi_bus.h	2014-01-17 19:14:18.770220809 +0100
@@ -90,6 +90,7 @@
 struct acpi_hotplug_profile {
 	struct kobject kobj;
 	bool enabled:1;
+	bool ignore:1;
 	enum acpi_hotplug_mode mode;
 };
 
diff -ruw linux-3.11.10/include/asm-generic/pgtable.h linux-3.11.10-fbx/include/asm-generic/pgtable.h
--- linux-3.11.10/include/asm-generic/pgtable.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/asm-generic/pgtable.h	2014-07-01 16:22:13.174329786 +0200
@@ -221,7 +221,7 @@
 #endif
 
 #ifndef pte_accessible
-# define pte_accessible(pte)		((void)(pte),1)
+# define pte_accessible(mm, pte)	((void)(pte), 1)
 #endif
 
 #ifndef flush_tlb_fix_spurious_fault
@@ -673,32 +673,47 @@
 #ifndef pte_mknonnuma
 static inline pte_t pte_mknonnuma(pte_t pte)
 {
-	pte = pte_clear_flags(pte, _PAGE_NUMA);
-	return pte_set_flags(pte, _PAGE_PRESENT|_PAGE_ACCESSED);
+	pteval_t val = pte_val(pte);
+
+	val &= ~_PAGE_NUMA;
+	val |= (_PAGE_PRESENT|_PAGE_ACCESSED);
+	return __pte(val);
 }
 #endif
 
 #ifndef pmd_mknonnuma
 static inline pmd_t pmd_mknonnuma(pmd_t pmd)
 {
-	pmd = pmd_clear_flags(pmd, _PAGE_NUMA);
-	return pmd_set_flags(pmd, _PAGE_PRESENT|_PAGE_ACCESSED);
+	pmdval_t val = pmd_val(pmd);
+
+	val &= ~_PAGE_NUMA;
+	val |= (_PAGE_PRESENT|_PAGE_ACCESSED);
+
+	return __pmd(val);
 }
 #endif
 
 #ifndef pte_mknuma
 static inline pte_t pte_mknuma(pte_t pte)
 {
-	pte = pte_set_flags(pte, _PAGE_NUMA);
-	return pte_clear_flags(pte, _PAGE_PRESENT);
+	pteval_t val = pte_val(pte);
+
+	val &= ~_PAGE_PRESENT;
+	val |= _PAGE_NUMA;
+
+	return __pte(val);
 }
 #endif
 
 #ifndef pmd_mknuma
 static inline pmd_t pmd_mknuma(pmd_t pmd)
 {
-	pmd = pmd_set_flags(pmd, _PAGE_NUMA);
-	return pmd_clear_flags(pmd, _PAGE_PRESENT);
+	pmdval_t val = pmd_val(pmd);
+
+	val &= ~_PAGE_PRESENT;
+	val |= _PAGE_NUMA;
+
+	return __pmd(val);
 }
 #endif
 #else
diff -ruw linux-3.11.10/include/crypto/scatterwalk.h linux-3.11.10-fbx/include/crypto/scatterwalk.h
--- linux-3.11.10/include/crypto/scatterwalk.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/crypto/scatterwalk.h	2014-01-17 19:14:18.770220809 +0100
@@ -36,6 +36,7 @@
 {
 	sg_set_page(&sg1[num - 1], (void *)sg2, 0, 0);
 	sg1[num - 1].page_link &= ~0x02;
+	sg1[num - 1].page_link |= 0x01;
 }
 
 static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
@@ -43,7 +44,7 @@
 	if (sg_is_last(sg))
 		return NULL;
 
-	return (++sg)->length ? sg : (void *)sg_page(sg);
+	return (++sg)->length ? sg : sg_chain_ptr(sg);
 }
 
 static inline void scatterwalk_crypto_chain(struct scatterlist *head,
diff -ruw linux-3.11.10/include/linux/audit.h linux-3.11.10-fbx/include/linux/audit.h
--- linux-3.11.10/include/linux/audit.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/audit.h	2014-05-09 14:12:54.312546159 +0200
@@ -135,7 +135,7 @@
 {
 	if (unlikely(current->audit_context)) {
 		int success = is_syscall_success(pt_regs);
-		int return_code = regs_return_value(pt_regs);
+		long return_code = regs_return_value(pt_regs);
 
 		__audit_syscall_exit(success, return_code);
 	}
@@ -178,8 +178,6 @@
 
 static inline void audit_seccomp(unsigned long syscall, long signr, int code)
 {
-	/* Force a record to be reported if a signal was delivered. */
-	if (signr || unlikely(!audit_dummy_context()))
 		__audit_seccomp(syscall, signr, code);
 }
 
diff -ruw linux-3.11.10/include/linux/auxvec.h linux-3.11.10-fbx/include/linux/auxvec.h
--- linux-3.11.10/include/linux/auxvec.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/auxvec.h	2014-01-17 19:14:18.770220809 +0100
@@ -3,6 +3,6 @@
 
 #include <uapi/linux/auxvec.h>
 
-#define AT_VECTOR_SIZE_BASE 19 /* NEW_AUX_ENT entries in auxiliary table */
+#define AT_VECTOR_SIZE_BASE 20 /* NEW_AUX_ENT entries in auxiliary table */
   /* number of "#define AT_.*" above, minus {AT_NULL, AT_IGNORE, AT_NOTELF} */
 #endif /* _LINUX_AUXVEC_H */
diff -ruw linux-3.11.10/include/linux/backing-dev.h linux-3.11.10-fbx/include/linux/backing-dev.h
--- linux-3.11.10/include/linux/backing-dev.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/backing-dev.h	2014-07-01 16:22:13.174329786 +0200
@@ -95,7 +95,7 @@
 	unsigned int max_ratio, max_prop_frac;
 
 	struct bdi_writeback wb;  /* default writeback info for this bdi */
-	spinlock_t wb_lock;	  /* protects work_list */
+	spinlock_t wb_lock;	  /* protects work_list & wb.dwork scheduling */
 
 	struct list_head work_list;
 
diff -ruw linux-3.11.10/include/linux/bitops.h linux-3.11.10-fbx/include/linux/bitops.h
--- linux-3.11.10/include/linux/bitops.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/bitops.h	2014-07-01 16:22:13.174329786 +0200
@@ -185,6 +185,21 @@
 
 #ifdef __KERNEL__
 
+#ifndef set_mask_bits
+#define set_mask_bits(ptr, _mask, _bits)	\
+({								\
+	const typeof(*ptr) mask = (_mask), bits = (_bits);	\
+	typeof(*ptr) old, new;					\
+								\
+	do {							\
+		old = ACCESS_ONCE(*ptr);			\
+		new = (old & ~mask) | bits;			\
+	} while (cmpxchg(ptr, old, new) != old);		\
+								\
+	new;							\
+})
+#endif
+
 #ifndef find_last_bit
 /**
  * find_last_bit - find the last set bit in a memory region
diff -ruw linux-3.11.10/include/linux/capability.h linux-3.11.10-fbx/include/linux/capability.h
--- linux-3.11.10/include/linux/capability.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/capability.h	2014-07-01 16:22:13.174329786 +0200
@@ -211,7 +211,7 @@
 extern bool capable(int cap);
 extern bool ns_capable(struct user_namespace *ns, int cap);
 extern bool nsown_capable(int cap);
-extern bool inode_capable(const struct inode *inode, int cap);
+extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
 extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
 
 /* audit system wants to get cap info from files as well */
diff -ruw linux-3.11.10/include/linux/compat.h linux-3.11.10-fbx/include/linux/compat.h
--- linux-3.11.10/include/linux/compat.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/compat.h	2014-05-09 14:12:54.312546159 +0200
@@ -326,16 +326,16 @@
 			      u32 arg2, u32 arg3, u32 arg4, u32 arg5);
 asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32);
 
-asmlinkage ssize_t compat_sys_readv(unsigned long fd,
-		const struct compat_iovec __user *vec, unsigned long vlen);
-asmlinkage ssize_t compat_sys_writev(unsigned long fd,
-		const struct compat_iovec __user *vec, unsigned long vlen);
-asmlinkage ssize_t compat_sys_preadv(unsigned long fd,
+asmlinkage ssize_t compat_sys_readv(compat_ulong_t fd,
+		const struct compat_iovec __user *vec, compat_ulong_t vlen);
+asmlinkage ssize_t compat_sys_writev(compat_ulong_t fd,
+		const struct compat_iovec __user *vec, compat_ulong_t vlen);
+asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd,
 		const struct compat_iovec __user *vec,
-		unsigned long vlen, u32 pos_low, u32 pos_high);
-asmlinkage ssize_t compat_sys_pwritev(unsigned long fd,
+		compat_ulong_t vlen, u32 pos_low, u32 pos_high);
+asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd,
 		const struct compat_iovec __user *vec,
-		unsigned long vlen, u32 pos_low, u32 pos_high);
+		compat_ulong_t vlen, u32 pos_low, u32 pos_high);
 asmlinkage long comat_sys_lseek(unsigned int, compat_off_t, unsigned int);
 
 asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv,
@@ -421,7 +421,7 @@
 asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
 				  compat_long_t addr, compat_long_t data);
 
-asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, size_t);
+asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, compat_size_t);
 /*
  * epoll (fs/eventpoll.c) compat bits follow ...
  */
diff -ruw linux-3.11.10/include/linux/compiler-gcc4.h linux-3.11.10-fbx/include/linux/compiler-gcc4.h
--- linux-3.11.10/include/linux/compiler-gcc4.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/compiler-gcc4.h	2014-05-09 14:12:54.312546159 +0200
@@ -75,11 +75,7 @@
  *
  * (asm goto is automatically volatile - the naming reflects this.)
  */
-#if GCC_VERSION <= 40801
 # define asm_volatile_goto(x...)	do { asm goto(x); asm (""); } while (0)
-#else
-# define asm_volatile_goto(x...)	do { asm goto(x); } while (0)
-#endif
 
 #ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
 #if GCC_VERSION >= 40400
diff -ruw linux-3.11.10/include/linux/efi.h linux-3.11.10-fbx/include/linux/efi.h
--- linux-3.11.10/include/linux/efi.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/efi.h	2014-01-17 19:14:18.770220809 +0100
@@ -782,6 +782,8 @@
 	struct efi_variable var;
 	struct list_head list;
 	struct kobject kobj;
+	bool scanning;
+	bool deleting;
 };
 
 extern struct list_head efivar_sysfs_list;
@@ -840,6 +842,8 @@
 #if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE)
 int efivars_sysfs_init(void);
 
+#define EFIVARS_DATA_SIZE_MAX 1024
+
 #endif /* CONFIG_EFI_VARS */
 
 #endif /* _LINUX_EFI_H */
diff -ruw linux-3.11.10/include/linux/ftrace_event.h linux-3.11.10-fbx/include/linux/ftrace_event.h
--- linux-3.11.10/include/linux/ftrace_event.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/ftrace_event.h	2014-07-01 16:22:13.174329786 +0200
@@ -325,10 +325,6 @@
 	FILTER_TRACE_FN,
 };
 
-#define EVENT_STORAGE_SIZE 128
-extern struct mutex event_storage_mutex;
-extern char event_storage[EVENT_STORAGE_SIZE];
-
 extern int trace_event_raw_init(struct ftrace_event_call *call);
 extern int trace_define_field(struct ftrace_event_call *call, const char *type,
 			      const char *name, int offset, int size,
diff -ruw linux-3.11.10/include/linux/ftrace.h linux-3.11.10-fbx/include/linux/ftrace.h
--- linux-3.11.10/include/linux/ftrace.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/ftrace.h	2014-07-01 16:22:13.174329786 +0200
@@ -524,6 +524,7 @@
 extern int ftrace_arch_read_dyn_info(char *buf, int size);
 
 extern int skip_trace(unsigned long ip);
+extern void ftrace_module_init(struct module *mod);
 
 extern void ftrace_disable_daemon(void);
 extern void ftrace_enable_daemon(void);
@@ -533,6 +534,7 @@
 static inline void ftrace_disable_daemon(void) { }
 static inline void ftrace_enable_daemon(void) { }
 static inline void ftrace_release_mod(struct module *mod) {}
+static inline void ftrace_module_init(struct module *mod) {}
 static inline int register_ftrace_command(struct ftrace_func_command *cmd)
 {
 	return -EINVAL;
diff -ruw linux-3.11.10/include/linux/futex.h linux-3.11.10-fbx/include/linux/futex.h
--- linux-3.11.10/include/linux/futex.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/futex.h	2014-07-01 16:22:13.174329786 +0200
@@ -55,7 +55,11 @@
 #ifdef CONFIG_FUTEX
 extern void exit_robust_list(struct task_struct *curr);
 extern void exit_pi_state_list(struct task_struct *curr);
+#ifdef CONFIG_HAVE_FUTEX_CMPXCHG
+#define futex_cmpxchg_enabled 1
+#else
 extern int futex_cmpxchg_enabled;
+#endif
 #else
 static inline void exit_robust_list(struct task_struct *curr)
 {
diff -ruw linux-3.11.10/include/linux/genhd.h linux-3.11.10-fbx/include/linux/genhd.h
--- linux-3.11.10/include/linux/genhd.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/genhd.h	2014-05-09 14:12:54.312546159 +0200
@@ -85,6 +85,7 @@
 	unsigned long ticks[2];
 	unsigned long io_ticks;
 	unsigned long time_in_queue;
+	unsigned long io_errors[2];
 };
 
 #define PARTITION_META_INFO_VOLNAMELTH	64
diff -ruw linux-3.11.10/include/linux/hugetlb.h linux-3.11.10-fbx/include/linux/hugetlb.h
--- linux-3.11.10/include/linux/hugetlb.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/hugetlb.h	2014-05-09 14:12:54.312546159 +0200
@@ -31,6 +31,7 @@
 void hugepage_put_subpool(struct hugepage_subpool *spool);
 
 int PageHuge(struct page *page);
+int PageHeadHuge(struct page *page_head);
 
 void reset_vma_resv_huge_pages(struct vm_area_struct *vma);
 int hugetlb_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *);
@@ -100,6 +101,11 @@
 {
 	return 0;
 }
+
+static inline int PageHeadHuge(struct page *page_head)
+{
+	return 0;
+}
 
 static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma)
 {
diff -ruw linux-3.11.10/include/linux/if_vlan.h linux-3.11.10-fbx/include/linux/if_vlan.h
--- linux-3.11.10/include/linux/if_vlan.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/if_vlan.h	2013-12-04 14:33:24.411479060 +0100
@@ -87,8 +87,10 @@
 extern struct net_device *__vlan_find_dev_deep(struct net_device *real_dev,
 					       __be16 vlan_proto, u16 vlan_id);
 extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
+extern struct net_device *vlan_dev_upper_dev(const struct net_device *dev);
 extern u16 vlan_dev_vlan_id(const struct net_device *dev);
 
+
 extern bool vlan_do_receive(struct sk_buff **skb);
 extern struct sk_buff *vlan_untag(struct sk_buff *skb);
 
@@ -113,6 +115,12 @@
 {
 	BUG();
 	return NULL;
+}
+
+static inline struct net_device *vlan_dev_upper_dev(const struct net_device *dev)
+{
+	BUG();
+	return NULL;
 }
 
 static inline u16 vlan_dev_vlan_id(const struct net_device *dev)
diff -ruw linux-3.11.10/include/linux/in.h linux-3.11.10-fbx/include/linux/in.h
--- linux-3.11.10/include/linux/in.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/in.h	2013-12-04 14:33:24.415479060 +0100
@@ -34,6 +34,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.11.10/include/linux/init_task.h linux-3.11.10-fbx/include/linux/init_task.h
--- linux-3.11.10/include/linux/init_task.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/init_task.h	2014-08-22 15:47:22.136063146 +0200
@@ -40,6 +40,7 @@
 
 #define INIT_SIGNALS(sig) {						\
 	.nr_threads	= 1,						\
+	.thread_head	= LIST_HEAD_INIT(init_task.thread_node),	\
 	.wait_chldexit	= __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\
 	.shared_pending	= { 						\
 		.list = LIST_HEAD_INIT(sig.shared_pending.list),	\
@@ -164,6 +165,7 @@
 	.stack		= &init_thread_info,				\
 	.usage		= ATOMIC_INIT(2),				\
 	.flags		= PF_KTHREAD,					\
+	.exec_mode	= EXEC_MODE_UNLIMITED,				\
 	.prio		= MAX_PRIO-20,					\
 	.static_prio	= MAX_PRIO-20,					\
 	.normal_prio	= MAX_PRIO-20,					\
@@ -213,6 +215,7 @@
 		[PIDTYPE_SID]  = INIT_PID_LINK(PIDTYPE_SID),		\
 	},								\
 	.thread_group	= LIST_HEAD_INIT(tsk.thread_group),		\
+	.thread_node	= LIST_HEAD_INIT(init_signals.thread_head),	\
 	INIT_IDS							\
 	INIT_PERF_EVENTS(tsk)						\
 	INIT_TRACE_IRQFLAGS						\
diff -ruw linux-3.11.10/include/linux/interrupt.h linux-3.11.10-fbx/include/linux/interrupt.h
--- linux-3.11.10/include/linux/interrupt.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/interrupt.h	2014-07-01 16:22:13.178329806 +0200
@@ -239,7 +239,40 @@
 
 extern cpumask_var_t irq_default_affinity;
 
-extern int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask);
+/* Internal implementation. Use the helpers below */
+extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask,
+			      bool force);
+
+/**
+ * irq_set_affinity - Set the irq affinity of a given irq
+ * @irq:	Interrupt to set affinity
+ * @mask:	cpumask
+ *
+ * Fails if cpumask does not contain an online CPU
+ */
+static inline int
+irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+	return __irq_set_affinity(irq, cpumask, false);
+}
+
+/**
+ * irq_force_affinity - Force the irq affinity of a given irq
+ * @irq:	Interrupt to set affinity
+ * @mask:	cpumask
+ *
+ * Same as irq_set_affinity, but without checking the mask against
+ * online cpus.
+ *
+ * Solely for low level cpu hotplug code, where we need to make per
+ * cpu interrupts affine before the cpu becomes online.
+ */
+static inline int
+irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+	return __irq_set_affinity(irq, cpumask, true);
+}
+
 extern int irq_can_set_affinity(unsigned int irq);
 extern int irq_select_affinity(unsigned int irq);
 
@@ -275,6 +308,11 @@
 	return -EINVAL;
 }
 
+static inline int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+	return 0;
+}
+
 static inline int irq_can_set_affinity(unsigned int irq)
 {
 	return 0;
diff -ruw linux-3.11.10/include/linux/ipc_namespace.h linux-3.11.10-fbx/include/linux/ipc_namespace.h
--- linux-3.11.10/include/linux/ipc_namespace.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/ipc_namespace.h	2014-07-01 16:22:13.178329806 +0200
@@ -34,9 +34,9 @@
 	int		sem_ctls[4];
 	int		used_sems;
 
-	int		msg_ctlmax;
-	int		msg_ctlmnb;
-	int		msg_ctlmni;
+	unsigned int	msg_ctlmax;
+	unsigned int	msg_ctlmnb;
+	unsigned int	msg_ctlmni;
 	atomic_t	msg_bytes;
 	atomic_t	msg_hdrs;
 	int		auto_msgmni;
@@ -119,9 +119,7 @@
  *     the new maximum will handle anyone else.  I may have to revisit this
  *     in the future.
  */
-#define MIN_QUEUESMAX			1
 #define DFLT_QUEUESMAX		      256
-#define HARD_QUEUESMAX		     1024
 #define MIN_MSGMAX			1
 #define DFLT_MSG		       10U
 #define DFLT_MSGMAX		       10
diff -ruw linux-3.11.10/include/linux/irqdesc.h linux-3.11.10-fbx/include/linux/irqdesc.h
--- linux-3.11.10/include/linux/irqdesc.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/irqdesc.h	2014-08-22 15:47:22.140063166 +0200
@@ -27,6 +27,8 @@
  * @irq_count:		stats field to detect stalled irqs
  * @last_unhandled:	aging timer for unhandled count
  * @irqs_unhandled:	stats field for spurious unhandled interrupts
+ * @threads_handled:	stats field for deferred spurious detection of threaded handlers
+ * @threads_handled_last: comparator field for deferred spurious detection of theraded handlers
  * @lock:		locking for SMP
  * @affinity_hint:	hint to user space for preferred irq affinity
  * @affinity_notify:	context for notification of affinity changes
@@ -52,6 +54,8 @@
 	unsigned int		irq_count;	/* For detecting broken IRQs */
 	unsigned long		last_unhandled;	/* Aging timer for unhandled count */
 	unsigned int		irqs_unhandled;
+	atomic_t		threads_handled;
+	int			threads_handled_last;
 	raw_spinlock_t		lock;
 	struct cpumask		*percpu_enabled;
 #ifdef CONFIG_SMP
diff -ruw linux-3.11.10/include/linux/irq.h linux-3.11.10-fbx/include/linux/irq.h
--- linux-3.11.10/include/linux/irq.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/irq.h	2014-07-01 16:22:13.178329806 +0200
@@ -380,7 +380,8 @@
 
 extern void irq_cpu_online(void);
 extern void irq_cpu_offline(void);
-extern int __irq_set_affinity_locked(struct irq_data *data,  const struct cpumask *cpumask);
+extern int irq_set_affinity_locked(struct irq_data *data,
+				   const struct cpumask *cpumask, bool force);
 
 #ifdef CONFIG_GENERIC_HARDIRQS
 
diff -ruw linux-3.11.10/include/linux/jiffies.h linux-3.11.10-fbx/include/linux/jiffies.h
--- linux-3.11.10/include/linux/jiffies.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/jiffies.h	2014-07-01 16:22:13.178329806 +0200
@@ -101,13 +101,13 @@
 #define time_after(a,b)		\
 	(typecheck(unsigned long, a) && \
 	 typecheck(unsigned long, b) && \
-	 ((long)(b) - (long)(a) < 0))
+	 ((long)((b) - (a)) < 0))
 #define time_before(a,b)	time_after(b,a)
 
 #define time_after_eq(a,b)	\
 	(typecheck(unsigned long, a) && \
 	 typecheck(unsigned long, b) && \
-	 ((long)(a) - (long)(b) >= 0))
+	 ((long)((a) - (b)) >= 0))
 #define time_before_eq(a,b)	time_after_eq(b,a)
 
 /*
@@ -130,13 +130,13 @@
 #define time_after64(a,b)	\
 	(typecheck(__u64, a) &&	\
 	 typecheck(__u64, b) && \
-	 ((__s64)(b) - (__s64)(a) < 0))
+	 ((__s64)((b) - (a)) < 0))
 #define time_before64(a,b)	time_after64(b,a)
 
 #define time_after_eq64(a,b)	\
 	(typecheck(__u64, a) && \
 	 typecheck(__u64, b) && \
-	 ((__s64)(a) - (__s64)(b) >= 0))
+	 ((__s64)((a) - (b)) >= 0))
 #define time_before_eq64(a,b)	time_after_eq64(b,a)
 
 #define time_in_range64(a, b, c) \
diff -ruw linux-3.11.10/include/linux/kexec.h linux-3.11.10-fbx/include/linux/kexec.h
--- linux-3.11.10/include/linux/kexec.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/kexec.h	2014-01-17 19:14:18.770220809 +0100
@@ -198,6 +198,9 @@
 extern size_t vmcoreinfo_size;
 extern size_t vmcoreinfo_max_size;
 
+/* flag to track if kexec reboot is in progress */
+extern bool kexec_in_progress;
+
 int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
 		unsigned long long *crash_size, unsigned long long *crash_base);
 int parse_crashkernel_high(char *cmdline, unsigned long long system_ram,
diff -ruw linux-3.11.10/include/linux/libata.h linux-3.11.10-fbx/include/linux/libata.h
--- linux-3.11.10/include/linux/libata.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/libata.h	2014-07-01 16:22:13.178329806 +0200
@@ -400,6 +400,8 @@
 	ATA_HORKAGE_DUMP_ID	= (1 << 16),	/* dump IDENTIFY data */
 	ATA_HORKAGE_MAX_SEC_LBA48 = (1 << 17),	/* Set max sects to 65535 */
 	ATA_HORKAGE_ATAPI_DMADIR = (1 << 18),	/* device requires dmadir */
+	ATA_HORKAGE_NOLPM	= (1 << 20),	/* don't use LPM */
+	ATA_HORKAGE_WD_BROKEN_LPM = (1 << 21),	/* some WDs have broken LPM */
 
 	 /* DMA mask for user DMA control: User visible values; DO NOT
 	    renumber */
@@ -771,6 +773,7 @@
 	unsigned long		qc_allocated;
 	unsigned int		qc_active;
 	int			nr_active_links; /* #links with active qcs */
+	unsigned int		last_tag;	/* track next tag hw expects */
 
 	struct ata_link		link;		/* host default link */
 	struct ata_link		*slave_link;	/* see ata_slave_link_init() */
diff -ruw linux-3.11.10/include/linux/list.h linux-3.11.10-fbx/include/linux/list.h
--- linux-3.11.10/include/linux/list.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/list.h	2014-07-01 16:22:13.178329806 +0200
@@ -373,6 +373,22 @@
 	(!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
 
 /**
+ * list_next_entry - get the next element in list
+ * @pos:	the type * to cursor
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_next_entry(pos, member) \
+	list_entry((pos)->member.next, typeof(*(pos)), member)
+
+/**
+ * list_prev_entry - get the prev element in list
+ * @pos:	the type * to cursor
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_prev_entry(pos, member) \
+	list_entry((pos)->member.prev, typeof(*(pos)), member)
+
+/**
  * list_for_each	-	iterate over a list
  * @pos:	the &struct list_head to use as a loop cursor.
  * @head:	the head for your list.
diff -ruw linux-3.11.10/include/linux/migrate.h linux-3.11.10-fbx/include/linux/migrate.h
--- linux-3.11.10/include/linux/migrate.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/migrate.h	2014-01-17 19:14:18.770220809 +0100
@@ -92,10 +92,18 @@
 #endif /* CONFIG_MIGRATION */
 
 #ifdef CONFIG_NUMA_BALANCING
-extern int migrate_misplaced_page(struct page *page, int node);
+extern bool pmd_trans_migrating(pmd_t pmd);
+extern void wait_migrate_huge_page(struct anon_vma *anon_vma, pmd_t *pmd);
 extern int migrate_misplaced_page(struct page *page, int node);
 extern bool migrate_ratelimited(int node);
 #else
+static inline bool pmd_trans_migrating(pmd_t pmd)
+{
+	return false;
+}
+static inline void wait_migrate_huge_page(struct anon_vma *anon_vma, pmd_t *pmd)
+{
+}
 static inline int migrate_misplaced_page(struct page *page, int node)
 {
 	return -EAGAIN; /* can't migrate now */
diff -ruw linux-3.11.10/include/linux/mm.h linux-3.11.10-fbx/include/linux/mm.h
--- linux-3.11.10/include/linux/mm.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/mm.h	2014-07-01 16:22:13.178329806 +0200
@@ -155,7 +155,7 @@
  * Special vmas that are non-mergable, non-mlock()able.
  * Note: mm/huge_memory.c VM_NO_THP depends on this definition.
  */
-#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP)
+#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP)
 
 /*
  * mapping from the currently active vm_flags protection bits (the
@@ -769,11 +769,14 @@
 #endif
 
 #if defined(WANT_PAGE_VIRTUAL)
-#define page_address(page) ((page)->virtual)
-#define set_page_address(page, address)			\
-	do {						\
-		(page)->virtual = (address);		\
-	} while(0)
+static inline void *page_address(const struct page *page)
+{
+	return page->virtual;
+}
+static inline void set_page_address(struct page *page, void *address)
+{
+	page->virtual = address;
+}
 #define page_address_init()  do { } while(0)
 #endif
 
diff -ruw linux-3.11.10/include/linux/mm_types.h linux-3.11.10-fbx/include/linux/mm_types.h
--- linux-3.11.10/include/linux/mm_types.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/mm_types.h	2014-01-17 19:14:18.774220809 +0100
@@ -434,6 +434,14 @@
 	 */
 	int first_nid;
 #endif
+#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
+	/*
+	 * An operation with batched TLB flushing is going on. Anything that
+	 * can move process memory needs to flush the TLB when moving a
+	 * PROT_NONE or PROT_NUMA mapped page.
+	 */
+	bool tlb_flush_pending;
+#endif
 	struct uprobes_state uprobes_state;
 };
 
@@ -454,4 +462,45 @@
 	return mm->cpu_vm_mask_var;
 }
 
+#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
+/*
+ * Memory barriers to keep this state in sync are graciously provided by
+ * the page table locks, outside of which no page table modifications happen.
+ * The barriers below prevent the compiler from re-ordering the instructions
+ * around the memory barriers that are already present in the code.
+ */
+static inline bool mm_tlb_flush_pending(struct mm_struct *mm)
+{
+	barrier();
+	return mm->tlb_flush_pending;
+}
+static inline void set_tlb_flush_pending(struct mm_struct *mm)
+{
+	mm->tlb_flush_pending = true;
+
+	/*
+	 * Guarantee that the tlb_flush_pending store does not leak into the
+	 * critical section updating the page tables
+	 */
+	smp_mb__before_spinlock();
+}
+/* Clearing is done after a TLB flush, which also provides a barrier. */
+static inline void clear_tlb_flush_pending(struct mm_struct *mm)
+{
+	barrier();
+	mm->tlb_flush_pending = false;
+}
+#else
+static inline bool mm_tlb_flush_pending(struct mm_struct *mm)
+{
+	return false;
+}
+static inline void set_tlb_flush_pending(struct mm_struct *mm)
+{
+}
+static inline void clear_tlb_flush_pending(struct mm_struct *mm)
+{
+}
+#endif
+
 #endif /* _LINUX_MM_TYPES_H */
diff -ruw linux-3.11.10/include/linux/mmzone.h linux-3.11.10-fbx/include/linux/mmzone.h
--- linux-3.11.10/include/linux/mmzone.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/mmzone.h	2014-08-22 15:47:22.140063166 +0200
@@ -75,9 +75,13 @@
 
 extern int page_group_by_mobility_disabled;
 
+#define NR_MIGRATETYPE_BITS (PB_migrate_end - PB_migrate + 1)
+#define MIGRATETYPE_MASK ((1UL << NR_MIGRATETYPE_BITS) - 1)
+
 static inline int get_pageblock_migratetype(struct page *page)
 {
-	return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end);
+	BUILD_BUG_ON(PB_migrate_end - PB_migrate != 2);
+	return get_pageblock_flags_mask(page, PB_migrate_end, MIGRATETYPE_MASK);
 }
 
 struct free_area {
diff -ruw linux-3.11.10/include/linux/msg.h linux-3.11.10-fbx/include/linux/msg.h
--- linux-3.11.10/include/linux/msg.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/msg.h	2014-01-17 19:14:18.774220809 +0100
@@ -8,7 +8,7 @@
 struct msg_msg {
 	struct list_head m_list; 
 	long  m_type;          
-	int m_ts;           /* message text size */
+	size_t m_ts;		/* message text size */
 	struct msg_msgseg* next;
 	void *security;
 	/* the actual message follows immediately */
diff -ruw linux-3.11.10/include/linux/mtd/map.h linux-3.11.10-fbx/include/linux/mtd/map.h
--- linux-3.11.10/include/linux/mtd/map.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/mtd/map.h	2014-01-17 19:14:18.774220809 +0100
@@ -365,7 +365,7 @@
 			bitpos = (map_bankwidth(map)-1-i)*8;
 #endif
 			orig.x[0] &= ~(0xff << bitpos);
-			orig.x[0] |= buf[i-start] << bitpos;
+			orig.x[0] |= (unsigned long)buf[i-start] << bitpos;
 		}
 	}
 	return orig;
@@ -384,7 +384,7 @@
 
 	if (map_bankwidth(map) < MAP_FF_LIMIT) {
 		int bw = 8 * map_bankwidth(map);
-		r.x[0] = (1 << bw) - 1;
+		r.x[0] = (1UL << bw) - 1;
 	} else {
 		for (i=0; i<map_words(map); i++)
 			r.x[i] = ~0UL;
diff -ruw linux-3.11.10/include/linux/mtd/mtd.h linux-3.11.10-fbx/include/linux/mtd/mtd.h
--- linux-3.11.10/include/linux/mtd/mtd.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/mtd/mtd.h	2013-12-04 14:33:24.531479062 +0100
@@ -166,6 +166,11 @@
 	 */
 	unsigned int bitflip_threshold;
 
+	/* 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.11.10/include/linux/mtd/nand.h linux-3.11.10-fbx/include/linux/mtd/nand.h
--- linux-3.11.10/include/linux/mtd/nand.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/mtd/nand.h	2013-12-04 14:33:24.531479062 +0100
@@ -191,6 +191,9 @@
  */
 #define NAND_BUSWIDTH_AUTO      0x00080000
 
+/* 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.11.10/include/linux/netdevice.h linux-3.11.10-fbx/include/linux/netdevice.h
--- linux-3.11.10/include/linux/netdevice.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/netdevice.h	2014-07-01 16:22:13.178329806 +0200
@@ -1336,6 +1336,12 @@
 	/* MRP */
 	struct mrp_port __rcu	*mrp_port;
 
+#ifdef CONFIG_FBXBRIDGE
+	struct fbxbridge	*fbx_bridge;
+	struct fbxbridge	*fbx_bridge_port;
+	int			fbx_bridge_maybe_port;
+#endif
+
 	/* class/net/name entry */
 	struct device		dev;
 	/* space for optional device, statistics, and wireless sysfs groups */
@@ -1836,6 +1842,15 @@
 	return dev->header_ops->parse(skb, haddr);
 }
 
+static inline int dev_rebuild_header(struct sk_buff *skb)
+{
+	const struct net_device *dev = skb->dev;
+
+	if (!dev->header_ops || !dev->header_ops->rebuild)
+		return 0;
+	return dev->header_ops->rebuild(skb);
+}
+
 typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len);
 extern int		register_gifconf(unsigned int family, gifconf_func_t * gifconf);
 static inline int unregister_gifconf(unsigned int family)
@@ -2833,7 +2848,12 @@
 void netif_stacked_transfer_operstate(const struct net_device *rootdev,
 					struct net_device *dev);
 
-netdev_features_t netif_skb_features(struct sk_buff *skb);
+netdev_features_t netif_skb_dev_features(struct sk_buff *skb,
+					 const struct net_device *dev);
+static inline netdev_features_t netif_skb_features(struct sk_buff *skb)
+{
+	return netif_skb_dev_features(skb, skb->dev);
+}
 
 static inline bool net_gso_ok(netdev_features_t features, int gso_type)
 {
@@ -2870,6 +2890,19 @@
 	dev->gso_max_size = size;
 }
 
+static inline void skb_gso_error_unwind(struct sk_buff *skb, __be16 protocol,
+					int pulled_hlen, u16 mac_offset,
+					int mac_len)
+{
+	skb->protocol = protocol;
+	skb->encapsulation = 1;
+	skb_push(skb, pulled_hlen);
+	skb_reset_transport_header(skb);
+	skb->mac_header = mac_offset;
+	skb->network_header = skb->mac_header + mac_len;
+	skb->mac_len = mac_len;
+}
+
 static inline bool netif_is_bond_master(struct net_device *dev)
 {
 	return dev->flags & IFF_MASTER && dev->priv_flags & IFF_BONDING;
diff -ruw linux-3.11.10/include/linux/net.h linux-3.11.10-fbx/include/linux/net.h
--- linux-3.11.10/include/linux/net.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/net.h	2014-01-17 19:14:18.774220809 +0100
@@ -163,6 +163,14 @@
 #endif
 	int		(*sendmsg)   (struct kiocb *iocb, struct socket *sock,
 				      struct msghdr *m, size_t total_len);
+	/* Notes for implementing recvmsg:
+	 * ===============================
+	 * msg->msg_namelen should get updated by the recvmsg handlers
+	 * iff msg_name != NULL. It is by default 0 to prevent
+	 * returning uninitialized memory to user space.  The recvfrom
+	 * handlers can assume that msg.msg_name is either NULL or has
+	 * a minimum size of sizeof(struct sockaddr_storage).
+	 */
 	int		(*recvmsg)   (struct kiocb *iocb, struct socket *sock,
 				      struct msghdr *m, size_t total_len,
 				      int flags);
@@ -172,7 +180,7 @@
 				      int offset, size_t size, int flags);
 	ssize_t 	(*splice_read)(struct socket *sock,  loff_t *ppos,
 				       struct pipe_inode_info *pipe, size_t len, unsigned int flags);
-	void		(*set_peek_off)(struct sock *sk, int val);
+	int		(*set_peek_off)(struct sock *sk, int val);
 };
 
 #define DECLARE_SOCKADDR(type, dst, src)	\
diff -ruw linux-3.11.10/include/linux/netlink.h linux-3.11.10-fbx/include/linux/netlink.h
--- linux-3.11.10/include/linux/netlink.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/netlink.h	2014-08-22 15:47:22.140063166 +0200
@@ -19,6 +19,7 @@
 	NETLINK_SKB_MMAPED	= 0x1,		/* Packet data is mmaped */
 	NETLINK_SKB_TX		= 0x2,		/* Packet was sent by userspace */
 	NETLINK_SKB_DELIVERED	= 0x4,		/* Packet was delivered */
+	NETLINK_SKB_DST		= 0x8,	/* Dst set in sendto or sendmsg */
 };
 
 struct netlink_skb_parms {
@@ -171,4 +172,11 @@
 extern int __netlink_remove_tap(struct netlink_tap *nt);
 extern int netlink_remove_tap(struct netlink_tap *nt);
 
+bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
+			  struct user_namespace *ns, int cap);
+bool netlink_ns_capable(const struct sk_buff *skb,
+			struct user_namespace *ns, int cap);
+bool netlink_capable(const struct sk_buff *skb, int cap);
+bool netlink_net_capable(const struct sk_buff *skb, int cap);
+
 #endif	/* __LINUX_NETLINK_H */
diff -ruw linux-3.11.10/include/linux/nfs4.h linux-3.11.10-fbx/include/linux/nfs4.h
--- linux-3.11.10/include/linux/nfs4.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/nfs4.h	2014-07-01 16:22:13.178329806 +0200
@@ -395,7 +395,7 @@
 #define FATTR4_WORD1_FS_LAYOUT_TYPES    (1UL << 30)
 #define FATTR4_WORD2_LAYOUT_BLKSIZE     (1UL << 1)
 #define FATTR4_WORD2_MDSTHRESHOLD       (1UL << 4)
-#define FATTR4_WORD2_SECURITY_LABEL     (1UL << 17)
+#define FATTR4_WORD2_SECURITY_LABEL     (1UL << 16)
 
 /* MDS threshold bitmap bits */
 #define THRESHOLD_RD                    (1UL << 0)
@@ -408,16 +408,6 @@
 #define NFS4_VERSION 4
 #define NFS4_MINOR_VERSION 0
 
-#if defined(CONFIG_NFS_V4_2)
-#define NFS4_MAX_MINOR_VERSION 2
-#else
-#if defined(CONFIG_NFS_V4_1)
-#define NFS4_MAX_MINOR_VERSION 1
-#else
-#define NFS4_MAX_MINOR_VERSION 0
-#endif /* CONFIG_NFS_V4_1 */
-#endif /* CONFIG_NFS_V4_2 */
-
 #define NFS4_DEBUG 1
 
 /* Index of predefined Linux client operations */
diff -ruw linux-3.11.10/include/linux/nfs_fs.h linux-3.11.10-fbx/include/linux/nfs_fs.h
--- linux-3.11.10/include/linux/nfs_fs.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/nfs_fs.h	2014-07-01 16:22:13.178329806 +0200
@@ -503,24 +503,6 @@
 extern void nfs_release_automount_timer(void);
 
 /*
- * linux/fs/nfs/nfs4proc.c
- */
-#ifdef CONFIG_NFS_V4_SECURITY_LABEL
-extern struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags);
-static inline void nfs4_label_free(struct nfs4_label *label)
-{
-	if (label) {
-		kfree(label->label);
-		kfree(label);
-	}
-	return;
-}
-#else
-static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
-static inline void nfs4_label_free(void *label) {}
-#endif
-
-/*
  * linux/fs/nfs/unlink.c
  */
 extern void nfs_complete_unlink(struct dentry *dentry, struct inode *);
diff -ruw linux-3.11.10/include/linux/pageblock-flags.h linux-3.11.10-fbx/include/linux/pageblock-flags.h
--- linux-3.11.10/include/linux/pageblock-flags.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/pageblock-flags.h	2014-08-22 15:47:22.140063166 +0200
@@ -30,9 +30,12 @@
 	PB_migrate,
 	PB_migrate_end = PB_migrate + 3 - 1,
 			/* 3 bits required for migrate types */
-#ifdef CONFIG_COMPACTION
 	PB_migrate_skip,/* If set the block is skipped by compaction */
-#endif /* CONFIG_COMPACTION */
+
+	/*
+	 * Assume the bits will always align on a word. If this assumption
+	 * changes then get/set pageblock needs updating.
+	 */
 	NR_PAGEBLOCK_BITS
 };
 
@@ -62,11 +65,33 @@
 /* Forward declaration */
 struct page;
 
+unsigned long get_pageblock_flags_mask(struct page *page,
+				unsigned long end_bitidx,
+				unsigned long mask);
+void set_pageblock_flags_mask(struct page *page,
+				unsigned long flags,
+				unsigned long end_bitidx,
+				unsigned long mask);
+
 /* Declarations for getting and setting flags. See mm/page_alloc.c */
-unsigned long get_pageblock_flags_group(struct page *page,
-					int start_bitidx, int end_bitidx);
-void set_pageblock_flags_group(struct page *page, unsigned long flags,
-					int start_bitidx, int end_bitidx);
+static inline unsigned long get_pageblock_flags_group(struct page *page,
+					int start_bitidx, int end_bitidx)
+{
+	unsigned long nr_flag_bits = end_bitidx - start_bitidx + 1;
+	unsigned long mask = (1 << nr_flag_bits) - 1;
+
+	return get_pageblock_flags_mask(page, end_bitidx, mask);
+}
+
+static inline void set_pageblock_flags_group(struct page *page,
+					unsigned long flags,
+					int start_bitidx, int end_bitidx)
+{
+	unsigned long nr_flag_bits = end_bitidx - start_bitidx + 1;
+	unsigned long mask = (1 << nr_flag_bits) - 1;
+
+	set_pageblock_flags_mask(page, flags, end_bitidx, mask);
+}
 
 #ifdef CONFIG_COMPACTION
 #define get_pageblock_skip(page) \
diff -ruw linux-3.11.10/include/linux/page-flags.h linux-3.11.10-fbx/include/linux/page-flags.h
--- linux-3.11.10/include/linux/page-flags.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/page-flags.h	2014-08-22 15:47:22.140063166 +0200
@@ -317,13 +317,23 @@
 extern void cancel_dirty_page(struct page *page, unsigned int account_size);
 
 int test_clear_page_writeback(struct page *page);
-int test_set_page_writeback(struct page *page);
+int __test_set_page_writeback(struct page *page, bool keep_write);
+
+#define test_set_page_writeback(page)			\
+	__test_set_page_writeback(page, false)
+#define test_set_page_writeback_keepwrite(page)	\
+	__test_set_page_writeback(page, true)
 
 static inline void set_page_writeback(struct page *page)
 {
 	test_set_page_writeback(page);
 }
 
+static inline void set_page_writeback_keepwrite(struct page *page)
+{
+	test_set_page_writeback_keepwrite(page);
+}
+
 #ifdef CONFIG_PAGEFLAGS_EXTENDED
 /*
  * System with lots of page flags available. This allows separate
diff -ruw linux-3.11.10/include/linux/pci_ids.h linux-3.11.10-fbx/include/linux/pci_ids.h
--- linux-3.11.10/include/linux/pci_ids.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/pci_ids.h	2013-12-17 18:03:42.951570855 +0100
@@ -2964,3 +2964,6 @@
 #define PCI_DEVICE_ID_XEN_PLATFORM	0x0001
 
 #define PCI_VENDOR_ID_OCZ		0x1b85
+
+#define PCI_VENDOR_ID_PERICOM		0x12d8
+#define PCI_DEVICE_ID_PI7C9X20303SL	0xa303
diff -ruw linux-3.11.10/include/linux/percpu-refcount.h linux-3.11.10-fbx/include/linux/percpu-refcount.h
--- linux-3.11.10/include/linux/percpu-refcount.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/percpu-refcount.h	2014-07-01 16:22:13.178329806 +0200
@@ -110,7 +110,7 @@
 	pcpu_count = ACCESS_ONCE(ref->pcpu_count);
 
 	if (likely(REF_STATUS(pcpu_count) == PCPU_REF_PTR))
-		__this_cpu_inc(*pcpu_count);
+		this_cpu_inc(*pcpu_count);
 	else
 		atomic_inc(&ref->count);
 
@@ -139,7 +139,7 @@
 	pcpu_count = ACCESS_ONCE(ref->pcpu_count);
 
 	if (likely(REF_STATUS(pcpu_count) == PCPU_REF_PTR)) {
-		__this_cpu_inc(*pcpu_count);
+		this_cpu_inc(*pcpu_count);
 		ret = true;
 	}
 
@@ -164,7 +164,7 @@
 	pcpu_count = ACCESS_ONCE(ref->pcpu_count);
 
 	if (likely(REF_STATUS(pcpu_count) == PCPU_REF_PTR))
-		__this_cpu_dec(*pcpu_count);
+		this_cpu_dec(*pcpu_count);
 	else if (unlikely(atomic_dec_and_test(&ref->count)))
 		ref->release(ref);
 
diff -ruw linux-3.11.10/include/linux/phy.h linux-3.11.10-fbx/include/linux/phy.h
--- linux-3.11.10/include/linux/phy.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/phy.h	2013-12-04 14:33:24.643479064 +0100
@@ -145,7 +145,7 @@
 struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
 int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
 int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
-
+struct mii_bus *mdio_find_bus(const char *name);
 
 #define PHY_INTERRUPT_DISABLED	0x0
 #define PHY_INTERRUPT_ENABLED	0x80000000
diff -ruw linux-3.11.10/include/linux/pipe_fs_i.h linux-3.11.10-fbx/include/linux/pipe_fs_i.h
--- linux-3.11.10/include/linux/pipe_fs_i.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/pipe_fs_i.h	2014-05-09 14:12:54.316546160 +0200
@@ -157,6 +157,8 @@
 int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
 void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
 
+extern const struct pipe_buf_operations nosteal_pipe_buf_ops;
+
 /* for F_SETPIPE_SZ and F_GETPIPE_SZ */
 long pipe_fcntl(struct file *, unsigned int, unsigned long arg);
 struct pipe_inode_info *get_pipe_info(struct file *file);
diff -ruw linux-3.11.10/include/linux/ppp_channel.h linux-3.11.10-fbx/include/linux/ppp_channel.h
--- linux-3.11.10/include/linux/ppp_channel.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/ppp_channel.h	2013-12-04 14:33:24.811479066 +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.11.10/include/linux/ptrace.h linux-3.11.10-fbx/include/linux/ptrace.h
--- linux-3.11.10/include/linux/ptrace.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/ptrace.h	2014-08-22 15:47:22.140063166 +0200
@@ -5,6 +5,7 @@
 #include <linux/sched.h>		/* For struct task_struct.  */
 #include <linux/err.h>			/* for IS_ERR_VALUE */
 #include <linux/bug.h>			/* For BUG_ON.  */
+#include <linux/pid_namespace.h>	/* For task_active_pid_ns.  */
 #include <uapi/linux/ptrace.h>
 
 /*
@@ -129,6 +130,37 @@
 }
 
 /**
+ * ptrace_event_pid - possibly stop for a ptrace event notification
+ * @event:	%PTRACE_EVENT_* value to report
+ * @pid:	process identifier for %PTRACE_GETEVENTMSG to return
+ *
+ * Check whether @event is enabled and, if so, report @event and @pid
+ * to the ptrace parent.  @pid is reported as the pid_t seen from the
+ * the ptrace parent's pid namespace.
+ *
+ * Called without locks.
+ */
+static inline void ptrace_event_pid(int event, struct pid *pid)
+{
+	/*
+	 * FIXME: There's a potential race if a ptracer in a different pid
+	 * namespace than parent attaches between computing message below and
+	 * when we acquire tasklist_lock in ptrace_stop().  If this happens,
+	 * the ptracer will get a bogus pid from PTRACE_GETEVENTMSG.
+	 */
+	unsigned long message = 0;
+	struct pid_namespace *ns;
+
+	rcu_read_lock();
+	ns = task_active_pid_ns(rcu_dereference(current->parent));
+	if (ns)
+		message = pid_nr_ns(pid, ns);
+	rcu_read_unlock();
+
+	ptrace_event(event, message);
+}
+
+/**
  * ptrace_init_task - initialize ptrace state for a new child
  * @child:		new child task
  * @ptrace:		true if child should be ptrace'd by parent's tracer
@@ -302,6 +334,9 @@
  * calling arch_ptrace_stop() when it would be superfluous.  For example,
  * if the thread has not been back to user mode since the last stop, the
  * thread state might indicate that nothing needs to be done.
+ *
+ * This is guaranteed to be invoked once before a task stops for ptrace and
+ * may include arch-specific operations necessary prior to a ptrace stop.
  */
 #define arch_ptrace_stop_needed(code, info)	(0)
 #endif
diff -ruw linux-3.11.10/include/linux/random.h linux-3.11.10-fbx/include/linux/random.h
--- linux-3.11.10/include/linux/random.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/random.h	2014-01-17 19:14:18.774220809 +0100
@@ -50,9 +50,9 @@
 {
 	u32 i = (seed >> 32) ^ (seed << 10) ^ seed;
 
-	state->s1 = __seed(i, 1);
-	state->s2 = __seed(i, 7);
-	state->s3 = __seed(i, 15);
+	state->s1 = __seed(i, 2);
+	state->s2 = __seed(i, 8);
+	state->s3 = __seed(i, 16);
 }
 
 #ifdef CONFIG_ARCH_RANDOM
diff -ruw linux-3.11.10/include/linux/reboot.h linux-3.11.10-fbx/include/linux/reboot.h
--- linux-3.11.10/include/linux/reboot.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/reboot.h	2014-01-17 19:14:18.774220809 +0100
@@ -43,6 +43,7 @@
  * Architecture-specific implementations of sys_reboot commands.
  */
 
+extern void migrate_to_reboot_cpu(void);
 extern void machine_restart(char *cmd);
 extern void machine_halt(void);
 extern void machine_power_off(void);
diff -ruw linux-3.11.10/include/linux/ring_buffer.h linux-3.11.10-fbx/include/linux/ring_buffer.h
--- linux-3.11.10/include/linux/ring_buffer.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/ring_buffer.h	2014-08-22 15:47:22.140063166 +0200
@@ -97,7 +97,7 @@
 	__ring_buffer_alloc((size), (flags), &__key);	\
 })
 
-void ring_buffer_wait(struct ring_buffer *buffer, int cpu);
+int ring_buffer_wait(struct ring_buffer *buffer, int cpu);
 int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,
 			  struct file *filp, poll_table *poll_table);
 
diff -ruw linux-3.11.10/include/linux/sched.h linux-3.11.10-fbx/include/linux/sched.h
--- linux-3.11.10/include/linux/sched.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/sched.h	2014-08-22 15:47:22.140063166 +0200
@@ -478,6 +478,7 @@
 	atomic_t		sigcnt;
 	atomic_t		live;
 	int			nr_threads;
+	struct list_head	thread_head;
 
 	wait_queue_head_t	wait_chldexit;	/* for wait4() */
 
@@ -1028,6 +1029,12 @@
 	perf_nr_task_contexts,
 };
 
+enum task_exec_mode {
+	EXEC_MODE_DENIED,
+	EXEC_MODE_ONCE,
+	EXEC_MODE_UNLIMITED,
+};
+
 struct task_struct {
 	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
 	void *stack;
@@ -1035,6 +1042,8 @@
 	unsigned int flags;	/* per process flags, defined below */
 	unsigned int ptrace;
 
+	enum task_exec_mode exec_mode;
+
 #ifdef CONFIG_SMP
 	struct llist_node wake_entry;
 	int on_cpu;
@@ -1153,6 +1162,7 @@
 	/* PID/PID hash table linkage. */
 	struct pid_link pids[PIDTYPE_MAX];
 	struct list_head thread_group;
+	struct list_head thread_node;
 
 	struct completion *vfork_done;		/* for vfork() */
 	int __user *set_child_tid;		/* CLONE_CHILD_SETTID */
@@ -1229,6 +1239,7 @@
 	unsigned int sessionid;
 #endif
 	struct seccomp seccomp;
+	struct fbxlsmjail *fbxjail;
 
 /* Thread group tracking */
    	u32 parent_exec_id;
@@ -1500,6 +1511,24 @@
 }
 
 
+static int pid_alive(const struct task_struct *p);
+static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
+{
+	pid_t pid = 0;
+
+	rcu_read_lock();
+	if (pid_alive(tsk))
+		pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns);
+	rcu_read_unlock();
+
+	return pid;
+}
+
+static inline pid_t task_ppid_nr(const struct task_struct *tsk)
+{
+	return task_ppid_nr_ns(tsk, &init_pid_ns);
+}
+
 static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk,
 					struct pid_namespace *ns)
 {
@@ -1539,7 +1568,7 @@
  *
  * Return: 1 if the process is alive. 0 otherwise.
  */
-static inline int pid_alive(struct task_struct *p)
+static inline int pid_alive(const struct task_struct *p)
 {
 	return p->pids[PIDTYPE_PID].pid != NULL;
 }
@@ -2162,6 +2191,16 @@
 #define while_each_thread(g, t) \
 	while ((t = next_thread(t)) != g)
 
+#define __for_each_thread(signal, t)	\
+	list_for_each_entry_rcu(t, &(signal)->thread_head, thread_node)
+
+#define for_each_thread(p, t)		\
+	__for_each_thread((p)->signal, t)
+
+/* Careful: this is a double loop, 'break' won't work as expected. */
+#define for_each_process_thread(p, t)	\
+	for_each_process(p) for_each_thread(p, t)
+
 static inline int get_nr_threads(struct task_struct *tsk)
 {
 	return tsk->signal->nr_threads;
diff -ruw linux-3.11.10/include/linux/seccomp.h linux-3.11.10-fbx/include/linux/seccomp.h
--- linux-3.11.10/include/linux/seccomp.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/seccomp.h	2013-12-04 14:33:24.999479069 +0100
@@ -6,6 +6,7 @@
 #ifdef CONFIG_SECCOMP
 
 #include <linux/thread_info.h>
+#include <linux/filter.h>
 #include <asm/seccomp.h>
 
 struct seccomp_filter;
@@ -47,6 +48,44 @@
 	return s->mode;
 }
 
+/**
+ * struct seccomp_filter - container for seccomp BPF programs
+ *
+ * @usage: reference count to manage the object lifetime.
+ *         get/put helpers should be used when accessing an instance
+ *         outside of a lifetime-guarded section.  In general, this
+ *         is only needed for handling filters shared across tasks.
+ * @prev: points to a previously installed, or inherited, filter
+ * @len: the number of instructions in the program
+ * @insns: the BPF program instructions to evaluate
+ *
+ * seccomp_filter objects are organized in a tree linked via the @prev
+ * pointer.  For any task, it appears to be a singly-linked list starting
+ * with current->seccomp.filter, the most recently attached or inherited filter.
+ * However, multiple filters may share a @prev node, by way of fork(), which
+ * results in a unidirectional tree existing in memory.  This is similar to
+ * how namespaces work.
+ *
+ * seccomp_filter objects should never be modified after being attached
+ * to a task_struct (other than @usage).
+ */
+struct seccomp_filter {
+	atomic_t usage;
+	struct seccomp_filter *prev;
+	unsigned short len;  /* Instruction count */
+	unsigned int (*bpf_func)(const struct sk_buff *skb,
+				 const struct sock_filter *filter);
+	struct sock_filter insns[];
+};
+
+#ifdef CONFIG_SECCOMP_FILTER_JIT
+extern void seccomp_jit_compile(struct seccomp_filter *fp);
+extern void seccomp_jit_free(struct seccomp_filter *fp);
+#else
+static inline void seccomp_jit_compile(struct seccomp_filter *fp) { }
+static inline void seccomp_jit_free(struct seccomp_filter *fp) { }
+#endif
+
 #else /* CONFIG_SECCOMP */
 
 #include <linux/errno.h>
diff -ruw linux-3.11.10/include/linux/skbuff.h linux-3.11.10-fbx/include/linux/skbuff.h
--- linux-3.11.10/include/linux/skbuff.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/skbuff.h	2014-07-01 16:22:13.182329834 +0200
@@ -333,10 +333,12 @@
 typedef unsigned char *sk_buff_data_t;
 #endif
 
-#if defined(CONFIG_NF_DEFRAG_IPV4) || defined(CONFIG_NF_DEFRAG_IPV4_MODULE) || \
-    defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE)
-#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
@@ -370,7 +372,6 @@
  *	@protocol: Packet protocol from driver
  *	@destructor: Destruct function
  *	@nfct: Associated connection, if any
- *	@nfct_reasm: netfilter conntrack re-assembly pointer
  *	@nf_bridge: Saved data about a bridged frame - see br_netfilter.c
  *	@skb_iif: ifindex of device we arrived on
  *	@tc_index: Traffic control index
@@ -459,13 +460,18 @@
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 	struct nf_conntrack	*nfct;
 #endif
-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-	struct sk_buff		*nfct_reasm;
+#ifdef CONFIG_IP_FFN
+	int			ffn_state;
+	int			ffn_orig_tos;
 #endif
 #ifdef CONFIG_BRIDGE_NETFILTER
 	struct nf_bridge_info	*nf_bridge;
 #endif
 
+#ifdef CONFIG_FBXBRIDGE
+	int			fbxbridge_state;
+#endif
+
 	int			skb_iif;
 
 	__u32			rxhash;
@@ -480,6 +486,10 @@
 #endif
 #endif
 
+#ifdef CONFIG_NETRXTHREAD
+	int			rxthread_prio;
+#endif
+
 	__u16			queue_mapping;
 	kmemcheck_bitfield_begin(flags2);
 #ifdef CONFIG_IPV6_NDISC_NODETYPE
@@ -1652,6 +1662,11 @@
 	skb->mac_header += offset;
 }
 
+static inline void skb_pop_mac_header(struct sk_buff *skb)
+{
+	skb->mac_header = skb->network_header;
+}
+
 static inline void skb_probe_transport_header(struct sk_buff *skb,
 					      const int offset_hint)
 {
@@ -1754,6 +1769,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
@@ -2395,6 +2414,8 @@
 extern struct sk_buff *skb_segment(struct sk_buff *skb,
 				   netdev_features_t features);
 
+unsigned int skb_gso_transport_seglen(const struct sk_buff *skb);
+
 static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
 				       int len, void *buffer)
 {
@@ -2603,18 +2624,6 @@
 		atomic_inc(&nfct->use);
 }
 #endif
-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-static inline void nf_conntrack_get_reasm(struct sk_buff *skb)
-{
-	if (skb)
-		atomic_inc(&skb->users);
-}
-static inline void nf_conntrack_put_reasm(struct sk_buff *skb)
-{
-	if (skb)
-		kfree_skb(skb);
-}
-#endif
 #ifdef CONFIG_BRIDGE_NETFILTER
 static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
 {
@@ -2633,10 +2642,6 @@
 	nf_conntrack_put(skb->nfct);
 	skb->nfct = NULL;
 #endif
-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-	nf_conntrack_put_reasm(skb->nfct_reasm);
-	skb->nfct_reasm = NULL;
-#endif
 #ifdef CONFIG_BRIDGE_NETFILTER
 	nf_bridge_put(skb->nf_bridge);
 	skb->nf_bridge = NULL;
@@ -2658,10 +2663,6 @@
 	nf_conntrack_get(src->nfct);
 	dst->nfctinfo = src->nfctinfo;
 #endif
-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-	dst->nfct_reasm = src->nfct_reasm;
-	nf_conntrack_get_reasm(src->nfct_reasm);
-#endif
 #ifdef CONFIG_BRIDGE_NETFILTER
 	dst->nf_bridge  = src->nf_bridge;
 	nf_bridge_get(src->nf_bridge);
@@ -2673,9 +2674,6 @@
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 	nf_conntrack_put(dst->nfct);
 #endif
-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-	nf_conntrack_put_reasm(dst->nfct_reasm);
-#endif
 #ifdef CONFIG_BRIDGE_NETFILTER
 	nf_bridge_put(dst->nf_bridge);
 #endif
@@ -2841,5 +2839,22 @@
 {
 	return !skb->head_frag || skb_cloned(skb);
 }
+
+/**
+ * skb_gso_network_seglen - Return length of individual segments of a gso packet
+ *
+ * @skb: GSO skb
+ *
+ * skb_gso_network_seglen is used to determine the real size of the
+ * individual segments, including Layer3 (IP, IPv6) and L4 headers (TCP/UDP).
+ *
+ * The MAC/L2 header is not accounted for.
+ */
+static inline unsigned int skb_gso_network_seglen(const struct sk_buff *skb)
+{
+	unsigned int hdr_len = skb_transport_header(skb) -
+			       skb_network_header(skb);
+	return hdr_len + skb_gso_transport_seglen(skb);
+}
 #endif	/* __KERNEL__ */
 #endif	/* _LINUX_SKBUFF_H */
diff -ruw linux-3.11.10/include/linux/sock_diag.h linux-3.11.10-fbx/include/linux/sock_diag.h
--- linux-3.11.10/include/linux/sock_diag.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/sock_diag.h	2014-08-22 15:47:22.140063166 +0200
@@ -23,7 +23,7 @@
 void sock_diag_save_cookie(void *sk, __u32 *cookie);
 
 int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr);
-int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
+int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk,
 			     struct sk_buff *skb, int attrtype);
 
 #endif
diff -ruw linux-3.11.10/include/linux/sunrpc/svcsock.h linux-3.11.10-fbx/include/linux/sunrpc/svcsock.h
--- linux-3.11.10/include/linux/sunrpc/svcsock.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/sunrpc/svcsock.h	2014-07-01 16:22:13.182329834 +0200
@@ -56,6 +56,7 @@
 int		svc_send(struct svc_rqst *);
 void		svc_drop(struct svc_rqst *);
 void		svc_sock_update_bufs(struct svc_serv *serv);
+bool		svc_alien_sock(struct net *net, int fd);
 int		svc_addsock(struct svc_serv *serv, const int fd,
 					char *name_return, const size_t len);
 void		svc_init_xprt_sock(void);
diff -ruw linux-3.11.10/include/linux/tracepoint.h linux-3.11.10-fbx/include/linux/tracepoint.h
--- linux-3.11.10/include/linux/tracepoint.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/tracepoint.h	2014-07-01 16:22:13.182329834 +0200
@@ -60,6 +60,12 @@
 	unsigned int num_tracepoints;
 	struct tracepoint * const *tracepoints_ptrs;
 };
+bool trace_module_has_bad_taint(struct module *mod);
+#else
+static inline bool trace_module_has_bad_taint(struct module *mod)
+{
+	return false;
+}
 #endif /* CONFIG_MODULES */
 
 struct tracepoint_iter {
diff -ruw linux-3.11.10/include/linux/usb.h linux-3.11.10-fbx/include/linux/usb.h
--- linux-3.11.10/include/linux/usb.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/usb.h	2014-01-17 19:14:18.774220809 +0100
@@ -474,7 +474,8 @@
  * @lpm_capable: device supports LPM
  * @usb2_hw_lpm_capable: device can perform USB2 hardware LPM
  * @usb2_hw_lpm_besl_capable: device can perform USB2 hardware BESL LPM
- * @usb2_hw_lpm_enabled: USB2 hardware LPM enabled
+ * @usb2_hw_lpm_enabled: USB2 hardware LPM is enabled
+ * @usb2_hw_lpm_allowed: Userspace allows USB 2.0 LPM to be enabled
  * @usb3_lpm_enabled: USB3 hardware LPM enabled
  * @string_langid: language ID for strings
  * @product: iProduct string, if present (static)
@@ -547,6 +548,7 @@
 	unsigned usb2_hw_lpm_capable:1;
 	unsigned usb2_hw_lpm_besl_capable:1;
 	unsigned usb2_hw_lpm_enabled:1;
+	unsigned usb2_hw_lpm_allowed:1;
 	unsigned usb3_lpm_enabled:1;
 	int string_langid;
 
diff -ruw linux-3.11.10/include/linux/vm_event_item.h linux-3.11.10-fbx/include/linux/vm_event_item.h
--- linux-3.11.10/include/linux/vm_event_item.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/linux/vm_event_item.h	2014-01-17 19:14:18.774220809 +0100
@@ -39,6 +39,7 @@
 		PAGEOUTRUN, ALLOCSTALL, PGROTATED,
 #ifdef CONFIG_NUMA_BALANCING
 		NUMA_PTE_UPDATES,
+		NUMA_HUGE_PTE_UPDATES,
 		NUMA_HINT_FAULTS,
 		NUMA_HINT_FAULTS_LOCAL,
 		NUMA_PAGE_MIGRATE,
diff -ruw linux-3.11.10/include/net/inetpeer.h linux-3.11.10-fbx/include/net/inetpeer.h
--- linux-3.11.10/include/net/inetpeer.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/net/inetpeer.h	2014-08-22 15:47:22.140063166 +0200
@@ -178,16 +178,9 @@
 /* can be called with or without local BH being disabled */
 static inline int inet_getid(struct inet_peer *p, int more)
 {
-	int old, new;
 	more++;
 	inet_peer_refcheck(p);
-	do {
-		old = atomic_read(&p->ip_id_count);
-		new = old + more;
-		if (!new)
-			new = 1;
-	} while (atomic_cmpxchg(&p->ip_id_count, old, new) != old);
-	return new;
+	return atomic_add_return(more, &p->ip_id_count) - more;
 }
 
 #endif /* _NET_INETPEER_H */
diff -ruw linux-3.11.10/include/net/ip6_route.h linux-3.11.10-fbx/include/net/ip6_route.h
--- linux-3.11.10/include/net/ip6_route.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/net/ip6_route.h	2014-07-01 16:22:13.182329834 +0200
@@ -32,6 +32,11 @@
 #define RT6_LOOKUP_F_SRCPREF_PUBLIC	0x00000010
 #define RT6_LOOKUP_F_SRCPREF_COA	0x00000020
 
+/* We do not (yet ?) support IPv6 jumbograms (RFC 2675)
+ * Unlike IPv4, hdr->seg_len doesn't include the IPv6 header
+ */
+#define IP6_MAX_MTU (0xFFFF + sizeof(struct ipv6hdr))
+
 /*
  * rt6_srcprefs2flags() and rt6_flags2srcprefs() translate
  * between IPV6_ADDR_PREFERENCES socket option values
diff -ruw linux-3.11.10/include/net/ip.h linux-3.11.10-fbx/include/net/ip.h
--- linux-3.11.10/include/net/ip.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/net/ip.h	2014-01-17 19:14:18.774220809 +0100
@@ -415,6 +415,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
  */
  
@@ -454,7 +468,7 @@
 			int optname, char __user *optval, int __user *optlen);
 extern int	ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *));
 
-extern int 	ip_recv_error(struct sock *sk, struct msghdr *msg, int len);
+extern int 	ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len);
 extern void	ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 
 			      __be16 port, u32 info, u8 *payload);
 extern void	ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
diff -ruw linux-3.11.10/include/net/ipv6.h linux-3.11.10-fbx/include/net/ipv6.h
--- linux-3.11.10/include/net/ipv6.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/net/ipv6.h	2014-01-17 19:14:18.778220809 +0100
@@ -799,8 +799,10 @@
 extern int			ip6_datagram_connect(struct sock *sk, 
 						     struct sockaddr *addr, int addr_len);
 
-extern int 			ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len);
-extern int 			ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len);
+extern int 			ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
+						int *addr_len);
+extern int 			ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
+						 int *addr_len);
 extern void			ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
 						u32 info, u8 *payload);
 extern void			ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
diff -ruw linux-3.11.10/include/net/netfilter/ipv6/nf_defrag_ipv6.h linux-3.11.10-fbx/include/net/netfilter/ipv6/nf_defrag_ipv6.h
--- linux-3.11.10/include/net/netfilter/ipv6/nf_defrag_ipv6.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/net/netfilter/ipv6/nf_defrag_ipv6.h	2014-01-17 19:14:18.778220809 +0100
@@ -6,10 +6,7 @@
 extern int nf_ct_frag6_init(void);
 extern void nf_ct_frag6_cleanup(void);
 extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user);
-extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
-			       struct net_device *in,
-			       struct net_device *out,
-			       int (*okfn)(struct sk_buff *));
+extern void nf_ct_frag6_consume_orig(struct sk_buff *skb);
 
 struct inet_frags_ctl;
 
diff -ruw linux-3.11.10/include/net/netfilter/nf_conntrack_extend.h linux-3.11.10-fbx/include/net/netfilter/nf_conntrack_extend.h
--- linux-3.11.10/include/net/netfilter/nf_conntrack_extend.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/net/netfilter/nf_conntrack_extend.h	2014-07-01 16:22:13.182329834 +0200
@@ -41,8 +41,8 @@
 /* Extensions: optional stuff which isn't permanently in struct. */
 struct nf_ct_ext {
 	struct rcu_head rcu;
-	u8 offset[NF_CT_EXT_NUM];
-	u8 len;
+	u16 offset[NF_CT_EXT_NUM];
+	u16 len;
 	char data[0];
 };
 
@@ -80,7 +80,7 @@
 static inline void nf_ct_ext_free(struct nf_conn *ct)
 {
 	if (ct->ext)
-		kfree(ct->ext);
+		kfree_rcu(ct->ext, rcu);
 }
 
 /* Add this type, returns pointer to data or NULL. */
diff -ruw linux-3.11.10/include/net/ping.h linux-3.11.10-fbx/include/net/ping.h
--- linux-3.11.10/include/net/ping.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/net/ping.h	2014-01-17 19:14:18.778220809 +0100
@@ -31,7 +31,8 @@
 
 /* Compatibility glue so we can support IPv6 when it's compiled as a module */
 struct pingv6_ops {
-	int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len);
+	int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len,
+			       int *addr_len);
 	int (*ip6_datagram_recv_ctl)(struct sock *sk, struct msghdr *msg,
 				     struct sk_buff *skb);
 	int (*icmpv6_err_convert)(u8 type, u8 code, int *err);
diff -ruw linux-3.11.10/include/net/sock.h linux-3.11.10-fbx/include/net/sock.h
--- linux-3.11.10/include/net/sock.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/net/sock.h	2014-08-22 15:47:22.140063166 +0200
@@ -182,6 +182,7 @@
 	volatile unsigned char	skc_state;
 	unsigned char		skc_reuse:4;
 	unsigned char		skc_reuseport:4;
+	unsigned char		skc_reuse_conflict;
 	int			skc_bound_dev_if;
 	union {
 		struct hlist_node	skc_bind_node;
@@ -303,6 +304,7 @@
 #define sk_state		__sk_common.skc_state
 #define sk_reuse		__sk_common.skc_reuse
 #define sk_reuseport		__sk_common.skc_reuseport
+#define sk_reuse_conflict	__sk_common.skc_reuse_conflict
 #define sk_bound_dev_if		__sk_common.skc_bound_dev_if
 #define sk_bind_node		__sk_common.skc_bind_node
 #define sk_prot			__sk_common.skc_prot
@@ -676,6 +678,7 @@
 		     */
 	SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */
 	SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
+	SOCK_UDP_DUP_UNICAST,
 };
 
 static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
@@ -1443,6 +1446,11 @@
  */
 #define sock_owned_by_user(sk)	((sk)->sk_lock.owned)
 
+static inline void sock_release_ownership(struct sock *sk)
+{
+	sk->sk_lock.owned = 0;
+}
+
 /*
  * Macro so as to not evaluate some arguments when
  * lockdep is not enabled.
@@ -2252,6 +2260,11 @@
 extern int sock_get_timestamp(struct sock *, struct timeval __user *);
 extern int sock_get_timestampns(struct sock *, struct timespec __user *);
 
+bool sk_ns_capable(const struct sock *sk,
+		   struct user_namespace *user_ns, int cap);
+bool sk_capable(const struct sock *sk, int cap);
+bool sk_net_capable(const struct sock *sk, int cap);
+
 /*
  *	Enable debug/info messages
  */
diff -ruw linux-3.11.10/include/net/tcp.h linux-3.11.10-fbx/include/net/tcp.h
--- linux-3.11.10/include/net/tcp.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/net/tcp.h	2014-07-01 16:22:13.182329834 +0200
@@ -1308,7 +1308,8 @@
 	/* Fast Open cookie. Size 0 means a cookie request */
 	struct tcp_fastopen_cookie	cookie;
 	struct msghdr			*data;  /* data in MSG_FASTOPEN */
-	u16				copied;	/* queued in tcp_connect() */
+	size_t				size;
+	int				copied;	/* queued in tcp_connect() */
 };
 void tcp_free_fastopen_req(struct tcp_sock *tp);
 
diff -ruw linux-3.11.10/include/scsi/scsi_device.h linux-3.11.10-fbx/include/scsi/scsi_device.h
--- linux-3.11.10/include/scsi/scsi_device.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/scsi/scsi_device.h	2014-07-01 16:22:13.182329834 +0200
@@ -249,7 +249,7 @@
 	struct list_head	siblings;
 	struct list_head	devices;
 	struct device		dev;
-	unsigned int		reap_ref; /* protected by the host lock */
+	struct kref		reap_ref; /* last put renders target invisible */
 	unsigned int		channel;
 	unsigned int		id; /* target id ... replace
 				     * scsi_device.id eventually */
@@ -273,7 +273,6 @@
 #define SCSI_DEFAULT_TARGET_BLOCKED	3
 
 	char			scsi_level;
-	struct execute_work	ew;
 	enum scsi_target_state	state;
 	void 			*hostdata; /* available to low-level driver */
 	unsigned long		starget_data[0]; /* for the transport */
diff -ruw linux-3.11.10/include/scsi/scsi_host.h linux-3.11.10-fbx/include/scsi/scsi_host.h
--- linux-3.11.10/include/scsi/scsi_host.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/scsi/scsi_host.h	2014-01-17 19:14:18.778220809 +0100
@@ -475,6 +475,9 @@
 	 */
 	unsigned ordered_tag:1;
 
+	/* True if the controller does not support WRITE SAME */
+	unsigned no_write_same:1;
+
 	/*
 	 * Countdown for host blocking with no commands outstanding.
 	 */
@@ -674,6 +677,9 @@
 	/* Don't resume host in EH */
 	unsigned eh_noresume:1;
 
+	/* The controller does not support WRITE SAME */
+	unsigned no_write_same:1;
+
 	/*
 	 * Optional work queue to be utilized by the transport
 	 */
diff -ruw linux-3.11.10/include/sound/core.h linux-3.11.10-fbx/include/sound/core.h
--- linux-3.11.10/include/sound/core.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/sound/core.h	2014-08-22 15:47:22.140063166 +0200
@@ -120,6 +120,8 @@
 	int user_ctl_count;		/* count of all user controls */
 	struct list_head controls;	/* all controls for this card */
 	struct list_head ctl_files;	/* active control files */
+	struct mutex user_ctl_lock;	/* protects user controls against
+					   concurrent access */
 
 	struct snd_info_entry *proc_root;	/* root for soundcard specific files */
 	struct snd_info_entry *proc_id;	/* the card id */
diff -ruw linux-3.11.10/include/sound/memalloc.h linux-3.11.10-fbx/include/sound/memalloc.h
--- linux-3.11.10/include/sound/memalloc.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/sound/memalloc.h	2014-01-17 19:14:18.778220809 +0100
@@ -103,7 +103,7 @@
 {
 	struct snd_sg_buf *sgbuf = dmab->private_data;
 	dma_addr_t addr = sgbuf->table[offset >> PAGE_SHIFT].addr;
-	addr &= PAGE_MASK;
+	addr &= ~((dma_addr_t)PAGE_SIZE - 1);
 	return addr + offset % PAGE_SIZE;
 }
 
diff -ruw linux-3.11.10/include/trace/events/block.h linux-3.11.10-fbx/include/trace/events/block.h
--- linux-3.11.10/include/trace/events/block.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/trace/events/block.h	2014-07-01 16:22:13.182329834 +0200
@@ -132,6 +132,7 @@
  * block_rq_complete - block IO operation completed by device driver
  * @q: queue containing the block operation request
  * @rq: block operations request
+ * @nr_bytes: number of completed bytes
  *
  * The block_rq_complete tracepoint event indicates that some portion
  * of operation request has been completed by the device driver.  If
@@ -139,11 +140,37 @@
  * do for the request. If @rq->bio is non-NULL then there is
  * additional work required to complete the request.
  */
-DEFINE_EVENT(block_rq_with_error, block_rq_complete,
+TRACE_EVENT(block_rq_complete,
 
-	TP_PROTO(struct request_queue *q, struct request *rq),
+	TP_PROTO(struct request_queue *q, struct request *rq,
+		 unsigned int nr_bytes),
 
-	TP_ARGS(q, rq)
+	TP_ARGS(q, rq, nr_bytes),
+
+	TP_STRUCT__entry(
+		__field(  dev_t,	dev			)
+		__field(  sector_t,	sector			)
+		__field(  unsigned int,	nr_sector		)
+		__field(  int,		errors			)
+		__array(  char,		rwbs,	RWBS_LEN	)
+		__dynamic_array( char,	cmd,	blk_cmd_buf_len(rq)	)
+	),
+
+	TP_fast_assign(
+		__entry->dev	   = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
+		__entry->sector    = blk_rq_pos(rq);
+		__entry->nr_sector = nr_bytes >> 9;
+		__entry->errors    = rq->errors;
+
+		blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, nr_bytes);
+		blk_dump_cmd(__get_str(cmd), rq);
+	),
+
+	TP_printk("%d,%d %s (%s) %llu + %u [%d]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __entry->rwbs, __get_str(cmd),
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->errors)
 );
 
 DECLARE_EVENT_CLASS(block_rq,
diff -ruw linux-3.11.10/include/trace/events/module.h linux-3.11.10-fbx/include/trace/events/module.h
--- linux-3.11.10/include/trace/events/module.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/trace/events/module.h	2014-07-01 16:22:13.182329834 +0200
@@ -78,7 +78,7 @@
 
 	TP_fast_assign(
 		__entry->ip	= ip;
-		__entry->refcnt	= __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs);
+		__entry->refcnt	= __this_cpu_read(mod->refptr->incs) - __this_cpu_read(mod->refptr->decs);
 		__assign_str(name, mod->name);
 	),
 
diff -ruw linux-3.11.10/include/trace/syscall.h linux-3.11.10-fbx/include/trace/syscall.h
--- linux-3.11.10/include/trace/syscall.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/trace/syscall.h	2014-08-22 15:47:22.140063166 +0200
@@ -4,6 +4,7 @@
 #include <linux/tracepoint.h>
 #include <linux/unistd.h>
 #include <linux/ftrace_event.h>
+#include <linux/thread_info.h>
 
 #include <asm/ptrace.h>
 
@@ -32,4 +33,18 @@
 	struct ftrace_event_call *exit_event;
 };
 
+#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_HAVE_SYSCALL_TRACEPOINTS)
+static inline void syscall_tracepoint_update(struct task_struct *p)
+{
+	if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+		set_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
+	else
+		clear_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
+}
+#else
+static inline void syscall_tracepoint_update(struct task_struct *p)
+{
+}
+#endif
+
 #endif /* _TRACE_SYSCALL_H */
diff -ruw linux-3.11.10/include/uapi/asm-generic/socket.h linux-3.11.10-fbx/include/uapi/asm-generic/socket.h
--- linux-3.11.10/include/uapi/asm-generic/socket.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/asm-generic/socket.h	2013-12-04 14:33:25.323479075 +0100
@@ -78,4 +78,6 @@
 
 #define SO_BUSY_POLL		46
 
+#define SO_UDP_DUP_UNICAST	47
+
 #endif /* __ASM_GENERIC_SOCKET_H */
diff -ruw linux-3.11.10/include/uapi/drm/tegra_drm.h linux-3.11.10-fbx/include/uapi/drm/tegra_drm.h
--- linux-3.11.10/include/uapi/drm/tegra_drm.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/drm/tegra_drm.h	2014-07-01 16:22:13.182329834 +0200
@@ -105,7 +105,6 @@
 	__u32 num_waitchks;
 	__u32 waitchk_mask;
 	__u32 timeout;
-	__u32 pad;
 	__u64 syncpts;
 	__u64 cmdbufs;
 	__u64 relocs;
diff -ruw linux-3.11.10/include/uapi/linux/Kbuild linux-3.11.10-fbx/include/uapi/linux/Kbuild
--- linux-3.11.10/include/uapi/linux/Kbuild	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/linux/Kbuild	2013-12-04 14:33:25.323479075 +0100
@@ -110,11 +110,16 @@
 header-y += errqueue.h
 header-y += ethtool.h
 header-y += eventpoll.h
+header-y += exfat_user.h
 header-y += fadvise.h
 header-y += falloc.h
 header-y += fanotify.h
 header-y += fb.h
 header-y += fcntl.h
+header-y += fbxatm.h
+header-y += fbxjtag.h
+header-y += fbxbridge.h
+header-y += fbxmtd_map_ioctl.h
 header-y += fd.h
 header-y += fdreg.h
 header-y += fib_rules.h
@@ -422,3 +427,5 @@
 header-y += xattr.h
 header-y += xfrm.h
 header-y += hw_breakpoint.h
+header-y += remoti/
+header-y += hdmi-cec/
diff -ruw linux-3.11.10/include/uapi/linux/major.h linux-3.11.10-fbx/include/uapi/linux/major.h
--- linux-3.11.10/include/uapi/linux/major.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/linux/major.h	2013-12-04 14:33:25.375479075 +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.11.10/include/uapi/linux/netlink.h linux-3.11.10-fbx/include/uapi/linux/netlink.h
--- linux-3.11.10/include/uapi/linux/netlink.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/linux/netlink.h	2013-12-04 14:33:25.383479075 +0100
@@ -1,7 +1,7 @@
 #ifndef _UAPI__LINUX_NETLINK_H
 #define _UAPI__LINUX_NETLINK_H
 
-#include <linux/kernel.h>
+//#include <linux/kernel.h>
 #include <linux/socket.h> /* for __kernel_sa_family_t */
 #include <linux/types.h>
 
diff -ruw linux-3.11.10/include/uapi/linux/nl80211.h linux-3.11.10-fbx/include/uapi/linux/nl80211.h
--- linux-3.11.10/include/uapi/linux/nl80211.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/linux/nl80211.h	2014-05-09 14:12:54.340546160 +0200
@@ -126,6 +126,31 @@
  */
 
 /**
+ * DOC: packet coalesce support
+ *
+ * In most cases, host that receives IPv4 and IPv6 multicast/broadcast
+ * packets does not do anything with these packets. Therefore the
+ * reception of these unwanted packets causes unnecessary processing
+ * and power consumption.
+ *
+ * Packet coalesce feature helps to reduce number of received interrupts
+ * to host by buffering these packets in firmware/hardware for some
+ * predefined time. Received interrupt will be generated when one of the
+ * following events occur.
+ * a) Expiration of hardware timer whose expiration time is set to maximum
+ * coalescing delay of matching coalesce rule.
+ * b) Coalescing buffer in hardware reaches it's limit.
+ * c) Packet doesn't match any of the configured coalesce rules.
+ *
+ * User needs to configure following parameters for creating a coalesce
+ * rule.
+ * a) Maximum coalescing delay
+ * b) List of packet patterns which needs to be matched
+ * c) Condition for coalescence. pattern 'match' or 'no match'
+ * Multiple such rules can be created.
+ */
+
+/**
  * enum nl80211_commands - supported nl80211 commands
  *
  * @NL80211_CMD_UNSPEC: unspecified command to catch errors
@@ -393,8 +418,18 @@
  *	%NL80211_ATTR_SSID attribute, and can optionally specify the association
  *	IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP,
  *	%NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
- *	%NL80211_ATTR_CONTROL_PORT_ETHERTYPE and
- *	%NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT.
+ *	%NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
+ *	%NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, %NL80211_ATTR_MAC_HINT, and
+ *	%NL80211_ATTR_WIPHY_FREQ_HINT.
+ *	If included, %NL80211_ATTR_MAC and %NL80211_ATTR_WIPHY_FREQ are
+ *	restrictions on BSS selection, i.e., they effectively prevent roaming
+ *	within the ESS. %NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT
+ *	can be included to provide a recommendation of the initial BSS while
+ *	allowing the driver to roam to other BSSes within the ESS and also to
+ *	ignore this recommendation if the indicated BSS is not ideal. Only one
+ *	set of BSSID,frequency parameters is used (i.e., either the enforcing
+ *	%NL80211_ATTR_MAC,%NL80211_ATTR_WIPHY_FREQ or the less strict
+ *	%NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT).
  *	Background scan period can optionally be
  *	specified in %NL80211_ATTR_BG_SCAN_PERIOD,
  *	if not specified default background scan configuration
@@ -556,7 +591,14 @@
  *	operation, %NL80211_ATTR_MAC contains the peer MAC address, and
  *	%NL80211_ATTR_REASON_CODE the reason code to be used (only with
  *	%NL80211_TDLS_TEARDOWN).
- * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame.
+ * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. The
+ *	%NL80211_ATTR_TDLS_ACTION attribute determines the type of frame to be
+ *	sent. Public Action codes (802.11-2012 8.1.5.1) will be sent as
+ *	802.11 management frames, while TDLS action codes (802.11-2012
+ *	8.5.13.1) will be encapsulated and sent as data frames. The currently
+ *	supported Public Action code is %WLAN_PUB_ACTION_TDLS_DISCOVER_RES
+ *	and the currently supported TDLS actions codes are given in
+ *	&enum ieee80211_tdls_actioncode.
  *
  * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
  *	(or GO) interface (i.e. hostapd) to ask for unexpected frames to
@@ -648,6 +690,34 @@
  * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can
  *	return back to normal.
  *
+ * @NL80211_CMD_GET_COALESCE: Get currently supported coalesce rules.
+ * @NL80211_CMD_SET_COALESCE: Configure coalesce rules or clear existing rules.
+ *
+ * @NL80211_CMD_CHANNEL_SWITCH: Perform a channel switch by announcing the
+ *	the new channel information (Channel Switch Announcement - CSA)
+ *	in the beacon for some time (as defined in the
+ *	%NL80211_ATTR_CH_SWITCH_COUNT parameter) and then change to the
+ *	new channel. Userspace provides the new channel information (using
+ *	%NL80211_ATTR_WIPHY_FREQ and the attributes determining channel
+ *	width). %NL80211_ATTR_CH_SWITCH_BLOCK_TX may be supplied to inform
+ *	other station that transmission must be blocked until the channel
+ *	switch is complete.
+ *
+ * @NL80211_CMD_VENDOR: Vendor-specified command/event. The command is specified
+ *	by the %NL80211_ATTR_VENDOR_ID attribute and a sub-command in
+ *	%NL80211_ATTR_VENDOR_SUBCMD. Parameter(s) can be transported in
+ *	%NL80211_ATTR_VENDOR_DATA.
+ *	For feature advertisement, the %NL80211_ATTR_VENDOR_DATA attribute is
+ *	used in the wiphy data as a nested attribute containing descriptions
+ *	(&struct nl80211_vendor_cmd_info) of the supported vendor commands.
+ *	This may also be sent as an event with the same attributes.
+ *
+ * @NL80211_CMD_SET_QOS_MAP: Set Interworking QoS mapping for IP DSCP values.
+ *	The QoS mapping information is included in %NL80211_ATTR_QOS_MAP. If
+ *	that attribute is not included, QoS mapping is disabled. Since this
+ *	QoS mapping is relevant for IP packets, it is only valid during an
+ *	association. This is cleared on disassociation and AP restart.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -810,6 +880,15 @@
 	NL80211_CMD_CRIT_PROTOCOL_START,
 	NL80211_CMD_CRIT_PROTOCOL_STOP,
 
+	NL80211_CMD_GET_COALESCE,
+	NL80211_CMD_SET_COALESCE,
+
+	NL80211_CMD_CHANNEL_SWITCH,
+
+	NL80211_CMD_VENDOR,
+
+	NL80211_CMD_SET_QOS_MAP,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -945,7 +1024,7 @@
  * 	to query the CRDA to retrieve one regulatory domain. This attribute can
  * 	also be used by userspace to query the kernel for the currently set
  * 	regulatory domain. We chose an alpha2 as that is also used by the
- * 	IEEE-802.11d country information element to identify a country.
+ * 	IEEE-802.11 country information element to identify a country.
  * 	Users can also simply ask the wireless core to set regulatory domain
  * 	to a specific alpha2.
  * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory
@@ -1436,6 +1515,70 @@
  *	allowed to be used with the first @NL80211_CMD_SET_STATION command to
  *	update a TDLS peer STA entry.
  *
+ * @NL80211_ATTR_COALESCE_RULE: Coalesce rule information.
+ *
+ * @NL80211_ATTR_CH_SWITCH_COUNT: u32 attribute specifying the number of TBTT's
+ *	until the channel switch event.
+ * @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission
+ *	must be blocked on the current channel (before the channel switch
+ *	operation).
+ * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
+ *	for the time while performing a channel switch.
+ * @NL80211_ATTR_CSA_C_OFF_BEACON: Offset of the channel switch counter
+ *	field in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
+ * @NL80211_ATTR_CSA_C_OFF_PRESP: Offset of the channel switch counter
+ *	field in the probe response (%NL80211_ATTR_PROBE_RESP).
+ *
+ * @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32.
+ *	As specified in the &enum nl80211_rxmgmt_flags.
+ *
+ * @NL80211_ATTR_STA_SUPPORTED_CHANNELS: array of supported channels.
+ *
+ * @NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES: array of supported
+ *      supported operating classes.
+ *
+ * @NL80211_ATTR_HANDLE_DFS: A flag indicating whether user space
+ *	controls DFS operation in IBSS mode. If the flag is included in
+ *	%NL80211_CMD_JOIN_IBSS request, the driver will allow use of DFS
+ *	channels and reports radar events to userspace. Userspace is required
+ *	to react to radar events, e.g. initiate a channel switch or leave the
+ *	IBSS network.
+ *
+ * @NL80211_ATTR_SUPPORT_5_MHZ: A flag indicating that the device supports
+ *	5 MHz channel bandwidth.
+ * @NL80211_ATTR_SUPPORT_10_MHZ: A flag indicating that the device supports
+ *	10 MHz channel bandwidth.
+ *
+ * @NL80211_ATTR_OPMODE_NOTIF: Operating mode field from Operating Mode
+ *	Notification Element based on association request when used with
+ *	%NL80211_CMD_NEW_STATION; u8 attribute.
+ *
+ * @NL80211_ATTR_VENDOR_ID: The vendor ID, either a 24-bit OUI or, if
+ *	%NL80211_VENDOR_ID_IS_LINUX is set, a special Linux ID (not used yet)
+ * @NL80211_ATTR_VENDOR_SUBCMD: vendor sub-command
+ * @NL80211_ATTR_VENDOR_DATA: data for the vendor command, if any; this
+ *	attribute is also used for vendor command feature advertisement
+ * @NL80211_ATTR_VENDOR_EVENTS: used for event list advertising in the wiphy
+ *	info, containing a nested array of possible events
+ *
+ * @NL80211_ATTR_QOS_MAP: IP DSCP mapping for Interworking QoS mapping. This
+ *	data is in the format defined for the payload of the QoS Map Set element
+ *	in IEEE Std 802.11-2012, 8.4.2.97.
+ *
+ * @NL80211_ATTR_MAC_HINT: MAC address recommendation as initial BSS
+ * @NL80211_ATTR_WIPHY_FREQ_HINT: frequency of the recommended initial BSS
+ *
+ * @NL80211_ATTR_MAX_AP_ASSOC_STA: Device attribute that indicates how many
+ *	associated stations are supported in AP mode (including P2P GO); u32.
+ *	Since drivers may not have a fixed limit on the maximum number (e.g.,
+ *	other concurrent operations may affect this), drivers are allowed to
+ *	advertise values that cannot always be met. In such cases, an attempt
+ *	to add a new station entry with @NL80211_CMD_NEW_STATION may fail.
+ *
+ * @NL80211_ATTR_CH_SWITCH_IFACES: Nested attribute with channel switch
+ *	settings in each entry (ifindex, frequency, beacon IEs). Also used as a
+ *	device capability flag in nl80211_send_wiphy().
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1736,6 +1879,41 @@
 
 	NL80211_ATTR_PEER_AID,
 
+	NL80211_ATTR_COALESCE_RULE,
+
+	NL80211_ATTR_CH_SWITCH_COUNT,
+	NL80211_ATTR_CH_SWITCH_BLOCK_TX,
+	NL80211_ATTR_CSA_IES,
+	NL80211_ATTR_CSA_C_OFF_BEACON,
+	NL80211_ATTR_CSA_C_OFF_PRESP,
+
+	NL80211_ATTR_RXMGMT_FLAGS,
+
+	NL80211_ATTR_STA_SUPPORTED_CHANNELS,
+
+	NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
+
+	NL80211_ATTR_HANDLE_DFS,
+
+	NL80211_ATTR_SUPPORT_5_MHZ,
+	NL80211_ATTR_SUPPORT_10_MHZ,
+
+	NL80211_ATTR_OPMODE_NOTIF,
+
+	NL80211_ATTR_VENDOR_ID,
+	NL80211_ATTR_VENDOR_SUBCMD,
+	NL80211_ATTR_VENDOR_DATA,
+	NL80211_ATTR_VENDOR_EVENTS,
+
+	NL80211_ATTR_QOS_MAP,
+
+	NL80211_ATTR_MAC_HINT,
+	NL80211_ATTR_WIPHY_FREQ_HINT,
+
+	NL80211_ATTR_MAX_AP_ASSOC_STA,
+
+	NL80211_ATTR_CH_SWITCH_IFACES,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -2136,10 +2314,9 @@
  * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz
  * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current
  *	regulatory domain.
- * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is
- *	permitted on this channel in current regulatory domain.
- * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted
- *	on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation
+ * 	are permitted on this channel, this includes sending probe
+ * 	requests, or modes of operation that require beaconing.
  * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory
  *	on this channel in current regulatory domain.
  * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm
@@ -2166,8 +2343,8 @@
 	__NL80211_FREQUENCY_ATTR_INVALID,
 	NL80211_FREQUENCY_ATTR_FREQ,
 	NL80211_FREQUENCY_ATTR_DISABLED,
-	NL80211_FREQUENCY_ATTR_PASSIVE_SCAN,
-	NL80211_FREQUENCY_ATTR_NO_IBSS,
+	NL80211_FREQUENCY_ATTR_NO_IR,
+	__NL80211_FREQUENCY_ATTR_NO_IBSS,
 	NL80211_FREQUENCY_ATTR_RADAR,
 	NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
 	NL80211_FREQUENCY_ATTR_DFS_STATE,
@@ -2183,6 +2360,9 @@
 };
 
 #define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER
+#define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN	NL80211_FREQUENCY_ATTR_NO_IR
+#define NL80211_FREQUENCY_ATTR_NO_IBSS		NL80211_FREQUENCY_ATTR_NO_IR
+#define NL80211_FREQUENCY_ATTR_NO_IR		NL80211_FREQUENCY_ATTR_NO_IR
 
 /**
  * enum nl80211_bitrate_attr - bitrate attributes
@@ -2325,8 +2505,9 @@
  * @NL80211_RRF_DFS: DFS support is required to be used
  * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links
  * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links
- * @NL80211_RRF_PASSIVE_SCAN: passive scan is required
- * @NL80211_RRF_NO_IBSS: no IBSS is allowed
+ * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed,
+ * 	this includes probe requests or modes of operation that require
+ * 	beaconing.
  */
 enum nl80211_reg_rule_flags {
 	NL80211_RRF_NO_OFDM		= 1<<0,
@@ -2336,10 +2517,17 @@
 	NL80211_RRF_DFS			= 1<<4,
 	NL80211_RRF_PTP_ONLY		= 1<<5,
 	NL80211_RRF_PTMP_ONLY		= 1<<6,
-	NL80211_RRF_PASSIVE_SCAN	= 1<<7,
-	NL80211_RRF_NO_IBSS		= 1<<8,
+	NL80211_RRF_NO_IR		= 1<<7,
+	__NL80211_RRF_NO_IBSS		= 1<<8,
 };
 
+#define NL80211_RRF_PASSIVE_SCAN	NL80211_RRF_NO_IR
+#define NL80211_RRF_NO_IBSS		NL80211_RRF_NO_IR
+#define NL80211_RRF_NO_IR		NL80211_RRF_NO_IR
+
+/* For backport compatibility with older userspace */
+#define NL80211_RRF_NO_IR_ALL		(NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS)
+
 /**
  * enum nl80211_dfs_regions - regulatory DFS regions
  *
@@ -2773,6 +2961,21 @@
 };
 
 /**
+ * enum nl80211_bss_scan_width - control channel width for a BSS
+ *
+ * These values are used with the %NL80211_BSS_CHAN_WIDTH attribute.
+ *
+ * @NL80211_BSS_CHAN_WIDTH_20: control channel is 20 MHz wide or compatible
+ * @NL80211_BSS_CHAN_WIDTH_10: control channel is 10 MHz wide
+ * @NL80211_BSS_CHAN_WIDTH_5: control channel is 5 MHz wide
+ */
+enum nl80211_bss_scan_width {
+	NL80211_BSS_CHAN_WIDTH_20,
+	NL80211_BSS_CHAN_WIDTH_10,
+	NL80211_BSS_CHAN_WIDTH_5,
+};
+
+/**
  * enum nl80211_bss - netlink attributes for a BSS
  *
  * @__NL80211_BSS_INVALID: invalid
@@ -2796,6 +2999,8 @@
  * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information
  *	elements from a Beacon frame (bin); not present if no Beacon frame has
  *	yet been received
+ * @NL80211_BSS_CHAN_WIDTH: channel width of the control channel
+ *	(u32, enum nl80211_bss_scan_width)
  * @__NL80211_BSS_AFTER_LAST: internal
  * @NL80211_BSS_MAX: highest BSS attribute
  */
@@ -2812,6 +3017,7 @@
 	NL80211_BSS_STATUS,
 	NL80211_BSS_SEEN_MS_AGO,
 	NL80211_BSS_BEACON_IES,
+	NL80211_BSS_CHAN_WIDTH,
 
 	/* keep last */
 	__NL80211_BSS_AFTER_LAST,
@@ -2952,21 +3158,43 @@
  *	in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with
  *	1 = 500 kbps) but without the IE length restriction (at most
  *	%NL80211_MAX_SUPP_RATES in a single array).
- * @NL80211_TXRATE_MCS: HT (MCS) rates allowed for TX rate selection
+ * @NL80211_TXRATE_HT: HT (MCS) rates allowed for TX rate selection
  *	in an array of MCS numbers.
+ * @NL80211_TXRATE_VHT: VHT rates allowed for TX rate selection,
+ *	see &struct nl80211_txrate_vht
+ * @NL80211_TXRATE_GI: configure GI, see &enum nl80211_txrate_gi
  * @__NL80211_TXRATE_AFTER_LAST: internal
  * @NL80211_TXRATE_MAX: highest TX rate attribute
  */
 enum nl80211_tx_rate_attributes {
 	__NL80211_TXRATE_INVALID,
 	NL80211_TXRATE_LEGACY,
-	NL80211_TXRATE_MCS,
+	NL80211_TXRATE_HT,
+	NL80211_TXRATE_VHT,
+	NL80211_TXRATE_GI,
 
 	/* keep last */
 	__NL80211_TXRATE_AFTER_LAST,
 	NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1
 };
 
+#define NL80211_TXRATE_MCS NL80211_TXRATE_HT
+#define NL80211_VHT_NSS_MAX		8
+
+/**
+ * struct nl80211_txrate_vht - VHT MCS/NSS txrate bitmap
+ * @mcs: MCS bitmap table for each NSS (array index 0 for 1 stream, etc.)
+ */
+struct nl80211_txrate_vht {
+	__u16 mcs[NL80211_VHT_NSS_MAX];
+};
+
+enum nl80211_txrate_gi {
+	NL80211_TXRATE_DEFAULT_GI,
+	NL80211_TXRATE_FORCE_SGI,
+	NL80211_TXRATE_FORCE_LGI,
+};
+
 /**
  * enum nl80211_band - Frequency band
  * @NL80211_BAND_2GHZ: 2.4 GHz ISM band
@@ -3060,11 +3288,11 @@
 };
 
 /**
- * enum nl80211_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute
- * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute
- * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has
+ * enum nl80211_packet_pattern_attr - packet pattern attribute
+ * @__NL80211_PKTPAT_INVALID: invalid number for nested attribute
+ * @NL80211_PKTPAT_PATTERN: the pattern, values where the mask has
  *	a zero bit are ignored
- * @NL80211_WOWLAN_PKTPAT_MASK: pattern mask, must be long enough to have
+ * @NL80211_PKTPAT_MASK: pattern mask, must be long enough to have
  *	a bit for each byte in the pattern. The lowest-order bit corresponds
  *	to the first byte of the pattern, but the bytes of the pattern are
  *	in a little-endian-like format, i.e. the 9th byte of the pattern
@@ -3075,39 +3303,50 @@
  *	Note that the pattern matching is done as though frames were not
  *	802.11 frames but 802.3 frames, i.e. the frame is fully unpacked
  *	first (including SNAP header unpacking) and then matched.
- * @NL80211_WOWLAN_PKTPAT_OFFSET: packet offset, pattern is matched after
+ * @NL80211_PKTPAT_OFFSET: packet offset, pattern is matched after
  *	these fixed number of bytes of received packet
- * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes
- * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number
+ * @NUM_NL80211_PKTPAT: number of attributes
+ * @MAX_NL80211_PKTPAT: max attribute number
  */
-enum nl80211_wowlan_packet_pattern_attr {
-	__NL80211_WOWLAN_PKTPAT_INVALID,
-	NL80211_WOWLAN_PKTPAT_MASK,
-	NL80211_WOWLAN_PKTPAT_PATTERN,
-	NL80211_WOWLAN_PKTPAT_OFFSET,
+enum nl80211_packet_pattern_attr {
+	__NL80211_PKTPAT_INVALID,
+	NL80211_PKTPAT_MASK,
+	NL80211_PKTPAT_PATTERN,
+	NL80211_PKTPAT_OFFSET,
 
-	NUM_NL80211_WOWLAN_PKTPAT,
-	MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1,
+	NUM_NL80211_PKTPAT,
+	MAX_NL80211_PKTPAT = NUM_NL80211_PKTPAT - 1,
 };
 
 /**
- * struct nl80211_wowlan_pattern_support - pattern support information
+ * struct nl80211_pattern_support - packet pattern support information
  * @max_patterns: maximum number of patterns supported
  * @min_pattern_len: minimum length of each pattern
  * @max_pattern_len: maximum length of each pattern
  * @max_pkt_offset: maximum Rx packet offset
  *
  * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when
- * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the
- * capability information given by the kernel to userspace.
+ * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED or in
+ * %NL80211_ATTR_COALESCE_RULE_PKT_PATTERN when that is part of
+ * %NL80211_ATTR_COALESCE_RULE in the capability information given
+ * by the kernel to userspace.
  */
-struct nl80211_wowlan_pattern_support {
+struct nl80211_pattern_support {
 	__u32 max_patterns;
 	__u32 min_pattern_len;
 	__u32 max_pattern_len;
 	__u32 max_pkt_offset;
 } __attribute__((packed));
 
+/* only for backward compatibility */
+#define __NL80211_WOWLAN_PKTPAT_INVALID __NL80211_PKTPAT_INVALID
+#define NL80211_WOWLAN_PKTPAT_MASK NL80211_PKTPAT_MASK
+#define NL80211_WOWLAN_PKTPAT_PATTERN NL80211_PKTPAT_PATTERN
+#define NL80211_WOWLAN_PKTPAT_OFFSET NL80211_PKTPAT_OFFSET
+#define NUM_NL80211_WOWLAN_PKTPAT NUM_NL80211_PKTPAT
+#define MAX_NL80211_WOWLAN_PKTPAT MAX_NL80211_PKTPAT
+#define nl80211_wowlan_pattern_support nl80211_pattern_support
+
 /**
  * enum nl80211_wowlan_triggers - WoWLAN trigger definitions
  * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes
@@ -3127,7 +3366,7 @@
  *	pattern matching is done after the packet is converted to the MSDU.
  *
  *	In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
- *	carrying a &struct nl80211_wowlan_pattern_support.
+ *	carrying a &struct nl80211_pattern_support.
  *
  *	When reporting wakeup. it is a u32 attribute containing the 0-based
  *	index of the pattern that caused the wakeup, in the patterns passed
@@ -3284,7 +3523,7 @@
  * @NL80211_WOWLAN_TCP_WAKE_PAYLOAD: wake packet payload, for advertising a
  *	u32 attribute holding the maximum length
  * @NL80211_WOWLAN_TCP_WAKE_MASK: Wake packet payload mask, not used for
- *	feature advertising. The mask works like @NL80211_WOWLAN_PKTPAT_MASK
+ *	feature advertising. The mask works like @NL80211_PKTPAT_MASK
  *	but on the TCP payload only.
  * @NUM_NL80211_WOWLAN_TCP: number of TCP attributes
  * @MAX_NL80211_WOWLAN_TCP: highest attribute number
@@ -3309,6 +3548,55 @@
 };
 
 /**
+ * struct nl80211_coalesce_rule_support - coalesce rule support information
+ * @max_rules: maximum number of rules supported
+ * @pat: packet pattern support information
+ * @max_delay: maximum supported coalescing delay in msecs
+ *
+ * This struct is carried in %NL80211_ATTR_COALESCE_RULE in the
+ * capability information given by the kernel to userspace.
+ */
+struct nl80211_coalesce_rule_support {
+	__u32 max_rules;
+	struct nl80211_pattern_support pat;
+	__u32 max_delay;
+} __attribute__((packed));
+
+/**
+ * enum nl80211_attr_coalesce_rule - coalesce rule attribute
+ * @__NL80211_COALESCE_RULE_INVALID: invalid number for nested attribute
+ * @NL80211_ATTR_COALESCE_RULE_DELAY: delay in msecs used for packet coalescing
+ * @NL80211_ATTR_COALESCE_RULE_CONDITION: condition for packet coalescence,
+ *	see &enum nl80211_coalesce_condition.
+ * @NL80211_ATTR_COALESCE_RULE_PKT_PATTERN: packet offset, pattern is matched
+ *	after these fixed number of bytes of received packet
+ * @NUM_NL80211_ATTR_COALESCE_RULE: number of attributes
+ * @NL80211_ATTR_COALESCE_RULE_MAX: max attribute number
+ */
+enum nl80211_attr_coalesce_rule {
+	__NL80211_COALESCE_RULE_INVALID,
+	NL80211_ATTR_COALESCE_RULE_DELAY,
+	NL80211_ATTR_COALESCE_RULE_CONDITION,
+	NL80211_ATTR_COALESCE_RULE_PKT_PATTERN,
+
+	/* keep last */
+	NUM_NL80211_ATTR_COALESCE_RULE,
+	NL80211_ATTR_COALESCE_RULE_MAX = NUM_NL80211_ATTR_COALESCE_RULE - 1
+};
+
+/**
+ * enum nl80211_coalesce_condition - coalesce rule conditions
+ * @NL80211_COALESCE_CONDITION_MATCH: coalaesce Rx packets when patterns
+ *	in a rule are matched.
+ * @NL80211_COALESCE_CONDITION_NO_MATCH: coalesce Rx packets when patterns
+ *	in a rule are not matched.
+ */
+enum nl80211_coalesce_condition {
+	NL80211_COALESCE_CONDITION_MATCH,
+	NL80211_COALESCE_CONDITION_NO_MATCH
+};
+
+/**
  * enum nl80211_iface_limit_attrs - limit attributes
  * @NL80211_IFACE_LIMIT_UNSPEC: (reserved)
  * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that
@@ -3712,13 +4000,12 @@
  *
  * Channel states used by the DFS code.
  *
- * @IEEE80211_DFS_USABLE: The channel can be used, but channel availability
+ * @NL80211_DFS_USABLE: The channel can be used, but channel availability
  *	check (CAC) must be performed before using it for AP or IBSS.
- * @IEEE80211_DFS_UNAVAILABLE: A radar has been detected on this channel, it
+ * @NL80211_DFS_UNAVAILABLE: A radar has been detected on this channel, it
  *	is therefore marked as not available.
- * @IEEE80211_DFS_AVAILABLE: The channel has been CAC checked and is available.
+ * @NL80211_DFS_AVAILABLE: The channel has been CAC checked and is available.
  */
-
 enum nl80211_dfs_state {
 	NL80211_DFS_USABLE,
 	NL80211_DFS_UNAVAILABLE,
@@ -3758,4 +4045,35 @@
 /* maximum duration for critical protocol measures */
 #define NL80211_CRIT_PROTO_MAX_DURATION		5000 /* msec */
 
+/**
+ * enum nl80211_rxmgmt_flags - flags for received management frame.
+ *
+ * Used by cfg80211_rx_mgmt()
+ *
+ * @NL80211_RXMGMT_FLAG_ANSWERED: frame was answered by device/driver.
+ */
+enum nl80211_rxmgmt_flags {
+	NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0,
+};
+
+/*
+ * If this flag is unset, the lower 24 bits are an OUI, if set
+ * a Linux nl80211 vendor ID is used (no such IDs are allocated
+ * yet, so that's not valid so far)
+ */
+#define NL80211_VENDOR_ID_IS_LINUX	0x80000000
+
+/**
+ * struct nl80211_vendor_cmd_info - vendor command data
+ * @vendor_id: If the %NL80211_VENDOR_ID_IS_LINUX flag is clear, then the
+ *	value is a 24-bit OUI; if it is set then a separately allocated ID
+ *	may be used, but no such IDs are allocated yet. New IDs should be
+ *	added to this file when needed.
+ * @subcmd: sub-command ID for the command
+ */
+struct nl80211_vendor_cmd_info {
+	__u32 vendor_id;
+	__u32 subcmd;
+};
+
 #endif /* __LINUX_NL80211_H */
diff -ruw linux-3.11.10/include/uapi/linux/prctl.h linux-3.11.10-fbx/include/uapi/linux/prctl.h
--- linux-3.11.10/include/uapi/linux/prctl.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/linux/prctl.h	2014-08-22 15:47:22.140063166 +0200
@@ -149,4 +149,25 @@
 
 #define PR_GET_TID_ADDRESS	40
 
+/*
+ * Freebox addition
+ */
+#define PR_SET_JAIL		50
+#define PR_GET_JAIL		51
+#define PR_JAIL_EXEC_ALL	0x0
+#define PR_JAIL_EXEC_ONCE	0x1
+#define PR_JAIL_EXEC_NO		0x2
+
+#define PR_SET_JAIL_ENTRIES	52
+
+#define PR_ADD_JAIL_FILES	53
+#define PR_JAIL_FILE_READ	0x1
+#define PR_JAIL_FILE_WRITE	0x2
+
+/*
+ * Freebox addition: set/get exec mode.
+ */
+#define PR_SET_EXEC_MODE	54
+#define PR_GET_EXEC_MODE	55
+
 #endif /* _LINUX_PRCTL_H */
diff -ruw linux-3.11.10/include/uapi/linux/serial_reg.h linux-3.11.10-fbx/include/uapi/linux/serial_reg.h
--- linux-3.11.10/include/uapi/linux/serial_reg.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/linux/serial_reg.h	2013-12-04 14:33:25.391479076 +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 */
@@ -44,7 +58,12 @@
 #define UART_IIR_XOFF		0x10 /* OMAP XOFF/Special Character */
 #define UART_IIR_CTS_RTS_DSR	0x20 /* OMAP CTS/RTS/DSR Change */
 
+#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 */
@@ -88,7 +107,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.
@@ -111,7 +135,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) */
@@ -122,8 +150,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 */
@@ -133,7 +167,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 */
@@ -144,18 +182,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.11.10/include/uapi/linux/sockios.h linux-3.11.10-fbx/include/uapi/linux/sockios.h
--- linux-3.11.10/include/uapi/linux/sockios.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/linux/sockios.h	2013-12-04 14:33:25.395479076 +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.11.10/include/uapi/linux/tty.h linux-3.11.10-fbx/include/uapi/linux/tty.h
--- linux-3.11.10/include/uapi/linux/tty.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/linux/tty.h	2013-12-04 14:33:25.395479076 +0100
@@ -34,5 +34,6 @@
 #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 */
 
 #endif /* _UAPI_LINUX_TTY_H */
diff -ruw linux-3.11.10/include/uapi/linux/usb/cdc-wdm.h linux-3.11.10-fbx/include/uapi/linux/usb/cdc-wdm.h
--- linux-3.11.10/include/uapi/linux/usb/cdc-wdm.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/linux/usb/cdc-wdm.h	2014-07-01 16:22:13.182329834 +0200
@@ -9,6 +9,8 @@
 #ifndef _UAPI__LINUX_USB_CDC_WDM_H
 #define _UAPI__LINUX_USB_CDC_WDM_H
 
+#include <linux/types.h>
+
 /*
  * This IOCTL is used to retrieve the wMaxCommand for the device,
  * defining the message limit for both reading and writing.
diff -ruw linux-3.11.10/include/uapi/linux/usb/Kbuild linux-3.11.10-fbx/include/uapi/linux/usb/Kbuild
--- linux-3.11.10/include/uapi/linux/usb/Kbuild	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/linux/usb/Kbuild	2014-07-01 16:22:13.182329834 +0200
@@ -1,6 +1,7 @@
 # UAPI Header export list
 header-y += audio.h
 header-y += cdc.h
+header-y += cdc-wdm.h
 header-y += ch11.h
 header-y += ch9.h
 header-y += functionfs.h
diff -ruw linux-3.11.10/include/uapi/sound/compress_offload.h linux-3.11.10-fbx/include/uapi/sound/compress_offload.h
--- linux-3.11.10/include/uapi/sound/compress_offload.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/sound/compress_offload.h	2014-08-22 15:47:22.140063166 +0200
@@ -30,7 +30,7 @@
 #include <sound/compress_params.h>
 
 
-#define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 1)
+#define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 2)
 /**
  * struct snd_compressed_buffer: compressed buffer
  * @fragment_size: size of buffer fragment in bytes
@@ -67,8 +67,8 @@
 struct snd_compr_tstamp {
 	__u32 byte_offset;
 	__u32 copied_total;
-	snd_pcm_uframes_t pcm_frames;
-	snd_pcm_uframes_t pcm_io_frames;
+	__u32 pcm_frames;
+	__u32 pcm_io_frames;
 	__u32 sampling_rate;
 };
 
@@ -80,7 +80,7 @@
 struct snd_compr_avail {
 	__u64 avail;
 	struct snd_compr_tstamp tstamp;
-};
+} __attribute__((packed));
 
 enum snd_compr_direction {
 	SND_COMPRESS_PLAYBACK = 0,
diff -ruw linux-3.11.10/include/uapi/xen/Kbuild linux-3.11.10-fbx/include/uapi/xen/Kbuild
--- linux-3.11.10/include/uapi/xen/Kbuild	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/include/uapi/xen/Kbuild	2014-05-09 14:12:54.340546160 +0200
@@ -1,3 +1,5 @@
 # UAPI Header export list
 header-y += evtchn.h
+header-y += gntalloc.h
+header-y += gntdev.h
 header-y += privcmd.h
diff -ruw linux-3.11.10/init/Kconfig linux-3.11.10-fbx/init/Kconfig
--- linux-3.11.10/init/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/init/Kconfig	2014-07-01 16:22:13.182329834 +0200
@@ -789,6 +789,15 @@
 		     13 =>  8 KB
 		     12 =>  4 KB
 
+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:
 #
@@ -1291,7 +1300,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
@@ -1402,6 +1410,13 @@
 	  support for "fast userspace mutexes".  The resulting kernel may not
 	  run glibc-based applications correctly.
 
+config HAVE_FUTEX_CMPXCHG
+	bool
+	help
+	  Architectures should select this if futex_atomic_cmpxchg_inatomic()
+	  is implemented and always working. This removes a couple of runtime
+	  checks.
+
 config EPOLL
 	bool "Enable eventpoll support" if EXPERT
 	default y
diff -ruw linux-3.11.10/init/Makefile linux-3.11.10-fbx/init/Makefile
--- linux-3.11.10/init/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/init/Makefile	2013-12-04 14:33:26.239479089 +0100
@@ -13,6 +13,7 @@
 ifneq ($(CONFIG_ARCH_INIT_TASK),y)
 obj-y                          += init_task.o
 endif
+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
diff -ruw linux-3.11.10/ipc/ipc_sysctl.c linux-3.11.10-fbx/ipc/ipc_sysctl.c
--- linux-3.11.10/ipc/ipc_sysctl.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/ipc/ipc_sysctl.c	2014-01-17 19:14:18.778220809 +0100
@@ -62,7 +62,7 @@
 	return err;
 }
 
-static int proc_ipc_callback_dointvec(ctl_table *table, int write,
+static int proc_ipc_callback_dointvec_minmax(ctl_table *table, int write,
 	void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	struct ctl_table ipc_table;
@@ -72,7 +72,7 @@
 	memcpy(&ipc_table, table, sizeof(ipc_table));
 	ipc_table.data = get_ipc(table);
 
-	rc = proc_dointvec(&ipc_table, write, buffer, lenp, ppos);
+	rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
 
 	if (write && !rc && lenp_bef == *lenp)
 		/*
@@ -152,15 +152,13 @@
 #define proc_ipc_dointvec	   NULL
 #define proc_ipc_dointvec_minmax   NULL
 #define proc_ipc_dointvec_minmax_orphans   NULL
-#define proc_ipc_callback_dointvec NULL
+#define proc_ipc_callback_dointvec_minmax  NULL
 #define proc_ipcauto_dointvec_minmax NULL
 #endif
 
 static int zero;
 static int one = 1;
-#ifdef CONFIG_CHECKPOINT_RESTORE
 static int int_max = INT_MAX;
-#endif
 
 static struct ctl_table ipc_kern_table[] = {
 	{
@@ -198,21 +196,27 @@
 		.data		= &init_ipc_ns.msg_ctlmax,
 		.maxlen		= sizeof (init_ipc_ns.msg_ctlmax),
 		.mode		= 0644,
-		.proc_handler	= proc_ipc_dointvec,
+		.proc_handler	= proc_ipc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &int_max,
 	},
 	{
 		.procname	= "msgmni",
 		.data		= &init_ipc_ns.msg_ctlmni,
 		.maxlen		= sizeof (init_ipc_ns.msg_ctlmni),
 		.mode		= 0644,
-		.proc_handler	= proc_ipc_callback_dointvec,
+		.proc_handler	= proc_ipc_callback_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &int_max,
 	},
 	{
 		.procname	=  "msgmnb",
 		.data		= &init_ipc_ns.msg_ctlmnb,
 		.maxlen		= sizeof (init_ipc_ns.msg_ctlmnb),
 		.mode		= 0644,
-		.proc_handler	= proc_ipc_dointvec,
+		.proc_handler	= proc_ipc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &int_max,
 	},
 	{
 		.procname	= "sem",
diff -ruw linux-3.11.10/ipc/mq_sysctl.c linux-3.11.10-fbx/ipc/mq_sysctl.c
--- linux-3.11.10/ipc/mq_sysctl.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/ipc/mq_sysctl.c	2014-07-01 16:22:13.186329848 +0200
@@ -22,6 +22,16 @@
 	return which;
 }
 
+static int proc_mq_dointvec(ctl_table *table, int write,
+			    void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	struct ctl_table mq_table;
+	memcpy(&mq_table, table, sizeof(mq_table));
+	mq_table.data = get_mq(table);
+
+	return proc_dointvec(&mq_table, write, buffer, lenp, ppos);
+}
+
 static int proc_mq_dointvec_minmax(ctl_table *table, int write,
 	void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -33,12 +43,10 @@
 					lenp, ppos);
 }
 #else
+#define proc_mq_dointvec NULL
 #define proc_mq_dointvec_minmax NULL
 #endif
 
-static int msg_queues_limit_min = MIN_QUEUESMAX;
-static int msg_queues_limit_max = HARD_QUEUESMAX;
-
 static int msg_max_limit_min = MIN_MSGMAX;
 static int msg_max_limit_max = HARD_MSGMAX;
 
@@ -51,9 +59,7 @@
 		.data		= &init_ipc_ns.mq_queues_max,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_mq_dointvec_minmax,
-		.extra1		= &msg_queues_limit_min,
-		.extra2		= &msg_queues_limit_max,
+		.proc_handler	= proc_mq_dointvec,
 	},
 	{
 		.procname	= "msg_max",
diff -ruw linux-3.11.10/ipc/mqueue.c linux-3.11.10-fbx/ipc/mqueue.c
--- linux-3.11.10/ipc/mqueue.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/ipc/mqueue.c	2014-07-01 16:22:13.186329848 +0200
@@ -433,9 +433,9 @@
 		error = -EACCES;
 		goto out_unlock;
 	}
-	if (ipc_ns->mq_queues_count >= HARD_QUEUESMAX ||
-	    (ipc_ns->mq_queues_count >= ipc_ns->mq_queues_max &&
-	     !capable(CAP_SYS_RESOURCE))) {
+
+	if (ipc_ns->mq_queues_count >= ipc_ns->mq_queues_max &&
+	    !capable(CAP_SYS_RESOURCE)) {
 		error = -ENOSPC;
 		goto out_unlock;
 	}
diff -ruw linux-3.11.10/ipc/msg.c linux-3.11.10-fbx/ipc/msg.c
--- linux-3.11.10/ipc/msg.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/ipc/msg.c	2014-07-01 16:22:13.186329848 +0200
@@ -885,6 +885,8 @@
 		return -EINVAL;
 
 	if (msgflg & MSG_COPY) {
+		if ((msgflg & MSG_EXCEPT) || !(msgflg & IPC_NOWAIT))
+			return -EINVAL;
 		copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax));
 		if (IS_ERR(copy))
 			return PTR_ERR(copy);
diff -ruw linux-3.11.10/ipc/msgutil.c linux-3.11.10-fbx/ipc/msgutil.c
--- linux-3.11.10/ipc/msgutil.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/ipc/msgutil.c	2014-01-17 19:14:18.778220809 +0100
@@ -41,15 +41,15 @@
 	/* the next part of the message follows immediately */
 };
 
-#define DATALEN_MSG	(int)(PAGE_SIZE-sizeof(struct msg_msg))
-#define DATALEN_SEG	(int)(PAGE_SIZE-sizeof(struct msg_msgseg))
+#define DATALEN_MSG	((size_t)PAGE_SIZE-sizeof(struct msg_msg))
+#define DATALEN_SEG	((size_t)PAGE_SIZE-sizeof(struct msg_msgseg))
 
 
-static struct msg_msg *alloc_msg(int len)
+static struct msg_msg *alloc_msg(size_t len)
 {
 	struct msg_msg *msg;
 	struct msg_msgseg **pseg;
-	int alen;
+	size_t alen;
 
 	alen = min(len, DATALEN_MSG);
 	msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL);
@@ -80,12 +80,12 @@
 	return NULL;
 }
 
-struct msg_msg *load_msg(const void __user *src, int len)
+struct msg_msg *load_msg(const void __user *src, size_t len)
 {
 	struct msg_msg *msg;
 	struct msg_msgseg *seg;
 	int err = -EFAULT;
-	int alen;
+	size_t alen;
 
 	msg = alloc_msg(len);
 	if (msg == NULL)
@@ -117,8 +117,8 @@
 struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
 {
 	struct msg_msgseg *dst_pseg, *src_pseg;
-	int len = src->m_ts;
-	int alen;
+	size_t len = src->m_ts;
+	size_t alen;
 
 	BUG_ON(dst == NULL);
 	if (src->m_ts > dst->m_ts)
@@ -147,9 +147,9 @@
 	return ERR_PTR(-ENOSYS);
 }
 #endif
-int store_msg(void __user *dest, struct msg_msg *msg, int len)
+int store_msg(void __user *dest, struct msg_msg *msg, size_t len)
 {
-	int alen;
+	size_t alen;
 	struct msg_msgseg *seg;
 
 	alen = min(len, DATALEN_MSG);
diff -ruw linux-3.11.10/ipc/sem.c linux-3.11.10-fbx/ipc/sem.c
--- linux-3.11.10/ipc/sem.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/ipc/sem.c	2014-01-17 19:14:18.778220809 +0100
@@ -1282,6 +1282,12 @@
 
 	sem_lock(sma, NULL, -1);
 
+	if (sma->sem_perm.deleted) {
+		sem_unlock(sma, -1);
+		rcu_read_unlock();
+		return -EIDRM;
+	}
+
 	curr = &sma->sem_base[semnum];
 
 	ipc_assert_locked_object(&sma->sem_perm);
@@ -1336,12 +1342,14 @@
 		int i;
 
 		sem_lock(sma, NULL, -1);
+		if (sma->sem_perm.deleted) {
+			err = -EIDRM;
+			goto out_unlock;
+		}
 		if(nsems > SEMMSL_FAST) {
 			if (!ipc_rcu_getref(sma)) {
-				sem_unlock(sma, -1);
-				rcu_read_unlock();
 				err = -EIDRM;
-				goto out_free;
+				goto out_unlock;
 			}
 			sem_unlock(sma, -1);
 			rcu_read_unlock();
@@ -1354,10 +1362,8 @@
 			rcu_read_lock();
 			sem_lock_and_putref(sma);
 			if (sma->sem_perm.deleted) {
-				sem_unlock(sma, -1);
-				rcu_read_unlock();
 				err = -EIDRM;
-				goto out_free;
+				goto out_unlock;
 			}
 		}
 		for (i = 0; i < sma->sem_nsems; i++)
@@ -1375,8 +1381,8 @@
 		struct sem_undo *un;
 
 		if (!ipc_rcu_getref(sma)) {
-			rcu_read_unlock();
-			return -EIDRM;
+			err = -EIDRM;
+			goto out_rcu_wakeup;
 		}
 		rcu_read_unlock();
 
@@ -1404,10 +1410,8 @@
 		rcu_read_lock();
 		sem_lock_and_putref(sma);
 		if (sma->sem_perm.deleted) {
-			sem_unlock(sma, -1);
-			rcu_read_unlock();
 			err = -EIDRM;
-			goto out_free;
+			goto out_unlock;
 		}
 
 		for (i = 0; i < nsems; i++)
@@ -1431,6 +1435,10 @@
 		goto out_rcu_wakeup;
 
 	sem_lock(sma, NULL, -1);
+	if (sma->sem_perm.deleted) {
+		err = -EIDRM;
+		goto out_unlock;
+	}
 	curr = &sma->sem_base[semnum];
 
 	switch (cmd) {
@@ -1836,6 +1844,10 @@
 	if (error)
 		goto out_rcu_wakeup;
 
+	error = -EIDRM;
+	locknum = sem_lock(sma, sops, nsops);
+	if (sma->sem_perm.deleted)
+		goto out_unlock_free;
 	/*
 	 * semid identifiers are not unique - find_alloc_undo may have
 	 * allocated an undo structure, it was invalidated by an RMID
@@ -1843,8 +1855,6 @@
 	 * This case can be detected checking un->semid. The existence of
 	 * "un" itself is guaranteed by rcu.
 	 */
-	error = -EIDRM;
-	locknum = sem_lock(sma, sops, nsops);
 	if (un && un->semid == -1)
 		goto out_unlock_free;
 
@@ -2057,6 +2067,12 @@
 		}
 
 		sem_lock(sma, NULL, -1);
+		/* exit_sem raced with IPC_RMID, nothing to do */
+		if (sma->sem_perm.deleted) {
+			sem_unlock(sma, -1);
+			rcu_read_unlock();
+			continue;
+		}
 		un = __lookup_undo(ulp, semid);
 		if (un == NULL) {
 			/* exit_sem raced with IPC_RMID+semget() that created
diff -ruw linux-3.11.10/ipc/util.c linux-3.11.10-fbx/ipc/util.c
--- linux-3.11.10/ipc/util.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/ipc/util.c	2014-01-17 19:14:18.778220809 +0100
@@ -17,12 +17,27 @@
  *            Pavel Emelianov <xemul@openvz.org>
  *
  * General sysv ipc locking scheme:
- *  when doing ipc id lookups, take the ids->rwsem
  *      rcu_read_lock()
- *          obtain the ipc object (kern_ipc_perm)
- *          perform security, capabilities, auditing and permission checks, etc.
- *          acquire the ipc lock (kern_ipc_perm.lock) throught ipc_lock_object()
- *             perform data updates (ie: SET, RMID, LOCK/UNLOCK commands)
+ *          obtain the ipc object (kern_ipc_perm) by looking up the id in an idr
+ *	    tree.
+ *	    - perform initial checks (capabilities, auditing and permission,
+ *	      etc).
+ *	    - perform read-only operations, such as STAT, INFO commands.
+ *	      acquire the ipc lock (kern_ipc_perm.lock) through
+ *	      ipc_lock_object()
+ *		- perform data updates, such as SET, RMID commands and
+ *		  mechanism-specific operations (semop/semtimedop,
+ *		  msgsnd/msgrcv, shmat/shmdt).
+ *	    drop the ipc lock, through ipc_unlock_object().
+ *	rcu_read_unlock()
+ *
+ *  The ids->rwsem must be taken when:
+ *	- creating, removing and iterating the existing entries in ipc
+ *	  identifier sets.
+ *	- iterating through files under /proc/sysvipc/
+ *
+ *  Note that sems have a special fast path that avoids kern_ipc_perm.lock -
+ *  see sem_lock().
  */
 
 #include <linux/mm.h>
diff -ruw linux-3.11.10/ipc/util.h linux-3.11.10-fbx/ipc/util.h
--- linux-3.11.10/ipc/util.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/ipc/util.h	2014-01-17 19:14:18.778220809 +0100
@@ -148,9 +148,9 @@
 #endif
 
 extern void free_msg(struct msg_msg *msg);
-extern struct msg_msg *load_msg(const void __user *src, int len);
+extern struct msg_msg *load_msg(const void __user *src, size_t len);
 extern struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst);
-extern int store_msg(void __user *dest, struct msg_msg *msg, int len);
+extern int store_msg(void __user *dest, struct msg_msg *msg, size_t len);
 
 extern void recompute_msgmni(struct ipc_namespace *);
 
diff -ruw linux-3.11.10/kernel/audit.c linux-3.11.10-fbx/kernel/audit.c
--- linux-3.11.10/kernel/audit.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/audit.c	2014-08-22 15:47:22.140063166 +0200
@@ -103,7 +103,8 @@
 
 /* Number of outstanding audit_buffers allowed. */
 static int	audit_backlog_limit = 64;
-static int	audit_backlog_wait_time = 60 * HZ;
+#define AUDIT_BACKLOG_WAIT_TIME (60 * HZ)
+static int	audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME;
 static int	audit_backlog_wait_overflow = 0;
 
 /* The identity of the user shutting down the audit system. */
@@ -592,13 +593,13 @@
 	case AUDIT_TTY_SET:
 	case AUDIT_TRIM:
 	case AUDIT_MAKE_EQUIV:
-		if (!capable(CAP_AUDIT_CONTROL))
+		if (!netlink_capable(skb, CAP_AUDIT_CONTROL))
 			err = -EPERM;
 		break;
 	case AUDIT_USER:
 	case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
 	case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
-		if (!capable(CAP_AUDIT_WRITE))
+		if (!netlink_capable(skb, CAP_AUDIT_WRITE))
 			err = -EPERM;
 		break;
 	default:  /* bad msg */
@@ -613,7 +614,7 @@
 	int rc = 0;
 	uid_t uid = from_kuid(&init_user_ns, current_uid());
 
-	if (!audit_enabled) {
+	if (!audit_enabled && msg_type != AUDIT_USER_AVC) {
 		*ab = NULL;
 		return rc;
 	}
@@ -659,6 +660,7 @@
 
 	switch (msg_type) {
 	case AUDIT_GET:
+		status_set.mask		 = 0;
 		status_set.enabled	 = audit_enabled;
 		status_set.failure	 = audit_failure;
 		status_set.pid		 = audit_pid;
@@ -670,7 +672,7 @@
 				 &status_set, sizeof(status_set));
 		break;
 	case AUDIT_SET:
-		if (nlh->nlmsg_len < sizeof(struct audit_status))
+		if (nlmsg_len(nlh) < sizeof(struct audit_status))
 			return -EINVAL;
 		status_get   = (struct audit_status *)data;
 		if (status_get->mask & AUDIT_STATUS_ENABLED) {
@@ -832,7 +834,7 @@
 
 		memset(&s, 0, sizeof(s));
 		/* guard against past and future API changes */
-		memcpy(&s, data, min(sizeof(s), (size_t)nlh->nlmsg_len));
+		memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh)));
 		if ((s.enabled != 0 && s.enabled != 1) ||
 		    (s.log_passwd != 0 && s.log_passwd != 1))
 			return -EINVAL;
@@ -1134,6 +1136,8 @@
 		return NULL;
 	}
 
+	audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME;
+
 	ab = audit_buffer_alloc(ctx, gfp_mask, type);
 	if (!ab) {
 		audit_log_lost("out of memory in audit_log_start");
@@ -1536,6 +1540,26 @@
 		}
 	}
 
+	/* log the audit_names record type */
+	audit_log_format(ab, " nametype=");
+	switch(n->type) {
+	case AUDIT_TYPE_NORMAL:
+		audit_log_format(ab, "NORMAL");
+		break;
+	case AUDIT_TYPE_PARENT:
+		audit_log_format(ab, "PARENT");
+		break;
+	case AUDIT_TYPE_CHILD_DELETE:
+		audit_log_format(ab, "DELETE");
+		break;
+	case AUDIT_TYPE_CHILD_CREATE:
+		audit_log_format(ab, "CREATE");
+		break;
+	default:
+		audit_log_format(ab, "UNKNOWN");
+		break;
+	}
+
 	audit_log_fcaps(ab, n);
 	audit_log_end(ab);
 }
@@ -1589,10 +1613,10 @@
 	spin_unlock_irq(&tsk->sighand->siglock);
 
 	audit_log_format(ab,
-			 " ppid=%ld pid=%d auid=%u uid=%u gid=%u"
+			 " ppid=%d pid=%d auid=%u uid=%u gid=%u"
 			 " euid=%u suid=%u fsuid=%u"
-			 " egid=%u sgid=%u fsgid=%u ses=%u tty=%s",
-			 sys_getppid(),
+			 " egid=%u sgid=%u fsgid=%u tty=%s ses=%u",
+			 task_ppid_nr(tsk),
 			 tsk->pid,
 			 from_kuid(&init_user_ns, audit_get_loginuid(tsk)),
 			 from_kuid(&init_user_ns, cred->uid),
@@ -1603,7 +1627,7 @@
 			 from_kgid(&init_user_ns, cred->egid),
 			 from_kgid(&init_user_ns, cred->sgid),
 			 from_kgid(&init_user_ns, cred->fsgid),
-			 audit_get_sessionid(tsk), tty);
+			 tty, audit_get_sessionid(tsk));
 
 	get_task_comm(name, tsk);
 	audit_log_format(ab, " comm=");
diff -ruw linux-3.11.10/kernel/auditsc.c linux-3.11.10-fbx/kernel/auditsc.c
--- linux-3.11.10/kernel/auditsc.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/auditsc.c	2014-07-01 16:22:13.186329848 +0200
@@ -472,7 +472,7 @@
 		case AUDIT_PPID:
 			if (ctx) {
 				if (!ctx->ppid)
-					ctx->ppid = sys_getppid();
+					ctx->ppid = task_ppid_nr(tsk);
 				result = audit_comparator(ctx->ppid, f->op, f->val);
 			}
 			break;
@@ -733,6 +733,22 @@
 	return AUDIT_BUILD_CONTEXT;
 }
 
+static int audit_in_mask(const struct audit_krule *rule, unsigned long val)
+{
+	int word, bit;
+
+	if (val > 0xffffffff)
+		return false;
+
+	word = AUDIT_WORD(val);
+	if (word >= AUDIT_BITMASK_SIZE)
+		return false;
+
+	bit = AUDIT_BIT(val);
+
+	return rule->mask[word] & bit;
+}
+
 /* At syscall entry and exit time, this filter is called if the
  * audit_state is not low enough that auditing cannot take place, but is
  * also not high enough that we already know we have to write an audit
@@ -750,11 +766,8 @@
 
 	rcu_read_lock();
 	if (!list_empty(list)) {
-		int word = AUDIT_WORD(ctx->major);
-		int bit  = AUDIT_BIT(ctx->major);
-
 		list_for_each_entry_rcu(e, list, list) {
-			if ((e->rule.mask[word] & bit) == bit &&
+			if (audit_in_mask(&e->rule, ctx->major) &&
 			    audit_filter_rules(tsk, &e->rule, ctx, NULL,
 					       &state, false)) {
 				rcu_read_unlock();
@@ -774,20 +787,16 @@
 static int audit_filter_inode_name(struct task_struct *tsk,
 				   struct audit_names *n,
 				   struct audit_context *ctx) {
-	int word, bit;
 	int h = audit_hash_ino((u32)n->ino);
 	struct list_head *list = &audit_inode_hash[h];
 	struct audit_entry *e;
 	enum audit_state state;
 
-	word = AUDIT_WORD(ctx->major);
-	bit  = AUDIT_BIT(ctx->major);
-
 	if (list_empty(list))
 		return 0;
 
 	list_for_each_entry_rcu(e, list, list) {
-		if ((e->rule.mask[word] & bit) == bit &&
+		if (audit_in_mask(&e->rule, ctx->major) &&
 		    audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) {
 			ctx->current_state = state;
 			return 1;
diff -ruw linux-3.11.10/kernel/capability.c linux-3.11.10-fbx/kernel/capability.c
--- linux-3.11.10/kernel/capability.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/capability.c	2014-07-01 16:22:13.186329848 +0200
@@ -445,22 +445,18 @@
 }
 
 /**
- * inode_capable - Check superior capability over inode
+ * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
  * @inode: The inode in question
  * @cap: The capability in question
  *
- * Return true if the current task has the given superior capability
- * targeted at it's own user namespace and that the given inode is owned
- * by the current user namespace or a child namespace.
- *
- * Currently we check to see if an inode is owned by the current
- * user namespace by seeing if the inode's owner maps into the
- * current user namespace.
- *
+ * Return true if the current task has the given capability targeted at
+ * its own user namespace and that the given inode's uid and gid are
+ * mapped into the current user namespace.
  */
-bool inode_capable(const struct inode *inode, int cap)
+bool capable_wrt_inode_uidgid(const struct inode *inode, int cap)
 {
 	struct user_namespace *ns = current_user_ns();
 
-	return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid);
+	return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) &&
+		kgid_has_mapping(ns, inode->i_gid);
 }
diff -ruw linux-3.11.10/kernel/cgroup.c linux-3.11.10-fbx/kernel/cgroup.c
--- linux-3.11.10/kernel/cgroup.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/cgroup.c	2014-07-01 16:22:13.186329848 +0200
@@ -3014,9 +3014,14 @@
 		 * We should check if the process is exiting, otherwise
 		 * it will race with cgroup_exit() in that the list
 		 * entry won't be deleted though the process has exited.
+		 * Do it while holding siglock so that we don't end up
+		 * racing against cgroup_exit().
 		 */
+		spin_lock_irq(&p->sighand->siglock);
 		if (!(p->flags & PF_EXITING) && list_empty(&p->cg_list))
 			list_add(&p->cg_list, &task_css_set(p)->tasks);
+		spin_unlock_irq(&p->sighand->siglock);
+
 		task_unlock(p);
 	} while_each_thread(g, p);
 	read_unlock(&tasklist_lock);
diff -ruw linux-3.11.10/kernel/events/core.c linux-3.11.10-fbx/kernel/events/core.c
--- linux-3.11.10/kernel/events/core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/events/core.c	2014-07-01 16:22:13.190329866 +0200
@@ -192,7 +192,7 @@
 		void __user *buffer, size_t *lenp,
 		loff_t *ppos)
 {
-	int ret = proc_dointvec(table, write, buffer, lenp, ppos);
+	int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
 
 	if (ret || !write)
 		return ret;
@@ -1423,6 +1423,11 @@
 		cpuctx->exclusive = 0;
 }
 
+struct remove_event {
+	struct perf_event *event;
+	bool detach_group;
+};
+
 /*
  * Cross CPU call to remove a performance event
  *
@@ -1431,12 +1436,15 @@
  */
 static int __perf_remove_from_context(void *info)
 {
-	struct perf_event *event = info;
+	struct remove_event *re = info;
+	struct perf_event *event = re->event;
 	struct perf_event_context *ctx = event->ctx;
 	struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
 
 	raw_spin_lock(&ctx->lock);
 	event_sched_out(event, cpuctx, ctx);
+	if (re->detach_group)
+		perf_group_detach(event);
 	list_del_event(event, ctx);
 	if (!ctx->nr_events && cpuctx->task_ctx == ctx) {
 		ctx->is_active = 0;
@@ -1461,10 +1469,14 @@
  * When called from perf_event_exit_task, it's OK because the
  * context has been detached from its task.
  */
-static void perf_remove_from_context(struct perf_event *event)
+static void perf_remove_from_context(struct perf_event *event, bool detach_group)
 {
 	struct perf_event_context *ctx = event->ctx;
 	struct task_struct *task = ctx->task;
+	struct remove_event re = {
+		.event = event,
+		.detach_group = detach_group,
+	};
 
 	lockdep_assert_held(&ctx->mutex);
 
@@ -1473,12 +1485,12 @@
 		 * Per cpu events are removed via an smp call and
 		 * the removal is always successful.
 		 */
-		cpu_function_call(event->cpu, __perf_remove_from_context, event);
+		cpu_function_call(event->cpu, __perf_remove_from_context, &re);
 		return;
 	}
 
 retry:
-	if (!task_function_call(task, __perf_remove_from_context, event))
+	if (!task_function_call(task, __perf_remove_from_context, &re))
 		return;
 
 	raw_spin_lock_irq(&ctx->lock);
@@ -1495,6 +1507,8 @@
 	 * Since the task isn't running, its safe to remove the event, us
 	 * holding the ctx->lock ensures the task won't get scheduled in.
 	 */
+	if (detach_group)
+		perf_group_detach(event);
 	list_del_event(event, ctx);
 	raw_spin_unlock_irq(&ctx->lock);
 }
@@ -2207,9 +2221,6 @@
 	perf_event_update_userpage(next_event);
 }
 
-#define list_next_entry(pos, member) \
-	list_entry(pos->member.next, typeof(*pos), member)
-
 static void perf_event_sync_stat(struct perf_event_context *ctx,
 				   struct perf_event_context *next_ctx)
 {
@@ -3207,10 +3218,7 @@
 	 *     to trigger the AB-BA case.
 	 */
 	mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING);
-	raw_spin_lock_irq(&ctx->lock);
-	perf_group_detach(event);
-	raw_spin_unlock_irq(&ctx->lock);
-	perf_remove_from_context(event);
+	perf_remove_from_context(event, true);
 	mutex_unlock(&ctx->mutex);
 
 	free_event(event);
@@ -5236,6 +5244,9 @@
 
 	/* Recursion avoidance in each contexts */
 	int				recursion[PERF_NR_CONTEXTS];
+
+	/* Keeps track of cpu being initialized/exited */
+	bool				online;
 };
 
 static DEFINE_PER_CPU(struct swevent_htable, swevent_htable);
@@ -5482,8 +5493,14 @@
 	hwc->state = !(flags & PERF_EF_START);
 
 	head = find_swevent_head(swhash, event);
-	if (WARN_ON_ONCE(!head))
+	if (!head) {
+		/*
+		 * We can race with cpu hotplug code. Do not
+		 * WARN if the cpu just got unplugged.
+		 */
+		WARN_ON_ONCE(swhash->online);
 		return -EINVAL;
+	}
 
 	hlist_add_head_rcu(&event->hlist_entry, head);
 
@@ -6819,6 +6836,9 @@
 	if (attr.freq) {
 		if (attr.sample_freq > sysctl_perf_event_sample_rate)
 			return -EINVAL;
+	} else {
+		if (attr.sample_period & (1ULL << 63))
+			return -EINVAL;
 	}
 
 	/*
@@ -6965,7 +6985,7 @@
 		struct perf_event_context *gctx = group_leader->ctx;
 
 		mutex_lock(&gctx->mutex);
-		perf_remove_from_context(group_leader);
+		perf_remove_from_context(group_leader, false);
 
 		/*
 		 * Removing from the context ends up with disabled
@@ -6975,7 +6995,7 @@
 		perf_event__state_init(group_leader);
 		list_for_each_entry(sibling, &group_leader->sibling_list,
 				    group_entry) {
-			perf_remove_from_context(sibling);
+			perf_remove_from_context(sibling, false);
 			perf_event__state_init(sibling);
 			put_ctx(gctx);
 		}
@@ -7105,7 +7125,7 @@
 	mutex_lock(&src_ctx->mutex);
 	list_for_each_entry_safe(event, tmp, &src_ctx->event_list,
 				 event_entry) {
-		perf_remove_from_context(event);
+		perf_remove_from_context(event, false);
 		put_ctx(src_ctx);
 		list_add(&event->event_entry, &events);
 	}
@@ -7165,13 +7185,7 @@
 			 struct perf_event_context *child_ctx,
 			 struct task_struct *child)
 {
-	if (child_event->parent) {
-		raw_spin_lock_irq(&child_ctx->lock);
-		perf_group_detach(child_event);
-		raw_spin_unlock_irq(&child_ctx->lock);
-	}
-
-	perf_remove_from_context(child_event);
+	perf_remove_from_context(child_event, !!child_event->parent);
 
 	/*
 	 * It can happen that the parent exits first, and has events
@@ -7633,6 +7647,7 @@
 	struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
 
 	mutex_lock(&swhash->hlist_mutex);
+	swhash->online = true;
 	if (swhash->hlist_refcount > 0) {
 		struct swevent_hlist *hlist;
 
@@ -7655,15 +7670,15 @@
 
 static void __perf_event_exit_context(void *__info)
 {
+	struct remove_event re = { .detach_group = false };
 	struct perf_event_context *ctx = __info;
-	struct perf_event *event, *tmp;
 
 	perf_pmu_rotate_stop(ctx->pmu);
 
-	list_for_each_entry_safe(event, tmp, &ctx->pinned_groups, group_entry)
-		__perf_remove_from_context(event);
-	list_for_each_entry_safe(event, tmp, &ctx->flexible_groups, group_entry)
-		__perf_remove_from_context(event);
+	rcu_read_lock();
+	list_for_each_entry_rcu(re.event, &ctx->event_list, event_entry)
+		__perf_remove_from_context(&re);
+	rcu_read_unlock();
 }
 
 static void perf_event_exit_cpu_context(int cpu)
@@ -7687,11 +7702,12 @@
 {
 	struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
 
+	perf_event_exit_cpu_context(cpu);
+
 	mutex_lock(&swhash->hlist_mutex);
+	swhash->online = false;
 	swevent_hlist_release(swhash);
 	mutex_unlock(&swhash->hlist_mutex);
-
-	perf_event_exit_cpu_context(cpu);
 }
 #else
 static inline void perf_event_exit_cpu(int cpu) { }
diff -ruw linux-3.11.10/kernel/exit.c linux-3.11.10-fbx/kernel/exit.c
--- linux-3.11.10/kernel/exit.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/exit.c	2014-08-22 15:47:22.144063186 +0200
@@ -74,6 +74,7 @@
 		__this_cpu_dec(process_counts);
 	}
 	list_del_rcu(&p->thread_group);
+	list_del_rcu(&p->thread_node);
 }
 
 /*
@@ -559,9 +560,6 @@
 				struct list_head *dead)
 {
 	list_move_tail(&p->sibling, &p->real_parent->children);
-
-	if (p->exit_state == EXIT_DEAD)
-		return;
 	/*
 	 * If this is a threaded reparent there is no need to
 	 * notify anyone anything has happened.
@@ -569,9 +567,19 @@
 	if (same_thread_group(p->real_parent, father))
 		return;
 
-	/* We don't want people slaying init.  */
+	/*
+	 * We don't want people slaying init.
+	 *
+	 * Note: we do this even if it is EXIT_DEAD, wait_task_zombie()
+	 * can change ->exit_state to EXIT_ZOMBIE. If this is the final
+	 * state, do_notify_parent() was already called and ->exit_signal
+	 * doesn't matter.
+	 */
 	p->exit_signal = SIGCHLD;
 
+	if (p->exit_state == EXIT_DEAD)
+		return;
+
 	/* If it has exited notify the new parent about this child's death. */
 	if (!p->ptrace &&
 	    p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) {
@@ -783,6 +791,8 @@
 	exit_shm(tsk);
 	exit_files(tsk);
 	exit_fs(tsk);
+	if (group_dead)
+		disassociate_ctty(1);
 	exit_task_namespaces(tsk);
 	exit_task_work(tsk);
 	check_stack_usage();
@@ -798,13 +808,9 @@
 
 	cgroup_exit(tsk, 1);
 
-	if (group_dead)
-		disassociate_ctty(1);
-
 	module_put(task_thread_info(tsk)->exec_domain->module);
 
 	proc_exit_connector(tsk);
-
 	/*
 	 * FIXME: do that only when needed, using sched_exit tracepoint
 	 */
diff -ruw linux-3.11.10/kernel/fork.c linux-3.11.10-fbx/kernel/fork.c
--- linux-3.11.10/kernel/fork.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/fork.c	2014-08-22 15:47:22.144063186 +0200
@@ -214,6 +214,8 @@
 	ftrace_graph_exit_task(tsk);
 	put_seccomp_filter(tsk);
 	arch_release_task_struct(tsk);
+	if (tsk->fbxjail)
+		kfree(tsk->fbxjail);
 	free_task_struct(tsk);
 }
 EXPORT_SYMBOL(free_task);
@@ -335,6 +337,11 @@
 
 	account_kernel_stack(ti, 1);
 
+	/*
+	 * inherit parent exec_mode.
+	 */
+	tsk->exec_mode = orig->exec_mode;
+
 	return tsk;
 
 free_ti:
@@ -540,6 +547,7 @@
 	spin_lock_init(&mm->page_table_lock);
 	mm_init_aio(mm);
 	mm_init_owner(mm, p);
+	clear_tlb_flush_pending(mm);
 
 	if (likely(!mm_alloc_pgd(mm))) {
 		mm->def_flags = 0;
@@ -1040,6 +1048,11 @@
 	sig->nr_threads = 1;
 	atomic_set(&sig->live, 1);
 	atomic_set(&sig->sigcnt, 1);
+
+	/* list_add(thread_node, thread_head) without INIT_LIST_HEAD() */
+	sig->thread_head = (struct list_head)LIST_HEAD_INIT(tsk->thread_node);
+	tsk->thread_node = (struct list_head)LIST_HEAD_INIT(sig->thread_head);
+
 	init_waitqueue_head(&sig->wait_chldexit);
 	sig->curr_target = tsk;
 	init_sigpending(&sig->shared_pending);
@@ -1476,6 +1489,8 @@
 			atomic_inc(&current->signal->sigcnt);
 			list_add_tail_rcu(&p->thread_group,
 					  &p->group_leader->thread_group);
+			list_add_tail_rcu(&p->thread_node,
+					  &p->signal->thread_head);
 		}
 		attach_pid(p, PIDTYPE_PID);
 		nr_threads++;
@@ -1483,7 +1498,9 @@
 
 	total_forks++;
 	spin_unlock(&current->sighand->siglock);
+	syscall_tracepoint_update(p);
 	write_unlock_irq(&tasklist_lock);
+
 	proc_fork_connector(p);
 	cgroup_post_fork(p);
 	if (clone_flags & CLONE_THREAD)
@@ -1611,10 +1628,12 @@
 	 */
 	if (!IS_ERR(p)) {
 		struct completion vfork;
+		struct pid *pid;
 
 		trace_sched_process_fork(current, p);
 
-		nr = task_pid_vnr(p);
+		pid = get_task_pid(p, PIDTYPE_PID);
+		nr = pid_vnr(pid);
 
 		if (clone_flags & CLONE_PARENT_SETTID)
 			put_user(nr, parent_tidptr);
@@ -1629,12 +1648,14 @@
 
 		/* forking complete and child started to run, tell ptracer */
 		if (unlikely(trace))
-			ptrace_event(trace, nr);
+			ptrace_event_pid(trace, pid);
 
 		if (clone_flags & CLONE_VFORK) {
 			if (!wait_for_vfork_done(p, &vfork))
-				ptrace_event(PTRACE_EVENT_VFORK_DONE, nr);
+				ptrace_event_pid(PTRACE_EVENT_VFORK_DONE, pid);
 		}
+
+		put_pid(pid);
 	} else {
 		nr = PTR_ERR(p);
 	}
diff -ruw linux-3.11.10/kernel/freezer.c linux-3.11.10-fbx/kernel/freezer.c
--- linux-3.11.10/kernel/freezer.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/freezer.c	2014-01-17 19:14:18.782220809 +0100
@@ -19,6 +19,12 @@
 bool pm_freezing;
 bool pm_nosig_freezing;
 
+/*
+ * Temporary export for the deadlock workaround in ata_scsi_hotplug().
+ * Remove once the hack becomes unnecessary.
+ */
+EXPORT_SYMBOL_GPL(pm_freezing);
+
 /* protects freezing and frozen transitions */
 static DEFINE_SPINLOCK(freezer_lock);
 
diff -ruw linux-3.11.10/kernel/futex.c linux-3.11.10-fbx/kernel/futex.c
--- linux-3.11.10/kernel/futex.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/futex.c	2014-07-01 16:22:13.190329866 +0200
@@ -68,7 +68,9 @@
 
 #include "rtmutex_common.h"
 
+#ifndef CONFIG_HAVE_FUTEX_CMPXCHG
 int __read_mostly futex_cmpxchg_enabled;
+#endif
 
 #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8)
 
@@ -288,7 +290,7 @@
 		put_page(page);
 		/* serialize against __split_huge_page_splitting() */
 		local_irq_disable();
-		if (likely(__get_user_pages_fast(address, 1, 1, &page) == 1)) {
+		if (likely(__get_user_pages_fast(address, 1, !ro, &page) == 1)) {
 			page_head = compound_head(page);
 			/*
 			 * page_head is valid pointer but we must pin
@@ -591,6 +593,55 @@
 	raw_spin_unlock_irq(&curr->pi_lock);
 }
 
+/*
+ * We need to check the following states:
+ *
+ *      Waiter | pi_state | pi->owner | uTID      | uODIED | ?
+ *
+ * [1]  NULL   | ---      | ---       | 0         | 0/1    | Valid
+ * [2]  NULL   | ---      | ---       | >0        | 0/1    | Valid
+ *
+ * [3]  Found  | NULL     | --        | Any       | 0/1    | Invalid
+ *
+ * [4]  Found  | Found    | NULL      | 0         | 1      | Valid
+ * [5]  Found  | Found    | NULL      | >0        | 1      | Invalid
+ *
+ * [6]  Found  | Found    | task      | 0         | 1      | Valid
+ *
+ * [7]  Found  | Found    | NULL      | Any       | 0      | Invalid
+ *
+ * [8]  Found  | Found    | task      | ==taskTID | 0/1    | Valid
+ * [9]  Found  | Found    | task      | 0         | 0      | Invalid
+ * [10] Found  | Found    | task      | !=taskTID | 0/1    | Invalid
+ *
+ * [1]	Indicates that the kernel can acquire the futex atomically. We
+ *	came came here due to a stale FUTEX_WAITERS/FUTEX_OWNER_DIED bit.
+ *
+ * [2]	Valid, if TID does not belong to a kernel thread. If no matching
+ *      thread is found then it indicates that the owner TID has died.
+ *
+ * [3]	Invalid. The waiter is queued on a non PI futex
+ *
+ * [4]	Valid state after exit_robust_list(), which sets the user space
+ *	value to FUTEX_WAITERS | FUTEX_OWNER_DIED.
+ *
+ * [5]	The user space value got manipulated between exit_robust_list()
+ *	and exit_pi_state_list()
+ *
+ * [6]	Valid state after exit_pi_state_list() which sets the new owner in
+ *	the pi_state but cannot access the user space value.
+ *
+ * [7]	pi_state->owner can only be NULL when the OWNER_DIED bit is set.
+ *
+ * [8]	Owner and user space value match
+ *
+ * [9]	There is no transient state which sets the user space TID to 0
+ *	except exit_robust_list(), but this is indicated by the
+ *	FUTEX_OWNER_DIED bit. See [4]
+ *
+ * [10] There is no transient state which leaves owner and user space
+ *	TID out of sync.
+ */
 static int
 lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
 		union futex_key *key, struct futex_pi_state **ps)
@@ -606,12 +657,13 @@
 	plist_for_each_entry_safe(this, next, head, list) {
 		if (match_futex(&this->key, key)) {
 			/*
-			 * Another waiter already exists - bump up
-			 * the refcount and return its pi_state:
+			 * Sanity check the waiter before increasing
+			 * the refcount and attaching to it.
 			 */
 			pi_state = this->pi_state;
 			/*
-			 * Userspace might have messed up non-PI and PI futexes
+			 * Userspace might have messed up non-PI and
+			 * PI futexes [3]
 			 */
 			if (unlikely(!pi_state))
 				return -EINVAL;
@@ -619,34 +671,70 @@
 			WARN_ON(!atomic_read(&pi_state->refcount));
 
 			/*
-			 * When pi_state->owner is NULL then the owner died
-			 * and another waiter is on the fly. pi_state->owner
-			 * is fixed up by the task which acquires
-			 * pi_state->rt_mutex.
-			 *
-			 * We do not check for pid == 0 which can happen when
-			 * the owner died and robust_list_exit() cleared the
-			 * TID.
+			 * Handle the owner died case:
+			 */
+			if (uval & FUTEX_OWNER_DIED) {
+				/*
+				 * exit_pi_state_list sets owner to NULL and
+				 * wakes the topmost waiter. The task which
+				 * acquires the pi_state->rt_mutex will fixup
+				 * owner.
+				 */
+				if (!pi_state->owner) {
+					/*
+					 * No pi state owner, but the user
+					 * space TID is not 0. Inconsistent
+					 * state. [5]
+					 */
+					if (pid)
+						return -EINVAL;
+					/*
+					 * Take a ref on the state and
+					 * return. [4]
+					 */
+					goto out_state;
+				}
+
+				/*
+				 * If TID is 0, then either the dying owner
+				 * has not yet executed exit_pi_state_list()
+				 * or some waiter acquired the rtmutex in the
+				 * pi state, but did not yet fixup the TID in
+				 * user space.
+				 *
+				 * Take a ref on the state and return. [6]
 			 */
-			if (pid && pi_state->owner) {
+				if (!pid)
+					goto out_state;
+			} else {
+				/*
+				 * If the owner died bit is not set,
+				 * then the pi_state must have an
+				 * owner. [7]
+				 */
+				if (!pi_state->owner)
+					return -EINVAL;
+			}
+
 				/*
 				 * Bail out if user space manipulated the
-				 * futex value.
+			 * futex value. If pi state exists then the
+			 * owner TID must be the same as the user
+			 * space TID. [9/10]
 				 */
 				if (pid != task_pid_vnr(pi_state->owner))
 					return -EINVAL;
-			}
 
+		out_state:
 			atomic_inc(&pi_state->refcount);
 			*ps = pi_state;
-
 			return 0;
 		}
 	}
 
 	/*
 	 * We are the first waiter - try to look up the real owner and attach
-	 * the new pi_state to it, but bail out when TID = 0
+	 * the new pi_state to it, but bail out when TID = 0 [1]
 	 */
 	if (!pid)
 		return -ESRCH;
@@ -654,6 +742,11 @@
 	if (!p)
 		return -ESRCH;
 
+	if (!p->mm) {
+		put_task_struct(p);
+		return -EPERM;
+	}
+
 	/*
 	 * We need to look at the task state flags to figure out,
 	 * whether the task is exiting. To protect against the do_exit
@@ -674,6 +767,9 @@
 		return ret;
 	}
 
+	/*
+	 * No existing pi state. First waiter. [2]
+	 */
 	pi_state = alloc_pi_state();
 
 	/*
@@ -745,10 +841,18 @@
 		return -EDEADLK;
 
 	/*
-	 * Surprise - we got the lock. Just return to userspace:
+	 * Surprise - we got the lock, but we do not trust user space at all.
 	 */
-	if (unlikely(!curval))
-		return 1;
+	if (unlikely(!curval)) {
+		/*
+		 * We verify whether there is kernel state for this
+		 * futex. If not, we can safely assume, that the 0 ->
+		 * TID transition is correct. If state exists, we do
+		 * not bother to fixup the user space state as it was
+		 * corrupted already.
+		 */
+		return futex_top_waiter(hb, key) ? -EINVAL : 1;
+	}
 
 	uval = curval;
 
@@ -878,6 +982,7 @@
 	struct task_struct *new_owner;
 	struct futex_pi_state *pi_state = this->pi_state;
 	u32 uninitialized_var(curval), newval;
+	int ret = 0;
 
 	if (!pi_state)
 		return -EINVAL;
@@ -901,13 +1006,10 @@
 		new_owner = this->task;
 
 	/*
-	 * We pass it to the next owner. (The WAITERS bit is always
-	 * kept enabled while there is PI state around. We must also
-	 * preserve the owner died bit.)
+	 * We pass it to the next owner. The WAITERS bit is always
+	 * kept enabled while there is PI state around. We cleanup the
+	 * owner died bit, because we are the owner.
 	 */
-	if (!(uval & FUTEX_OWNER_DIED)) {
-		int ret = 0;
-
 		newval = FUTEX_WAITERS | task_pid_vnr(new_owner);
 
 		if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))
@@ -918,7 +1020,6 @@
 			raw_spin_unlock(&pi_state->pi_mutex.wait_lock);
 			return ret;
 		}
-	}
 
 	raw_spin_lock_irq(&pi_state->owner->pi_lock);
 	WARN_ON(list_empty(&pi_state->list));
@@ -1196,7 +1297,7 @@
  *
  * Return:
  *  0 - failed to acquire the lock atomically;
- *  1 - acquired the lock;
+ * >0 - acquired the lock, return value is vpid of the top_waiter
  * <0 - error
  */
 static int futex_proxy_trylock_atomic(u32 __user *pifutex,
@@ -1207,7 +1308,7 @@
 {
 	struct futex_q *top_waiter = NULL;
 	u32 curval;
-	int ret;
+	int ret, vpid;
 
 	if (get_futex_value_locked(&curval, pifutex))
 		return -EFAULT;
@@ -1235,11 +1336,13 @@
 	 * the contended case or if set_waiters is 1.  The pi_state is returned
 	 * in ps in contended cases.
 	 */
+	vpid = task_pid_vnr(top_waiter->task);
 	ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task,
 				   set_waiters);
-	if (ret == 1)
+	if (ret == 1) {
 		requeue_pi_wake_futex(top_waiter, key2, hb2);
-
+		return vpid;
+	}
 	return ret;
 }
 
@@ -1271,10 +1374,16 @@
 	struct futex_hash_bucket *hb1, *hb2;
 	struct plist_head *head1;
 	struct futex_q *this, *next;
-	u32 curval2;
 
 	if (requeue_pi) {
 		/*
+		 * Requeue PI only works on two distinct uaddrs. This
+		 * check is only valid for private futexes. See below.
+		 */
+		if (uaddr1 == uaddr2)
+			return -EINVAL;
+
+		/*
 		 * requeue_pi requires a pi_state, try to allocate it now
 		 * without any locks in case it fails.
 		 */
@@ -1312,6 +1421,15 @@
 	if (unlikely(ret != 0))
 		goto out_put_key1;
 
+	/*
+	 * The check above which compares uaddrs is not sufficient for
+	 * shared futexes. We need to compare the keys:
+	 */
+	if (requeue_pi && match_futex(&key1, &key2)) {
+		ret = -EINVAL;
+		goto out_put_keys;
+	}
+
 	hb1 = hash_futex(&key1);
 	hb2 = hash_futex(&key2);
 
@@ -1357,16 +1475,25 @@
 		 * At this point the top_waiter has either taken uaddr2 or is
 		 * waiting on it.  If the former, then the pi_state will not
 		 * exist yet, look it up one more time to ensure we have a
-		 * reference to it.
+		 * reference to it. If the lock was taken, ret contains the
+		 * vpid of the top waiter task.
 		 */
-		if (ret == 1) {
+		if (ret > 0) {
 			WARN_ON(pi_state);
 			drop_count++;
 			task_count++;
-			ret = get_futex_value_locked(&curval2, uaddr2);
-			if (!ret)
-				ret = lookup_pi_state(curval2, hb2, &key2,
-						      &pi_state);
+			/*
+			 * If we acquired the lock, then the user
+			 * space value of uaddr2 should be vpid. It
+			 * cannot be changed by the top waiter as it
+			 * is blocked on hb2 lock if it tries to do
+			 * so. If something fiddled with it behind our
+			 * back the pi state lookup might unearth
+			 * it. So we rather use the known value than
+			 * rereading and handing potential crap to
+			 * lookup_pi_state.
+			 */
+			ret = lookup_pi_state(ret, hb2, &key2, &pi_state);
 		}
 
 		switch (ret) {
@@ -2136,9 +2263,10 @@
 	/*
 	 * To avoid races, try to do the TID -> 0 atomic transition
 	 * again. If it succeeds then we can return without waking
-	 * anyone else up:
+	 * anyone else up. We only try this if neither the waiters nor
+	 * the owner died bit are set.
 	 */
-	if (!(uval & FUTEX_OWNER_DIED) &&
+	if (!(uval & ~FUTEX_TID_MASK) &&
 	    cmpxchg_futex_value_locked(&uval, uaddr, vpid, 0))
 		goto pi_faulted;
 	/*
@@ -2170,11 +2298,9 @@
 	/*
 	 * No waiters - kernel unlocks the futex:
 	 */
-	if (!(uval & FUTEX_OWNER_DIED)) {
 		ret = unlock_futex_pi(uaddr, uval);
 		if (ret == -EFAULT)
 			goto pi_faulted;
-	}
 
 out_unlock:
 	spin_unlock(&hb->lock);
@@ -2333,6 +2459,15 @@
 	if (ret)
 		goto out_key2;
 
+	/*
+	 * The check above which compares uaddrs is not sufficient for
+	 * shared futexes. We need to compare the keys:
+	 */
+	if (match_futex(&q.key, &key2)) {
+		ret = -EINVAL;
+		goto out_put_keys;
+	}
+
 	/* Queue the futex_q, drop the hb lock, wait for wakeup. */
 	futex_wait_queue_me(hb, &q, to);
 
@@ -2730,10 +2865,10 @@
 	return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
 }
 
-static int __init futex_init(void)
+static void __init futex_detect_cmpxchg(void)
 {
+#ifndef CONFIG_HAVE_FUTEX_CMPXCHG
 	u32 curval;
-	int i;
 
 	/*
 	 * This will fail and we want it. Some arch implementations do
@@ -2747,6 +2882,14 @@
 	 */
 	if (cmpxchg_futex_value_locked(&curval, NULL, 0, 0) == -EFAULT)
 		futex_cmpxchg_enabled = 1;
+#endif
+}
+
+static int __init futex_init(void)
+{
+	int i;
+
+	futex_detect_cmpxchg();
 
 	for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
 		plist_head_init(&futex_queues[i].chain);
diff -ruw linux-3.11.10/kernel/hrtimer.c linux-3.11.10-fbx/kernel/hrtimer.c
--- linux-3.11.10/kernel/hrtimer.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/hrtimer.c	2014-07-01 16:22:13.190329866 +0200
@@ -246,6 +246,11 @@
 			goto again;
 		}
 		timer->base = new_base;
+	} else {
+		if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) {
+			cpu = this_cpu;
+			goto again;
+		}
 	}
 	return new_base;
 }
@@ -581,6 +586,23 @@
 
 	cpu_base->expires_next.tv64 = expires_next.tv64;
 
+	/*
+	 * If a hang was detected in the last timer interrupt then we
+	 * leave the hang delay active in the hardware. We want the
+	 * system to make progress. That also prevents the following
+	 * scenario:
+	 * T1 expires 50ms from now
+	 * T2 expires 5s from now
+	 *
+	 * T1 is removed, so this code is called and would reprogram
+	 * the hardware to 5s from now. Any hrtimer_start after that
+	 * will not reprogram the hardware due to hang_detected being
+	 * set. So we'd effectivly block all timers until the T2 event
+	 * fires.
+	 */
+	if (cpu_base->hang_detected)
+		return;
+
 	if (cpu_base->expires_next.tv64 != KTIME_MAX)
 		tick_program_event(cpu_base->expires_next, 1);
 }
@@ -980,11 +1002,8 @@
 	/* Remove an active timer from the queue: */
 	ret = remove_hrtimer(timer, base);
 
-	/* Switch the timer base, if necessary: */
-	new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
-
 	if (mode & HRTIMER_MODE_REL) {
-		tim = ktime_add_safe(tim, new_base->get_time());
+		tim = ktime_add_safe(tim, base->get_time());
 		/*
 		 * CONFIG_TIME_LOW_RES is a temporary way for architectures
 		 * to signal that they simply return xtime in
@@ -999,6 +1018,9 @@
 
 	hrtimer_set_expires_range_ns(timer, tim, delta_ns);
 
+	/* Switch the timer base, if necessary: */
+	new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
+
 	timer_stats_hrtimer_set_start_info(timer);
 
 	leftmost = enqueue_hrtimer(timer, new_base);
diff -ruw linux-3.11.10/kernel/irq/irqdesc.c linux-3.11.10-fbx/kernel/irq/irqdesc.c
--- linux-3.11.10/kernel/irq/irqdesc.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/irq/irqdesc.c	2014-05-09 14:12:54.344546160 +0200
@@ -274,6 +274,7 @@
 {
 	return (irq < NR_IRQS) ? irq_desc + irq : NULL;
 }
+EXPORT_SYMBOL(irq_to_desc);
 
 static void free_desc(unsigned int irq)
 {
diff -ruw linux-3.11.10/kernel/irq/Kconfig linux-3.11.10-fbx/kernel/irq/Kconfig
--- linux-3.11.10/kernel/irq/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/irq/Kconfig	2014-05-09 14:12:54.344546160 +0200
@@ -51,6 +51,7 @@
 # Generic configurable interrupt chip implementation
 config GENERIC_IRQ_CHIP
        bool
+       select IRQ_DOMAIN
 
 # Generic irq_domain hw <--> linux irq number translation
 config IRQ_DOMAIN
diff -ruw linux-3.11.10/kernel/irq/manage.c linux-3.11.10-fbx/kernel/irq/manage.c
--- linux-3.11.10/kernel/irq/manage.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/irq/manage.c	2014-08-22 15:47:22.144063186 +0200
@@ -150,7 +150,7 @@
 	struct irq_chip *chip = irq_data_get_irq_chip(data);
 	int ret;
 
-	ret = chip->irq_set_affinity(data, mask, false);
+	ret = chip->irq_set_affinity(data, mask, force);
 	switch (ret) {
 	case IRQ_SET_MASK_OK:
 		cpumask_copy(data->affinity, mask);
@@ -162,7 +162,8 @@
 	return ret;
 }
 
-int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask)
+int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask,
+			    bool force)
 {
 	struct irq_chip *chip = irq_data_get_irq_chip(data);
 	struct irq_desc *desc = irq_data_to_desc(data);
@@ -172,7 +173,7 @@
 		return -EINVAL;
 
 	if (irq_can_move_pcntxt(data)) {
-		ret = irq_do_set_affinity(data, mask, false);
+		ret = irq_do_set_affinity(data, mask, force);
 	} else {
 		irqd_set_move_pending(data);
 		irq_copy_pending(desc, mask);
@@ -187,13 +188,7 @@
 	return ret;
 }
 
-/**
- *	irq_set_affinity - Set the irq affinity of a given irq
- *	@irq:		Interrupt to set affinity
- *	@mask:		cpumask
- *
- */
-int irq_set_affinity(unsigned int irq, const struct cpumask *mask)
+int __irq_set_affinity(unsigned int irq, const struct cpumask *mask, bool force)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
 	unsigned long flags;
@@ -203,7 +198,7 @@
 		return -EINVAL;
 
 	raw_spin_lock_irqsave(&desc->lock, flags);
-	ret =  __irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask);
+	ret = irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask, force);
 	raw_spin_unlock_irqrestore(&desc->lock, flags);
 	return ret;
 }
@@ -802,8 +797,7 @@
 
 static void wake_threads_waitq(struct irq_desc *desc)
 {
-	if (atomic_dec_and_test(&desc->threads_active) &&
-	    waitqueue_active(&desc->wait_for_threads))
+	if (atomic_dec_and_test(&desc->threads_active))
 		wake_up(&desc->wait_for_threads);
 }
 
@@ -862,8 +856,8 @@
 		irq_thread_check_affinity(desc, action);
 
 		action_ret = handler_fn(desc, action);
-		if (!noirqdebug)
-			note_interrupt(action->irq, desc, action_ret);
+		if (action_ret == IRQ_HANDLED)
+			atomic_inc(&desc->threads_handled);
 
 		wake_threads_waitq(desc);
 	}
@@ -956,7 +950,7 @@
 			goto out_mput;
 		}
 
-		sched_setscheduler(t, SCHED_FIFO, &param);
+		sched_setscheduler_nocheck(t, SCHED_FIFO, &param);
 
 		/*
 		 * We keep the reference to the task struct even if
diff -ruw linux-3.11.10/kernel/irq/spurious.c linux-3.11.10-fbx/kernel/irq/spurious.c
--- linux-3.11.10/kernel/irq/spurious.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/irq/spurious.c	2014-08-22 15:47:22.144063186 +0200
@@ -265,21 +265,119 @@
 	return action && (action->flags & IRQF_IRQPOLL);
 }
 
+#define SPURIOUS_DEFERRED	0x80000000
+
 void note_interrupt(unsigned int irq, struct irq_desc *desc,
 		    irqreturn_t action_ret)
 {
 	if (desc->istate & IRQS_POLL_INPROGRESS)
 		return;
 
-	/* we get here again via the threaded handler */
-	if (action_ret == IRQ_WAKE_THREAD)
-		return;
-
 	if (bad_action_ret(action_ret)) {
 		report_bad_irq(irq, desc, action_ret);
 		return;
 	}
 
+	/*
+	 * We cannot call note_interrupt from the threaded handler
+	 * because we need to look at the compound of all handlers
+	 * (primary and threaded). Aside of that in the threaded
+	 * shared case we have no serialization against an incoming
+	 * hardware interrupt while we are dealing with a threaded
+	 * result.
+	 *
+	 * So in case a thread is woken, we just note the fact and
+	 * defer the analysis to the next hardware interrupt.
+	 *
+	 * The threaded handlers store whether they sucessfully
+	 * handled an interrupt and we check whether that number
+	 * changed versus the last invocation.
+	 *
+	 * We could handle all interrupts with the delayed by one
+	 * mechanism, but for the non forced threaded case we'd just
+	 * add pointless overhead to the straight hardirq interrupts
+	 * for the sake of a few lines less code.
+	 */
+	if (action_ret & IRQ_WAKE_THREAD) {
+		/*
+		 * There is a thread woken. Check whether one of the
+		 * shared primary handlers returned IRQ_HANDLED. If
+		 * not we defer the spurious detection to the next
+		 * interrupt.
+		 */
+		if (action_ret == IRQ_WAKE_THREAD) {
+			int handled;
+			/*
+			 * We use bit 31 of thread_handled_last to
+			 * denote the deferred spurious detection
+			 * active. No locking necessary as
+			 * thread_handled_last is only accessed here
+			 * and we have the guarantee that hard
+			 * interrupts are not reentrant.
+			 */
+			if (!(desc->threads_handled_last & SPURIOUS_DEFERRED)) {
+				desc->threads_handled_last |= SPURIOUS_DEFERRED;
+				return;
+			}
+			/*
+			 * Check whether one of the threaded handlers
+			 * returned IRQ_HANDLED since the last
+			 * interrupt happened.
+			 *
+			 * For simplicity we just set bit 31, as it is
+			 * set in threads_handled_last as well. So we
+			 * avoid extra masking. And we really do not
+			 * care about the high bits of the handled
+			 * count. We just care about the count being
+			 * different than the one we saw before.
+			 */
+			handled = atomic_read(&desc->threads_handled);
+			handled |= SPURIOUS_DEFERRED;
+			if (handled != desc->threads_handled_last) {
+				action_ret = IRQ_HANDLED;
+				/*
+				 * Note: We keep the SPURIOUS_DEFERRED
+				 * bit set. We are handling the
+				 * previous invocation right now.
+				 * Keep it for the current one, so the
+				 * next hardware interrupt will
+				 * account for it.
+				 */
+				desc->threads_handled_last = handled;
+			} else {
+				/*
+				 * None of the threaded handlers felt
+				 * responsible for the last interrupt
+				 *
+				 * We keep the SPURIOUS_DEFERRED bit
+				 * set in threads_handled_last as we
+				 * need to account for the current
+				 * interrupt as well.
+				 */
+				action_ret = IRQ_NONE;
+			}
+		} else {
+			/*
+			 * One of the primary handlers returned
+			 * IRQ_HANDLED. So we don't care about the
+			 * threaded handlers on the same line. Clear
+			 * the deferred detection bit.
+			 *
+			 * In theory we could/should check whether the
+			 * deferred bit is set and take the result of
+			 * the previous run into account here as
+			 * well. But it's really not worth the
+			 * trouble. If every other interrupt is
+			 * handled we never trigger the spurious
+			 * detector. And if this is just the one out
+			 * of 100k unhandled ones which is handled
+			 * then we merily delay the spurious detection
+			 * by one hard interrupt. Not a real problem.
+			 */
+			desc->threads_handled_last &= ~SPURIOUS_DEFERRED;
+		}
+	}
+
 	if (unlikely(action_ret == IRQ_NONE)) {
 		/*
 		 * If we are seeing only the odd spurious IRQ caused by
diff -ruw linux-3.11.10/kernel/module.c linux-3.11.10-fbx/kernel/module.c
--- linux-3.11.10/kernel/module.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/module.c	2014-07-01 16:22:13.190329866 +0200
@@ -3288,6 +3288,9 @@
 
 	dynamic_debug_setup(info->debug, info->num_debug);
 
+	/* Ftrace init must be called in the MODULE_STATE_UNFORMED state */
+	ftrace_module_init(mod);
+
 	/* Finally it's fully formed, ready to start executing. */
 	err = complete_formation(mod, info);
 	if (err)
diff -ruw linux-3.11.10/kernel/pid.c linux-3.11.10-fbx/kernel/pid.c
--- linux-3.11.10/kernel/pid.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/pid.c	2013-12-17 18:03:43.031570857 +0100
@@ -81,7 +81,7 @@
 	.user_ns = &init_user_ns,
 	.proc_inum = PROC_PID_INIT_INO,
 };
-EXPORT_SYMBOL_GPL(init_pid_ns);
+EXPORT_SYMBOL(init_pid_ns);
 
 /*
  * Note: disable interrupts while the pidmap_lock is held as an
diff -ruw linux-3.11.10/kernel/pid_namespace.c linux-3.11.10-fbx/kernel/pid_namespace.c
--- linux-3.11.10/kernel/pid_namespace.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/pid_namespace.c	2014-07-01 16:22:13.190329866 +0200
@@ -312,7 +312,9 @@
 	struct pid_namespace *ns;
 
 	rcu_read_lock();
-	ns = get_pid_ns(task_active_pid_ns(task));
+	ns = task_active_pid_ns(task);
+	if (ns)
+		get_pid_ns(ns);
 	rcu_read_unlock();
 
 	return ns;
diff -ruw linux-3.11.10/kernel/printk/printk.c linux-3.11.10-fbx/kernel/printk/printk.c
--- linux-3.11.10/kernel/printk/printk.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/printk/printk.c	2014-07-01 16:22:13.190329866 +0200
@@ -54,6 +54,10 @@
 #include "console_cmdline.h"
 #include "braille.h"
 
+#ifdef CONFIG_DEBUG_LL
+extern void printascii(char *);
+#endif
+
 /* printk's without a loglevel use this.. */
 #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL
 
@@ -1080,7 +1084,6 @@
 		next_seq = log_next_seq;
 
 		len = 0;
-		prev = 0;
 		while (len >= 0 && seq < next_seq) {
 			struct printk_log *msg = log_from_idx(idx);
 			int textlen;
@@ -1547,6 +1550,10 @@
 	 */
 	text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
 
+#ifdef CONFIG_DEBUG_LL
+	printascii(text);
+#endif
+
 	/* mark and strip a trailing newline */
 	if (text_len && text[text_len-1] == '\n') {
 		text_len--;
@@ -2783,7 +2790,6 @@
 	next_idx = idx;
 
 	l = 0;
-	prev = 0;
 	while (seq < dumper->next_seq) {
 		struct printk_log *msg = log_from_idx(idx);
 
diff -ruw linux-3.11.10/kernel/reboot.c linux-3.11.10-fbx/kernel/reboot.c
--- linux-3.11.10/kernel/reboot.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/reboot.c	2014-01-17 19:14:18.782220809 +0100
@@ -104,7 +104,7 @@
 }
 EXPORT_SYMBOL(unregister_reboot_notifier);
 
-static void migrate_to_reboot_cpu(void)
+void migrate_to_reboot_cpu(void)
 {
 	/* The boot cpu is always logical cpu 0 */
 	int cpu = reboot_cpu;
diff -ruw linux-3.11.10/kernel/resource.c linux-3.11.10-fbx/kernel/resource.c
--- linux-3.11.10/kernel/resource.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/resource.c	2013-12-04 14:33:27.499479109 +0100
@@ -342,15 +342,14 @@
 	read_lock(&resource_lock);
 	for (p = iomem_resource.child; p ; p = p->sibling) {
 		/* system ram is just marked as IORESOURCE_MEM */
-		if (p->flags != res->flags)
-			continue;
-		if (name && strcmp(p->name, name))
-			continue;
 		if (p->start > end) {
 			p = NULL;
 			break;
 		}
-		if ((p->end >= start) && (p->start < end))
+		if (p->flags != res->flags)
+			continue;
+		if ((p->end >= start) && (p->start < end) &&
+		    (name == NULL || !strcmp(p->name, name)))
 			break;
 	}
 	read_unlock(&resource_lock);
diff -ruw linux-3.11.10/kernel/rtmutex.c linux-3.11.10-fbx/kernel/rtmutex.c
--- linux-3.11.10/kernel/rtmutex.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/rtmutex.c	2014-08-22 15:47:22.144063186 +0200
@@ -82,6 +82,47 @@
 		owner = *p;
 	} while (cmpxchg(p, owner, owner | RT_MUTEX_HAS_WAITERS) != owner);
 }
+
+/*
+ * Safe fastpath aware unlock:
+ * 1) Clear the waiters bit
+ * 2) Drop lock->wait_lock
+ * 3) Try to unlock the lock with cmpxchg
+ */
+static inline bool unlock_rt_mutex_safe(struct rt_mutex *lock)
+	__releases(lock->wait_lock)
+{
+	struct task_struct *owner = rt_mutex_owner(lock);
+
+	clear_rt_mutex_waiters(lock);
+	raw_spin_unlock(&lock->wait_lock);
+	/*
+	 * If a new waiter comes in between the unlock and the cmpxchg
+	 * we have two situations:
+	 *
+	 * unlock(wait_lock);
+	 *					lock(wait_lock);
+	 * cmpxchg(p, owner, 0) == owner
+	 *					mark_rt_mutex_waiters(lock);
+	 *					acquire(lock);
+	 * or:
+	 *
+	 * unlock(wait_lock);
+	 *					lock(wait_lock);
+	 *					mark_rt_mutex_waiters(lock);
+	 *
+	 * cmpxchg(p, owner, 0) != owner
+	 *					enqueue_waiter();
+	 *					unlock(wait_lock);
+	 * lock(wait_lock);
+	 * wake waiter();
+	 * unlock(wait_lock);
+	 *					lock(wait_lock);
+	 *					acquire(lock);
+	 */
+	return rt_mutex_cmpxchg(lock, owner, NULL);
+}
+
 #else
 # define rt_mutex_cmpxchg(l,c,n)	(0)
 static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
@@ -89,6 +130,17 @@
 	lock->owner = (struct task_struct *)
 			((unsigned long)lock->owner | RT_MUTEX_HAS_WAITERS);
 }
+
+/*
+ * Simple slow path only version: lock->owner is protected by lock->wait_lock.
+ */
+static inline bool unlock_rt_mutex_safe(struct rt_mutex *lock)
+	__releases(lock->wait_lock)
+{
+	lock->owner = NULL;
+	raw_spin_unlock(&lock->wait_lock);
+	return true;
+}
 #endif
 
 /*
@@ -142,16 +194,24 @@
  */
 int max_lock_depth = 1024;
 
+static inline struct rt_mutex *task_blocked_on_lock(struct task_struct *p)
+{
+	return p->pi_blocked_on ? p->pi_blocked_on->lock : NULL;
+}
+
 /*
  * Adjust the priority chain. Also used for deadlock detection.
  * Decreases task's usage by one - may thus free the task.
  *
- * @task: the task owning the mutex (owner) for which a chain walk is probably
- *	  needed
+ * @task:	the task owning the mutex (owner) for which a chain walk is
+ *		probably needed
  * @deadlock_detect: do we have to carry out deadlock detection?
  * @orig_lock: the mutex (can be NULL if we are walking the chain to recheck
  * 	       things for a task that has just got its priority adjusted, and
  *	       is waiting on a mutex)
+ * @next_lock:	the mutex on which the owner of @orig_lock was blocked before
+ *		we dropped its pi_lock. Is never dereferenced, only used for
+ *		comparison to detect lock chain changes.
  * @orig_waiter: rt_mutex_waiter struct for the task that has just donated
  *		 its priority to the mutex owner (can be NULL in the case
  *		 depicted above or if the top waiter is gone away and we are
@@ -163,6 +223,7 @@
 static int rt_mutex_adjust_prio_chain(struct task_struct *task,
 				      int deadlock_detect,
 				      struct rt_mutex *orig_lock,
+				      struct rt_mutex *next_lock,
 				      struct rt_mutex_waiter *orig_waiter,
 				      struct task_struct *top_task)
 {
@@ -196,7 +257,7 @@
 		}
 		put_task_struct(task);
 
-		return deadlock_detect ? -EDEADLK : 0;
+		return -EDEADLK;
 	}
  retry:
 	/*
@@ -221,13 +282,32 @@
 		goto out_unlock_pi;
 
 	/*
+	 * We dropped all locks after taking a refcount on @task, so
+	 * the task might have moved on in the lock chain or even left
+	 * the chain completely and blocks now on an unrelated lock or
+	 * on @orig_lock.
+	 *
+	 * We stored the lock on which @task was blocked in @next_lock,
+	 * so we can detect the chain change.
+	 */
+	if (next_lock != waiter->lock)
+		goto out_unlock_pi;
+
+	/*
 	 * Drop out, when the task has no waiters. Note,
 	 * top_waiter can be NULL, when we are in the deboosting
 	 * mode!
 	 */
-	if (top_waiter && (!task_has_pi_waiters(task) ||
-			   top_waiter != task_top_pi_waiter(task)))
+	if (top_waiter) {
+		if (!task_has_pi_waiters(task))
+			goto out_unlock_pi;
+		/*
+		 * If deadlock detection is off, we stop here if we
+		 * are not the top pi waiter of the task.
+		 */
+		if (!detect_deadlock && top_waiter != task_top_pi_waiter(task))
 		goto out_unlock_pi;
+	}
 
 	/*
 	 * When deadlock detection is off then we check, if further
@@ -243,11 +323,16 @@
 		goto retry;
 	}
 
-	/* Deadlock detection */
+	/*
+	 * Deadlock detection. If the lock is the same as the original
+	 * lock which caused us to walk the lock chain or if the
+	 * current lock is owned by the task which initiated the chain
+	 * walk, we detected a deadlock.
+	 */
 	if (lock == orig_lock || rt_mutex_owner(lock) == top_task) {
 		debug_rt_mutex_deadlock(deadlock_detect, orig_waiter, lock);
 		raw_spin_unlock(&lock->wait_lock);
-		ret = deadlock_detect ? -EDEADLK : 0;
+		ret = -EDEADLK;
 		goto out_unlock_pi;
 	}
 
@@ -294,11 +379,26 @@
 		__rt_mutex_adjust_prio(task);
 	}
 
+	/*
+	 * Check whether the task which owns the current lock is pi
+	 * blocked itself. If yes we store a pointer to the lock for
+	 * the lock chain change detection above. After we dropped
+	 * task->pi_lock next_lock cannot be dereferenced anymore.
+	 */
+	next_lock = task_blocked_on_lock(task);
+
 	raw_spin_unlock_irqrestore(&task->pi_lock, flags);
 
 	top_waiter = rt_mutex_top_waiter(lock);
 	raw_spin_unlock(&lock->wait_lock);
 
+	/*
+	 * We reached the end of the lock chain. Stop right here. No
+	 * point to go back just to figure that out.
+	 */
+	if (!next_lock)
+		goto out_put_task;
+
 	if (!detect_deadlock && waiter != top_waiter)
 		goto out_put_task;
 
@@ -409,8 +509,21 @@
 {
 	struct task_struct *owner = rt_mutex_owner(lock);
 	struct rt_mutex_waiter *top_waiter = waiter;
-	unsigned long flags;
+	struct rt_mutex *next_lock;
 	int chain_walk = 0, res;
+	unsigned long flags;
+
+	/*
+	 * Early deadlock detection. We really don't want the task to
+	 * enqueue on itself just to untangle the mess later. It's not
+	 * only an optimization. We drop the locks, so another waiter
+	 * can come in before the chain walk detects the deadlock. So
+	 * the other will detect the deadlock and return -EDEADLOCK,
+	 * which is wrong, as the other waiter is not in a deadlock
+	 * situation.
+	 */
+	if (owner == task)
+		return -EDEADLK;
 
 	raw_spin_lock_irqsave(&task->pi_lock, flags);
 	__rt_mutex_adjust_prio(task);
@@ -431,20 +544,28 @@
 	if (!owner)
 		return 0;
 
-	if (waiter == rt_mutex_top_waiter(lock)) {
 		raw_spin_lock_irqsave(&owner->pi_lock, flags);
+	if (waiter == rt_mutex_top_waiter(lock)) {
 		plist_del(&top_waiter->pi_list_entry, &owner->pi_waiters);
 		plist_add(&waiter->pi_list_entry, &owner->pi_waiters);
 
 		__rt_mutex_adjust_prio(owner);
 		if (owner->pi_blocked_on)
 			chain_walk = 1;
-		raw_spin_unlock_irqrestore(&owner->pi_lock, flags);
-	}
-	else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock))
+	} else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock)) {
 		chain_walk = 1;
+	}
 
-	if (!chain_walk)
+	/* Store the lock on which owner is blocked or NULL */
+	next_lock = task_blocked_on_lock(owner);
+
+	raw_spin_unlock_irqrestore(&owner->pi_lock, flags);
+	/*
+	 * Even if full deadlock detection is on, if the owner is not
+	 * blocked itself, we can avoid finding this out in the chain
+	 * walk.
+	 */
+	if (!chain_walk || !next_lock)
 		return 0;
 
 	/*
@@ -456,8 +577,8 @@
 
 	raw_spin_unlock(&lock->wait_lock);
 
-	res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock, waiter,
-					 task);
+	res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock,
+					 next_lock, waiter, task);
 
 	raw_spin_lock(&lock->wait_lock);
 
@@ -467,7 +588,8 @@
 /*
  * Wake up the next waiter on the lock.
  *
- * Remove the top waiter from the current tasks waiter list and wake it up.
+ * Remove the top waiter from the current tasks pi waiter list and
+ * wake it up.
  *
  * Called with lock->wait_lock held.
  */
@@ -488,10 +610,23 @@
 	 */
 	plist_del(&waiter->pi_list_entry, &current->pi_waiters);
 
-	rt_mutex_set_owner(lock, NULL);
+	/*
+	 * As we are waking up the top waiter, and the waiter stays
+	 * queued on the lock until it gets the lock, this lock
+	 * obviously has waiters. Just set the bit here and this has
+	 * the added benefit of forcing all new tasks into the
+	 * slow path making sure no task of lower priority than
+	 * the top waiter can steal this lock.
+	 */
+	lock->owner = (void *) RT_MUTEX_HAS_WAITERS;
 
 	raw_spin_unlock_irqrestore(&current->pi_lock, flags);
 
+	/*
+	 * It's safe to dereference waiter as it cannot go away as
+	 * long as we hold lock->wait_lock. The waiter task needs to
+	 * acquire it in order to dequeue the waiter.
+	 */
 	wake_up_process(waiter->task);
 }
 
@@ -506,8 +641,8 @@
 {
 	int first = (waiter == rt_mutex_top_waiter(lock));
 	struct task_struct *owner = rt_mutex_owner(lock);
+	struct rt_mutex *next_lock = NULL;
 	unsigned long flags;
-	int chain_walk = 0;
 
 	raw_spin_lock_irqsave(&current->pi_lock, flags);
 	plist_del(&waiter->list_entry, &lock->wait_list);
@@ -531,15 +666,15 @@
 		}
 		__rt_mutex_adjust_prio(owner);
 
-		if (owner->pi_blocked_on)
-			chain_walk = 1;
+		/* Store the lock on which owner is blocked or NULL */
+		next_lock = task_blocked_on_lock(owner);
 
 		raw_spin_unlock_irqrestore(&owner->pi_lock, flags);
 	}
 
 	WARN_ON(!plist_node_empty(&waiter->pi_list_entry));
 
-	if (!chain_walk)
+	if (!next_lock)
 		return;
 
 	/* gets dropped in rt_mutex_adjust_prio_chain()! */
@@ -547,7 +682,7 @@
 
 	raw_spin_unlock(&lock->wait_lock);
 
-	rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, current);
+	rt_mutex_adjust_prio_chain(owner, 0, lock, next_lock, NULL, current);
 
 	raw_spin_lock(&lock->wait_lock);
 }
@@ -560,6 +695,7 @@
 void rt_mutex_adjust_pi(struct task_struct *task)
 {
 	struct rt_mutex_waiter *waiter;
+	struct rt_mutex *next_lock;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&task->pi_lock, flags);
@@ -569,12 +705,13 @@
 		raw_spin_unlock_irqrestore(&task->pi_lock, flags);
 		return;
 	}
-
+	next_lock = waiter->lock;
 	raw_spin_unlock_irqrestore(&task->pi_lock, flags);
 
 	/* gets dropped in rt_mutex_adjust_prio_chain()! */
 	get_task_struct(task);
-	rt_mutex_adjust_prio_chain(task, 0, NULL, NULL, task);
+
+	rt_mutex_adjust_prio_chain(task, 0, NULL, next_lock, NULL, task);
 }
 
 /**
@@ -626,6 +763,26 @@
 	return ret;
 }
 
+static void rt_mutex_handle_deadlock(int res, int detect_deadlock,
+				     struct rt_mutex_waiter *w)
+{
+	/*
+	 * If the result is not -EDEADLOCK or the caller requested
+	 * deadlock detection, nothing to do here.
+	 */
+	if (res != -EDEADLOCK || detect_deadlock)
+		return;
+
+	/*
+	 * Yell lowdly and stop the task right here.
+	 */
+	rt_mutex_print_deadlock(w);
+	while (1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule();
+	}
+}
+
 /*
  * Slow path lock function:
  */
@@ -663,8 +820,10 @@
 
 	set_current_state(TASK_RUNNING);
 
-	if (unlikely(ret))
+	if (unlikely(ret)) {
 		remove_waiter(lock, &waiter);
+		rt_mutex_handle_deadlock(ret, detect_deadlock, &waiter);
+	}
 
 	/*
 	 * try_to_take_rt_mutex() sets the waiter bit
@@ -720,12 +879,49 @@
 
 	rt_mutex_deadlock_account_unlock(current);
 
-	if (!rt_mutex_has_waiters(lock)) {
-		lock->owner = NULL;
-		raw_spin_unlock(&lock->wait_lock);
+	/*
+	 * We must be careful here if the fast path is enabled. If we
+	 * have no waiters queued we cannot set owner to NULL here
+	 * because of:
+	 *
+	 * foo->lock->owner = NULL;
+	 *			rtmutex_lock(foo->lock);   <- fast path
+	 *			free = atomic_dec_and_test(foo->refcnt);
+	 *			rtmutex_unlock(foo->lock); <- fast path
+	 *			if (free)
+	 *				kfree(foo);
+	 * raw_spin_unlock(foo->lock->wait_lock);
+	 *
+	 * So for the fastpath enabled kernel:
+	 *
+	 * Nothing can set the waiters bit as long as we hold
+	 * lock->wait_lock. So we do the following sequence:
+	 *
+	 *	owner = rt_mutex_owner(lock);
+	 *	clear_rt_mutex_waiters(lock);
+	 *	raw_spin_unlock(&lock->wait_lock);
+	 *	if (cmpxchg(&lock->owner, owner, 0) == owner)
+	 *		return;
+	 *	goto retry;
+	 *
+	 * The fastpath disabled variant is simple as all access to
+	 * lock->owner is serialized by lock->wait_lock:
+	 *
+	 *	lock->owner = NULL;
+	 *	raw_spin_unlock(&lock->wait_lock);
+	 */
+	while (!rt_mutex_has_waiters(lock)) {
+		/* Drops lock->wait_lock ! */
+		if (unlock_rt_mutex_safe(lock) == true)
 		return;
+		/* Relock the rtmutex and try again */
+		raw_spin_lock(&lock->wait_lock);
 	}
 
+	/*
+	 * The wakeup next waiter path does not suffer from the above
+	 * race. See the comments there.
+	 */
 	wakeup_next_waiter(lock);
 
 	raw_spin_unlock(&lock->wait_lock);
@@ -972,7 +1168,8 @@
 		return 1;
 	}
 
-	ret = task_blocks_on_rt_mutex(lock, waiter, task, detect_deadlock);
+	/* We enforce deadlock detection for futexes */
+	ret = task_blocks_on_rt_mutex(lock, waiter, task, 1);
 
 	if (ret && !rt_mutex_owner(lock)) {
 		/*
diff -ruw linux-3.11.10/kernel/rtmutex.h linux-3.11.10-fbx/kernel/rtmutex.h
--- linux-3.11.10/kernel/rtmutex.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/rtmutex.h	2014-08-22 15:47:22.144063186 +0200
@@ -24,3 +24,8 @@
 #define debug_rt_mutex_print_deadlock(w)		do { } while (0)
 #define debug_rt_mutex_detect_deadlock(w,d)		(d)
 #define debug_rt_mutex_reset_waiter(w)			do { } while (0)
+
+static inline void rt_mutex_print_deadlock(struct rt_mutex_waiter *w)
+{
+	WARN(1, "rtmutex deadlock detected\n");
+}
diff -ruw linux-3.11.10/kernel/sched/core.c linux-3.11.10-fbx/kernel/sched/core.c
--- linux-3.11.10/kernel/sched/core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/sched/core.c	2014-01-17 19:14:18.786220809 +0100
@@ -7283,7 +7283,12 @@
 
 	runtime_enabled = quota != RUNTIME_INF;
 	runtime_was_enabled = cfs_b->quota != RUNTIME_INF;
-	account_cfs_bandwidth_used(runtime_enabled, runtime_was_enabled);
+	/*
+	 * If we need to toggle cfs_bandwidth_used, off->on must occur
+	 * before making related changes, and on->off must occur afterwards
+	 */
+	if (runtime_enabled && !runtime_was_enabled)
+		cfs_bandwidth_usage_inc();
 	raw_spin_lock_irq(&cfs_b->lock);
 	cfs_b->period = ns_to_ktime(period);
 	cfs_b->quota = quota;
@@ -7309,6 +7314,8 @@
 			unthrottle_cfs_rq(cfs_rq);
 		raw_spin_unlock_irq(&rq->lock);
 	}
+	if (runtime_was_enabled && !runtime_enabled)
+		cfs_bandwidth_usage_dec();
 out_unlock:
 	mutex_unlock(&cfs_constraints_mutex);
 
diff -ruw linux-3.11.10/kernel/sched/cpupri.c linux-3.11.10-fbx/kernel/sched/cpupri.c
--- linux-3.11.10/kernel/sched/cpupri.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/sched/cpupri.c	2014-07-01 16:22:13.194329886 +0200
@@ -70,8 +70,7 @@
 	int idx = 0;
 	int task_pri = convert_prio(p->prio);
 
-	if (task_pri >= MAX_RT_PRIO)
-		return 0;
+	BUG_ON(task_pri >= CPUPRI_NR_PRIORITIES);
 
 	for (idx = 0; idx < task_pri; idx++) {
 		struct cpupri_vec *vec  = &cp->pri_to_cpu[idx];
diff -ruw linux-3.11.10/kernel/sched/cputime.c linux-3.11.10-fbx/kernel/sched/cputime.c
--- linux-3.11.10/kernel/sched/cputime.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/sched/cputime.c	2014-07-01 16:22:13.194329886 +0200
@@ -326,50 +326,50 @@
  * softirq as those do not count in task exec_runtime any more.
  */
 static void irqtime_account_process_tick(struct task_struct *p, int user_tick,
-						struct rq *rq)
+					 struct rq *rq, int ticks)
 {
-	cputime_t one_jiffy_scaled = cputime_to_scaled(cputime_one_jiffy);
+	cputime_t scaled = cputime_to_scaled(cputime_one_jiffy);
+	u64 cputime = (__force u64) cputime_one_jiffy;
 	u64 *cpustat = kcpustat_this_cpu->cpustat;
 
 	if (steal_account_process_tick())
 		return;
 
+	cputime *= ticks;
+	scaled *= ticks;
+
 	if (irqtime_account_hi_update()) {
-		cpustat[CPUTIME_IRQ] += (__force u64) cputime_one_jiffy;
+		cpustat[CPUTIME_IRQ] += cputime;
 	} else if (irqtime_account_si_update()) {
-		cpustat[CPUTIME_SOFTIRQ] += (__force u64) cputime_one_jiffy;
+		cpustat[CPUTIME_SOFTIRQ] += cputime;
 	} else if (this_cpu_ksoftirqd() == p) {
 		/*
 		 * ksoftirqd time do not get accounted in cpu_softirq_time.
 		 * So, we have to handle it separately here.
 		 * Also, p->stime needs to be updated for ksoftirqd.
 		 */
-		__account_system_time(p, cputime_one_jiffy, one_jiffy_scaled,
-					CPUTIME_SOFTIRQ);
+		__account_system_time(p, cputime, scaled, CPUTIME_SOFTIRQ);
 	} else if (user_tick) {
-		account_user_time(p, cputime_one_jiffy, one_jiffy_scaled);
+		account_user_time(p, cputime, scaled);
 	} else if (p == rq->idle) {
-		account_idle_time(cputime_one_jiffy);
+		account_idle_time(cputime);
 	} else if (p->flags & PF_VCPU) { /* System time or guest time */
-		account_guest_time(p, cputime_one_jiffy, one_jiffy_scaled);
+		account_guest_time(p, cputime, scaled);
 	} else {
-		__account_system_time(p, cputime_one_jiffy, one_jiffy_scaled,
-					CPUTIME_SYSTEM);
+		__account_system_time(p, cputime, scaled,	CPUTIME_SYSTEM);
 	}
 }
 
 static void irqtime_account_idle_ticks(int ticks)
 {
-	int i;
 	struct rq *rq = this_rq();
 
-	for (i = 0; i < ticks; i++)
-		irqtime_account_process_tick(current, 0, rq);
+	irqtime_account_process_tick(current, 0, rq, ticks);
 }
 #else /* CONFIG_IRQ_TIME_ACCOUNTING */
 static inline void irqtime_account_idle_ticks(int ticks) {}
 static inline void irqtime_account_process_tick(struct task_struct *p, int user_tick,
-						struct rq *rq) {}
+						struct rq *rq, int nr_ticks) {}
 #endif /* CONFIG_IRQ_TIME_ACCOUNTING */
 
 /*
@@ -464,7 +464,7 @@
 		return;
 
 	if (sched_clock_irqtime) {
-		irqtime_account_process_tick(p, user_tick, rq);
+		irqtime_account_process_tick(p, user_tick, rq, 1);
 		return;
 	}
 
diff -ruw linux-3.11.10/kernel/sched/debug.c linux-3.11.10-fbx/kernel/sched/debug.c
--- linux-3.11.10/kernel/sched/debug.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/sched/debug.c	2014-01-17 19:14:18.786220809 +0100
@@ -225,6 +225,14 @@
 			atomic_read(&cfs_rq->tg->runnable_avg));
 #endif
 #endif
+#ifdef CONFIG_CFS_BANDWIDTH
+	SEQ_printf(m, "  .%-30s: %d\n", "tg->cfs_bandwidth.timer_active",
+			cfs_rq->tg->cfs_bandwidth.timer_active);
+	SEQ_printf(m, "  .%-30s: %d\n", "throttled",
+			cfs_rq->throttled);
+	SEQ_printf(m, "  .%-30s: %d\n", "throttle_count",
+			cfs_rq->throttle_count);
+#endif
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
 	print_cfs_group_stats(m, cpu, cfs_rq->tg);
diff -ruw linux-3.11.10/kernel/sched/fair.c linux-3.11.10-fbx/kernel/sched/fair.c
--- linux-3.11.10/kernel/sched/fair.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/sched/fair.c	2014-07-01 16:22:13.194329886 +0200
@@ -974,6 +974,13 @@
 		if (vma->vm_end - vma->vm_start < HPAGE_SIZE)
 			continue;
 
+		/*
+		 * Skip inaccessible VMAs to avoid any confusion between
+		 * PROT_NONE and NUMA hinting ptes
+		 */
+		if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
+			continue;
+
 		do {
 			start = max(start, vma->vm_start);
 			end = ALIGN(start + (pages << PAGE_SHIFT), HPAGE_SIZE);
@@ -2070,12 +2077,13 @@
 	return static_key_false(&__cfs_bandwidth_used);
 }
 
-void account_cfs_bandwidth_used(int enabled, int was_enabled)
+void cfs_bandwidth_usage_inc(void)
 {
-	/* only need to count groups transitioning between enabled/!enabled */
-	if (enabled && !was_enabled)
 		static_key_slow_inc(&__cfs_bandwidth_used);
-	else if (!enabled && was_enabled)
+}
+
+void cfs_bandwidth_usage_dec(void)
+{
 		static_key_slow_dec(&__cfs_bandwidth_used);
 }
 #else /* HAVE_JUMP_LABEL */
@@ -2084,7 +2092,8 @@
 	return true;
 }
 
-void account_cfs_bandwidth_used(int enabled, int was_enabled) {}
+void cfs_bandwidth_usage_inc(void) {}
+void cfs_bandwidth_usage_dec(void) {}
 #endif /* HAVE_JUMP_LABEL */
 
 /*
@@ -2335,6 +2344,8 @@
 	cfs_rq->throttled_clock = rq_clock(rq);
 	raw_spin_lock(&cfs_b->lock);
 	list_add_tail_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq);
+	if (!cfs_b->timer_active)
+		__start_cfs_bandwidth(cfs_b);
 	raw_spin_unlock(&cfs_b->lock);
 }
 
@@ -2448,6 +2459,13 @@
 	if (idle)
 		goto out_unlock;
 
+	/*
+	 * if we have relooped after returning idle once, we need to update our
+	 * status as actually running, so that other cpus doing
+	 * __start_cfs_bandwidth will stop trying to cancel us.
+	 */
+	cfs_b->timer_active = 1;
+
 	__refill_cfs_bandwidth_runtime(cfs_b);
 
 	if (!throttled) {
@@ -2508,7 +2526,13 @@
 /* how long we wait to gather additional slack before distributing */
 static const u64 cfs_bandwidth_slack_period = 5 * NSEC_PER_MSEC;
 
-/* are we near the end of the current quota period? */
+/*
+ * Are we near the end of the current quota period?
+ *
+ * Requires cfs_b->lock for hrtimer_expires_remaining to be safe against the
+ * hrtimer base being cleared by __hrtimer_start_range_ns. In the case of
+ * migrate_hrtimers, base is never cleared, so we are fine.
+ */
 static int runtime_refresh_within(struct cfs_bandwidth *cfs_b, u64 min_expire)
 {
 	struct hrtimer *refresh_timer = &cfs_b->period_timer;
@@ -2584,10 +2608,12 @@
 	u64 expires;
 
 	/* confirm we're still not at a refresh boundary */
-	if (runtime_refresh_within(cfs_b, min_bandwidth_expiration))
+	raw_spin_lock(&cfs_b->lock);
+	if (runtime_refresh_within(cfs_b, min_bandwidth_expiration)) {
+		raw_spin_unlock(&cfs_b->lock);
 		return;
+	}
 
-	raw_spin_lock(&cfs_b->lock);
 	if (cfs_b->quota != RUNTIME_INF && cfs_b->runtime > slice) {
 		runtime = cfs_b->runtime;
 		cfs_b->runtime = 0;
@@ -2708,11 +2734,11 @@
 	 * (timer_active==0 becomes visible before the hrtimer call-back
 	 * terminates).  In either case we ensure that it's re-programmed
 	 */
-	while (unlikely(hrtimer_active(&cfs_b->period_timer))) {
+	while (unlikely(hrtimer_active(&cfs_b->period_timer)) &&
+	       hrtimer_try_to_cancel(&cfs_b->period_timer) < 0) {
+		/* bounce the lock to allow do_sched_cfs_period_timer to run */
 		raw_spin_unlock(&cfs_b->lock);
-		/* ensure cfs_b->lock is available while we wait */
-		hrtimer_cancel(&cfs_b->period_timer);
-
+		cpu_relax();
 		raw_spin_lock(&cfs_b->lock);
 		/* if someone else restarted the timer then we're done */
 		if (cfs_b->timer_active)
@@ -5876,15 +5902,15 @@
 	struct cfs_rq *cfs_rq = cfs_rq_of(se);
 
 	/*
-	 * Ensure the task's vruntime is normalized, so that when its
+	 * Ensure the task's vruntime is normalized, so that when it's
 	 * switched back to the fair class the enqueue_entity(.flags=0) will
 	 * do the right thing.
 	 *
-	 * If it was on_rq, then the dequeue_entity(.flags=0) will already
-	 * have normalized the vruntime, if it was !on_rq, then only when
+	 * If it's on_rq, then the dequeue_entity(.flags=0) will already
+	 * have normalized the vruntime, if it's !on_rq, then only when
 	 * the task is sleeping will it still have non-normalized vruntime.
 	 */
-	if (!se->on_rq && p->state != TASK_RUNNING) {
+	if (!p->on_rq && p->state != TASK_RUNNING) {
 		/*
 		 * Fix up our vruntime so that the current sleep doesn't
 		 * cause 'unlimited' sleep bonus.
@@ -6105,7 +6131,8 @@
 		se->cfs_rq = parent->my_q;
 
 	se->my_q = cfs_rq;
-	update_load_set(&se->load, 0);
+	/* guarantee group entities always have weight */
+	update_load_set(&se->load, NICE_0_LOAD);
 	se->parent = parent;
 }
 
diff -ruw linux-3.11.10/kernel/sched/rt.c linux-3.11.10-fbx/kernel/sched/rt.c
--- linux-3.11.10/kernel/sched/rt.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/sched/rt.c	2014-01-17 19:14:18.786220809 +0100
@@ -899,6 +899,13 @@
 {
 	struct rq *rq = rq_of_rt_rq(rt_rq);
 
+#ifdef CONFIG_RT_GROUP_SCHED
+	/*
+	 * Change rq's cpupri only if rt_rq is the top queue.
+	 */
+	if (&rq->rt != rt_rq)
+		return;
+#endif
 	if (rq->online && prio < prev_prio)
 		cpupri_set(&rq->rd->cpupri, rq->cpu, prio);
 }
@@ -908,6 +915,13 @@
 {
 	struct rq *rq = rq_of_rt_rq(rt_rq);
 
+#ifdef CONFIG_RT_GROUP_SCHED
+	/*
+	 * Change rq's cpupri only if rt_rq is the top queue.
+	 */
+	if (&rq->rt != rt_rq)
+		return;
+#endif
 	if (rq->online && rt_rq->highest_prio.curr != prev_prio)
 		cpupri_set(&rq->rd->cpupri, rq->cpu, rt_rq->highest_prio.curr);
 }
diff -ruw linux-3.11.10/kernel/sched/sched.h linux-3.11.10-fbx/kernel/sched/sched.h
--- linux-3.11.10/kernel/sched/sched.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/sched/sched.h	2014-01-17 19:14:18.786220809 +0100
@@ -1305,7 +1305,8 @@
 extern void init_cfs_rq(struct cfs_rq *cfs_rq);
 extern void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq);
 
-extern void account_cfs_bandwidth_used(int enabled, int was_enabled);
+extern void cfs_bandwidth_usage_inc(void);
+extern void cfs_bandwidth_usage_dec(void);
 
 #ifdef CONFIG_NO_HZ_COMMON
 enum rq_nohz_flag_bits {
diff -ruw linux-3.11.10/kernel/seccomp.c linux-3.11.10-fbx/kernel/seccomp.c
--- linux-3.11.10/kernel/seccomp.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/seccomp.c	2013-12-04 14:33:27.711479112 +0100
@@ -30,34 +30,6 @@
 #include <linux/tracehook.h>
 #include <linux/uaccess.h>
 
-/**
- * struct seccomp_filter - container for seccomp BPF programs
- *
- * @usage: reference count to manage the object lifetime.
- *         get/put helpers should be used when accessing an instance
- *         outside of a lifetime-guarded section.  In general, this
- *         is only needed for handling filters shared across tasks.
- * @prev: points to a previously installed, or inherited, filter
- * @len: the number of instructions in the program
- * @insns: the BPF program instructions to evaluate
- *
- * seccomp_filter objects are organized in a tree linked via the @prev
- * pointer.  For any task, it appears to be a singly-linked list starting
- * with current->seccomp.filter, the most recently attached or inherited filter.
- * However, multiple filters may share a @prev node, by way of fork(), which
- * results in a unidirectional tree existing in memory.  This is similar to
- * how namespaces work.
- *
- * seccomp_filter objects should never be modified after being attached
- * to a task_struct (other than @usage).
- */
-struct seccomp_filter {
-	atomic_t usage;
-	struct seccomp_filter *prev;
-	unsigned short len;  /* Instruction count */
-	struct sock_filter insns[];
-};
-
 /* Limit any path through the tree to 256KB worth of instructions. */
 #define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter))
 
@@ -213,7 +185,7 @@
 	 * value always takes priority (ignoring the DATA).
 	 */
 	for (f = current->seccomp.filter; f; f = f->prev) {
-		u32 cur_ret = sk_run_filter(NULL, f->insns);
+		u32 cur_ret = f->bpf_func(NULL, f->insns);
 		if ((cur_ret & SECCOMP_RET_ACTION) < (ret & SECCOMP_RET_ACTION))
 			ret = cur_ret;
 	}
@@ -275,6 +247,9 @@
 	if (ret)
 		goto fail;
 
+	filter->bpf_func = sk_run_filter;
+	seccomp_jit_compile(filter);
+
 	/*
 	 * If there is an existing filter, make it the prev and don't drop its
 	 * task reference.
@@ -332,6 +307,7 @@
 	while (orig && atomic_dec_and_test(&orig->usage)) {
 		struct seccomp_filter *freeme = orig;
 		orig = orig->prev;
+		seccomp_jit_free(freeme);
 		kfree(freeme);
 	}
 }
diff -ruw linux-3.11.10/kernel/sys.c linux-3.11.10-fbx/kernel/sys.c
--- linux-3.11.10/kernel/sys.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/sys.c	2013-12-04 14:33:27.815479114 +0100
@@ -1963,6 +1963,10 @@
 			else
 				return -EINVAL;
 			break;
+		case PR_GET_NO_NEW_PRIVS:
+			if (arg2 || arg3 || arg4 || arg5)
+				return -EINVAL;
+			return current->no_new_privs ? 1 : 0;
 		default:
 			return -EINVAL;
 		}
@@ -1999,6 +2003,18 @@
 		if (arg2 || arg3 || arg4 || arg5)
 			return -EINVAL;
 		return current->no_new_privs ? 1 : 0;
+	case PR_SET_EXEC_MODE:
+		if (arg2 != EXEC_MODE_UNLIMITED &&
+		    arg2 != EXEC_MODE_ONCE &&
+		    arg2 != EXEC_MODE_DENIED)
+			return -EINVAL;
+
+		if (arg2 > current->exec_mode)
+			return -EPERM;
+		current->exec_mode = arg2;
+		return 0;
+	case PR_GET_EXEC_MODE:
+		return current->exec_mode;
 	default:
 		error = -EINVAL;
 		break;
diff -ruw linux-3.11.10/kernel/sysctl.c linux-3.11.10-fbx/kernel/sysctl.c
--- linux-3.11.10/kernel/sysctl.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/sysctl.c	2014-08-22 15:47:22.144063186 +0200
@@ -138,11 +138,15 @@
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
 static int minolduid;
-static int min_percpu_pagelist_fract = 8;
 
 static int ngroups_max = NGROUPS_MAX;
 static const int cap_last_cap = CAP_LAST_CAP;
 
+/*this is needed for proc_doulongvec_minmax of sysctl_hung_task_timeout_secs */
+#ifdef CONFIG_DETECT_HUNG_TASK
+static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
+#endif
+
 #ifdef CONFIG_INOTIFY_USER
 #include <linux/inotify.h>
 #endif
@@ -972,6 +976,7 @@
 		.maxlen		= sizeof(unsigned long),
 		.mode		= 0644,
 		.proc_handler	= proc_dohung_task_timeout_secs,
+		.extra2		= &hung_task_timeout_max,
 	},
 	{
 		.procname	= "hung_task_warnings",
@@ -1049,6 +1054,7 @@
 		.maxlen		= sizeof(sysctl_perf_event_sample_rate),
 		.mode		= 0644,
 		.proc_handler	= perf_proc_update_handler,
+		.extra1		= &one,
 	},
 	{
 		.procname	= "perf_cpu_time_max_percent",
@@ -1286,7 +1292,7 @@
 		.maxlen		= sizeof(percpu_pagelist_fraction),
 		.mode		= 0644,
 		.proc_handler	= percpu_pagelist_fraction_sysctl_handler,
-		.extra1		= &min_percpu_pagelist_fract,
+		.extra1		= &zero,
 	},
 #ifdef CONFIG_MMU
 	{
diff -ruw linux-3.11.10/kernel/time/alarmtimer.c linux-3.11.10-fbx/kernel/time/alarmtimer.c
--- linux-3.11.10/kernel/time/alarmtimer.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/time/alarmtimer.c	2014-01-17 19:14:18.790220810 +0100
@@ -490,7 +490,7 @@
 	clockid_t baseid = alarm_bases[clock2alarm(which_clock)].base_clockid;
 
 	if (!alarmtimer_get_rtcdev())
-		return -ENOTSUPP;
+		return -EINVAL;
 
 	return hrtimer_get_res(baseid, tp);
 }
@@ -507,7 +507,7 @@
 	struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)];
 
 	if (!alarmtimer_get_rtcdev())
-		return -ENOTSUPP;
+		return -EINVAL;
 
 	*tp = ktime_to_timespec(base->gettime());
 	return 0;
diff -ruw linux-3.11.10/kernel/time/jiffies.c linux-3.11.10-fbx/kernel/time/jiffies.c
--- linux-3.11.10/kernel/time/jiffies.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/time/jiffies.c	2014-05-09 14:12:54.344546160 +0200
@@ -51,7 +51,13 @@
  * HZ shrinks, so values greater than 8 overflow 32bits when
  * HZ=100.
  */
+#if HZ < 34
+#define JIFFIES_SHIFT	6
+#elif HZ < 67
+#define JIFFIES_SHIFT	7
+#else
 #define JIFFIES_SHIFT	8
+#endif
 
 static cycle_t jiffies_read(struct clocksource *cs)
 {
diff -ruw linux-3.11.10/kernel/time/ntp.c linux-3.11.10-fbx/kernel/time/ntp.c
--- linux-3.11.10/kernel/time/ntp.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/time/ntp.c	2014-01-17 19:14:18.790220810 +0100
@@ -475,6 +475,7 @@
 	 * called as close as possible to 500 ms before the new second starts.
 	 * This code is run on a timer.  If the clock is set, that timer
 	 * may not expire at the correct time.  Thus, we adjust...
+	 * We want the clock to be within a couple of ticks from the target.
 	 */
 	if (!ntp_synced()) {
 		/*
@@ -485,7 +486,7 @@
 	}
 
 	getnstimeofday(&now);
-	if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) {
+	if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec * 5) {
 		struct timespec adjust = now;
 
 		fail = -ENODEV;
diff -ruw linux-3.11.10/kernel/time/tick-broadcast.c linux-3.11.10-fbx/kernel/time/tick-broadcast.c
--- linux-3.11.10/kernel/time/tick-broadcast.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/time/tick-broadcast.c	2014-05-09 14:12:54.344546160 +0200
@@ -755,6 +755,7 @@
 static void tick_broadcast_clear_oneshot(int cpu)
 {
 	cpumask_clear_cpu(cpu, tick_broadcast_oneshot_mask);
+	cpumask_clear_cpu(cpu, tick_broadcast_pending_mask);
 }
 
 static void tick_broadcast_init_next_event(struct cpumask *mask,
diff -ruw linux-3.11.10/kernel/time/tick-common.c linux-3.11.10-fbx/kernel/time/tick-common.c
--- linux-3.11.10/kernel/time/tick-common.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/time/tick-common.c	2014-07-01 16:22:13.194329886 +0200
@@ -260,7 +260,7 @@
 bool tick_check_replacement(struct clock_event_device *curdev,
 			    struct clock_event_device *newdev)
 {
-	if (tick_check_percpu(curdev, newdev, smp_processor_id()))
+	if (!tick_check_percpu(curdev, newdev, smp_processor_id()))
 		return false;
 
 	return tick_check_preferred(curdev, newdev);
diff -ruw linux-3.11.10/kernel/time/tick-sched.c linux-3.11.10-fbx/kernel/time/tick-sched.c
--- linux-3.11.10/kernel/time/tick-sched.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/time/tick-sched.c	2014-08-22 15:47:22.144063186 +0200
@@ -714,8 +714,10 @@
 		return false;
 	}
 
-	if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
+	if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) {
+		ts->sleep_length = (ktime_t) { .tv64 = NSEC_PER_SEC/HZ };
 		return false;
+	}
 
 	if (need_resched())
 		return false;
diff -ruw linux-3.11.10/kernel/time/timekeeping.c linux-3.11.10-fbx/kernel/time/timekeeping.c
--- linux-3.11.10/kernel/time/timekeeping.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/time/timekeeping.c	2014-05-09 14:12:54.344546160 +0200
@@ -77,7 +77,7 @@
 	tk->wall_to_monotonic = wtm;
 	set_normalized_timespec(&tmp, -wtm.tv_sec, -wtm.tv_nsec);
 	tk->offs_real = timespec_to_ktime(tmp);
-	tk->offs_tai = ktime_sub(tk->offs_real, ktime_set(tk->tai_offset, 0));
+	tk->offs_tai = ktime_add(tk->offs_real, ktime_set(tk->tai_offset, 0));
 }
 
 static void tk_set_sleep_time(struct timekeeper *tk, struct timespec t)
@@ -595,7 +595,7 @@
 static void __timekeeping_set_tai_offset(struct timekeeper *tk, s32 tai_offset)
 {
 	tk->tai_offset = tai_offset;
-	tk->offs_tai = ktime_sub(tk->offs_real, ktime_set(tai_offset, 0));
+	tk->offs_tai = ktime_add(tk->offs_real, ktime_set(tai_offset, 0));
 }
 
 /**
@@ -610,6 +610,7 @@
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
 	write_seqcount_begin(&timekeeper_seq);
 	__timekeeping_set_tai_offset(tk, tai_offset);
+	timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET);
 	write_seqcount_end(&timekeeper_seq);
 	raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
 	clock_was_set();
@@ -1023,6 +1024,8 @@
 		timekeeping_suspend_time =
 			timespec_add(timekeeping_suspend_time, delta_delta);
 	}
+
+	timekeeping_update(tk, TK_MIRROR);
 	write_seqcount_end(&timekeeper_seq);
 	raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
 
@@ -1255,7 +1258,7 @@
 static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk)
 {
 	u64 nsecps = (u64)NSEC_PER_SEC << tk->shift;
-	unsigned int action = 0;
+	unsigned int clock_set = 0;
 
 	while (tk->xtime_nsec >= nsecps) {
 		int leap;
@@ -1277,11 +1280,10 @@
 
 			__timekeeping_set_tai_offset(tk, tk->tai_offset - leap);
 
-			clock_was_set_delayed();
-			action = TK_CLOCK_WAS_SET;
+			clock_set = TK_CLOCK_WAS_SET;
 		}
 	}
-	return action;
+	return clock_set;
 }
 
 /**
@@ -1294,7 +1296,8 @@
  * Returns the unconsumed cycles.
  */
 static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset,
-						u32 shift)
+						u32 shift,
+						unsigned int *clock_set)
 {
 	cycle_t interval = tk->cycle_interval << shift;
 	u64 raw_nsecs;
@@ -1308,7 +1311,7 @@
 	tk->cycle_last += interval;
 
 	tk->xtime_nsec += tk->xtime_interval << shift;
-	accumulate_nsecs_to_secs(tk);
+	*clock_set |= accumulate_nsecs_to_secs(tk);
 
 	/* Accumulate raw time */
 	raw_nsecs = (u64)tk->raw_interval << shift;
@@ -1347,7 +1350,7 @@
 	tk->xtime_nsec -= remainder;
 	tk->xtime_nsec += 1ULL << tk->shift;
 	tk->ntp_error += remainder << tk->ntp_error_shift;
-
+	tk->ntp_error -= (1ULL << tk->shift) << tk->ntp_error_shift;
 }
 #else
 #define old_vsyscall_fixup(tk)
@@ -1366,7 +1369,7 @@
 	struct timekeeper *tk = &shadow_timekeeper;
 	cycle_t offset;
 	int shift = 0, maxshift;
-	unsigned int action;
+	unsigned int clock_set = 0;
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
@@ -1401,7 +1404,8 @@
 	maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1;
 	shift = min(shift, maxshift);
 	while (offset >= tk->cycle_interval) {
-		offset = logarithmic_accumulation(tk, offset, shift);
+		offset = logarithmic_accumulation(tk, offset, shift,
+							&clock_set);
 		if (offset < tk->cycle_interval<<shift)
 			shift--;
 	}
@@ -1419,7 +1423,7 @@
 	 * Finally, make sure that after the rounding
 	 * xtime_nsec isn't larger than NSEC_PER_SEC
 	 */
-	action = accumulate_nsecs_to_secs(tk);
+	clock_set |= accumulate_nsecs_to_secs(tk);
 
 	write_seqcount_begin(&timekeeper_seq);
 	/* Update clock->cycle_last with the new value */
@@ -1435,10 +1439,23 @@
 	 * updating.
 	 */
 	memcpy(real_tk, tk, sizeof(*tk));
-	timekeeping_update(real_tk, action);
+	timekeeping_update(real_tk, clock_set);
 	write_seqcount_end(&timekeeper_seq);
 out:
 	raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
+	if (clock_set) {
+		/*
+		 * XXX -  I'd rather we just call clock_was_set(), but
+		 * since we're currently holding the jiffies lock, calling
+		 * clock_was_set would trigger an ipi which would then grab
+		 * the jiffies lock and we'd deadlock. :(
+		 * The right solution should probably be droping
+		 * the jiffies lock before calling update_wall_time
+		 * but that requires some rework of the tick sched
+		 * code.
+		 */
+		clock_was_set_delayed();
+	}
 }
 
 /**
@@ -1697,12 +1714,14 @@
 
 	if (tai != orig_tai) {
 		__timekeeping_set_tai_offset(tk, tai);
-		update_pvclock_gtod(tk, true);
-		clock_was_set_delayed();
+		timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET);
 	}
 	write_seqcount_end(&timekeeper_seq);
 	raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
 
+	if (tai != orig_tai)
+		clock_was_set();
+
 	ntp_notify_cmos_timer();
 
 	return ret;
diff -ruw linux-3.11.10/kernel/timer.c linux-3.11.10-fbx/kernel/timer.c
--- linux-3.11.10/kernel/timer.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/timer.c	2014-07-01 16:22:13.194329886 +0200
@@ -822,7 +822,7 @@
 
 	bit = find_last_bit(&mask, BITS_PER_LONG);
 
-	mask = (1 << bit) - 1;
+	mask = (1UL << bit) - 1;
 
 	expires_limit = expires_limit & ~(mask);
 
diff -ruw linux-3.11.10/kernel/workqueue.c linux-3.11.10-fbx/kernel/workqueue.c
--- linux-3.11.10/kernel/workqueue.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/kernel/workqueue.c	2014-08-22 15:47:22.148063206 +0200
@@ -304,6 +304,9 @@
 /* I: attributes used when instantiating standard unbound pools on demand */
 static struct workqueue_attrs *unbound_std_wq_attrs[NR_STD_WORKER_POOLS];
 
+/* I: attributes used when instantiating ordered pools on demand */
+static struct workqueue_attrs *ordered_wq_attrs[NR_STD_WORKER_POOLS];
+
 struct workqueue_struct *system_wq __read_mostly;
 EXPORT_SYMBOL(system_wq);
 struct workqueue_struct *system_highpri_wq __read_mostly;
@@ -1833,6 +1836,12 @@
 	if (worker->flags & WORKER_IDLE)
 		pool->nr_idle--;
 
+	/*
+	 * Once WORKER_DIE is set, the kworker may destroy itself at any
+	 * point.  Pin to ensure the task stays until we're done with it.
+	 */
+	get_task_struct(worker->task);
+
 	list_del_init(&worker->entry);
 	worker->flags |= WORKER_DIE;
 
@@ -1841,6 +1850,7 @@
 	spin_unlock_irq(&pool->lock);
 
 	kthread_stop(worker->task);
+	put_task_struct(worker->task);
 	kfree(worker);
 
 	spin_lock_irq(&pool->lock);
@@ -1884,6 +1894,12 @@
 
 	/* mayday mayday mayday */
 	if (list_empty(&pwq->mayday_node)) {
+		/*
+		 * If @pwq is for an unbound wq, its base ref may be put at
+		 * any time due to an attribute change.  Pin @pwq until the
+		 * rescuer is done with it.
+		 */
+		get_pwq(pwq);
 		list_add_tail(&pwq->mayday_node, &wq->maydays);
 		wake_up_process(wq->rescuer->task);
 	}
@@ -2359,6 +2375,7 @@
 	struct worker *rescuer = __rescuer;
 	struct workqueue_struct *wq = rescuer->rescue_wq;
 	struct list_head *scheduled = &rescuer->scheduled;
+	bool should_stop;
 
 	set_user_nice(current, RESCUER_NICE_LEVEL);
 
@@ -2370,11 +2387,15 @@
 repeat:
 	set_current_state(TASK_INTERRUPTIBLE);
 
-	if (kthread_should_stop()) {
-		__set_current_state(TASK_RUNNING);
-		rescuer->task->flags &= ~PF_WQ_WORKER;
-		return 0;
-	}
+	/*
+	 * By the time the rescuer is requested to stop, the workqueue
+	 * shouldn't have any work pending, but @wq->maydays may still have
+	 * pwq(s) queued.  This can happen by non-rescuer workers consuming
+	 * all the work items before the rescuer got to them.  Go through
+	 * @wq->maydays processing before acting on should_stop so that the
+	 * list is always empty on exit.
+	 */
+	should_stop = kthread_should_stop();
 
 	/* see whether any pwq is asking for help */
 	spin_lock_irq(&wq_mayday_lock);
@@ -2406,6 +2427,12 @@
 		process_scheduled_works(rescuer);
 
 		/*
+		 * Put the reference grabbed by send_mayday().  @pool won't
+		 * go away while we're holding its lock.
+		 */
+		put_pwq(pwq);
+
+		/*
 		 * Leave this pool.  If keep_working() is %true, notify a
 		 * regular worker; otherwise, we end up with 0 concurrency
 		 * and stalling the execution.
@@ -2420,6 +2447,12 @@
 
 	spin_unlock_irq(&wq_mayday_lock);
 
+	if (should_stop) {
+		__set_current_state(TASK_RUNNING);
+		rescuer->task->flags &= ~PF_WQ_WORKER;
+		return 0;
+	}
+
 	/* rescuers should never participate in concurrency management */
 	WARN_ON_ONCE(!(rescuer->flags & WORKER_NOT_RUNNING));
 	schedule();
@@ -3358,6 +3391,7 @@
 		}
 	}
 
+	dev_set_uevent_suppress(&wq_dev->dev, false);
 	kobject_uevent(&wq_dev->dev.kobj, KOBJ_ADD);
 	return 0;
 }
@@ -4051,7 +4085,8 @@
 	if (!pwq) {
 		pr_warning("workqueue: allocation failed while updating NUMA affinity of \"%s\"\n",
 			   wq->name);
-		goto out_unlock;
+		mutex_lock(&wq->mutex);
+		goto use_dfl_pwq;
 	}
 
 	/*
@@ -4077,7 +4112,7 @@
 static int alloc_and_link_pwqs(struct workqueue_struct *wq)
 {
 	bool highpri = wq->flags & WQ_HIGHPRI;
-	int cpu;
+	int cpu, ret;
 
 	if (!(wq->flags & WQ_UNBOUND)) {
 		wq->cpu_pwqs = alloc_percpu(struct pool_workqueue);
@@ -4097,6 +4132,13 @@
 			mutex_unlock(&wq->mutex);
 		}
 		return 0;
+	} else if (wq->flags & __WQ_ORDERED) {
+		ret = apply_workqueue_attrs(wq, ordered_wq_attrs[highpri]);
+		/* there should only be single pwq for ordering guarantee */
+		WARN(!ret && (wq->pwqs.next != &wq->dfl_pwq->pwqs_node ||
+			      wq->pwqs.prev != &wq->dfl_pwq->pwqs_node),
+		     "ordering guarantee broken for workqueue %s\n", wq->name);
+		return ret;
 	} else {
 		return apply_workqueue_attrs(wq, unbound_std_wq_attrs[highpri]);
 	}
@@ -4955,7 +4997,7 @@
 	BUG_ON(!tbl);
 
 	for_each_node(node)
-		BUG_ON(!alloc_cpumask_var_node(&tbl[node], GFP_KERNEL,
+		BUG_ON(!zalloc_cpumask_var_node(&tbl[node], GFP_KERNEL,
 				node_online(node) ? node : NUMA_NO_NODE));
 
 	for_each_possible_cpu(cpu) {
@@ -5019,13 +5061,23 @@
 		}
 	}
 
-	/* create default unbound wq attrs */
+	/* create default unbound and ordered wq attrs */
 	for (i = 0; i < NR_STD_WORKER_POOLS; i++) {
 		struct workqueue_attrs *attrs;
 
 		BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL)));
 		attrs->nice = std_nice[i];
 		unbound_std_wq_attrs[i] = attrs;
+
+		/*
+		 * An ordered wq should have only one pwq as ordering is
+		 * guaranteed by max_active which is enforced by pwqs.
+		 * Turn off NUMA so that dfl_pwq is used for all nodes.
+		 */
+		BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL)));
+		attrs->nice = std_nice[i];
+		attrs->no_numa = true;
+		ordered_wq_attrs[i] = attrs;
 	}
 
 	system_wq = alloc_workqueue("events", 0, 0);
diff -ruw linux-3.11.10/lib/idr.c linux-3.11.10-fbx/lib/idr.c
--- linux-3.11.10/lib/idr.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/lib/idr.c	2014-08-22 15:47:22.148063206 +0200
@@ -250,7 +250,7 @@
 			id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1;
 
 			/* if already at the top layer, we need to grow */
-			if (id >= 1 << (idp->layers * IDR_BITS)) {
+			if (id > idr_max(idp->layers)) {
 				*starting_id = id;
 				return -EAGAIN;
 			}
@@ -827,12 +827,10 @@
 	if (!p)
 		return ERR_PTR(-EINVAL);
 
-	n = (p->layer+1) * IDR_BITS;
-
-	if (id >= (1 << n))
+	if (id > idr_max(p->layer + 1))
 		return ERR_PTR(-EINVAL);
 
-	n -= IDR_BITS;
+	n = p->layer * IDR_BITS;
 	while ((n > 0) && p) {
 		p = p->ary[(id >> n) & IDR_MASK];
 		n -= IDR_BITS;
diff -ruw linux-3.11.10/lib/Kconfig linux-3.11.10-fbx/lib/Kconfig
--- linux-3.11.10/lib/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/lib/Kconfig	2013-12-04 14:33:28.087479118 +0100
@@ -425,4 +425,8 @@
 
 source "lib/fonts/Kconfig"
 
+config FBXSERIAL
+	bool
+	select CRC32
+
 endmenu
diff -ruw linux-3.11.10/lib/lzo/lzo1x_decompress_safe.c linux-3.11.10-fbx/lib/lzo/lzo1x_decompress_safe.c
--- linux-3.11.10/lib/lzo/lzo1x_decompress_safe.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/lib/lzo/lzo1x_decompress_safe.c	2014-08-22 15:47:22.148063206 +0200
@@ -19,11 +19,31 @@
 #include <linux/lzo.h>
 #include "lzodefs.h"
 
-#define HAVE_IP(x)      ((size_t)(ip_end - ip) >= (size_t)(x))
-#define HAVE_OP(x)      ((size_t)(op_end - op) >= (size_t)(x))
-#define NEED_IP(x)      if (!HAVE_IP(x)) goto input_overrun
-#define NEED_OP(x)      if (!HAVE_OP(x)) goto output_overrun
-#define TEST_LB(m_pos)  if ((m_pos) < out) goto lookbehind_overrun
+#define HAVE_IP(t, x)					\
+	(((size_t)(ip_end - ip) >= (size_t)(t + x)) &&	\
+	 (((t + x) >= t) && ((t + x) >= x)))
+
+#define HAVE_OP(t, x)					\
+	(((size_t)(op_end - op) >= (size_t)(t + x)) &&	\
+	 (((t + x) >= t) && ((t + x) >= x)))
+
+#define NEED_IP(t, x)					\
+	do {						\
+		if (!HAVE_IP(t, x))			\
+			goto input_overrun;		\
+	} while (0)
+
+#define NEED_OP(t, x)					\
+	do {						\
+		if (!HAVE_OP(t, x))			\
+			goto output_overrun;		\
+	} while (0)
+
+#define TEST_LB(m_pos)					\
+	do {						\
+		if ((m_pos) < out)			\
+			goto lookbehind_overrun;	\
+	} while (0)
 
 int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
 			  unsigned char *out, size_t *out_len)
@@ -58,14 +78,14 @@
 					while (unlikely(*ip == 0)) {
 						t += 255;
 						ip++;
-						NEED_IP(1);
+						NEED_IP(1, 0);
 					}
 					t += 15 + *ip++;
 				}
 				t += 3;
 copy_literal_run:
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
-				if (likely(HAVE_IP(t + 15) && HAVE_OP(t + 15))) {
+				if (likely(HAVE_IP(t, 15) && HAVE_OP(t, 15))) {
 					const unsigned char *ie = ip + t;
 					unsigned char *oe = op + t;
 					do {
@@ -81,8 +101,8 @@
 				} else
 #endif
 				{
-					NEED_OP(t);
-					NEED_IP(t + 3);
+					NEED_OP(t, 0);
+					NEED_IP(t, 3);
 					do {
 						*op++ = *ip++;
 					} while (--t > 0);
@@ -95,7 +115,7 @@
 				m_pos -= t >> 2;
 				m_pos -= *ip++ << 2;
 				TEST_LB(m_pos);
-				NEED_OP(2);
+				NEED_OP(2, 0);
 				op[0] = m_pos[0];
 				op[1] = m_pos[1];
 				op += 2;
@@ -119,10 +139,10 @@
 				while (unlikely(*ip == 0)) {
 					t += 255;
 					ip++;
-					NEED_IP(1);
+					NEED_IP(1, 0);
 				}
 				t += 31 + *ip++;
-				NEED_IP(2);
+				NEED_IP(2, 0);
 			}
 			m_pos = op - 1;
 			next = get_unaligned_le16(ip);
@@ -137,10 +157,10 @@
 				while (unlikely(*ip == 0)) {
 					t += 255;
 					ip++;
-					NEED_IP(1);
+					NEED_IP(1, 0);
 				}
 				t += 7 + *ip++;
-				NEED_IP(2);
+				NEED_IP(2, 0);
 			}
 			next = get_unaligned_le16(ip);
 			ip += 2;
@@ -154,7 +174,7 @@
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
 		if (op - m_pos >= 8) {
 			unsigned char *oe = op + t;
-			if (likely(HAVE_OP(t + 15))) {
+			if (likely(HAVE_OP(t, 15))) {
 				do {
 					COPY8(op, m_pos);
 					op += 8;
@@ -164,7 +184,7 @@
 					m_pos += 8;
 				} while (op < oe);
 				op = oe;
-				if (HAVE_IP(6)) {
+				if (HAVE_IP(6, 0)) {
 					state = next;
 					COPY4(op, ip);
 					op += next;
@@ -172,7 +192,7 @@
 					continue;
 				}
 			} else {
-				NEED_OP(t);
+				NEED_OP(t, 0);
 				do {
 					*op++ = *m_pos++;
 				} while (op < oe);
@@ -181,7 +201,7 @@
 #endif
 		{
 			unsigned char *oe = op + t;
-			NEED_OP(t);
+			NEED_OP(t, 0);
 			op[0] = m_pos[0];
 			op[1] = m_pos[1];
 			op += 2;
@@ -194,15 +214,15 @@
 		state = next;
 		t = next;
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
-		if (likely(HAVE_IP(6) && HAVE_OP(4))) {
+		if (likely(HAVE_IP(6, 0) && HAVE_OP(4, 0))) {
 			COPY4(op, ip);
 			op += t;
 			ip += t;
 		} else
 #endif
 		{
-			NEED_IP(t + 3);
-			NEED_OP(t);
+			NEED_IP(t, 3);
+			NEED_OP(t, 0);
 			while (t > 0) {
 				*op++ = *ip++;
 				t--;
diff -ruw linux-3.11.10/lib/Makefile linux-3.11.10-fbx/lib/Makefile
--- linux-3.11.10/lib/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/lib/Makefile	2014-05-09 14:12:54.364546160 +0200
@@ -45,6 +45,7 @@
 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
 lib-$(CONFIG_PERCPU_RWSEM) += percpu-rwsem.o
 
+GCOV_PROFILE_hweight.o := n
 CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS))
 obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
 
@@ -95,6 +96,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.11.10/lib/nlattr.c linux-3.11.10-fbx/lib/nlattr.c
--- linux-3.11.10/lib/nlattr.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/lib/nlattr.c	2014-08-22 15:47:22.148063206 +0200
@@ -201,8 +201,8 @@
 	}
 
 	if (unlikely(rem > 0))
-		printk(KERN_WARNING "netlink: %d bytes leftover after parsing "
-		       "attributes.\n", rem);
+		pr_warn_ratelimited("netlink: %d bytes leftover after parsing attributes in process `%s'.\n",
+				    rem, current->comm);
 
 	err = 0;
 errout:
@@ -303,9 +303,15 @@
  */
 int nla_strcmp(const struct nlattr *nla, const char *str)
 {
-	int len = strlen(str) + 1;
-	int d = nla_len(nla) - len;
+	int len = strlen(str);
+	char *buf = nla_data(nla);
+	int attrlen = nla_len(nla);
+	int d;
 
+	if (attrlen > 0 && buf[attrlen - 1] == '\0')
+		attrlen--;
+
+	d = attrlen - len;
 	if (d == 0)
 		d = memcmp(nla_data(nla), str, len);
 
diff -ruw linux-3.11.10/lib/percpu_counter.c linux-3.11.10-fbx/lib/percpu_counter.c
--- linux-3.11.10/lib/percpu_counter.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/lib/percpu_counter.c	2014-07-01 16:22:13.198329914 +0200
@@ -166,7 +166,7 @@
 	struct percpu_counter *fbc;
 
 	compute_batch_value();
-	if (action != CPU_DEAD)
+	if (action != CPU_DEAD && action != CPU_DEAD_FROZEN)
 		return NOTIFY_OK;
 
 	cpu = (unsigned long)hcpu;
diff -ruw linux-3.11.10/lib/random32.c linux-3.11.10-fbx/lib/random32.c
--- linux-3.11.10/lib/random32.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/lib/random32.c	2014-01-17 19:14:18.790220810 +0100
@@ -141,7 +141,7 @@
 	 */
 	for_each_possible_cpu (i) {
 		struct rnd_state *state = &per_cpu(net_rand_state, i);
-		state->s1 = __seed(state->s1 ^ entropy, 1);
+		state->s1 = __seed(state->s1 ^ entropy, 2);
 	}
 }
 EXPORT_SYMBOL(prandom_seed);
@@ -158,9 +158,9 @@
 		struct rnd_state *state = &per_cpu(net_rand_state,i);
 
 #define LCG(x)	((x) * 69069)	/* super-duper LCG */
-		state->s1 = __seed(LCG(i + jiffies), 1);
-		state->s2 = __seed(LCG(state->s1), 7);
-		state->s3 = __seed(LCG(state->s2), 15);
+		state->s1 = __seed(LCG(i + jiffies), 2);
+		state->s2 = __seed(LCG(state->s1), 8);
+		state->s3 = __seed(LCG(state->s2), 16);
 
 		/* "warm it up" */
 		prandom_u32_state(state);
@@ -187,9 +187,9 @@
 		u32 seeds[3];
 
 		get_random_bytes(&seeds, sizeof(seeds));
-		state->s1 = __seed(seeds[0], 1);
-		state->s2 = __seed(seeds[1], 7);
-		state->s3 = __seed(seeds[2], 15);
+		state->s1 = __seed(seeds[0], 2);
+		state->s2 = __seed(seeds[1], 8);
+		state->s3 = __seed(seeds[2], 16);
 
 		/* mix it in */
 		prandom_u32_state(state);
diff -ruw linux-3.11.10/lib/vsprintf.c linux-3.11.10-fbx/lib/vsprintf.c
--- linux-3.11.10/lib/vsprintf.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/lib/vsprintf.c	2014-01-17 19:14:18.790220810 +0100
@@ -26,6 +26,7 @@
 #include <linux/math64.h>
 #include <linux/uaccess.h>
 #include <linux/ioport.h>
+#include <linux/cred.h>
 #include <net/addrconf.h>
 
 #include <asm/page.h>		/* for PAGE_SIZE */
@@ -1236,11 +1237,37 @@
 				spec.field_width = default_width;
 			return string(buf, end, "pK-error", spec);
 		}
-		if (!((kptr_restrict == 0) ||
-		      (kptr_restrict == 1 &&
-		       has_capability_noaudit(current, CAP_SYSLOG))))
+
+		switch (kptr_restrict) {
+		case 0:
+			/* Always print %pK values */
+			break;
+		case 1: {
+			/*
+			 * Only print the real pointer value if the current
+			 * process has CAP_SYSLOG and is running with the
+			 * same credentials it started with. This is because
+			 * access to files is checked at open() time, but %pK
+			 * checks permission at read() time. We don't want to
+			 * leak pointer values if a binary opens a file using
+			 * %pK and then elevates privileges before reading it.
+			 */
+			const struct cred *cred = current_cred();
+
+			if (!has_capability_noaudit(current, CAP_SYSLOG) ||
+			    !uid_eq(cred->euid, cred->uid) ||
+			    !gid_eq(cred->egid, cred->gid))
+				ptr = NULL;
+			break;
+		}
+		case 2:
+		default:
+			/* Always print 0's for %pK */
 			ptr = NULL;
 		break;
+		}
+		break;
+
 	case 'N':
 		switch (fmt[1]) {
 		case 'F':
diff -ruw linux-3.11.10/Makefile linux-3.11.10-fbx/Makefile
--- linux-3.11.10/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/Makefile	2015-07-29 11:23:31.015266537 +0200
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 11
 SUBLEVEL = 10
-EXTRAVERSION =
+EXTRAVERSION = .14
 NAME = Linux for Workgroups
 
 # *DOCUMENTATION*
diff -ruw linux-3.11.10/mm/backing-dev.c linux-3.11.10-fbx/mm/backing-dev.c
--- linux-3.11.10/mm/backing-dev.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/backing-dev.c	2014-07-01 16:22:13.198329914 +0200
@@ -285,13 +285,19 @@
  * Note, we wouldn't bother setting up the timer, but this function is on the
  * fast-path (used by '__mark_inode_dirty()'), so we save few context switches
  * by delaying the wake-up.
+ *
+ * We have to be careful not to postpone flush work if it is scheduled for
+ * earlier. Thus we use queue_delayed_work().
  */
 void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi)
 {
 	unsigned long timeout;
 
 	timeout = msecs_to_jiffies(dirty_writeback_interval * 10);
-	mod_delayed_work(bdi_wq, &bdi->wb.dwork, timeout);
+	spin_lock_bh(&bdi->wb_lock);
+	if (test_bit(BDI_registered, &bdi->state))
+		queue_delayed_work(bdi_wq, &bdi->wb.dwork, timeout);
+	spin_unlock_bh(&bdi->wb_lock);
 }
 
 /*
@@ -304,9 +310,6 @@
 	spin_unlock_bh(&bdi_lock);
 
 	synchronize_rcu_expedited();
-
-	/* bdi_list is now unused, clear it to mark @bdi dying */
-	INIT_LIST_HEAD(&bdi->bdi_list);
 }
 
 int bdi_register(struct backing_dev_info *bdi, struct device *parent,
@@ -357,6 +360,11 @@
 	 */
 	bdi_remove_from_list(bdi);
 
+	/* Make sure nobody queues further work */
+	spin_lock_bh(&bdi->wb_lock);
+	clear_bit(BDI_registered, &bdi->state);
+	spin_unlock_bh(&bdi->wb_lock);
+
 	/*
 	 * Drain work list and shutdown the delayed_work.  At this point,
 	 * @bdi->bdi_list is empty telling bdi_Writeback_workfn() that @bdi
diff -ruw linux-3.11.10/mm/compaction.c linux-3.11.10-fbx/mm/compaction.c
--- linux-3.11.10/mm/compaction.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/compaction.c	2014-07-01 16:22:13.198329914 +0200
@@ -134,6 +134,10 @@
 			bool migrate_scanner)
 {
 	struct zone *zone = cc->zone;
+
+	if (cc->ignore_skip_hint)
+		return;
+
 	if (!page)
 		return;
 
@@ -248,7 +252,6 @@
 {
 	int nr_scanned = 0, total_isolated = 0;
 	struct page *cursor, *valid_page = NULL;
-	unsigned long nr_strict_required = end_pfn - blockpfn;
 	unsigned long flags;
 	bool locked = false;
 
@@ -261,11 +264,12 @@
 
 		nr_scanned++;
 		if (!pfn_valid_within(blockpfn))
-			continue;
+			goto isolate_fail;
+
 		if (!valid_page)
 			valid_page = page;
 		if (!PageBuddy(page))
-			continue;
+			goto isolate_fail;
 
 		/*
 		 * The zone lock must be held to isolate freepages.
@@ -286,12 +290,10 @@
 
 		/* Recheck this is a buddy page under lock */
 		if (!PageBuddy(page))
-			continue;
+			goto isolate_fail;
 
 		/* Found a free page, break it into order-0 pages */
 		isolated = split_free_page(page);
-		if (!isolated && strict)
-			break;
 		total_isolated += isolated;
 		for (i = 0; i < isolated; i++) {
 			list_add(&page->lru, freelist);
@@ -302,7 +304,15 @@
 		if (isolated) {
 			blockpfn += isolated - 1;
 			cursor += isolated - 1;
+			continue;
 		}
+
+isolate_fail:
+		if (strict)
+			break;
+		else
+			continue;
+
 	}
 
 	trace_mm_compaction_isolate_freepages(nr_scanned, total_isolated);
@@ -312,7 +322,7 @@
 	 * pages requested were isolated. If there were any failures, 0 is
 	 * returned and CMA will fail.
 	 */
-	if (strict && nr_strict_required > total_isolated)
+	if (strict && blockpfn < end_pfn)
 		total_isolated = 0;
 
 	if (locked)
@@ -647,17 +657,21 @@
 				struct compact_control *cc)
 {
 	struct page *page;
-	unsigned long high_pfn, low_pfn, pfn, z_end_pfn, end_pfn;
+	unsigned long high_pfn, low_pfn, pfn, z_end_pfn;
 	int nr_freepages = cc->nr_freepages;
 	struct list_head *freelist = &cc->freepages;
 
 	/*
 	 * Initialise the free scanner. The starting point is where we last
-	 * scanned from (or the end of the zone if starting). The low point
-	 * is the end of the pageblock the migration scanner is using.
+	 * successfully isolated from, zone-cached value, or the end of the
+	 * zone when isolating for the first time. We need this aligned to
+	 * the pageblock boundary, because we do pfn -= pageblock_nr_pages
+	 * in the for loop.
+	 * The low boundary is the end of the pageblock the migration scanner
+	 * is using.
 	 */
-	pfn = cc->free_pfn;
-	low_pfn = cc->migrate_pfn + pageblock_nr_pages;
+	pfn = cc->free_pfn & ~(pageblock_nr_pages-1);
+	low_pfn = ALIGN(cc->migrate_pfn + 1, pageblock_nr_pages);
 
 	/*
 	 * Take care that if the migration scanner is at the end of the zone
@@ -673,9 +687,10 @@
 	 * pages on cc->migratepages. We stop searching if the migrate
 	 * and free page scanners meet or enough free pages are isolated.
 	 */
-	for (; pfn > low_pfn && cc->nr_migratepages > nr_freepages;
+	for (; pfn >= low_pfn && cc->nr_migratepages > nr_freepages;
 					pfn -= pageblock_nr_pages) {
 		unsigned long isolated;
+		unsigned long end_pfn;
 
 		if (!pfn_valid(pfn))
 			continue;
@@ -703,13 +718,10 @@
 		isolated = 0;
 
 		/*
-		 * As pfn may not start aligned, pfn+pageblock_nr_page
-		 * may cross a MAX_ORDER_NR_PAGES boundary and miss
-		 * a pfn_valid check. Ensure isolate_freepages_block()
-		 * only scans within a pageblock
+		 * Take care when isolating in last pageblock of a zone which
+		 * ends in the middle of a pageblock.
 		 */
-		end_pfn = ALIGN(pfn + 1, pageblock_nr_pages);
-		end_pfn = min(end_pfn, z_end_pfn);
+		end_pfn = min(pfn + pageblock_nr_pages, z_end_pfn);
 		isolated = isolate_freepages_block(cc, pfn, end_pfn,
 						   freelist, false);
 		nr_freepages += isolated;
@@ -728,6 +740,13 @@
 	/* split_free_page does not map the pages */
 	map_pages(freelist);
 
+	/*
+	 * If we crossed the migrate scanner, we want to keep it that way
+	 * so that compact_finished() may detect this
+	 */
+	if (pfn < low_pfn)
+		cc->free_pfn = max(pfn, zone->zone_start_pfn);
+	else
 	cc->free_pfn = high_pfn;
 	cc->nr_freepages = nr_freepages;
 }
@@ -937,6 +956,14 @@
 	}
 
 	/*
+	 * Clear pageblock skip if there were failures recently and compaction
+	 * is about to be retried after being deferred. kswapd does not do
+	 * this reset as it'll reset the cached information when going to sleep.
+	 */
+	if (compaction_restarting(zone, cc->order) && !current_is_kswapd())
+		__reset_isolation_suitable(zone);
+
+	/*
 	 * Setup to move all movable pages to the end of the zone. Used cached
 	 * information on where the scanners should start but check that it
 	 * is initialised by ensuring the values are within zone boundaries.
@@ -952,14 +979,6 @@
 		zone->compact_cached_migrate_pfn = cc->migrate_pfn;
 	}
 
-	/*
-	 * Clear pageblock skip if there were failures recently and compaction
-	 * is about to be retried after being deferred. kswapd does not do
-	 * this reset as it'll reset the cached information when going to sleep.
-	 */
-	if (compaction_restarting(zone, cc->order) && !current_is_kswapd())
-		__reset_isolation_suitable(zone);
-
 	migrate_prep_local();
 
 	while ((ret = compact_finished(zone, cc)) == COMPACT_CONTINUE) {
@@ -993,7 +1012,11 @@
 		if (err) {
 			putback_movable_pages(&cc->migratepages);
 			cc->nr_migratepages = 0;
-			if (err == -ENOMEM) {
+			/*
+			 * migrate_pages() may return -ENOMEM when scanners meet
+			 * and we want compact_finished() to detect it
+			 */
+			if (err == -ENOMEM && cc->free_pfn > cc->migrate_pfn) {
 				ret = COMPACT_PARTIAL;
 				goto out;
 			}
diff -ruw linux-3.11.10/mm/fremap.c linux-3.11.10-fbx/mm/fremap.c
--- linux-3.11.10/mm/fremap.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/fremap.c	2014-01-17 19:14:18.794220810 +0100
@@ -208,9 +208,10 @@
 		if (mapping_cap_account_dirty(mapping)) {
 			unsigned long addr;
 			struct file *file = get_file(vma->vm_file);
+			/* mmap_region may free vma; grab the info now */
+			vm_flags = vma->vm_flags;
 
-			addr = mmap_region(file, start, size,
-					vma->vm_flags, pgoff);
+			addr = mmap_region(file, start, size, vm_flags, pgoff);
 			fput(file);
 			if (IS_ERR_VALUE(addr)) {
 				err = addr;
@@ -218,7 +219,7 @@
 				BUG_ON(addr != start);
 				err = 0;
 			}
-			goto out;
+			goto out_freed;
 		}
 		mutex_lock(&mapping->i_mmap_mutex);
 		flush_dcache_mmap_lock(mapping);
@@ -253,6 +254,7 @@
 out:
 	if (vma)
 		vm_flags = vma->vm_flags;
+out_freed:
 	if (likely(!has_write_lock))
 		up_read(&mm->mmap_sem);
 	else
diff -ruw linux-3.11.10/mm/memcontrol.c linux-3.11.10-fbx/mm/memcontrol.c
--- linux-3.11.10/mm/memcontrol.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/memcontrol.c	2014-07-01 16:22:13.202329926 +0200
@@ -349,7 +349,7 @@
 static size_t memcg_size(void)
 {
 	return sizeof(struct mem_cgroup) +
-		nr_node_ids * sizeof(struct mem_cgroup_per_node);
+		nr_node_ids * sizeof(struct mem_cgroup_per_node *);
 }
 
 /* internal only representation about the status of kmem accounting. */
@@ -1148,7 +1148,15 @@
 	if (iter->last_dead_count == *sequence) {
 		smp_rmb();
 		position = iter->last_visited;
-		if (position && !css_tryget(&position->css))
+
+		/*
+		 * We cannot take a reference to root because we might race
+		 * with root removal and returning NULL would end up in
+		 * an endless loop on the iterator user level when root
+		 * would be returned all the time.
+		 */
+		if (position && position != root &&
+				!css_tryget(&position->css))
 			position = NULL;
 	}
 	return position;
@@ -1157,9 +1165,11 @@
 static void mem_cgroup_iter_update(struct mem_cgroup_reclaim_iter *iter,
 				   struct mem_cgroup *last_visited,
 				   struct mem_cgroup *new_position,
+				   struct mem_cgroup *root,
 				   int sequence)
 {
-	if (last_visited)
+	/* root reference counting symmetric to mem_cgroup_iter_load */
+	if (last_visited && last_visited != root)
 		css_put(&last_visited->css);
 	/*
 	 * We store the sequence count from the time @last_visited was
@@ -1234,7 +1244,8 @@
 		memcg = __mem_cgroup_iter_next(root, last_visited);
 
 		if (reclaim) {
-			mem_cgroup_iter_update(iter, last_visited, memcg, seq);
+			mem_cgroup_iter_update(iter, last_visited, memcg, root,
+					seq);
 
 			if (!memcg)
 				iter->generation++;
@@ -6335,11 +6346,25 @@
 static void mem_cgroup_css_offline(struct cgroup *cont)
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
+	struct cgroup *iter;
 
 	kmem_cgroup_css_offline(memcg);
 
 	mem_cgroup_invalidate_reclaim_iterators(memcg);
+
+	/*
+	 * This requires that offlining is serialized.  Right now that is
+	 * guaranteed because css_killed_work_fn() holds the cgroup_mutex.
+	 */
+	rcu_read_lock();
+	cgroup_for_each_descendant_post(iter, cont) {
+		rcu_read_unlock();
+		mem_cgroup_reparent_charges(mem_cgroup_from_cont(iter));
+		rcu_read_lock();
+	}
+	rcu_read_unlock();
 	mem_cgroup_reparent_charges(memcg);
+
 	mem_cgroup_destroy_all_caches(memcg);
 	vmpressure_cleanup(&memcg->vmpressure);
 }
@@ -6347,6 +6372,42 @@
 static void mem_cgroup_css_free(struct cgroup *cont)
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
+	/*
+	 * XXX: css_offline() would be where we should reparent all
+	 * memory to prepare the cgroup for destruction.  However,
+	 * memcg does not do css_tryget() and res_counter charging
+	 * under the same RCU lock region, which means that charging
+	 * could race with offlining.  Offlining only happens to
+	 * cgroups with no tasks in them but charges can show up
+	 * without any tasks from the swapin path when the target
+	 * memcg is looked up from the swapout record and not from the
+	 * current task as it usually is.  A race like this can leak
+	 * charges and put pages with stale cgroup pointers into
+	 * circulation:
+	 *
+	 * #0                        #1
+	 *                           lookup_swap_cgroup_id()
+	 *                           rcu_read_lock()
+	 *                           mem_cgroup_lookup()
+	 *                           css_tryget()
+	 *                           rcu_read_unlock()
+	 * disable css_tryget()
+	 * call_rcu()
+	 *   offline_css()
+	 *     reparent_charges()
+	 *                           res_counter_charge()
+	 *                           css_put()
+	 *                             css_free()
+	 *                           pc->mem_cgroup = dead memcg
+	 *                           add page to lru
+	 *
+	 * The bulk of the charges are still moved in offline_css() to
+	 * avoid pinning a lot of pages in case a long-term reference
+	 * like a swapout record is deferring the css_free() to long
+	 * after offlining.  But this makes sure we catch any charges
+	 * made after offlining:
+	 */
+	mem_cgroup_reparent_charges(memcg);
 
 	memcg_destroy_kmem(memcg);
 	__mem_cgroup_free(memcg);
diff -ruw linux-3.11.10/mm/memory.c linux-3.11.10-fbx/mm/memory.c
--- linux-3.11.10/mm/memory.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/memory.c	2014-07-01 16:22:13.202329926 +0200
@@ -1940,12 +1940,17 @@
 		     unsigned long address, unsigned int fault_flags)
 {
 	struct vm_area_struct *vma;
+	vm_flags_t vm_flags;
 	int ret;
 
 	vma = find_extend_vma(mm, address);
 	if (!vma || address < vma->vm_start)
 		return -EFAULT;
 
+	vm_flags = (fault_flags & FAULT_FLAG_WRITE) ? VM_WRITE : VM_READ;
+	if (!(vm_flags & vma->vm_flags))
+		return -EFAULT;
+
 	ret = handle_mm_fault(mm, vma, address, fault_flags);
 	if (ret & VM_FAULT_ERROR) {
 		if (ret & VM_FAULT_OOM)
diff -ruw linux-3.11.10/mm/mlock.c linux-3.11.10-fbx/mm/mlock.c
--- linux-3.11.10/mm/mlock.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/mlock.c	2014-07-01 16:22:13.202329926 +0200
@@ -76,6 +76,7 @@
  */
 void mlock_vma_page(struct page *page)
 {
+	/* Serialize with page migration */
 	BUG_ON(!PageLocked(page));
 
 	if (!TestSetPageMlocked(page)) {
@@ -106,6 +107,7 @@
 {
 	unsigned int page_mask = 0;
 
+	/* For try_to_munlock() and to serialize with page migration */
 	BUG_ON(!PageLocked(page));
 
 	if (TestClearPageMlocked(page)) {
diff -ruw linux-3.11.10/mm/mmap.c linux-3.11.10-fbx/mm/mmap.c
--- linux-3.11.10/mm/mmap.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/mmap.c	2014-01-17 19:14:18.798220810 +0100
@@ -1855,7 +1855,7 @@
 	struct vm_area_struct *vma;
 	struct vm_unmapped_area_info info;
 
-	if (len > TASK_SIZE)
+	if (len > TASK_SIZE - mmap_min_addr)
 		return -ENOMEM;
 
 	if (flags & MAP_FIXED)
@@ -1864,7 +1864,7 @@
 	if (addr) {
 		addr = PAGE_ALIGN(addr);
 		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
+		if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
 		    (!vma || addr + len <= vma->vm_start))
 			return addr;
 	}
@@ -1894,7 +1894,7 @@
 	struct vm_unmapped_area_info info;
 
 	/* requested length too big for entire address space */
-	if (len > TASK_SIZE)
+	if (len > TASK_SIZE - mmap_min_addr)
 		return -ENOMEM;
 
 	if (flags & MAP_FIXED)
@@ -1904,14 +1904,14 @@
 	if (addr) {
 		addr = PAGE_ALIGN(addr);
 		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
+		if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
 				(!vma || addr + len <= vma->vm_start))
 			return addr;
 	}
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
-	info.low_limit = PAGE_SIZE;
+	info.low_limit = max(PAGE_SIZE, mmap_min_addr);
 	info.high_limit = mm->mmap_base;
 	info.align_mask = 0;
 	addr = vm_unmapped_area(&info);
diff -ruw linux-3.11.10/mm/mprotect.c linux-3.11.10-fbx/mm/mprotect.c
--- linux-3.11.10/mm/mprotect.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/mprotect.c	2014-01-17 19:14:18.798220810 +0100
@@ -54,13 +54,16 @@
 			pte_t ptent;
 			bool updated = false;
 
-			ptent = ptep_modify_prot_start(mm, addr, pte);
 			if (!prot_numa) {
+				ptent = ptep_modify_prot_start(mm, addr, pte);
+				if (pte_numa(ptent))
+					ptent = pte_mknonnuma(ptent);
 				ptent = pte_modify(ptent, newprot);
 				updated = true;
 			} else {
 				struct page *page;
 
+				ptent = *pte;
 				page = vm_normal_page(vma, addr, oldpte);
 				if (page) {
 					int this_nid = page_to_nid(page);
@@ -73,6 +76,7 @@
 					if (!pte_numa(oldpte) &&
 					    page_mapcount(page) == 1) {
 						ptent = pte_mknuma(ptent);
+						set_pte_at(mm, addr, pte, ptent);
 						updated = true;
 					}
 				}
@@ -89,6 +93,9 @@
 
 			if (updated)
 				pages++;
+
+			/* Only !prot_numa always clears the pte */
+			if (!prot_numa)
 			ptep_modify_prot_commit(mm, addr, pte, ptent);
 		} else if (IS_ENABLED(CONFIG_MIGRATION) && !pte_file(oldpte)) {
 			swp_entry_t entry = pte_to_swp_entry(oldpte);
@@ -138,6 +145,7 @@
 	pmd_t *pmd;
 	unsigned long next;
 	unsigned long pages = 0;
+	unsigned long nr_huge_updates = 0;
 	bool all_same_node;
 
 	pmd = pmd_offset(pud, addr);
@@ -148,7 +156,8 @@
 				split_huge_page_pmd(vma, addr, pmd);
 			else if (change_huge_pmd(vma, pmd, addr, newprot,
 						 prot_numa)) {
-				pages++;
+				pages += HPAGE_PMD_NR;
+				nr_huge_updates++;
 				continue;
 			}
 			/* fall through */
@@ -168,6 +177,9 @@
 			change_pmd_protnuma(vma->vm_mm, addr, pmd);
 	} while (pmd++, addr = next, addr != end);
 
+	if (nr_huge_updates)
+		count_vm_numa_events(NUMA_HUGE_PTE_UPDATES, nr_huge_updates);
+
 	return pages;
 }
 
@@ -204,6 +216,7 @@
 	BUG_ON(addr >= end);
 	pgd = pgd_offset(mm, addr);
 	flush_cache_range(vma, addr, end);
+	set_tlb_flush_pending(mm);
 	do {
 		next = pgd_addr_end(addr, end);
 		if (pgd_none_or_clear_bad(pgd))
@@ -215,6 +228,7 @@
 	/* Only flush the TLB if we actually modified any entries: */
 	if (pages)
 		flush_tlb_range(vma, start, end);
+	clear_tlb_flush_pending(mm);
 
 	return pages;
 }
diff -ruw linux-3.11.10/mm/mremap.c linux-3.11.10-fbx/mm/mremap.c
--- linux-3.11.10/mm/mremap.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/mremap.c	2014-07-01 16:22:13.202329926 +0200
@@ -194,10 +194,17 @@
 			break;
 		if (pmd_trans_huge(*old_pmd)) {
 			int err = 0;
-			if (extent == HPAGE_PMD_SIZE)
+			if (extent == HPAGE_PMD_SIZE) {
+				VM_BUG_ON(vma->vm_file || !vma->anon_vma);
+				/* See comment in move_ptes() */
+				if (need_rmap_locks)
+					anon_vma_lock_write(vma->anon_vma);
 				err = move_huge_pmd(vma, new_vma, old_addr,
 						    new_addr, old_end,
 						    old_pmd, new_pmd);
+				if (need_rmap_locks)
+					anon_vma_unlock_write(vma->anon_vma);
+			}
 			if (err > 0) {
 				need_flush = true;
 				continue;
diff -ruw linux-3.11.10/mm/oom_kill.c linux-3.11.10-fbx/mm/oom_kill.c
--- linux-3.11.10/mm/oom_kill.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/oom_kill.c	2014-05-09 14:12:54.376546160 +0200
@@ -170,7 +170,7 @@
 	 * implementation used by LSMs.
 	 */
 	if (has_capability_noaudit(p, CAP_SYS_ADMIN))
-		adj -= 30;
+		points -= (points * 3) / 100;
 
 	/* Normalize to oom_score_adj units */
 	adj *= totalpages / 1000;
diff -ruw linux-3.11.10/mm/page_alloc.c linux-3.11.10-fbx/mm/page_alloc.c
--- linux-3.11.10/mm/page_alloc.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/page_alloc.c	2014-08-22 15:47:22.152063226 +0200
@@ -68,6 +68,7 @@
 
 /* prevent >1 _updater_ of zone percpu pageset ->high and ->batch fields */
 static DEFINE_MUTEX(pcp_batch_high_lock);
+#define MIN_PERCPU_PAGELIST_FRACTION	(8)
 
 #ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID
 DEFINE_PER_CPU(int, numa_node);
@@ -779,9 +780,21 @@
 		set_page_count(p, 0);
 	} while (++p, --i);
 
-	set_page_refcounted(page);
 	set_pageblock_migratetype(page, MIGRATE_CMA);
+
+	if (pageblock_order >= MAX_ORDER) {
+		i = pageblock_nr_pages;
+		p = page;
+		do {
+			set_page_refcounted(p);
+			__free_pages(p, MAX_ORDER - 1);
+			p += MAX_ORDER_NR_PAGES;
+		} while (i -= MAX_ORDER_NR_PAGES);
+	} else {
+		set_page_refcounted(page);
 	__free_pages(page, pageblock_order);
+	}
+
 	adjust_managed_page_count(page, pageblock_nr_pages);
 }
 #endif
@@ -3988,7 +4001,7 @@
 	memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY)
 #endif
 
-static int __meminit zone_batchsize(struct zone *zone)
+static int zone_batchsize(struct zone *zone)
 {
 #ifdef CONFIG_MMU
 	int batch;
@@ -4104,7 +4117,7 @@
 	pageset_update(&p->pcp, high, batch);
 }
 
-static void __meminit pageset_set_high_and_batch(struct zone *zone,
+static void pageset_set_high_and_batch(struct zone *zone,
 		struct per_cpu_pageset *pcp)
 {
 	if (percpu_pagelist_fraction)
@@ -5689,23 +5702,38 @@
 	void __user *buffer, size_t *length, loff_t *ppos)
 {
 	struct zone *zone;
-	unsigned int cpu;
+	int old_percpu_pagelist_fraction;
 	int ret;
 
+	mutex_lock(&pcp_batch_high_lock);
+	old_percpu_pagelist_fraction = percpu_pagelist_fraction;
+
 	ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
-	if (!write || (ret < 0))
-		return ret;
+	if (!write || ret < 0)
+		goto out;
+
+	/* Sanity checking to avoid pcp imbalance */
+	if (percpu_pagelist_fraction &&
+	    percpu_pagelist_fraction < MIN_PERCPU_PAGELIST_FRACTION) {
+		percpu_pagelist_fraction = old_percpu_pagelist_fraction;
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* No change? */
+	if (percpu_pagelist_fraction == old_percpu_pagelist_fraction)
+		goto out;
 
-	mutex_lock(&pcp_batch_high_lock);
 	for_each_populated_zone(zone) {
-		unsigned long  high;
-		high = zone->managed_pages / percpu_pagelist_fraction;
+		unsigned int cpu;
+
 		for_each_possible_cpu(cpu)
-			pageset_set_high(per_cpu_ptr(zone->pageset, cpu),
-					 high);
+			pageset_set_high_and_batch(zone,
+					per_cpu_ptr(zone->pageset, cpu));
 	}
+out:
 	mutex_unlock(&pcp_batch_high_lock);
-	return 0;
+	return ret;
 }
 
 int hashdist = HASHDIST_DEFAULT;
@@ -5847,53 +5875,65 @@
  * @end_bitidx: The last bit of interest
  * returns pageblock_bits flags
  */
-unsigned long get_pageblock_flags_group(struct page *page,
-					int start_bitidx, int end_bitidx)
+unsigned long get_pageblock_flags_mask(struct page *page,
+					unsigned long end_bitidx,
+					unsigned long mask)
 {
 	struct zone *zone;
 	unsigned long *bitmap;
-	unsigned long pfn, bitidx;
-	unsigned long flags = 0;
-	unsigned long value = 1;
+	unsigned long pfn, bitidx, word_bitidx;
+	unsigned long word;
 
 	zone = page_zone(page);
 	pfn = page_to_pfn(page);
 	bitmap = get_pageblock_bitmap(zone, pfn);
 	bitidx = pfn_to_bitidx(zone, pfn);
+	word_bitidx = bitidx / BITS_PER_LONG;
+	bitidx &= (BITS_PER_LONG-1);
 
-	for (; start_bitidx <= end_bitidx; start_bitidx++, value <<= 1)
-		if (test_bit(bitidx + start_bitidx, bitmap))
-			flags |= value;
-
-	return flags;
+	word = bitmap[word_bitidx];
+	bitidx += end_bitidx;
+	return (word >> (BITS_PER_LONG - bitidx - 1)) & mask;
 }
 
 /**
- * set_pageblock_flags_group - Set the requested group of flags for a pageblock_nr_pages block of pages
+ * set_pageblock_flags_mask - Set the requested group of flags for a pageblock_nr_pages block of pages
  * @page: The page within the block of interest
  * @start_bitidx: The first bit of interest
  * @end_bitidx: The last bit of interest
  * @flags: The flags to set
  */
-void set_pageblock_flags_group(struct page *page, unsigned long flags,
-					int start_bitidx, int end_bitidx)
+void set_pageblock_flags_mask(struct page *page, unsigned long flags,
+					unsigned long end_bitidx,
+					unsigned long mask)
 {
 	struct zone *zone;
 	unsigned long *bitmap;
-	unsigned long pfn, bitidx;
-	unsigned long value = 1;
+	unsigned long pfn, bitidx, word_bitidx;
+	unsigned long old_word, word;
+
+	BUILD_BUG_ON(NR_PAGEBLOCK_BITS != 4);
 
 	zone = page_zone(page);
 	pfn = page_to_pfn(page);
 	bitmap = get_pageblock_bitmap(zone, pfn);
 	bitidx = pfn_to_bitidx(zone, pfn);
+	word_bitidx = bitidx / BITS_PER_LONG;
+	bitidx &= (BITS_PER_LONG-1);
+
 	VM_BUG_ON(!zone_spans_pfn(zone, pfn));
 
-	for (; start_bitidx <= end_bitidx; start_bitidx++, value <<= 1)
-		if (flags & value)
-			__set_bit(bitidx + start_bitidx, bitmap);
-		else
-			__clear_bit(bitidx + start_bitidx, bitmap);
+	bitidx += end_bitidx;
+	mask <<= (BITS_PER_LONG - bitidx - 1);
+	flags <<= (BITS_PER_LONG - bitidx - 1);
+
+	word = ACCESS_ONCE(bitmap[word_bitidx]);
+	for (;;) {
+		old_word = cmpxchg(&bitmap[word_bitidx], word, (word & ~mask) | flags);
+		if (word == old_word)
+			break;
+		word = old_word;
+	}
 }
 
 /*
diff -ruw linux-3.11.10/mm/page-writeback.c linux-3.11.10-fbx/mm/page-writeback.c
--- linux-3.11.10/mm/page-writeback.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/page-writeback.c	2014-08-22 15:47:22.152063226 +0200
@@ -188,6 +188,25 @@
  * global dirtyable memory first.
  */
 
+/**
+ * zone_dirtyable_memory - number of dirtyable pages in a zone
+ * @zone: the zone
+ *
+ * Returns the zone's number of pages potentially available for dirty
+ * page cache.  This is the base value for the per-zone dirty limits.
+ */
+static unsigned long zone_dirtyable_memory(struct zone *zone)
+{
+	unsigned long nr_pages;
+
+	nr_pages = zone_page_state(zone, NR_FREE_PAGES);
+	nr_pages -= min(nr_pages, zone->dirty_balance_reserve);
+
+	nr_pages += zone_reclaimable_pages(zone);
+
+	return nr_pages;
+}
+
 static unsigned long highmem_dirtyable_memory(unsigned long total)
 {
 #ifdef CONFIG_HIGHMEM
@@ -195,11 +214,9 @@
 	unsigned long x = 0;
 
 	for_each_node_state(node, N_HIGH_MEMORY) {
-		struct zone *z =
-			&NODE_DATA(node)->node_zones[ZONE_HIGHMEM];
+		struct zone *z = &NODE_DATA(node)->node_zones[ZONE_HIGHMEM];
 
-		x += zone_page_state(z, NR_FREE_PAGES) +
-		     zone_reclaimable_pages(z) - z->dirty_balance_reserve;
+		x += zone_dirtyable_memory(z);
 	}
 	/*
 	 * Unreclaimable memory (kernel memory or anonymous memory
@@ -235,9 +252,11 @@
 {
 	unsigned long x;
 
-	x = global_page_state(NR_FREE_PAGES) + global_reclaimable_pages();
+	x = global_page_state(NR_FREE_PAGES);
 	x -= min(x, dirty_balance_reserve);
 
+	x += global_reclaimable_pages();
+
 	if (!vm_highmem_is_dirtyable)
 		x -= highmem_dirtyable_memory(x);
 
@@ -289,32 +308,6 @@
 }
 
 /**
- * zone_dirtyable_memory - number of dirtyable pages in a zone
- * @zone: the zone
- *
- * Returns the zone's number of pages potentially available for dirty
- * page cache.  This is the base value for the per-zone dirty limits.
- */
-static unsigned long zone_dirtyable_memory(struct zone *zone)
-{
-	/*
-	 * The effective global number of dirtyable pages may exclude
-	 * highmem as a big-picture measure to keep the ratio between
-	 * dirty memory and lowmem reasonable.
-	 *
-	 * But this function is purely about the individual zone and a
-	 * highmem zone can hold its share of dirty pages, so we don't
-	 * care about vm_highmem_is_dirtyable here.
-	 */
-	unsigned long nr_pages = zone_page_state(zone, NR_FREE_PAGES) +
-		zone_reclaimable_pages(zone);
-
-	/* don't allow this to underflow */
-	nr_pages -= min(nr_pages, zone->dirty_balance_reserve);
-	return nr_pages;
-}
-
-/**
  * zone_dirty_limit - maximum number of dirty pages allowed in a zone
  * @zone: the zone
  *
@@ -696,7 +689,7 @@
 	 *     => fast response on large errors; small oscillation near setpoint
 	 */
 	setpoint = (freerun + limit) / 2;
-	x = div_s64(((s64)setpoint - (s64)dirty) << RATELIMIT_CALC_SHIFT,
+	x = div64_s64(((s64)setpoint - (s64)dirty) << RATELIMIT_CALC_SHIFT,
 		    limit - setpoint + 1);
 	pos_ratio = x;
 	pos_ratio = pos_ratio * x >> RATELIMIT_CALC_SHIFT;
@@ -762,7 +755,7 @@
 	x_intercept = bdi_setpoint + span;
 
 	if (bdi_dirty < x_intercept - span / 4) {
-		pos_ratio = div_u64(pos_ratio * (x_intercept - bdi_dirty),
+		pos_ratio = div64_u64(pos_ratio * (x_intercept - bdi_dirty),
 				    x_intercept - bdi_setpoint + 1);
 	} else
 		pos_ratio /= 4;
@@ -2031,11 +2024,12 @@
 	if (!TestSetPageDirty(page)) {
 		struct address_space *mapping = page_mapping(page);
 		struct address_space *mapping2;
+		unsigned long flags;
 
 		if (!mapping)
 			return 1;
 
-		spin_lock_irq(&mapping->tree_lock);
+		spin_lock_irqsave(&mapping->tree_lock, flags);
 		mapping2 = page_mapping(page);
 		if (mapping2) { /* Race with truncate? */
 			BUG_ON(mapping2 != mapping);
@@ -2044,7 +2038,7 @@
 			radix_tree_tag_set(&mapping->page_tree,
 				page_index(page), PAGECACHE_TAG_DIRTY);
 		}
-		spin_unlock_irq(&mapping->tree_lock);
+		spin_unlock_irqrestore(&mapping->tree_lock, flags);
 		if (mapping->host) {
 			/* !PageAnon && !swapper_space */
 			__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
@@ -2250,7 +2244,7 @@
 	return ret;
 }
 
-int test_set_page_writeback(struct page *page)
+int __test_set_page_writeback(struct page *page, bool keep_write)
 {
 	struct address_space *mapping = page_mapping(page);
 	int ret;
@@ -2272,6 +2266,7 @@
 			radix_tree_tag_clear(&mapping->page_tree,
 						page_index(page),
 						PAGECACHE_TAG_DIRTY);
+		if (!keep_write)
 		radix_tree_tag_clear(&mapping->page_tree,
 				     page_index(page),
 				     PAGECACHE_TAG_TOWRITE);
@@ -2284,7 +2279,7 @@
 	return ret;
 
 }
-EXPORT_SYMBOL(test_set_page_writeback);
+EXPORT_SYMBOL(__test_set_page_writeback);
 
 /*
  * Return true if any of the pages in the mapping are marked with the
diff -ruw linux-3.11.10/mm/percpu.c linux-3.11.10-fbx/mm/percpu.c
--- linux-3.11.10/mm/percpu.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/percpu.c	2014-07-01 16:22:13.202329926 +0200
@@ -612,7 +612,7 @@
 	chunk->map = pcpu_mem_zalloc(PCPU_DFL_MAP_ALLOC *
 						sizeof(chunk->map[0]));
 	if (!chunk->map) {
-		kfree(chunk);
+		pcpu_mem_free(chunk, pcpu_chunk_struct_size);
 		return NULL;
 	}
 
diff -ruw linux-3.11.10/mm/pgtable-generic.c linux-3.11.10-fbx/mm/pgtable-generic.c
--- linux-3.11.10/mm/pgtable-generic.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/pgtable-generic.c	2014-01-17 19:14:18.798220810 +0100
@@ -86,9 +86,10 @@
 pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long address,
 		       pte_t *ptep)
 {
+	struct mm_struct *mm = (vma)->vm_mm;
 	pte_t pte;
-	pte = ptep_get_and_clear((vma)->vm_mm, address, ptep);
-	if (pte_accessible(pte))
+	pte = ptep_get_and_clear(mm, address, ptep);
+	if (pte_accessible(mm, pte))
 		flush_tlb_page(vma, address);
 	return pte;
 }
@@ -167,6 +168,9 @@
 void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
 		     pmd_t *pmdp)
 {
+	pmd_t entry = *pmdp;
+	if (pmd_numa(entry))
+		entry = pmd_mknonnuma(entry);
 	set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(*pmdp));
 	flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
 }
diff -ruw linux-3.11.10/mm/rmap.c linux-3.11.10-fbx/mm/rmap.c
--- linux-3.11.10/mm/rmap.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/rmap.c	2014-08-22 15:47:22.152063226 +0200
@@ -103,6 +103,7 @@
 	 * LOCK should suffice since the actual taking of the lock must
 	 * happen _before_ what follows.
 	 */
+	might_sleep();
 	if (rwsem_is_locked(&anon_vma->root->rwsem)) {
 		anon_vma_lock_write(anon_vma);
 		anon_vma_unlock_write(anon_vma);
@@ -426,8 +427,9 @@
 	 * above cannot corrupt).
 	 */
 	if (!page_mapped(page)) {
+		rcu_read_unlock();
 		put_anon_vma(anon_vma);
-		anon_vma = NULL;
+		return NULL;
 	}
 out:
 	rcu_read_unlock();
@@ -477,9 +479,9 @@
 	}
 
 	if (!page_mapped(page)) {
+		rcu_read_unlock();
 		put_anon_vma(anon_vma);
-		anon_vma = NULL;
-		goto out;
+		return NULL;
 	}
 
 	/* we pinned the anon_vma, its safe to sleep */
@@ -600,7 +602,11 @@
 	spinlock_t *ptl;
 
 	if (unlikely(PageHuge(page))) {
+		/* when pud is not present, pte will be NULL */
 		pte = huge_pte_offset(mm, address);
+		if (!pte)
+			return NULL;
+
 		ptl = &mm->page_table_lock;
 		goto check;
 	}
@@ -1391,9 +1397,19 @@
 		BUG_ON(!page || PageAnon(page));
 
 		if (locked_vma) {
-			mlock_vma_page(page);   /* no-op if already mlocked */
-			if (page == check_page)
+			if (page == check_page) {
+				/* we know we have check_page locked */
+				mlock_vma_page(page);
 				ret = SWAP_MLOCK;
+			} else if (trylock_page(page)) {
+				/*
+				 * If we can lock the page, perform mlock.
+				 * Otherwise leave the page alone, it will be
+				 * eventually encountered again later.
+				 */
+				mlock_vma_page(page);
+				unlock_page(page);
+			}
 			continue;	/* don't unmap */
 		}
 
@@ -1670,10 +1686,9 @@
 {
 	struct anon_vma *root = anon_vma->root;
 
+	anon_vma_free(anon_vma);
 	if (root != anon_vma && atomic_dec_and_test(&root->refcount))
 		anon_vma_free(root);
-
-	anon_vma_free(anon_vma);
 }
 
 #ifdef CONFIG_MIGRATION
diff -ruw linux-3.11.10/mm/slub.c linux-3.11.10-fbx/mm/slub.c
--- linux-3.11.10/mm/slub.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/slub.c	2014-05-09 14:12:54.376546160 +0200
@@ -1210,8 +1210,8 @@
 	/*
 	 * Enable debugging if selected on the kernel commandline.
 	 */
-	if (slub_debug && (!slub_debug_slabs ||
-		!strncmp(slub_debug_slabs, name, strlen(slub_debug_slabs))))
+	if (slub_debug && (!slub_debug_slabs || (name &&
+		!strncmp(slub_debug_slabs, name, strlen(slub_debug_slabs)))))
 		flags |= slub_debug;
 
 	return flags;
@@ -4300,7 +4300,13 @@
 
 			page = ACCESS_ONCE(c->partial);
 			if (page) {
-				x = page->pobjects;
+				node = page_to_nid(page);
+				if (flags & SO_TOTAL)
+					WARN_ON_ONCE(1);
+				else if (flags & SO_OBJECTS)
+					WARN_ON_ONCE(1);
+				else
+					x = page->pages;
 				total += x;
 				nodes[node] += x;
 			}
diff -ruw linux-3.11.10/mm/swap.c linux-3.11.10-fbx/mm/swap.c
--- linux-3.11.10/mm/swap.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/swap.c	2014-05-09 14:12:54.376546160 +0200
@@ -82,19 +82,6 @@
 
 static void put_compound_page(struct page *page)
 {
-	/*
-	 * hugetlbfs pages cannot be split from under us.  If this is a
-	 * hugetlbfs page, check refcount on head page and release the page if
-	 * the refcount becomes zero.
-	 */
-	if (PageHuge(page)) {
-		page = compound_head(page);
-		if (put_page_testzero(page))
-			__put_compound_page(page);
-
-		return;
-	}
-
 	if (unlikely(PageTail(page))) {
 		/* __split_huge_page_refcount can run under us */
 		struct page *page_head = compound_trans_head(page);
@@ -111,14 +98,31 @@
 			 * still hot on arches that do not support
 			 * this_cpu_cmpxchg_double().
 			 */
-			if (PageSlab(page_head)) {
-				if (PageTail(page)) {
+			if (PageSlab(page_head) || PageHeadHuge(page_head)) {
+				if (likely(PageTail(page))) {
+					/*
+					 * __split_huge_page_refcount
+					 * cannot race here.
+					 */
+					VM_BUG_ON(!PageHead(page_head));
+					atomic_dec(&page->_mapcount);
 					if (put_page_testzero(page_head))
 						VM_BUG_ON(1);
-
-					atomic_dec(&page->_mapcount);
-					goto skip_lock_tail;
+					if (put_page_testzero(page_head))
+						__put_compound_page(page_head);
+					return;
 				} else
+					/*
+					 * __split_huge_page_refcount
+					 * run before us, "page" was a
+					 * THP tail. The split
+					 * page_head has been freed
+					 * and reallocated as slab or
+					 * hugetlbfs page of smaller
+					 * order (only possible if
+					 * reallocated as slab on
+					 * x86).
+					 */
 					goto skip_lock;
 			}
 			/*
@@ -132,8 +136,27 @@
 				/* __split_huge_page_refcount run before us */
 				compound_unlock_irqrestore(page_head, flags);
 skip_lock:
-				if (put_page_testzero(page_head))
+				if (put_page_testzero(page_head)) {
+					/*
+					 * The head page may have been
+					 * freed and reallocated as a
+					 * compound page of smaller
+					 * order and then freed again.
+					 * All we know is that it
+					 * cannot have become: a THP
+					 * page, a compound page of
+					 * higher order, a tail page.
+					 * That is because we still
+					 * hold the refcount of the
+					 * split THP tail and
+					 * page_head was the THP head
+					 * before the split.
+					 */
+					if (PageHead(page_head))
+						__put_compound_page(page_head);
+					else
 					__put_single_page(page_head);
+				}
 out_put_single:
 				if (put_page_testzero(page))
 					__put_single_page(page);
@@ -155,7 +178,6 @@
 			VM_BUG_ON(atomic_read(&page->_count) != 0);
 			compound_unlock_irqrestore(page_head, flags);
 
-skip_lock_tail:
 			if (put_page_testzero(page_head)) {
 				if (PageHead(page_head))
 					__put_compound_page(page_head);
@@ -198,30 +220,32 @@
 	 * proper PT lock that already serializes against
 	 * split_huge_page().
 	 */
-	bool got = false;
-	struct page *page_head;
-
-	/*
-	 * If this is a hugetlbfs page it cannot be split under us.  Simply
-	 * increment refcount for the head page.
-	 */
-	if (PageHuge(page)) {
-		page_head = compound_head(page);
-		atomic_inc(&page_head->_count);
-		got = true;
-	} else {
 		unsigned long flags;
+	bool got = false;
+	struct page *page_head = compound_trans_head(page);
 
-		page_head = compound_trans_head(page);
-		if (likely(page != page_head &&
-					get_page_unless_zero(page_head))) {
-
+	if (likely(page != page_head && get_page_unless_zero(page_head))) {
 			/* Ref to put_compound_page() comment. */
-			if (PageSlab(page_head)) {
+		if (PageSlab(page_head) || PageHeadHuge(page_head)) {
 				if (likely(PageTail(page))) {
+				/*
+				 * This is a hugetlbfs page or a slab
+				 * page. __split_huge_page_refcount
+				 * cannot race here.
+				 */
+				VM_BUG_ON(!PageHead(page_head));
 					__get_page_tail_foll(page, false);
 					return true;
 				} else {
+				/*
+				 * __split_huge_page_refcount run
+				 * before us, "page" was a THP
+				 * tail. The split page_head has been
+				 * freed and reallocated as slab or
+				 * hugetlbfs page of smaller order
+				 * (only possible if reallocated as
+				 * slab on x86).
+				 */
 					put_page(page_head);
 					return false;
 				}
@@ -243,7 +267,6 @@
 			if (unlikely(!got))
 				put_page(page_head);
 		}
-	}
 	return got;
 }
 EXPORT_SYMBOL(__get_page_tail);
diff -ruw linux-3.11.10/mm/util.c linux-3.11.10-fbx/mm/util.c
--- linux-3.11.10/mm/util.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/util.c	2014-05-09 14:12:54.376546160 +0200
@@ -387,7 +387,10 @@
 {
 	struct address_space *mapping = page->mapping;
 
-	VM_BUG_ON(PageSlab(page));
+	/* This happens if someone calls flush_dcache_page on slab page */
+	if (unlikely(PageSlab(page)))
+		return NULL;
+
 #ifdef CONFIG_SWAP
 	if (unlikely(PageSwapCache(page))) {
 		swp_entry_t entry;
diff -ruw linux-3.11.10/mm/vmscan.c linux-3.11.10-fbx/mm/vmscan.c
--- linux-3.11.10/mm/vmscan.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/vmscan.c	2014-08-22 15:47:22.152063226 +0200
@@ -1468,19 +1468,18 @@
 		 * If dirty pages are scanned that are not queued for IO, it
 		 * implies that flushers are not keeping up. In this case, flag
 		 * the zone ZONE_TAIL_LRU_DIRTY and kswapd will start writing
-		 * pages from reclaim context. It will forcibly stall in the
-		 * next check.
+		 * pages from reclaim context.
 		 */
 		if (nr_unqueued_dirty == nr_taken)
 			zone_set_flag(zone, ZONE_TAIL_LRU_DIRTY);
 
 		/*
-		 * In addition, if kswapd scans pages marked marked for
-		 * immediate reclaim and under writeback (nr_immediate), it
-		 * implies that pages are cycling through the LRU faster than
+		 * If kswapd scans pages marked marked for immediate
+		 * reclaim and under writeback (nr_immediate), it implies
+		 * that pages are cycling through the LRU faster than
 		 * they are written so also forcibly stall.
 		 */
-		if (nr_unqueued_dirty == nr_taken || nr_immediate)
+		if (nr_immediate)
 			congestion_wait(BLK_RW_ASYNC, HZ/10);
 	}
 
@@ -2431,10 +2430,17 @@
 
 	for (i = 0; i <= ZONE_NORMAL; i++) {
 		zone = &pgdat->node_zones[i];
+		if (!populated_zone(zone))
+			continue;
+
 		pfmemalloc_reserve += min_wmark_pages(zone);
 		free_pages += zone_page_state(zone, NR_FREE_PAGES);
 	}
 
+	/* If there are no reserves (unexpected config) then do not throttle */
+	if (!pfmemalloc_reserve)
+		return true;
+
 	wmark_ok = free_pages > pfmemalloc_reserve / 2;
 
 	/* kswapd must be awake if processes are being throttled */
@@ -2459,9 +2465,9 @@
 static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
 					nodemask_t *nodemask)
 {
+	struct zoneref *z;
 	struct zone *zone;
-	int high_zoneidx = gfp_zone(gfp_mask);
-	pg_data_t *pgdat;
+	pg_data_t *pgdat = NULL;
 
 	/*
 	 * Kernel threads should not be throttled as they may be indirectly
@@ -2480,11 +2486,35 @@
 	if (fatal_signal_pending(current))
 		goto out;
 
-	/* Check if the pfmemalloc reserves are ok */
-	first_zones_zonelist(zonelist, high_zoneidx, NULL, &zone);
+	/*
+	 * Check if the pfmemalloc reserves are ok by finding the first node
+	 * with a usable ZONE_NORMAL or lower zone. The expectation is that
+	 * GFP_KERNEL will be required for allocating network buffers when
+	 * swapping over the network so ZONE_HIGHMEM is unusable.
+	 *
+	 * Throttling is based on the first usable node and throttled processes
+	 * wait on a queue until kswapd makes progress and wakes them. There
+	 * is an affinity then between processes waking up and where reclaim
+	 * progress has been made assuming the process wakes on the same node.
+	 * More importantly, processes running on remote nodes will not compete
+	 * for remote pfmemalloc reserves and processes on different nodes
+	 * should make reasonable progress.
+	 */
+	for_each_zone_zonelist_nodemask(zone, z, zonelist,
+					gfp_mask, nodemask) {
+		if (zone_idx(zone) > ZONE_NORMAL)
+			continue;
+
+		/* Throttle based on the first usable node */
 	pgdat = zone->zone_pgdat;
 	if (pfmemalloc_watermark_ok(pgdat))
 		goto out;
+		break;
+	}
+
+	/* If no zone was usable by the allocation flags then do not throttle */
+	if (!pgdat)
+		goto out;
 
 	/* Account for the throttling */
 	count_vm_event(PGSCAN_DIRECT_THROTTLE);
@@ -3216,7 +3246,10 @@
 		}
 	}
 
+	tsk->flags &= ~(PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD);
 	current->reclaim_state = NULL;
+	lockdep_clear_current_reclaim_state();
+
 	return 0;
 }
 
diff -ruw linux-3.11.10/mm/vmstat.c linux-3.11.10-fbx/mm/vmstat.c
--- linux-3.11.10/mm/vmstat.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/mm/vmstat.c	2014-01-17 19:14:18.798220810 +0100
@@ -779,6 +779,7 @@
 
 #ifdef CONFIG_NUMA_BALANCING
 	"numa_pte_updates",
+	"numa_huge_pte_updates",
 	"numa_hint_faults",
 	"numa_hint_faults_local",
 	"numa_pages_migrated",
diff -ruw linux-3.11.10/net/8021q/vlan.c linux-3.11.10-fbx/net/8021q/vlan.c
--- linux-3.11.10/net/8021q/vlan.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/8021q/vlan.c	2014-07-01 16:22:13.202329926 +0200
@@ -207,7 +207,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);
@@ -305,9 +305,11 @@
 static void vlan_transfer_features(struct net_device *dev,
 				   struct net_device *vlandev)
 {
+	struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
+
 	vlandev->gso_max_size = dev->gso_max_size;
 
-	if (dev->features & NETIF_F_HW_VLAN_CTAG_TX)
+	if (vlan_hw_offload_capable(dev->features, vlan->vlan_proto))
 		vlandev->hard_header_len = dev->hard_header_len;
 	else
 		vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN;
diff -ruw linux-3.11.10/net/8021q/vlan_core.c linux-3.11.10-fbx/net/8021q/vlan_core.c
--- linux-3.11.10/net/8021q/vlan_core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/8021q/vlan_core.c	2013-12-04 14:33:29.407479139 +0100
@@ -89,6 +89,12 @@
 }
 EXPORT_SYMBOL(__vlan_find_dev_deep);
 
+struct net_device *vlan_dev_upper_dev(const struct net_device *dev)
+{
+	return vlan_dev_priv(dev)->real_dev;
+}
+EXPORT_SYMBOL(vlan_dev_upper_dev);
+
 struct net_device *vlan_dev_real_dev(const struct net_device *dev)
 {
 	struct net_device *ret = vlan_dev_priv(dev)->real_dev;
diff -ruw linux-3.11.10/net/8021q/vlan_dev.c linux-3.11.10-fbx/net/8021q/vlan_dev.c
--- linux-3.11.10/net/8021q/vlan_dev.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/8021q/vlan_dev.c	2014-07-01 16:22:13.202329926 +0200
@@ -28,6 +28,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
+#include <linux/pkt_sched.h>
 #include <net/arp.h>
 
 #include "vlan.h"
@@ -77,7 +78,7 @@
 
 	mp = vlan_dev_priv(dev)->egress_priority_map[(skb->priority & 0xF)];
 	while (mp) {
-		if (mp->priority == skb->priority) {
+		if (mp->priority == (skb->priority & TC_H_MIN_MASK)) {
 			return mp->vlan_qos; /* This should already be shifted
 					      * to mask correctly with the
 					      * VLAN's TCI */
@@ -512,10 +513,48 @@
 	}
 }
 
+static int vlan_calculate_locking_subclass(struct net_device *real_dev)
+{
+	int subclass = 0;
+
+	while (is_vlan_dev(real_dev)) {
+		subclass++;
+		real_dev = vlan_dev_priv(real_dev)->real_dev;
+	}
+
+	return subclass;
+}
+
+static void vlan_dev_mc_sync(struct net_device *to, struct net_device *from)
+{
+	int err = 0, subclass;
+
+	subclass = vlan_calculate_locking_subclass(to);
+
+	spin_lock_nested(&to->addr_list_lock, subclass);
+	err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len);
+	if (!err)
+		__dev_set_rx_mode(to);
+	spin_unlock(&to->addr_list_lock);
+}
+
+static void vlan_dev_uc_sync(struct net_device *to, struct net_device *from)
+{
+	int err = 0, subclass;
+
+	subclass = vlan_calculate_locking_subclass(to);
+
+	spin_lock_nested(&to->addr_list_lock, subclass);
+	err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len);
+	if (!err)
+		__dev_set_rx_mode(to);
+	spin_unlock(&to->addr_list_lock);
+}
+
 static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
 {
-	dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
-	dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
+	vlan_dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
+	vlan_dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
 }
 
 /*
@@ -549,6 +588,26 @@
 	.parse	 = eth_header_parse,
 };
 
+static int vlan_passthru_hard_header(struct sk_buff *skb, struct net_device *dev,
+				     unsigned short type,
+				     const void *daddr, const void *saddr,
+				     unsigned int len)
+{
+	struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
+	struct net_device *real_dev = vlan->real_dev;
+
+	if (saddr == NULL)
+		saddr = dev->dev_addr;
+
+	return dev_hard_header(skb, real_dev, type, daddr, saddr, len);
+}
+
+static const struct header_ops vlan_passthru_header_ops = {
+	.create	 = vlan_passthru_hard_header,
+	.rebuild = dev_rebuild_header,
+	.parse	 = eth_header_parse,
+};
+
 static struct device_type vlan_type = {
 	.name	= "vlan",
 };
@@ -591,8 +650,9 @@
 #endif
 
 	dev->needed_headroom = real_dev->needed_headroom;
-	if (real_dev->features & NETIF_F_HW_VLAN_CTAG_TX) {
-		dev->header_ops      = real_dev->header_ops;
+	if (vlan_hw_offload_capable(real_dev->features,
+				    vlan_dev_priv(dev)->vlan_proto)) {
+		dev->header_ops      = &vlan_passthru_header_ops;
 		dev->hard_header_len = real_dev->hard_header_len;
 	} else {
 		dev->header_ops      = &vlan_header_ops;
@@ -603,9 +663,7 @@
 
 	SET_NETDEV_DEVTYPE(dev, &vlan_type);
 
-	if (is_vlan_dev(real_dev))
-		subclass = 1;
-
+	subclass = vlan_calculate_locking_subclass(dev);
 	vlan_dev_set_lockdep_class(dev, subclass);
 
 	vlan_dev_priv(dev)->vlan_pcpu_stats = alloc_percpu(struct vlan_pcpu_stats);
diff -ruw linux-3.11.10/net/bluetooth/af_bluetooth.c linux-3.11.10-fbx/net/bluetooth/af_bluetooth.c
--- linux-3.11.10/net/bluetooth/af_bluetooth.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/bluetooth/af_bluetooth.c	2014-01-17 19:14:18.802220810 +0100
@@ -221,8 +221,6 @@
 	if (flags & (MSG_OOB))
 		return -EOPNOTSUPP;
 
-	msg->msg_namelen = 0;
-
 	skb = skb_recv_datagram(sk, flags, noblock, &err);
 	if (!skb) {
 		if (sk->sk_shutdown & RCV_SHUTDOWN)
@@ -287,8 +285,6 @@
 	if (flags & MSG_OOB)
 		return -EOPNOTSUPP;
 
-	msg->msg_namelen = 0;
-
 	BT_DBG("sk %p size %zu", sk, size);
 
 	lock_sock(sk);
diff -ruw linux-3.11.10/net/bluetooth/hci_conn.c linux-3.11.10-fbx/net/bluetooth/hci_conn.c
--- linux-3.11.10/net/bluetooth/hci_conn.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/bluetooth/hci_conn.c	2014-08-22 15:47:22.152063226 +0200
@@ -652,14 +652,17 @@
 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
 		struct hci_cp_auth_requested cp;
 
-		/* encrypt must be pending if auth is also pending */
-		set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
-
 		cp.handle = cpu_to_le16(conn->handle);
 		hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
 			     sizeof(cp), &cp);
-		if (conn->key_type != 0xff)
+
+		/* If we're already encrypted set the REAUTH_PEND flag,
+		 * otherwise set the ENCRYPT_PEND.
+		 */
+		if (conn->link_mode & HCI_LM_ENCRYPT)
 			set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
+		else
+			set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
 	}
 
 	return 0;
diff -ruw linux-3.11.10/net/bluetooth/hci_event.c linux-3.11.10-fbx/net/bluetooth/hci_event.c
--- linux-3.11.10/net/bluetooth/hci_event.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/bluetooth/hci_event.c	2014-08-22 15:47:22.156063246 +0200
@@ -47,6 +47,10 @@
 	smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
 	wake_up_bit(&hdev->flags, HCI_INQUIRY);
 
+	hci_dev_lock(hdev);
+	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+	hci_dev_unlock(hdev);
+
 	hci_conn_check_pending(hdev);
 }
 
@@ -2992,6 +2996,12 @@
 	if (!conn)
 		goto unlock;
 
+	/* For BR/EDR the necessary steps are taken through the
+	 * auth_complete event.
+	 */
+	if (conn->type != LE_LINK)
+		goto unlock;
+
 	if (!ev->status)
 		conn->sec_level = conn->pending_sec_level;
 
@@ -3153,8 +3163,11 @@
 
 		/* If we're not the initiators request authorization to
 		 * proceed from user space (mgmt_user_confirm with
-		 * confirm_hint set to 1). */
-		if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
+		 * confirm_hint set to 1). The exception is if neither
+		 * side had MITM in which case we do auto-accept.
+		 */
+		if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
+		    (loc_mitm || rem_mitm)) {
 			BT_DBG("Confirming auto-accept as acceptor");
 			confirm_hint = 1;
 			goto confirm;
@@ -3560,7 +3573,13 @@
 
 	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
 
-	if (ltk->type & HCI_SMP_STK) {
+	/* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
+	 * temporary key used to encrypt a connection following
+	 * pairing. It is used during the Encrypted Session Setup to
+	 * distribute the keys. Later, security can be re-established
+	 * using a distributed LTK.
+	 */
+	if (ltk->type == HCI_SMP_STK_SLAVE) {
 		list_del(&ltk->list);
 		kfree(ltk);
 	}
diff -ruw linux-3.11.10/net/bluetooth/hci_sock.c linux-3.11.10-fbx/net/bluetooth/hci_sock.c
--- linux-3.11.10/net/bluetooth/hci_sock.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/bluetooth/hci_sock.c	2014-01-17 19:14:18.802220810 +0100
@@ -752,8 +752,6 @@
 	if (!skb)
 		return err;
 
-	msg->msg_namelen = 0;
-
 	copied = skb->len;
 	if (len < copied) {
 		msg->msg_flags |= MSG_TRUNC;
@@ -928,6 +926,7 @@
 		{
 			struct hci_filter *f = &hci_pi(sk)->filter;
 
+			memset(&uf, 0, sizeof(uf));
 			uf.type_mask = f->type_mask;
 			uf.opcode    = f->opcode;
 			uf.event_mask[0] = *((u32 *) f->event_mask + 0);
diff -ruw linux-3.11.10/net/bluetooth/l2cap_sock.c linux-3.11.10-fbx/net/bluetooth/l2cap_sock.c
--- linux-3.11.10/net/bluetooth/l2cap_sock.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/bluetooth/l2cap_sock.c	2014-08-22 15:47:22.156063246 +0200
@@ -631,11 +631,6 @@
 
 		/*change security for LE channels */
 		if (chan->scid == L2CAP_CID_ATT) {
-			if (!conn->hcon->out) {
-				err = -EINVAL;
-				break;
-			}
-
 			if (smp_conn_security(conn->hcon, sec.level))
 				break;
 			sk->sk_state = BT_CONFIG;
@@ -949,13 +944,16 @@
 	/* Check for backlog size */
 	if (sk_acceptq_is_full(parent)) {
 		BT_DBG("backlog full %d", parent->sk_ack_backlog);
+		release_sock(parent);
 		return NULL;
 	}
 
 	sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
 			      GFP_ATOMIC);
-	if (!sk)
+	if (!sk) {
+		release_sock(parent);
 		return NULL;
+        }
 
 	bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
 
diff -ruw linux-3.11.10/net/bluetooth/mgmt.c linux-3.11.10-fbx/net/bluetooth/mgmt.c
--- linux-3.11.10/net/bluetooth/mgmt.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/bluetooth/mgmt.c	2014-08-22 15:47:22.156063246 +0200
@@ -2319,8 +2319,13 @@
 	}
 
 	if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) {
-		/* Continue with pairing via SMP */
+		/* Continue with pairing via SMP. The hdev lock must be
+		 * released as SMP may try to recquire it for crypto
+		 * purposes.
+		 */
+		hci_dev_unlock(hdev);
 		err = smp_user_confirm_reply(conn, mgmt_op, passkey);
+		hci_dev_lock(hdev);
 
 		if (!err)
 			err = cmd_complete(sk, hdev->id, mgmt_op,
diff -ruw linux-3.11.10/net/bluetooth/sco.c linux-3.11.10-fbx/net/bluetooth/sco.c
--- linux-3.11.10/net/bluetooth/sco.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/bluetooth/sco.c	2014-01-17 19:14:18.802220810 +0100
@@ -700,7 +700,6 @@
 	    test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
 		sco_conn_defer_accept(pi->conn->hcon, 0);
 		sk->sk_state = BT_CONFIG;
-		msg->msg_namelen = 0;
 
 		release_sock(sk);
 		return 0;
diff -ruw linux-3.11.10/net/core/dev.c linux-3.11.10-fbx/net/core/dev.c
--- linux-3.11.10/net/core/dev.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/core/dev.c	2014-08-22 15:47:22.156063246 +0200
@@ -131,6 +131,7 @@
 #include <linux/static_key.h>
 #include <linux/hashtable.h>
 #include <linux/vmalloc.h>
+#include <linux/kthread.h>
 
 #include "net-sysfs.h"
 
@@ -146,6 +147,19 @@
 struct list_head ptype_all __read_mostly;	/* Taps */
 static struct list_head offload_base __read_mostly;
 
+#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];
+unsigned int krxd_stats_pkts[CONFIG_NETRXTHREAD_RX_QUEUE];
+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.
@@ -2401,7 +2415,7 @@
  * 2. No high memory really exists on this machine.
  */
 
-static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
+static int illegal_highdma(const struct net_device *dev, struct sk_buff *skb)
 {
 #ifdef CONFIG_HIGHMEM
 	int i;
@@ -2481,34 +2495,36 @@
 }
 
 static netdev_features_t harmonize_features(struct sk_buff *skb,
+					    const struct net_device *dev,
 	netdev_features_t features)
 {
 	if (skb->ip_summed != CHECKSUM_NONE &&
 	    !can_checksum_protocol(features, skb_network_protocol(skb))) {
 		features &= ~NETIF_F_ALL_CSUM;
-	} else if (illegal_highdma(skb->dev, skb)) {
+	} else if (illegal_highdma(dev, skb)) {
 		features &= ~NETIF_F_SG;
 	}
 
 	return features;
 }
 
-netdev_features_t netif_skb_features(struct sk_buff *skb)
+netdev_features_t netif_skb_dev_features(struct sk_buff *skb,
+					 const struct net_device *dev)
 {
 	__be16 protocol = skb->protocol;
-	netdev_features_t features = skb->dev->features;
+	netdev_features_t features = dev->features;
 
-	if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs)
+	if (skb_shinfo(skb)->gso_segs > dev->gso_max_segs)
 		features &= ~NETIF_F_GSO_MASK;
 
 	if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) {
 		struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
 		protocol = veh->h_vlan_encapsulated_proto;
 	} else if (!vlan_tx_tag_present(skb)) {
-		return harmonize_features(skb, features);
+		return harmonize_features(skb, dev, features);
 	}
 
-	features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX |
+	features &= (dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX |
 					       NETIF_F_HW_VLAN_STAG_TX);
 
 	if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD))
@@ -2516,9 +2532,9 @@
 				NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
 				NETIF_F_HW_VLAN_STAG_TX;
 
-	return harmonize_features(skb, features);
+	return harmonize_features(skb, dev, features);
 }
-EXPORT_SYMBOL(netif_skb_features);
+EXPORT_SYMBOL(netif_skb_dev_features);
 
 /*
  * Returns true if either:
@@ -3211,6 +3227,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
@@ -3344,6 +3377,36 @@
 EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook);
 #endif
 
+#ifdef CONFIG_FBXBRIDGE
+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
@@ -3488,21 +3551,7 @@
 	int ret = NET_RX_DROP;
 	__be16 type;
 
-	net_timestamp_check(!netdev_tstamp_prequeue, skb);
-
-	trace_netif_receive_skb(skb);
-
-	/* if we've gotten here through NAPI, check netpoll */
-	if (netpoll_receive_skb(skb))
-		goto out;
-
 	orig_dev = skb->dev;
-
-	skb_reset_network_header(skb);
-	if (!skb_transport_header_was_set(skb))
-		skb_reset_transport_header(skb);
-	skb_reset_mac_len(skb);
-
 	pt_prev = NULL;
 
 	rcu_read_lock();
@@ -3538,6 +3587,10 @@
 	}
 
 skip_taps:
+	skb = handle_fbxbridge(skb, &pt_prev, &ret, orig_dev);
+	if (!skb)
+		goto unlock;
+
 #ifdef CONFIG_NET_CLS_ACT
 	skb = handle_ing(skb, &pt_prev, &ret, orig_dev);
 	if (!skb)
@@ -3622,11 +3675,10 @@
 
 unlock:
 	rcu_read_unlock();
-out:
 	return ret;
 }
 
-static int __netif_receive_skb(struct sk_buff *skb)
+static int __netif_receive_skb_end(struct sk_buff *skb)
 {
 	int ret;
 
@@ -3651,6 +3703,101 @@
 	return ret;
 }
 
+#ifdef CONFIG_NETRXTHREAD
+
+
+static int krxd_action(void *unused)
+{
+	struct sk_buff *skb;
+
+	set_user_nice(current, -5);
+	current->flags |= PF_NOFREEZE;
+	__set_current_state(TASK_RUNNING);
+
+	local_bh_disable();
+	while (1) {
+		unsigned int i, queue, count;
+
+		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);
+			local_bh_disable();
+			continue;
+		}
+
+		__netif_receive_skb_end(skb);
+
+		/* only schedule when working on lowest prio queue */
+		if (queue == 0) {
+			if (need_resched()) {
+				local_bh_enable();
+				schedule();
+				local_bh_disable();
+			}
+		}
+	}
+	return 0;
+}
+#endif /* RXTHREAD */
+
+static int __netif_receive_skb(struct sk_buff *skb)
+{
+#ifdef CONFIG_NETRXTHREAD
+	unsigned int len, queue;
+#endif
+	net_timestamp_check(!netdev_tstamp_prequeue, skb);
+
+	trace_netif_receive_skb(skb);
+
+	/* if we've gotten here through NAPI, check netpoll */
+	if (netpoll_receive_skb(skb))
+		return NET_RX_DROP;
+
+	skb_reset_network_header(skb);
+	if (!skb_transport_header_was_set(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->rxthread_prio & 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
@@ -3960,6 +4107,7 @@
 	skb->vlan_tci = 0;
 	skb->dev = napi->dev;
 	skb->skb_iif = 0;
+	skb->truesize = SKB_TRUESIZE(skb_end_offset(skb));
 
 	napi->skb = skb;
 }
@@ -4598,7 +4746,7 @@
 {
 	const struct net_device_ops *ops = dev->netdev_ops;
 
-	if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags)
+	if (ops->ndo_change_rx_flags)
 		ops->ndo_change_rx_flags(dev, flags);
 }
 
@@ -4749,6 +4897,7 @@
 	if (ops->ndo_set_rx_mode)
 		ops->ndo_set_rx_mode(dev);
 }
+EXPORT_SYMBOL(__dev_set_rx_mode);
 
 void dev_set_rx_mode(struct net_device *dev)
 {
@@ -5599,7 +5748,7 @@
 			rebroadcast_time = jiffies;
 		}
 
-		msleep(250);
+		msleep(1);
 
 		refcnt = netdev_refcnt_read(dev);
 
@@ -5960,6 +6109,9 @@
 /**
  *	unregister_netdevice_many - unregister many devices
  *	@head: list of devices
+ *
+ *  Note: As most callers use a stack allocated list_head,
+ *  we force a list_del() to make sure stack wont be corrupted later.
  */
 void unregister_netdevice_many(struct list_head *head)
 {
@@ -5969,6 +6121,7 @@
 		rollback_registered_many(head);
 		list_for_each_entry(dev, head, unreg_list)
 			net_set_todo(dev);
+		list_del(head);
 	}
 }
 EXPORT_SYMBOL(unregister_netdevice_many);
@@ -6385,7 +6538,6 @@
 		}
 	}
 	unregister_netdevice_many(&dev_kill_list);
-	list_del(&dev_kill_list);
 	rtnl_unlock();
 }
 
@@ -6477,6 +6629,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();
 	rc = 0;
@@ -6485,3 +6650,7 @@
 }
 
 subsys_initcall(net_dev_init);
+
+#if defined(CONFIG_FBXBRIDGE_MODULE)
+EXPORT_SYMBOL(fbxbridge_handle_frame_hook);
+#endif
diff -ruw linux-3.11.10/net/core/filter.c linux-3.11.10-fbx/net/core/filter.c
--- linux-3.11.10/net/core/filter.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/core/filter.c	2014-07-01 16:22:13.210329963 +0200
@@ -36,7 +36,6 @@
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 #include <linux/filter.h>
-#include <linux/reciprocal_div.h>
 #include <linux/ratelimit.h>
 #include <linux/seccomp.h>
 #include <linux/if_vlan.h>
@@ -166,7 +165,7 @@
 			A /= X;
 			continue;
 		case BPF_S_ALU_DIV_K:
-			A = reciprocal_divide(A, K);
+			A /= K;
 			continue;
 		case BPF_S_ALU_MOD_X:
 			if (X == 0)
@@ -356,6 +355,8 @@
 
 			if (skb_is_nonlinear(skb))
 				return 0;
+			if (skb->len < sizeof(struct nlattr))
+				return 0;
 			if (A > skb->len - sizeof(struct nlattr))
 				return 0;
 
@@ -372,11 +373,13 @@
 
 			if (skb_is_nonlinear(skb))
 				return 0;
+			if (skb->len < sizeof(struct nlattr))
+				return 0;
 			if (A > skb->len - sizeof(struct nlattr))
 				return 0;
 
 			nla = (struct nlattr *)&skb->data[A];
-			if (nla->nla_len > A - skb->len)
+			if (nla->nla_len > skb->len - A)
 				return 0;
 
 			nla = nla_find_nested(nla, X);
@@ -553,11 +556,6 @@
 		/* Some instructions need special checks */
 		switch (code) {
 		case BPF_S_ALU_DIV_K:
-			/* check for division by zero */
-			if (ftest->k == 0)
-				return -EINVAL;
-			ftest->k = reciprocal_value(ftest->k);
-			break;
 		case BPF_S_ALU_MOD_K:
 			/* check for division by zero */
 			if (ftest->k == 0)
@@ -853,26 +851,6 @@
 	to->code = decodes[code];
 	to->jt = filt->jt;
 	to->jf = filt->jf;
-
-	if (code == BPF_S_ALU_DIV_K) {
-		/*
-		 * When loaded this rule user gave us X, which was
-		 * translated into R = r(X). Now we calculate the
-		 * RR = r(R) and report it back. If next time this
-		 * value is loaded and RRR = r(RR) is calculated
-		 * then the R == RRR will be true.
-		 *
-		 * One exception. X == 1 translates into R == 0 and
-		 * we can't calculate RR out of it with r().
-		 */
-
-		if (filt->k == 0)
-			to->k = 1;
-		else
-			to->k = reciprocal_value(filt->k);
-
-		BUG_ON(reciprocal_value(to->k) != filt->k);
-	} else
 		to->k = filt->k;
 }
 
diff -ruw linux-3.11.10/net/core/iovec.c linux-3.11.10-fbx/net/core/iovec.c
--- linux-3.11.10/net/core/iovec.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/core/iovec.c	2014-01-17 19:14:18.806220810 +0100
@@ -48,6 +48,7 @@
 			if (err < 0)
 				return err;
 		}
+		if (m->msg_name)
 		m->msg_name = address;
 	} else {
 		m->msg_name = NULL;
diff -ruw linux-3.11.10/net/core/neighbour.c linux-3.11.10-fbx/net/core/neighbour.c
--- linux-3.11.10/net/core/neighbour.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/core/neighbour.c	2014-07-01 16:22:13.210329963 +0200
@@ -764,9 +764,6 @@
 	nht = rcu_dereference_protected(tbl->nht,
 					lockdep_is_held(&tbl->lock));
 
-	if (atomic_read(&tbl->entries) < tbl->gc_thresh1)
-		goto out;
-
 	/*
 	 *	periodically recompute ReachableTime from random function
 	 */
@@ -779,6 +776,9 @@
 				neigh_rand_reach_time(p->base_reachable_time);
 	}
 
+	if (atomic_read(&tbl->entries) < tbl->gc_thresh1)
+		goto out;
+
 	for (i = 0 ; i < (1 << nht->hash_shift); i++) {
 		np = &nht->hash_buckets[i];
 
@@ -1274,7 +1274,7 @@
 
 	if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL,
 			    skb->len) < 0 &&
-	    dev->header_ops->rebuild(skb))
+	    dev_rebuild_header(skb))
 		return 0;
 
 	return dev_queue_xmit(skb);
diff -ruw linux-3.11.10/net/core/net-procfs.c linux-3.11.10-fbx/net/core/net-procfs.c
--- linux-3.11.10/net/core/net-procfs.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/core/net-procfs.c	2013-12-04 14:33:29.559479142 +0100
@@ -311,6 +311,86 @@
 	.release = seq_release_net,
 };
 
+#ifdef CONFIG_NETRXTHREAD
+extern unsigned int krxd_stats_pkts[CONFIG_NETRXTHREAD_RX_QUEUE];
+extern unsigned int krxd_stats_dropped[CONFIG_NETRXTHREAD_RX_QUEUE];
+
+/*
+ *	This is invoked by the /proc filesystem handler to display a device
+ *	in detail.
+ */
+static 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;
+}
+
+static 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;
+}
+
+static 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 /* KRXTHREAD */
 
 static int __net_init dev_proc_net_init(struct net *net)
 {
@@ -323,9 +403,13 @@
 		goto out_dev;
 	if (!proc_create("ptype", S_IRUGO, net->proc_net, &ptype_seq_fops))
 		goto out_softnet;
-
 	if (wext_proc_init(net))
 		goto out_ptype;
+#ifdef CONFIG_NETRXTHREAD
+	if (!proc_create("krxthread", S_IRUGO, net->proc_net,
+			 &krxthread_seq_fops))
+		goto out_ptype;
+#endif
 	rc = 0;
 out:
 	return rc;
diff -ruw linux-3.11.10/net/core/rtnetlink.c linux-3.11.10-fbx/net/core/rtnetlink.c
--- linux-3.11.10/net/core/rtnetlink.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/core/rtnetlink.c	2014-08-22 15:47:22.156063246 +0200
@@ -714,7 +714,8 @@
 		return 0;
 }
 
-static size_t rtnl_port_size(const struct net_device *dev)
+static size_t rtnl_port_size(const struct net_device *dev,
+			     u32 ext_filter_mask)
 {
 	size_t port_size = nla_total_size(4)		/* PORT_VF */
 		+ nla_total_size(PORT_PROFILE_MAX)	/* PORT_PROFILE */
@@ -730,7 +731,8 @@
 	size_t port_self_size = nla_total_size(sizeof(struct nlattr))
 		+ port_size;
 
-	if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent)
+	if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent ||
+	    !(ext_filter_mask & RTEXT_FILTER_VF))
 		return 0;
 	if (dev_num_vf(dev->dev.parent))
 		return port_self_size + vf_ports_size +
@@ -765,7 +767,7 @@
 	       + nla_total_size(ext_filter_mask
 			        & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
 	       + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
-	       + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
+	       + rtnl_port_size(dev, ext_filter_mask) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
 	       + rtnl_link_get_size(dev) /* IFLA_LINKINFO */
 	       + rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */
 }
@@ -826,11 +828,13 @@
 	return 0;
 }
 
-static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev)
+static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev,
+			  u32 ext_filter_mask)
 {
 	int err;
 
-	if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent)
+	if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent ||
+	    !(ext_filter_mask & RTEXT_FILTER_VF))
 		return 0;
 
 	err = rtnl_port_self_fill(skb, dev);
@@ -994,7 +998,7 @@
 		nla_nest_end(skb, vfinfo);
 	}
 
-	if (rtnl_port_fill(skb, dev))
+	if (rtnl_port_fill(skb, dev, ext_filter_mask))
 		goto nla_put_failure;
 
 	if (dev->rtnl_link_ops) {
@@ -1048,6 +1052,8 @@
 	struct hlist_head *head;
 	struct nlattr *tb[IFLA_MAX+1];
 	u32 ext_filter_mask = 0;
+	int err;
+	int hdrlen;
 
 	s_h = cb->args[0];
 	s_idx = cb->args[1];
@@ -1055,8 +1061,17 @@
 	rcu_read_lock();
 	cb->seq = net->dev_base_seq;
 
-	if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
-			ifla_policy) >= 0) {
+	/* A hack to preserve kernel<->userspace interface.
+	 * The correct header is ifinfomsg. It is consistent with rtnl_getlink.
+	 * However, before Linux v3.9 the code here assumed rtgenmsg and that's
+	 * what iproute2 < v3.9.0 used.
+	 * We can detect the old iproute2. Even including the IFLA_EXT_MASK
+	 * attribute, its netlink message is shorter than struct ifinfomsg.
+	 */
+	hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ?
+		 sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
+
+	if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) {
 
 		if (tb[IFLA_EXT_MASK])
 			ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
@@ -1068,11 +1083,17 @@
 		hlist_for_each_entry_rcu(dev, head, index_hlist) {
 			if (idx < s_idx)
 				goto cont;
-			if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
+			err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
 					     NETLINK_CB(cb->skb).portid,
 					     cb->nlh->nlmsg_seq, 0,
 					     NLM_F_MULTI,
-					     ext_filter_mask) <= 0)
+					       ext_filter_mask);
+			/* If we ran out of room on the first message,
+			 * we're in trouble
+			 */
+			WARN_ON((err == -EMSGSIZE) && (skb->len == 0));
+
+			if (err <= 0)
 				goto out;
 
 			nl_dump_check_consistent(cb, nlmsg_hdr(skb));
@@ -1301,7 +1322,8 @@
 	return 0;
 }
 
-static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
+static int do_setlink(const struct sk_buff *skb,
+		      struct net_device *dev, struct ifinfomsg *ifm,
 		      struct nlattr **tb, char *ifname, int modified)
 {
 	const struct net_device_ops *ops = dev->netdev_ops;
@@ -1313,7 +1335,7 @@
 			err = PTR_ERR(net);
 			goto errout;
 		}
-		if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) {
+		if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
 			err = -EPERM;
 			goto errout;
 		}
@@ -1567,7 +1589,7 @@
 	if (err < 0)
 		goto errout;
 
-	err = do_setlink(dev, ifm, tb, ifname, 0);
+	err = do_setlink(skb, dev, ifm, tb, ifname, 0);
 errout:
 	return err;
 }
@@ -1607,7 +1629,6 @@
 
 	ops->dellink(dev, &list_kill);
 	unregister_netdevice_many(&list_kill);
-	list_del(&list_kill);
 	return 0;
 }
 
@@ -1685,7 +1706,8 @@
 }
 EXPORT_SYMBOL(rtnl_create_link);
 
-static int rtnl_group_changelink(struct net *net, int group,
+static int rtnl_group_changelink(const struct sk_buff *skb,
+		struct net *net, int group,
 		struct ifinfomsg *ifm,
 		struct nlattr **tb)
 {
@@ -1694,7 +1716,7 @@
 
 	for_each_netdev(net, dev) {
 		if (dev->group == group) {
-			err = do_setlink(dev, ifm, tb, NULL, 0);
+			err = do_setlink(skb, dev, ifm, tb, NULL, 0);
 			if (err < 0)
 				return err;
 		}
@@ -1796,12 +1818,12 @@
 				modified = 1;
 			}
 
-			return do_setlink(dev, ifm, tb, ifname, modified);
+			return do_setlink(skb, dev, ifm, tb, ifname, modified);
 		}
 
 		if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
 			if (ifm->ifi_index == 0 && tb[IFLA_GROUP])
-				return rtnl_group_changelink(net,
+				return rtnl_group_changelink(skb, net,
 						nla_get_u32(tb[IFLA_GROUP]),
 						ifm, tb);
 			return -ENODEV;
@@ -1913,9 +1935,13 @@
 	struct nlattr *tb[IFLA_MAX+1];
 	u32 ext_filter_mask = 0;
 	u16 min_ifinfo_dump_size = 0;
+	int hdrlen;
+
+	/* Same kernel<->userspace interface hack as in rtnl_dump_ifinfo. */
+	hdrlen = nlmsg_len(nlh) < sizeof(struct ifinfomsg) ?
+		 sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
 
-	if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
-			ifla_policy) >= 0) {
+	if (nlmsg_parse(nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) {
 		if (tb[IFLA_EXT_MASK])
 			ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
 	}
@@ -1991,12 +2017,13 @@
 static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
 				   struct net_device *dev,
 				   u8 *addr, u32 pid, u32 seq,
-				   int type, unsigned int flags)
+				   int type, unsigned int flags,
+				   int nlflags)
 {
 	struct nlmsghdr *nlh;
 	struct ndmsg *ndm;
 
-	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), NLM_F_MULTI);
+	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), nlflags);
 	if (!nlh)
 		return -EMSGSIZE;
 
@@ -2034,7 +2061,7 @@
 	if (!skb)
 		goto errout;
 
-	err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF);
+	err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF, 0);
 	if (err < 0) {
 		kfree_skb(skb);
 		goto errout;
@@ -2181,7 +2208,7 @@
 	int err = -EINVAL;
 	__u8 *addr;
 
-	if (!capable(CAP_NET_ADMIN))
+	if (!netlink_capable(skb, CAP_NET_ADMIN))
 		return -EPERM;
 
 	err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
@@ -2259,7 +2286,8 @@
 
 		err = nlmsg_populate_fdb_fill(skb, dev, ha->addr,
 					      portid, seq,
-					      RTM_NEWNEIGH, NTF_SELF);
+					      RTM_NEWNEIGH, NTF_SELF,
+					      NLM_F_MULTI);
 		if (err < 0)
 			return err;
 skip:
@@ -2632,7 +2660,7 @@
 	sz_idx = type>>2;
 	kind = type&3;
 
-	if (kind != 2 && !ns_capable(net->user_ns, CAP_NET_ADMIN))
+	if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
 		return -EPERM;
 
 	if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
diff -ruw linux-3.11.10/net/core/skbuff.c linux-3.11.10-fbx/net/core/skbuff.c
--- linux-3.11.10/net/core/skbuff.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/core/skbuff.c	2014-07-01 16:22:13.210329963 +0200
@@ -47,6 +47,8 @@
 #include <linux/in.h>
 #include <linux/inet.h>
 #include <linux/slab.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
 #include <linux/netdevice.h>
 #ifdef CONFIG_NET_CLS_ACT
 #include <net/pkt_sched.h>
@@ -74,36 +76,6 @@
 struct kmem_cache *skbuff_head_cache __read_mostly;
 static struct kmem_cache *skbuff_fclone_cache __read_mostly;
 
-static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
-				  struct pipe_buffer *buf)
-{
-	put_page(buf->page);
-}
-
-static void sock_pipe_buf_get(struct pipe_inode_info *pipe,
-				struct pipe_buffer *buf)
-{
-	get_page(buf->page);
-}
-
-static int sock_pipe_buf_steal(struct pipe_inode_info *pipe,
-			       struct pipe_buffer *buf)
-{
-	return 1;
-}
-
-
-/* Pipe buffer operations for a socket. */
-static const struct pipe_buf_operations sock_pipe_buf_ops = {
-	.can_merge = 0,
-	.map = generic_pipe_buf_map,
-	.unmap = generic_pipe_buf_unmap,
-	.confirm = generic_pipe_buf_confirm,
-	.release = sock_pipe_buf_release,
-	.steal = sock_pipe_buf_steal,
-	.get = sock_pipe_buf_get,
-};
-
 /**
  *	skb_panic - private function for out-of-line support
  *	@skb:	buffer
@@ -580,9 +552,6 @@
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
 	nf_conntrack_put(skb->nfct);
 #endif
-#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-	nf_conntrack_put_reasm(skb->nfct_reasm);
-#endif
 #ifdef CONFIG_BRIDGE_NETFILTER
 	nf_bridge_put(skb->nf_bridge);
 #endif
@@ -722,6 +691,9 @@
 	new->ipvs_property	= old->ipvs_property;
 #endif
 	new->pfmemalloc		= old->pfmemalloc;
+#ifdef CONFIG_IP_FFN
+	new->ffn_state		= FFN_STATE_INIT;
+#endif
 	new->protocol		= old->protocol;
 	new->mark		= old->mark;
 	new->skb_iif		= old->skb_iif;
@@ -762,6 +734,9 @@
 	C(mac_len);
 	n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
 	n->cloned = 1;
+#ifdef CONFIG_FBXBRIDGE
+	n->fbxbridge_state = 0;
+#endif
 	n->nohdr = 0;
 	n->destructor = NULL;
 	C(tail);
@@ -1115,6 +1090,9 @@
 	skb->cloned   = 0;
 	skb->hdr_len  = 0;
 	skb->nohdr    = 0;
+#ifdef CONFIG_FBXBRIDGE
+	skb->fbxbridge_state = 0;
+#endif
 	atomic_set(&skb_shinfo(skb)->dataref, 1);
 	return 0;
 
@@ -1552,6 +1530,10 @@
 	skb->tail     += delta;
 	skb->data_len -= delta;
 
+#ifdef CONFIG_FBXBRIDGE
+	skb->fbxbridge_state = 0;
+#endif
+
 	return skb_tail_pointer(skb);
 }
 EXPORT_SYMBOL(__pskb_pull_tail);
@@ -1803,7 +1785,7 @@
 		.partial = partial,
 		.nr_pages_max = MAX_SKB_FRAGS,
 		.flags = flags,
-		.ops = &sock_pipe_buf_ops,
+		.ops = &nosteal_pipe_buf_ops,
 		.spd_release = sock_spd_release,
 	};
 	struct sk_buff *frag_iter;
@@ -2869,6 +2851,9 @@
 		skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG;
 
 		while (pos < offset + len && i < nfrags) {
+			if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC)))
+				goto err;
+
 			*frag = skb_shinfo(skb)->frags[i];
 			__skb_frag_ref(frag);
 			size = skb_frag_size(frag);
@@ -3514,6 +3499,7 @@
 	skb->tstamp.tv64 = 0;
 	skb->pkt_type = PACKET_HOST;
 	skb->skb_iif = 0;
+	skb->local_df = 0;
 	skb_dst_drop(skb);
 	skb->mark = 0;
 	secpath_reset(skb);
@@ -3521,3 +3507,28 @@
 	nf_reset_trace(skb);
 }
 EXPORT_SYMBOL_GPL(skb_scrub_packet);
+
+/**
+ * skb_gso_transport_seglen - Return length of individual segments of a gso packet
+ *
+ * @skb: GSO skb
+ *
+ * skb_gso_transport_seglen is used to determine the real size of the
+ * individual segments, including Layer4 headers (TCP/UDP).
+ *
+ * The MAC/L2 or network (IP, IPv6) headers are not accounted for.
+ */
+unsigned int skb_gso_transport_seglen(const struct sk_buff *skb)
+{
+	const struct skb_shared_info *shinfo = skb_shinfo(skb);
+
+	if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
+		return tcp_hdrlen(skb) + shinfo->gso_size;
+
+	/* UFO sets gso_size to the size of the fragmentation
+	 * payload, i.e. the size of the L4 (UDP) header is already
+	 * accounted for.
+	 */
+	return shinfo->gso_size;
+}
+EXPORT_SYMBOL_GPL(skb_gso_transport_seglen);
diff -ruw linux-3.11.10/net/core/sock.c linux-3.11.10-fbx/net/core/sock.c
--- linux-3.11.10/net/core/sock.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/core/sock.c	2014-08-22 15:47:22.156063246 +0200
@@ -144,6 +144,55 @@
 static DEFINE_MUTEX(proto_list_mutex);
 static LIST_HEAD(proto_list);
 
+/**
+ * sk_ns_capable - General socket capability test
+ * @sk: Socket to use a capability on or through
+ * @user_ns: The user namespace of the capability to use
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket had when the socket was
+ * created and the current process has the capability @cap in the user
+ * namespace @user_ns.
+ */
+bool sk_ns_capable(const struct sock *sk,
+		   struct user_namespace *user_ns, int cap)
+{
+	return file_ns_capable(sk->sk_socket->file, user_ns, cap) &&
+		ns_capable(user_ns, cap);
+}
+EXPORT_SYMBOL(sk_ns_capable);
+
+/**
+ * sk_capable - Socket global capability test
+ * @sk: Socket to use a capability on or through
+ * @cap: The global capbility to use
+ *
+ * Test to see if the opener of the socket had when the socket was
+ * created and the current process has the capability @cap in all user
+ * namespaces.
+ */
+bool sk_capable(const struct sock *sk, int cap)
+{
+	return sk_ns_capable(sk, &init_user_ns, cap);
+}
+EXPORT_SYMBOL(sk_capable);
+
+/**
+ * sk_net_capable - Network namespace socket capability test
+ * @sk: Socket to use a capability on or through
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket had when the socke was created
+ * and the current process has the capability @cap over the network namespace
+ * the socket is a member of.
+ */
+bool sk_net_capable(const struct sock *sk, int cap)
+{
+	return sk_ns_capable(sk, sock_net(sk)->user_ns, cap);
+}
+EXPORT_SYMBOL(sk_net_capable);
+
+
 #ifdef CONFIG_MEMCG_KMEM
 int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
 {
@@ -887,7 +936,7 @@
 
 	case SO_PEEK_OFF:
 		if (sock->ops->set_peek_off)
-			sock->ops->set_peek_off(sk, val);
+			ret = sock->ops->set_peek_off(sk, val);
 		else
 			ret = -EOPNOTSUPP;
 		break;
@@ -913,6 +962,11 @@
 		}
 		break;
 #endif
+
+	case SO_UDP_DUP_UNICAST:
+		sock_valbool_flag(sk, SOCK_UDP_DUP_UNICAST, valbool);
+		break;
+
 	default:
 		ret = -ENOPROTOOPT;
 		break;
@@ -1176,6 +1230,10 @@
 		break;
 #endif
 
+	case SO_UDP_DUP_UNICAST:
+		v.val = sock_flag(sk, SOCK_UDP_DUP_UNICAST);
+		break;
+
 	default:
 		return -ENOPROTOOPT;
 	}
@@ -1835,7 +1893,7 @@
 		gfp_t gfp = sk->sk_allocation;
 
 		if (order)
-			gfp |= __GFP_COMP | __GFP_NOWARN;
+			gfp |= __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY;
 		pfrag->page = alloc_pages(gfp, order);
 		if (likely(pfrag->page)) {
 			pfrag->offset = 0;
@@ -2335,10 +2393,13 @@
 	if (sk->sk_backlog.tail)
 		__release_sock(sk);
 
+	/* Warning : release_cb() might need to release sk ownership,
+	 * ie call sock_release_ownership(sk) before us.
+	 */
 	if (sk->sk_prot->release_cb)
 		sk->sk_prot->release_cb(sk);
 
-	sk->sk_lock.owned = 0;
+	sock_release_ownership(sk);
 	if (waitqueue_active(&sk->sk_lock.wq))
 		wake_up(&sk->sk_lock.wq);
 	spin_unlock_bh(&sk->sk_lock.slock);
diff -ruw linux-3.11.10/net/core/sock_diag.c linux-3.11.10-fbx/net/core/sock_diag.c
--- linux-3.11.10/net/core/sock_diag.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/core/sock_diag.c	2014-08-22 15:47:22.156063246 +0200
@@ -49,7 +49,7 @@
 }
 EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
 
-int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
+int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk,
 			     struct sk_buff *skb, int attrtype)
 {
 	struct nlattr *attr;
@@ -57,7 +57,7 @@
 	unsigned int len;
 	int err = 0;
 
-	if (!ns_capable(user_ns, CAP_NET_ADMIN)) {
+	if (!may_report_filterinfo) {
 		nla_reserve(skb, attrtype, 0);
 		return 0;
 	}
diff -ruw linux-3.11.10/net/ipv4/datagram.c linux-3.11.10-fbx/net/ipv4/datagram.c
--- linux-3.11.10/net/ipv4/datagram.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/datagram.c	2014-08-22 15:47:22.160063265 +0200
@@ -57,7 +57,7 @@
 	if (IS_ERR(rt)) {
 		err = PTR_ERR(rt);
 		if (err == -ENETUNREACH)
-			IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
+			IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
 		goto out;
 	}
 
@@ -86,18 +86,26 @@
 }
 EXPORT_SYMBOL(ip4_datagram_connect);
 
+/* Because UDP xmit path can manipulate sk_dst_cache without holding
+ * socket lock, we need to use sk_dst_set() here,
+ * even if we own the socket lock.
+ */
 void ip4_datagram_release_cb(struct sock *sk)
 {
 	const struct inet_sock *inet = inet_sk(sk);
 	const struct ip_options_rcu *inet_opt;
 	__be32 daddr = inet->inet_daddr;
+	struct dst_entry *dst;
 	struct flowi4 fl4;
 	struct rtable *rt;
 
-	if (! __sk_dst_get(sk) || __sk_dst_check(sk, 0))
-		return;
-
 	rcu_read_lock();
+
+	dst = __sk_dst_get(sk);
+	if (!dst || !dst->obsolete || dst->ops->check(dst, 0)) {
+		rcu_read_unlock();
+		return;
+	}
 	inet_opt = rcu_dereference(inet->inet_opt);
 	if (inet_opt && inet_opt->opt.srr)
 		daddr = inet_opt->opt.faddr;
@@ -105,8 +113,10 @@
 				   inet->inet_saddr, inet->inet_dport,
 				   inet->inet_sport, sk->sk_protocol,
 				   RT_CONN_FLAGS(sk), sk->sk_bound_dev_if);
-	if (!IS_ERR(rt))
-		__sk_dst_set(sk, &rt->dst);
+
+	dst = !IS_ERR(rt) ? &rt->dst : NULL;
+	sk_dst_set(sk, dst);
+
 	rcu_read_unlock();
 }
 EXPORT_SYMBOL_GPL(ip4_datagram_release_cb);
diff -ruw linux-3.11.10/net/ipv4/devinet.c linux-3.11.10-fbx/net/ipv4/devinet.c
--- linux-3.11.10/net/ipv4/devinet.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/devinet.c	2014-07-01 16:22:13.214329992 +0200
@@ -1434,7 +1434,8 @@
 	       + nla_total_size(4) /* IFA_ADDRESS */
 	       + nla_total_size(4) /* IFA_LOCAL */
 	       + nla_total_size(4) /* IFA_BROADCAST */
-	       + nla_total_size(IFNAMSIZ); /* IFA_LABEL */
+	       + nla_total_size(IFNAMSIZ) /* IFA_LABEL */
+	       + nla_total_size(sizeof(struct ifa_cacheinfo)); /* IFA_CACHEINFO */
 }
 
 static inline u32 cstamp_delta(unsigned long cstamp)
diff -ruw linux-3.11.10/net/ipv4/fib_frontend.c linux-3.11.10-fbx/net/ipv4/fib_frontend.c
--- linux-3.11.10/net/ipv4/fib_frontend.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/fib_frontend.c	2014-05-09 14:12:54.380546161 +0200
@@ -1049,6 +1049,8 @@
 	}
 
 	in_dev = __in_dev_get_rtnl(dev);
+	if (!in_dev)
+		return NOTIFY_DONE;
 
 	switch (event) {
 	case NETDEV_UP:
diff -ruw linux-3.11.10/net/ipv4/fib_semantics.c linux-3.11.10-fbx/net/ipv4/fib_semantics.c
--- linux-3.11.10/net/ipv4/fib_semantics.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/fib_semantics.c	2014-07-01 16:22:13.214329992 +0200
@@ -819,13 +819,13 @@
 	fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
 	if (fi == NULL)
 		goto failure;
+	fib_info_cnt++;
 	if (cfg->fc_mx) {
 		fi->fib_metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL);
 		if (!fi->fib_metrics)
 			goto failure;
 	} else
 		fi->fib_metrics = (u32 *) dst_default_metrics;
-	fib_info_cnt++;
 
 	fi->fib_net = hold_net(net);
 	fi->fib_protocol = cfg->fc_protocol;
diff -ruw linux-3.11.10/net/ipv4/inet_fragment.c linux-3.11.10-fbx/net/ipv4/inet_fragment.c
--- linux-3.11.10/net/ipv4/inet_fragment.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/inet_fragment.c	2014-07-01 16:22:13.214329992 +0200
@@ -211,7 +211,7 @@
 	}
 
 	work = frag_mem_limit(nf) - nf->low_thresh;
-	while (work > 0) {
+	while (work > 0 || force) {
 		spin_lock(&nf->lru_lock);
 
 		if (list_empty(&nf->lru_list)) {
@@ -281,9 +281,10 @@
 
 	atomic_inc(&qp->refcnt);
 	hlist_add_head(&qp->list, &hb->chain);
+	inet_frag_lru_add(nf, qp);
 	spin_unlock(&hb->chain_lock);
 	read_unlock(&f->lock);
-	inet_frag_lru_add(nf, qp);
+
 	return qp;
 }
 
diff -ruw linux-3.11.10/net/ipv4/ipconfig.c linux-3.11.10-fbx/net/ipv4/ipconfig.c
--- linux-3.11.10/net/ipv4/ipconfig.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/ipconfig.c	2013-12-04 14:33:29.639479143 +0100
@@ -191,15 +191,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)
 {
@@ -219,8 +265,13 @@
 			pr_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;
@@ -268,7 +319,7 @@
 		int wait, elapsed;
 
 		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);
@@ -720,8 +771,10 @@
 			e += len;
 		}
 		if (*vendor_class_identifier) {
+#ifdef IPCONFIG_DEBUG
 			pr_info("DHCP: sending class identifier \"%s\"\n",
 				vendor_class_identifier);
+#endif
 			*e++ = 60;	/* Class-identifier */
 			len = strlen(vendor_class_identifier);
 			*e++ = len;
@@ -1378,7 +1431,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.11.10/net/ipv4/ip_forward.c linux-3.11.10-fbx/net/ipv4/ip_forward.c
--- linux-3.11.10/net/ipv4/ip_forward.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/ip_forward.c	2014-07-01 16:22:13.214329992 +0200
@@ -39,6 +39,71 @@
 #include <net/route.h>
 #include <net/xfrm.h>
 
+static bool ip_may_fragment(const struct sk_buff *skb)
+{
+	return unlikely((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) ||
+		skb->local_df;
+}
+
+static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
+{
+	if (skb->len <= mtu)
+		return false;
+
+	if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu)
+		return false;
+
+	return true;
+}
+
+static bool ip_gso_exceeds_dst_mtu(const struct sk_buff *skb)
+{
+	unsigned int mtu;
+
+	if (skb->local_df || !skb_is_gso(skb))
+		return false;
+
+	mtu = dst_mtu(skb_dst(skb));
+
+	/* if seglen > mtu, do software segmentation for IP fragmentation on
+	 * output.  DF bit cannot be set since ip_forward would have sent
+	 * icmp error.
+	 */
+	return skb_gso_network_seglen(skb) > mtu;
+}
+
+/* called if GSO skb needs to be fragmented on forward */
+static int ip_forward_finish_gso(struct sk_buff *skb)
+{
+	struct dst_entry *dst = skb_dst(skb);
+	netdev_features_t features;
+	struct sk_buff *segs;
+	int ret = 0;
+
+	features = netif_skb_dev_features(skb, dst->dev);
+	segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
+	if (IS_ERR(segs)) {
+		kfree_skb(skb);
+		return -ENOMEM;
+	}
+
+	consume_skb(skb);
+
+	do {
+		struct sk_buff *nskb = segs->next;
+		int err;
+
+		segs->next = NULL;
+		err = dst_output(segs);
+
+		if (err && ret == 0)
+			ret = err;
+		segs = nskb;
+	} while (segs);
+
+	return ret;
+}
+
 static int ip_forward_finish(struct sk_buff *skb)
 {
 	struct ip_options *opt	= &(IPCB(skb)->opt);
@@ -49,6 +114,9 @@
 	if (unlikely(opt->optlen))
 		ip_forward_options(skb);
 
+	if (ip_gso_exceeds_dst_mtu(skb))
+		return ip_forward_finish_gso(skb);
+
 	return dst_output(skb);
 }
 
@@ -88,8 +156,7 @@
 	if (opt->is_strictroute && rt->rt_uses_gateway)
 		goto sr_failed;
 
-	if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) &&
-		     (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) {
+	if (!ip_may_fragment(skb) && ip_exceeds_mtu(skb, dst_mtu(&rt->dst))) {
 		IP_INC_STATS(dev_net(rt->dst.dev), IPSTATS_MIB_FRAGFAILS);
 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
 			  htonl(dst_mtu(&rt->dst)));
diff -ruw linux-3.11.10/net/ipv4/ip_fragment.c linux-3.11.10-fbx/net/ipv4/ip_fragment.c
--- linux-3.11.10/net/ipv4/ip_fragment.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/ip_fragment.c	2014-05-09 14:12:54.380546161 +0200
@@ -623,8 +623,7 @@
 	IPCB(head)->frag_max_size = qp->q.max_size;
 
 	iph = ip_hdr(head);
-	/* max_size != 0 implies at least one fragment had IP_DF set */
-	iph->frag_off = qp->q.max_size ? htons(IP_DF) : 0;
+	iph->frag_off = 0;
 	iph->tot_len = htons(len);
 	iph->tos |= ecn;
 	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
diff -ruw linux-3.11.10/net/ipv4/ip_input.c linux-3.11.10-fbx/net/ipv4/ip_input.c
--- linux-3.11.10/net/ipv4/ip_input.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/ip_input.c	2014-05-09 14:12:54.380546161 +0200
@@ -186,10 +186,15 @@
 	return false;
 }
 
-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, skb_network_header_len(skb));
 
 	rcu_read_lock();
@@ -313,7 +318,7 @@
 	const struct iphdr *iph = ip_hdr(skb);
 	struct rtable *rt;
 
-	if (sysctl_ip_early_demux && !skb_dst(skb)) {
+	if (sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) {
 		const struct net_protocol *ipprot;
 		int protocol = iph->protocol;
 
@@ -442,6 +447,11 @@
 	/* Must drop socket now because of tproxy. */
 	skb_orphan(skb);
 
+#ifdef CONFIG_IP_FFN
+	if (!ip_ffn_process(skb))
+		return NET_RX_SUCCESS;
+#endif
+
 	return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, dev, NULL,
 		       ip_rcv_finish);
 
diff -ruw linux-3.11.10/net/ipv4/ip_output.c linux-3.11.10-fbx/net/ipv4/ip_output.c
--- linux-3.11.10/net/ipv4/ip_output.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/ip_output.c	2013-12-17 18:03:43.075570857 +0100
@@ -192,6 +192,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_bh();
 	nexthop = (__force u32) rt_nexthop(rt, ip_hdr(skb)->daddr);
 	neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
@@ -199,7 +204,6 @@
 		neigh = __neigh_create(&arp_tbl, &nexthop, dev, false);
 	if (!IS_ERR(neigh)) {
 		int res = dst_neigh_output(dst, neigh, skb);
-
 		rcu_read_unlock_bh();
 		return res;
 	}
@@ -296,6 +300,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));
@@ -1537,4 +1546,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.11.10/net/ipv4/ip_sockglue.c linux-3.11.10-fbx/net/ipv4/ip_sockglue.c
--- linux-3.11.10/net/ipv4/ip_sockglue.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/ip_sockglue.c	2014-01-17 19:14:18.810220810 +0100
@@ -368,7 +368,7 @@
 /*
  *	Handle MSG_ERRQUEUE
  */
-int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
+int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
 {
 	struct sock_exterr_skb *serr;
 	struct sk_buff *skb, *skb2;
@@ -405,6 +405,7 @@
 						   serr->addr_offset);
 		sin->sin_port = serr->port;
 		memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
+		*addr_len = sizeof(*sin);
 	}
 
 	memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
diff -ruw linux-3.11.10/net/ipv4/ip_tunnel_core.c linux-3.11.10-fbx/net/ipv4/ip_tunnel_core.c
--- linux-3.11.10/net/ipv4/ip_tunnel_core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/ip_tunnel_core.c	2013-12-17 18:03:43.075570857 +0100
@@ -45,6 +45,9 @@
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include <net/rtnetlink.h>
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+#include <net/netfilter/nf_conntrack.h>
+#endif
 
 int iptunnel_xmit(struct net *net, struct rtable *rt,
 		  struct sk_buff *skb,
@@ -56,6 +59,13 @@
 	int err;
 
 	nf_reset(skb);
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	if (proto == IPPROTO_IPV6) {
+		skb->nfct = &nf_ct_untracked_get()->ct_general;
+		skb->nfctinfo = IP_CT_NEW;
+		nf_conntrack_get(skb->nfct);
+	}
+#endif
 	secpath_reset(skb);
 	skb->rxhash = 0;
 	skb_dst_drop(skb);
diff -ruw linux-3.11.10/net/ipv4/Kconfig linux-3.11.10-fbx/net/ipv4/Kconfig
--- linux-3.11.10/net/ipv4/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/Kconfig	2013-12-04 14:33:29.631479143 +0100
@@ -369,6 +369,11 @@
 	tristate
 	default n
 
+config INET_XFRM_GC_THRESH
+	int "IP: xfrm garbage collect threshold"
+	depends on XFRM
+	default 1024
+
 config INET_XFRM_MODE_TRANSPORT
 	tristate "IP: IPsec transport mode"
 	default y
diff -ruw linux-3.11.10/net/ipv4/Makefile linux-3.11.10-fbx/net/ipv4/Makefile
--- linux-3.11.10/net/ipv4/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/Makefile	2013-12-04 14:33:29.631479143 +0100
@@ -15,6 +15,8 @@
 
 obj-$(CONFIG_NET_IP_TUNNEL) += ip_tunnel.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.11.10/net/ipv4/netfilter/ip_tables.c linux-3.11.10-fbx/net/ipv4/netfilter/ip_tables.c
--- linux-3.11.10/net/ipv4/netfilter/ip_tables.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/netfilter/ip_tables.c	2014-07-01 16:22:13.214329992 +0200
@@ -30,6 +30,9 @@
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <net/netfilter/nf_log.h>
 #include "../../netfilter/xt_repldata.h"
+#ifdef CONFIG_FBXBRIDGE
+#include <linux/fbxbridge.h>
+#endif
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
@@ -1226,8 +1229,10 @@
 
 	xt_free_table_info(oldinfo);
 	if (copy_to_user(counters_ptr, counters,
-			 sizeof(struct xt_counters) * num_counters) != 0)
-		ret = -EFAULT;
+			 sizeof(struct xt_counters) * num_counters) != 0) {
+		/* Silent error, can't fail, new table is already in place */
+		net_warn_ratelimited("iptables: counters copy to user failed while replacing table\n");
+	}
 	vfree(counters);
 	xt_table_unlock(t);
 	return ret;
@@ -1280,6 +1285,14 @@
 			   tmp.num_counters, tmp.counters);
 	if (ret)
 		goto free_newinfo_untrans;
+
+#ifdef CONFIG_IP_FFN
+	ip_ffn_flush_all();
+#endif
+
+#if defined(CONFIG_FBXBRIDGE) || defined(CONFIG_FBXBRIDGE_MODULE)
+	fbxbridge_fp_flush_all();
+#endif
 	return 0;
 
  free_newinfo_untrans:
diff -ruw linux-3.11.10/net/ipv4/netfilter/Kconfig linux-3.11.10-fbx/net/ipv4/netfilter/Kconfig
--- linux-3.11.10/net/ipv4/netfilter/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/netfilter/Kconfig	2013-12-04 14:33:29.639479143 +0100
@@ -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.11.10/net/ipv4/netfilter/nf_defrag_ipv4.c linux-3.11.10-fbx/net/ipv4/netfilter/nf_defrag_ipv4.c
--- linux-3.11.10/net/ipv4/netfilter/nf_defrag_ipv4.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/netfilter/nf_defrag_ipv4.c	2014-07-01 16:22:13.214329992 +0200
@@ -22,7 +22,6 @@
 #endif
 #include <net/netfilter/nf_conntrack_zones.h>
 
-/* Returns new sk_buff, or NULL */
 static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
 {
 	int err;
@@ -33,8 +32,10 @@
 	err = ip_defrag(skb, user);
 	local_bh_enable();
 
-	if (!err)
+	if (!err) {
 		ip_send_check(ip_hdr(skb));
+		skb->local_df = 1;
+	}
 
 	return err;
 }
diff -ruw linux-3.11.10/net/ipv4/ping.c linux-3.11.10-fbx/net/ipv4/ping.c
--- linux-3.11.10/net/ipv4/ping.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/ping.c	2014-07-01 16:22:13.214329992 +0200
@@ -249,26 +249,33 @@
 {
 	struct net *net = sock_net(sk);
 	kgid_t group = current_egid();
-	struct group_info *group_info = get_current_groups();
-	int i, j, count = group_info->ngroups;
+	struct group_info *group_info;
+	int i, j, count;
 	kgid_t low, high;
+	int ret = 0;
 
 	inet_get_ping_group_range_net(net, &low, &high);
 	if (gid_lte(low, group) && gid_lte(group, high))
 		return 0;
 
+	group_info = get_current_groups();
+	count = group_info->ngroups;
 	for (i = 0; i < group_info->nblocks; i++) {
 		int cp_count = min_t(int, NGROUPS_PER_BLOCK, count);
 		for (j = 0; j < cp_count; j++) {
 			kgid_t gid = group_info->blocks[i][j];
 			if (gid_lte(low, gid) && gid_lte(gid, high))
-				return 0;
+				goto out_release_group;
 		}
 
 		count -= cp_count;
 	}
 
-	return -EACCES;
+	ret = -EACCES;
+
+out_release_group:
+	put_group_info(group_info);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(ping_init_sock);
 
@@ -769,7 +776,7 @@
 		err = PTR_ERR(rt);
 		rt = NULL;
 		if (err == -ENETUNREACH)
-			IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
+			IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
 		goto out;
 	}
 
@@ -827,8 +834,6 @@
 {
 	struct inet_sock *isk = inet_sk(sk);
 	int family = sk->sk_family;
-	struct sockaddr_in *sin;
-	struct sockaddr_in6 *sin6;
 	struct sk_buff *skb;
 	int copied, err;
 
@@ -838,19 +843,13 @@
 	if (flags & MSG_OOB)
 		goto out;
 
-	if (addr_len) {
-		if (family == AF_INET)
-			*addr_len = sizeof(*sin);
-		else if (family == AF_INET6 && addr_len)
-			*addr_len = sizeof(*sin6);
-	}
-
 	if (flags & MSG_ERRQUEUE) {
 		if (family == AF_INET) {
-			return ip_recv_error(sk, msg, len);
+			return ip_recv_error(sk, msg, len, addr_len);
 #if IS_ENABLED(CONFIG_IPV6)
 		} else if (family == AF_INET6) {
-			return pingv6_ops.ipv6_recv_error(sk, msg, len);
+			return pingv6_ops.ipv6_recv_error(sk, msg, len,
+							  addr_len);
 #endif
 		}
 	}
@@ -874,11 +873,15 @@
 
 	/* Copy the address and add cmsg data. */
 	if (family == AF_INET) {
-		sin = (struct sockaddr_in *) msg->msg_name;
+		struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
+
+		if (sin) {
 		sin->sin_family = AF_INET;
 		sin->sin_port = 0 /* skb->h.uh->source */;
 		sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
 		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+			*addr_len = sizeof(*sin);
+		}
 
 		if (isk->cmsg_flags)
 			ip_cmsg_recv(msg, skb);
@@ -887,17 +890,21 @@
 	} else if (family == AF_INET6) {
 		struct ipv6_pinfo *np = inet6_sk(sk);
 		struct ipv6hdr *ip6 = ipv6_hdr(skb);
-		sin6 = (struct sockaddr_in6 *) msg->msg_name;
+		struct sockaddr_in6 *sin6 =
+			(struct sockaddr_in6 *)msg->msg_name;
+
+		if (sin6) {
 		sin6->sin6_family = AF_INET6;
 		sin6->sin6_port = 0;
 		sin6->sin6_addr = ip6->saddr;
-
 		sin6->sin6_flowinfo = 0;
 		if (np->sndflow)
 			sin6->sin6_flowinfo = ip6_flowinfo(ip6);
-
-		sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
+			sin6->sin6_scope_id =
+				ipv6_iface_scope_id(&sin6->sin6_addr,
 							  IP6CB(skb)->iif);
+			*addr_len = sizeof(*sin6);
+		}
 
 		if (inet6_sk(sk)->rxopt.all)
 			pingv6_ops.ip6_datagram_recv_ctl(sk, msg, skb);
diff -ruw linux-3.11.10/net/ipv4/raw.c linux-3.11.10-fbx/net/ipv4/raw.c
--- linux-3.11.10/net/ipv4/raw.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/raw.c	2014-01-17 19:14:18.810220810 +0100
@@ -692,11 +692,8 @@
 	if (flags & MSG_OOB)
 		goto out;
 
-	if (addr_len)
-		*addr_len = sizeof(*sin);
-
 	if (flags & MSG_ERRQUEUE) {
-		err = ip_recv_error(sk, msg, len);
+		err = ip_recv_error(sk, msg, len, addr_len);
 		goto out;
 	}
 
@@ -722,6 +719,7 @@
 		sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
 		sin->sin_port = 0;
 		memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
+		*addr_len = sizeof(*sin);
 	}
 	if (inet->cmsg_flags)
 		ip_cmsg_recv(msg, skb);
diff -ruw linux-3.11.10/net/ipv4/route.c linux-3.11.10-fbx/net/ipv4/route.c
--- linux-3.11.10/net/ipv4/route.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/route.c	2014-07-01 16:22:13.214329992 +0200
@@ -1527,7 +1527,7 @@
 	struct in_device *out_dev;
 	unsigned int flags = 0;
 	bool do_cache;
-	u32 itag;
+	u32 itag = 0;
 
 	/* get a working reference to the output device */
 	out_dev = __in_dev_get_rcu(FIB_RES_DEV(*res));
@@ -1598,6 +1598,7 @@
 	rth->rt_gateway	= 0;
 	rth->rt_uses_gateway = 0;
 	INIT_LIST_HEAD(&rth->rt_uncached);
+	RT_CACHE_STAT_INC(in_slow_tot);
 
 	rth->dst.input = ip_forward;
 	rth->dst.output = ip_output;
@@ -1699,8 +1700,6 @@
 	if (err != 0)
 		goto no_route;
 
-	RT_CACHE_STAT_INC(in_slow_tot);
-
 	if (res.type == RTN_BROADCAST)
 		goto brd_input;
 
@@ -1769,13 +1768,18 @@
 	rth->rt_gateway	= 0;
 	rth->rt_uses_gateway = 0;
 	INIT_LIST_HEAD(&rth->rt_uncached);
+	RT_CACHE_STAT_INC(in_slow_tot);
 	if (res.type == RTN_UNREACHABLE) {
 		rth->dst.input= ip_error;
 		rth->dst.error= -err;
 		rth->rt_flags 	&= ~RTCF_LOCAL;
 	}
-	if (do_cache)
-		rt_cache_route(&FIB_RES_NH(res), rth);
+	if (do_cache) {
+		if (unlikely(!rt_cache_route(&FIB_RES_NH(res), rth))) {
+			rth->dst.flags |= DST_NOCACHE;
+			rt_add_uncached_list(rth);
+		}
+	}
 	skb_dst_set(skb, &rth->dst);
 	err = 0;
 	goto out;
@@ -2356,7 +2360,7 @@
 			}
 		} else
 #endif
-			if (nla_put_u32(skb, RTA_IIF, rt->rt_iif))
+			if (nla_put_u32(skb, RTA_IIF, skb->dev->ifindex))
 				goto nla_put_failure;
 	}
 
diff -ruw linux-3.11.10/net/ipv4/tcp.c linux-3.11.10-fbx/net/ipv4/tcp.c
--- linux-3.11.10/net/ipv4/tcp.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/tcp.c	2014-07-01 16:22:13.214329992 +0200
@@ -810,12 +810,6 @@
 		xmit_size_goal = min_t(u32, gso_size,
 				       sk->sk_gso_max_size - 1 - hlen);
 
-		/* TSQ : try to have at least two segments in flight
-		 * (one in NIC TX ring, another in Qdisc)
-		 */
-		xmit_size_goal = min_t(u32, xmit_size_goal,
-				       sysctl_tcp_limit_output_bytes >> 1);
-
 		xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal);
 
 		/* We try hard to avoid divides here */
@@ -1010,7 +1004,8 @@
 	}
 }
 
-static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *size)
+static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
+				int *copied, size_t size)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	int err, flags;
@@ -1025,11 +1020,12 @@
 	if (unlikely(tp->fastopen_req == NULL))
 		return -ENOBUFS;
 	tp->fastopen_req->data = msg;
+	tp->fastopen_req->size = size;
 
 	flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0;
 	err = __inet_stream_connect(sk->sk_socket, msg->msg_name,
 				    msg->msg_namelen, flags);
-	*size = tp->fastopen_req->copied;
+	*copied = tp->fastopen_req->copied;
 	tcp_free_fastopen_req(tp);
 	return err;
 }
@@ -1049,7 +1045,7 @@
 
 	flags = msg->msg_flags;
 	if (flags & MSG_FASTOPEN) {
-		err = tcp_sendmsg_fastopen(sk, msg, &copied_syn);
+		err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size);
 		if (err == -EINPROGRESS && copied_syn > 0)
 			goto out;
 		else if (err)
diff -ruw linux-3.11.10/net/ipv4/tcp_cubic.c linux-3.11.10-fbx/net/ipv4/tcp_cubic.c
--- linux-3.11.10/net/ipv4/tcp_cubic.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/tcp_cubic.c	2014-07-01 16:22:13.214329992 +0200
@@ -408,7 +408,7 @@
 		ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT;
 		ratio += cnt;
 
-		ca->delayed_ack = min(ratio, ACK_RATIO_LIMIT);
+		ca->delayed_ack = clamp(ratio, 1U, ACK_RATIO_LIMIT);
 	}
 
 	/* Some calls are for duplicates without timetamps */
diff -ruw linux-3.11.10/net/ipv4/tcp_input.c linux-3.11.10-fbx/net/ipv4/tcp_input.c
--- linux-3.11.10/net/ipv4/tcp_input.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/tcp_input.c	2014-08-22 15:47:22.160063265 +0200
@@ -2622,13 +2622,12 @@
 	bool recovered = !before(tp->snd_una, tp->high_seq);
 
 	if (tp->frto) { /* F-RTO RFC5682 sec 3.1 (sack enhanced version). */
-		if (flag & FLAG_ORIG_SACK_ACKED) {
 			/* Step 3.b. A timeout is spurious if not all data are
 			 * lost, i.e., never-retransmitted data are (s)acked.
 			 */
-			tcp_try_undo_loss(sk, true);
+		if (tcp_try_undo_loss(sk, flag & FLAG_ORIG_SACK_ACKED))
 			return;
-		}
+
 		if (after(tp->snd_nxt, tp->high_seq) &&
 		    (flag & FLAG_DATA_SACKED || is_dupack)) {
 			tp->frto = 0; /* Loss was real: 2nd part of step 3.a */
diff -ruw linux-3.11.10/net/ipv4/tcp_ipv4.c linux-3.11.10-fbx/net/ipv4/tcp_ipv4.c
--- linux-3.11.10/net/ipv4/tcp_ipv4.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/tcp_ipv4.c	2014-01-17 19:14:18.810220810 +0100
@@ -177,7 +177,7 @@
 	if (IS_ERR(rt)) {
 		err = PTR_ERR(rt);
 		if (err == -ENETUNREACH)
-			IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
+			IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
 		return err;
 	}
 
diff -ruw linux-3.11.10/net/ipv4/tcp_metrics.c linux-3.11.10-fbx/net/ipv4/tcp_metrics.c
--- linux-3.11.10/net/ipv4/tcp_metrics.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/tcp_metrics.c	2014-05-09 14:12:54.380546161 +0200
@@ -22,6 +22,9 @@
 
 int sysctl_tcp_nometrics_save __read_mostly;
 
+static struct tcp_metrics_block *__tcp_get_metrics(const struct inetpeer_addr *addr,
+						   struct net *net, unsigned int hash);
+
 struct tcp_fastopen_metrics {
 	u16	mss;
 	u16	syn_loss:10;		/* Recurring Fast Open SYN losses */
@@ -130,16 +133,41 @@
 	}
 }
 
+#define TCP_METRICS_TIMEOUT		(60 * 60 * HZ)
+
+static void tcpm_check_stamp(struct tcp_metrics_block *tm, struct dst_entry *dst)
+{
+	if (tm && unlikely(time_after(jiffies, tm->tcpm_stamp + TCP_METRICS_TIMEOUT)))
+		tcpm_suck_dst(tm, dst, false);
+}
+
+#define TCP_METRICS_RECLAIM_DEPTH	5
+#define TCP_METRICS_RECLAIM_PTR		(struct tcp_metrics_block *) 0x1UL
+
 static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst,
 					  struct inetpeer_addr *addr,
-					  unsigned int hash,
-					  bool reclaim)
+					  unsigned int hash)
 {
 	struct tcp_metrics_block *tm;
 	struct net *net;
+	bool reclaim = false;
 
 	spin_lock_bh(&tcp_metrics_lock);
 	net = dev_net(dst->dev);
+
+	/* While waiting for the spin-lock the cache might have been populated
+	 * with this entry and so we have to check again.
+	 */
+	tm = __tcp_get_metrics(addr, net, hash);
+	if (tm == TCP_METRICS_RECLAIM_PTR) {
+		reclaim = true;
+		tm = NULL;
+	}
+	if (tm) {
+		tcpm_check_stamp(tm, dst);
+		goto out_unlock;
+	}
+
 	if (unlikely(reclaim)) {
 		struct tcp_metrics_block *oldest;
 
@@ -169,17 +197,6 @@
 	return tm;
 }
 
-#define TCP_METRICS_TIMEOUT		(60 * 60 * HZ)
-
-static void tcpm_check_stamp(struct tcp_metrics_block *tm, struct dst_entry *dst)
-{
-	if (tm && unlikely(time_after(jiffies, tm->tcpm_stamp + TCP_METRICS_TIMEOUT)))
-		tcpm_suck_dst(tm, dst, false);
-}
-
-#define TCP_METRICS_RECLAIM_DEPTH	5
-#define TCP_METRICS_RECLAIM_PTR		(struct tcp_metrics_block *) 0x1UL
-
 static struct tcp_metrics_block *tcp_get_encode(struct tcp_metrics_block *tm, int depth)
 {
 	if (tm)
@@ -280,7 +297,6 @@
 	struct inetpeer_addr addr;
 	unsigned int hash;
 	struct net *net;
-	bool reclaim;
 
 	addr.family = sk->sk_family;
 	switch (addr.family) {
@@ -300,13 +316,10 @@
 	hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);
 
 	tm = __tcp_get_metrics(&addr, net, hash);
-	reclaim = false;
-	if (tm == TCP_METRICS_RECLAIM_PTR) {
-		reclaim = true;
+	if (tm == TCP_METRICS_RECLAIM_PTR)
 		tm = NULL;
-	}
 	if (!tm && create)
-		tm = tcpm_new(dst, &addr, hash, reclaim);
+		tm = tcpm_new(dst, &addr, hash);
 	else
 		tcpm_check_stamp(tm, dst);
 
@@ -665,10 +678,13 @@
 void tcp_fastopen_cache_set(struct sock *sk, u16 mss,
 			    struct tcp_fastopen_cookie *cookie, bool syn_lost)
 {
+	struct dst_entry *dst = __sk_dst_get(sk);
 	struct tcp_metrics_block *tm;
 
+	if (!dst)
+		return;
 	rcu_read_lock();
-	tm = tcp_get_metrics(sk, __sk_dst_get(sk), true);
+	tm = tcp_get_metrics(sk, dst, true);
 	if (tm) {
 		struct tcp_fastopen_metrics *tfom = &tm->tcpm_fastopen;
 
diff -ruw linux-3.11.10/net/ipv4/tcp_offload.c linux-3.11.10-fbx/net/ipv4/tcp_offload.c
--- linux-3.11.10/net/ipv4/tcp_offload.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/tcp_offload.c	2014-01-17 19:14:18.810220810 +0100
@@ -272,33 +272,32 @@
 {
 	const struct iphdr *iph = skb_gro_network_header(skb);
 	__wsum wsum;
-	__sum16 sum;
+
+	/* Don't bother verifying checksum if we're going to flush anyway. */
+	if (NAPI_GRO_CB(skb)->flush)
+		goto skip_csum;
+
+	wsum = skb->csum;
 
 	switch (skb->ip_summed) {
+	case CHECKSUM_NONE:
+		wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
+				    0);
+
+		/* fall through */
+
 	case CHECKSUM_COMPLETE:
 		if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr,
-				  skb->csum)) {
+				  wsum)) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			break;
 		}
-flush:
+
 		NAPI_GRO_CB(skb)->flush = 1;
 		return NULL;
-
-	case CHECKSUM_NONE:
-		wsum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
-					  skb_gro_len(skb), IPPROTO_TCP, 0);
-		sum = csum_fold(skb_checksum(skb,
-					     skb_gro_offset(skb),
-					     skb_gro_len(skb),
-					     wsum));
-		if (sum)
-			goto flush;
-
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
-		break;
 	}
 
+skip_csum:
 	return tcp_gro_receive(head, skb);
 }
 
diff -ruw linux-3.11.10/net/ipv4/tcp_output.c linux-3.11.10-fbx/net/ipv4/tcp_output.c
--- linux-3.11.10/net/ipv4/tcp_output.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/tcp_output.c	2014-07-01 16:22:13.218330008 +0200
@@ -691,7 +691,8 @@
 	if ((1 << sk->sk_state) &
 	    (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_CLOSING |
 	     TCPF_CLOSE_WAIT  | TCPF_LAST_ACK))
-		tcp_write_xmit(sk, tcp_current_mss(sk), 0, 0, GFP_ATOMIC);
+		tcp_write_xmit(sk, tcp_current_mss(sk), tcp_sk(sk)->nonagle,
+			       0, GFP_ATOMIC);
 }
 /*
  * One tasklest per cpu tries to send more skbs.
@@ -759,6 +760,17 @@
 	if (flags & (1UL << TCP_TSQ_DEFERRED))
 		tcp_tsq_handler(sk);
 
+	/* Here begins the tricky part :
+	 * We are called from release_sock() with :
+	 * 1) BH disabled
+	 * 2) sk_lock.slock spinlock held
+	 * 3) socket owned by us (sk->sk_lock.owned == 1)
+	 *
+	 * But following code is meant to be called from BH handlers,
+	 * so we should keep BH disabled, but early release socket ownership
+	 */
+	sock_release_ownership(sk);
+
 	if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) {
 		tcp_write_timer_handler(sk);
 		__sock_put(sk);
@@ -1871,11 +1883,23 @@
 		 *  - better RTT estimation and ACK scheduling
 		 *  - faster recovery
 		 *  - high rates
+		 * Alas, some drivers / subsystems require a fair amount
+		 * of queued bytes to ensure line rate.
+		 * One example is wifi aggregation (802.11 AMPDU)
 		 */
-		limit = max(skb->truesize, sk->sk_pacing_rate >> 10);
+		limit = max_t(unsigned int, sysctl_tcp_limit_output_bytes,
+			      sk->sk_pacing_rate >> 10);
 
 		if (atomic_read(&sk->sk_wmem_alloc) > limit) {
 			set_bit(TSQ_THROTTLED, &tp->tsq_flags);
+			/* It is possible TX completion already happened
+			 * before we set TSQ_THROTTLED, so we must
+			 * test again the condition.
+			 * We abuse smp_mb__after_clear_bit() because
+			 * there is no smp_mb__after_set_bit() yet
+			 */
+			smp_mb__after_clear_bit();
+			if (atomic_read(&sk->sk_wmem_alloc) > limit)
 			break;
 		}
 
@@ -2885,7 +2909,12 @@
 	space = __tcp_mtu_to_mss(sk, inet_csk(sk)->icsk_pmtu_cookie) -
 		MAX_TCP_OPTION_SPACE;
 
-	syn_data = skb_copy_expand(syn, skb_headroom(syn), space,
+	space = min_t(size_t, space, fo->size);
+
+	/* limit to order-0 allocations */
+	space = min_t(size_t, space, SKB_MAX_HEAD(MAX_TCP_HEADER));
+
+	syn_data = skb_copy_expand(syn, MAX_TCP_HEADER, space,
 				   sk->sk_allocation);
 	if (syn_data == NULL)
 		goto fallback;
@@ -3104,7 +3133,6 @@
 {
 	if (sk->sk_state == TCP_ESTABLISHED) {
 		tcp_sk(sk)->snd_wl1 = tcp_sk(sk)->rcv_nxt - 1;
-		tcp_sk(sk)->snd_nxt = tcp_sk(sk)->write_seq;
 		tcp_xmit_probe_skb(sk, 0);
 	}
 }
diff -ruw linux-3.11.10/net/ipv4/udp.c linux-3.11.10-fbx/net/ipv4/udp.c
--- linux-3.11.10/net/ipv4/udp.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/udp.c	2014-05-09 14:12:54.384546161 +0200
@@ -208,6 +208,8 @@
 					 const struct sock *sk2),
 		     unsigned int hash2_nulladdr)
 {
+	struct sock *sk2;
+	struct hlist_nulls_node *node;
 	struct udp_hslot *hslot, *hslot2;
 	struct udp_table *udptable = sk->sk_prot->h.udp_table;
 	int    error = 1;
@@ -287,6 +289,48 @@
 	inet_sk(sk)->inet_num = snum;
 	udp_sk(sk)->udp_port_hash = snum;
 	udp_sk(sk)->udp_portaddr_hash ^= snum;
+
+	/* resolve udp reuse conflict */
+	if (sk->sk_reuse) {
+		bool found;
+
+		found = false;
+		sk_nulls_for_each(sk2, node, &hslot->head) {
+			if (!net_eq(sock_net(sk2), net) ||
+			    sk2 == sk ||
+			    (udp_sk(sk2)->udp_port_hash != snum))
+				continue;
+
+			if (sk2->sk_bound_dev_if &&
+			    sk->sk_bound_dev_if &&
+			    sk2->sk_bound_dev_if != sk->sk_bound_dev_if)
+				continue;
+
+			if (!(*saddr_comp)(sk, sk2))
+				continue;
+
+			found = true;
+			break;
+		}
+
+		sk_nulls_for_each(sk2, node, &hslot->head) {
+			if (!net_eq(sock_net(sk2), net) ||
+			    sk2 == sk ||
+			    (udp_sk(sk2)->udp_port_hash != snum))
+				continue;
+
+			if (sk2->sk_bound_dev_if &&
+			    sk->sk_bound_dev_if &&
+			    sk2->sk_bound_dev_if != sk->sk_bound_dev_if)
+				continue;
+
+			if (!(*saddr_comp)(sk, sk2))
+				continue;
+
+			sk->sk_reuse_conflict = found;
+		}
+	}
+
 	if (sk_unhashed(sk)) {
 		sk_nulls_add_node_rcu(sk, &hslot->head);
 		hslot->count++;
@@ -972,7 +1016,7 @@
 			err = PTR_ERR(rt);
 			rt = NULL;
 			if (err == -ENETUNREACH)
-				IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
+				IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
 			goto out;
 		}
 
@@ -1071,6 +1115,9 @@
 	struct udp_sock *up = udp_sk(sk);
 	int ret;
 
+	if (flags & MSG_SENDPAGE_NOTLAST)
+		flags |= MSG_MORE;
+
 	if (!up->pending) {
 		struct msghdr msg = {	.msg_flags = flags|MSG_MORE };
 
@@ -1208,14 +1255,8 @@
 	int is_udplite = IS_UDPLITE(sk);
 	bool slow;
 
-	/*
-	 *	Check any passed addresses
-	 */
-	if (addr_len)
-		*addr_len = sizeof(*sin);
-
 	if (flags & MSG_ERRQUEUE)
-		return ip_recv_error(sk, msg, len);
+		return ip_recv_error(sk, msg, len, addr_len);
 
 try_again:
 	skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
@@ -1275,6 +1316,7 @@
 		sin->sin_port = udp_hdr(skb)->source;
 		sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
 		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+		*addr_len = sizeof(*sin);
 	}
 	if (inet->cmsg_flags)
 		ip_cmsg_recv(msg, skb);
@@ -1628,6 +1670,64 @@
 	return 0;
 }
 
+/*
+ *	Unicast goes to one listener and all sockets with dup flag
+ *
+ *	Note: called only from the BH handler context.
+ */
+static int __udp4_lib_uc_conflict_deliver(struct net *net, struct sk_buff *skb,
+					  struct udphdr  *uh,
+					  __be32 saddr, __be32 daddr,
+					  struct udp_table *udptable)
+{
+	struct sock *sk, *stack[256 / sizeof(struct sock *)];
+	struct udp_hslot *hslot = udp_hashslot(udptable, net, ntohs(uh->dest));
+	int dif;
+	unsigned int i, count = 0, non_dup_count = 0;
+
+	spin_lock(&hslot->lock);
+	sk = sk_nulls_head(&hslot->head);
+	dif = skb->dev->ifindex;
+	sk = udp_v4_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif);
+	while (sk) {
+		if (!sock_flag(sk, SOCK_UDP_DUP_UNICAST)) {
+			if (!non_dup_count)
+				stack[count++] = sk;
+			non_dup_count = 1;
+		} else
+			stack[count++] = sk;
+
+		sk = udp_v4_mcast_next(net, sk_nulls_next(sk), uh->dest,
+				       daddr, uh->source, saddr, dif);
+		if (unlikely(count == ARRAY_SIZE(stack))) {
+			if (!sk)
+				break;
+			flush_stack(stack, count, skb, ~0);
+			count = 0;
+		}
+	}
+	/*
+	 * before releasing chain lock, we must take a reference on sockets
+	 */
+	for (i = 0; i < count; i++)
+		sock_hold(stack[i]);
+
+	spin_unlock(&hslot->lock);
+
+	/*
+	 * do the slow work with no lock held
+	 */
+	if (count) {
+		flush_stack(stack, count, skb, count - 1);
+
+		for (i = 0; i < count; i++)
+			sock_put(stack[i]);
+	} else {
+		kfree_skb(skb);
+	}
+	return 0;
+}
+
 /* Initialize UDP checksum. If exited with zero value (success),
  * CHECKSUM_UNNECESSARY means, that no more checks are required.
  * Otherwise, csum completion requires chacksumming packet body,
@@ -1714,6 +1814,13 @@
 		int ret;
 
 		sk_mark_napi_id(sk, skb);
+		if (sk->sk_reuse_conflict) {
+			sock_put(sk);
+			return __udp4_lib_uc_conflict_deliver(net, skb, uh,
+							      saddr, daddr,
+							      udptable);
+		}
+
 		ret = udp_queue_rcv_skb(sk, skb);
 		sock_put(sk);
 
@@ -2295,6 +2402,7 @@
 				       netdev_features_t features)
 {
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
+	u16 mac_offset = skb->mac_header;
 	int mac_len = skb->mac_len;
 	int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb);
 	__be16 protocol = skb->protocol;
@@ -2314,8 +2422,11 @@
 	/* segment inner packet. */
 	enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
 	segs = skb_mac_gso_segment(skb, enc_features);
-	if (!segs || IS_ERR(segs))
+	if (!segs || IS_ERR(segs)) {
+		skb_gso_error_unwind(skb, protocol, tnl_hlen, mac_offset,
+				     mac_len);
 		goto out;
+	}
 
 	outer_hlen = skb_tnl_header_len(skb);
 	skb = segs;
diff -ruw linux-3.11.10/net/ipv4/udp_offload.c linux-3.11.10-fbx/net/ipv4/udp_offload.c
--- linux-3.11.10/net/ipv4/udp_offload.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/udp_offload.c	2014-05-09 14:12:54.384546161 +0200
@@ -41,6 +41,14 @@
 {
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
 	unsigned int mss;
+	int offset;
+	__wsum csum;
+
+	if (skb->encapsulation &&
+	    skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) {
+		segs = skb_udp_tunnel_segment(skb, features);
+		goto out;
+	}
 
 	mss = skb_shinfo(skb)->gso_size;
 	if (unlikely(skb->len <= mss))
@@ -62,15 +70,6 @@
 		goto out;
 	}
 
-	/* Fragment the skb. IP headers of the fragments are updated in
-	 * inet_gso_segment()
-	 */
-	if (skb->encapsulation && skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL)
-		segs = skb_udp_tunnel_segment(skb, features);
-	else {
-		int offset;
-		__wsum csum;
-
 		/* Do software UFO. Complete and fill in the UDP checksum as
 		 * HW cannot do checksum of UDP packets sent as multiple
 		 * IP fragments.
@@ -81,8 +80,10 @@
 		*(__sum16 *)(skb->data + offset) = csum_fold(csum);
 		skb->ip_summed = CHECKSUM_NONE;
 
+	/* Fragment the skb. IP headers of the fragments are updated in
+	 * inet_gso_segment()
+	 */
 		segs = skb_segment(skb, features);
-	}
 out:
 	return segs;
 }
diff -ruw linux-3.11.10/net/ipv4/xfrm4_policy.c linux-3.11.10-fbx/net/ipv4/xfrm4_policy.c
--- linux-3.11.10/net/ipv4/xfrm4_policy.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv4/xfrm4_policy.c	2013-12-04 14:33:29.655479143 +0100
@@ -235,7 +235,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.11.10/net/ipv6/addrconf.c linux-3.11.10-fbx/net/ipv6/addrconf.c
--- linux-3.11.10/net/ipv6/addrconf.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/addrconf.c	2014-07-01 16:22:13.218330008 +0200
@@ -1113,8 +1113,11 @@
 	 * Lifetime is greater than REGEN_ADVANCE time units.  In particular,
 	 * an implementation must not create a temporary address with a zero
 	 * Preferred Lifetime.
+	 * Use age calculation as in addrconf_verify to avoid unnecessary
+	 * temporary addresses being generated.
 	 */
-	if (tmp_prefered_lft <= regen_advance) {
+	age = (now - tmp_tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
+	if (tmp_prefered_lft <= regen_advance + age) {
 		in6_ifa_put(ifp);
 		in6_dev_put(idev);
 		ret = -1;
diff -ruw linux-3.11.10/net/ipv6/datagram.c linux-3.11.10-fbx/net/ipv6/datagram.c
--- linux-3.11.10/net/ipv6/datagram.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/datagram.c	2014-01-17 19:14:18.814220810 +0100
@@ -318,7 +318,7 @@
 /*
  *	Handle MSG_ERRQUEUE
  */
-int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
+int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sock_exterr_skb *serr;
@@ -369,6 +369,7 @@
 					       &sin->sin6_addr);
 			sin->sin6_scope_id = 0;
 		}
+		*addr_len = sizeof(*sin);
 	}
 
 	memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
@@ -377,6 +378,7 @@
 	if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
 		sin->sin6_family = AF_INET6;
 		sin->sin6_flowinfo = 0;
+		sin->sin6_port = 0;
 		if (skb->protocol == htons(ETH_P_IPV6)) {
 			sin->sin6_addr = ipv6_hdr(skb)->saddr;
 			if (np->rxopt.all)
@@ -423,7 +425,8 @@
 /*
  *	Handle IPV6_RECVPATHMTU
  */
-int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
+int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
+		     int *addr_len)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sk_buff *skb;
@@ -457,6 +460,7 @@
 		sin->sin6_port = 0;
 		sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id;
 		sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr;
+		*addr_len = sizeof(*sin);
 	}
 
 	put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info);
diff -ruw linux-3.11.10/net/ipv6/exthdrs_core.c linux-3.11.10-fbx/net/ipv6/exthdrs_core.c
--- linux-3.11.10/net/ipv6/exthdrs_core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/exthdrs_core.c	2014-07-01 16:22:13.218330008 +0200
@@ -212,7 +212,7 @@
 		found = (nexthdr == target);
 
 		if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
-			if (target < 0)
+			if (target < 0 || found)
 				break;
 			return -ENOENT;
 		}
diff -ruw linux-3.11.10/net/ipv6/exthdrs_offload.c linux-3.11.10-fbx/net/ipv6/exthdrs_offload.c
--- linux-3.11.10/net/ipv6/exthdrs_offload.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/exthdrs_offload.c	2014-07-01 16:22:13.218330008 +0200
@@ -25,11 +25,11 @@
 	int ret;
 
 	ret = inet6_add_offload(&rthdr_offload, IPPROTO_ROUTING);
-	if (!ret)
+	if (ret)
 		goto out;
 
 	ret = inet6_add_offload(&dstopt_offload, IPPROTO_DSTOPTS);
-	if (!ret)
+	if (ret)
 		goto out_rt;
 
 out:
diff -ruw linux-3.11.10/net/ipv6/icmp.c linux-3.11.10-fbx/net/ipv6/icmp.c
--- linux-3.11.10/net/ipv6/icmp.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/icmp.c	2014-07-01 16:22:13.218330008 +0200
@@ -516,7 +516,7 @@
 			      np->tclass, NULL, &fl6, (struct rt6_info *)dst,
 			      MSG_DONTWAIT, np->dontfrag);
 	if (err) {
-		ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
+		ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
 		ip6_flush_pending_frames(sk);
 	} else {
 		err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
diff -ruw linux-3.11.10/net/ipv6/ip6_fib.c linux-3.11.10-fbx/net/ipv6/ip6_fib.c
--- linux-3.11.10/net/ipv6/ip6_fib.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/ip6_fib.c	2014-07-01 16:22:13.218330008 +0200
@@ -1418,7 +1418,7 @@
 
 				if (w->skip) {
 					w->skip--;
-					continue;
+					goto skip;
 				}
 
 				err = w->func(w);
@@ -1428,6 +1428,7 @@
 				w->count++;
 				continue;
 			}
+skip:
 			w->state = FWS_U;
 		case FWS_U:
 			if (fn == w->root)
diff -ruw linux-3.11.10/net/ipv6/ip6_flowlabel.c linux-3.11.10-fbx/net/ipv6/ip6_flowlabel.c
--- linux-3.11.10/net/ipv6/ip6_flowlabel.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/ip6_flowlabel.c	2014-01-17 19:14:18.814220810 +0100
@@ -453,8 +453,10 @@
 	if (room > FL_MAX_SIZE - FL_MAX_PER_SOCK)
 		return 0;
 
+	rcu_read_lock_bh();
 	for_each_sk_fl_rcu(np, sfl)
 		count++;
+	rcu_read_unlock_bh();
 
 	if (room <= 0 ||
 	    ((count >= FL_MAX_PER_SOCK ||
diff -ruw linux-3.11.10/net/ipv6/ip6_input.c linux-3.11.10-fbx/net/ipv6/ip6_input.c
--- linux-3.11.10/net/ipv6/ip6_input.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/ip6_input.c	2014-05-09 14:12:54.384546161 +0200
@@ -49,7 +49,7 @@
 
 int ip6_rcv_finish(struct sk_buff *skb)
 {
-	if (sysctl_ip_early_demux && !skb_dst(skb)) {
+	if (sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) {
 		const struct inet6_protocol *ipprot;
 
 		ipprot = rcu_dereference(inet6_protos[ipv6_hdr(skb)->nexthdr]);
diff -ruw linux-3.11.10/net/ipv6/ip6_output.c linux-3.11.10-fbx/net/ipv6/ip6_output.c
--- linux-3.11.10/net/ipv6/ip6_output.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/ip6_output.c	2014-07-01 16:22:13.218330008 +0200
@@ -141,7 +141,7 @@
 	}
 	rcu_read_unlock_bh();
 
-	IP6_INC_STATS_BH(dev_net(dst->dev),
+	IP6_INC_STATS(dev_net(dst->dev),
 			 ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
 	kfree_skb(skb);
 	return -EINVAL;
@@ -150,7 +150,8 @@
 static int ip6_finish_output(struct sk_buff *skb)
 {
 	if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
-	    dst_allfrag(skb_dst(skb)))
+	    dst_allfrag(skb_dst(skb)) ||
+	    (IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size))
 		return ip6_fragment(skb, ip6_finish_output2);
 	else
 		return ip6_finish_output2(skb);
@@ -345,6 +346,24 @@
 	return dst_output(skb);
 }
 
+static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
+{
+	if (skb->len <= mtu)
+		return false;
+
+	/* ipv6 conntrack defrag sets max_frag_size + local_df */
+	if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)
+		return true;
+
+	if (skb->local_df)
+		return false;
+
+	if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu)
+		return false;
+
+	return true;
+}
+
 int ip6_forward(struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb_dst(skb);
@@ -467,8 +486,7 @@
 	if (mtu < IPV6_MIN_MTU)
 		mtu = IPV6_MIN_MTU;
 
-	if ((!skb->local_df && skb->len > mtu && !skb_is_gso(skb)) ||
-	    (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)) {
+	if (ip6_pkt_too_big(skb, mtu)) {
 		/* Again, force OUTPUT device used as source address */
 		skb->dev = dst->dev;
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
@@ -1096,21 +1114,19 @@
 				unsigned int fragheaderlen,
 				struct sk_buff *skb,
 				struct rt6_info *rt,
-				bool pmtuprobe)
+				unsigned int orig_mtu)
 {
 	if (!(rt->dst.flags & DST_XFRM_TUNNEL)) {
 		if (skb == NULL) {
 			/* first fragment, reserve header_len */
-			*mtu = *mtu - rt->dst.header_len;
+			*mtu = orig_mtu - rt->dst.header_len;
 
 		} else {
 			/*
 			 * this fragment is not first, the headers
 			 * space is regarded as data space.
 			 */
-			*mtu = min(*mtu, pmtuprobe ?
-				   rt->dst.dev->mtu :
-				   dst_mtu(rt->dst.path));
+			*mtu = orig_mtu;
 		}
 		*maxfraglen = ((*mtu - fragheaderlen) & ~7)
 			      + fragheaderlen - sizeof(struct frag_hdr);
@@ -1127,7 +1143,7 @@
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct inet_cork *cork;
 	struct sk_buff *skb, *skb_prev = NULL;
-	unsigned int maxfraglen, fragheaderlen, mtu;
+	unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu;
 	int exthdrlen;
 	int dst_exthdrlen;
 	int hh_len;
@@ -1209,6 +1225,7 @@
 		dst_exthdrlen = 0;
 		mtu = cork->fragsize;
 	}
+	orig_mtu = mtu;
 
 	hh_len = LL_RESERVED_SPACE(rt->dst.dev);
 
@@ -1288,8 +1305,7 @@
 			if (skb == NULL || skb_prev == NULL)
 				ip6_append_data_mtu(&mtu, &maxfraglen,
 						    fragheaderlen, skb, rt,
-						    np->pmtudisc ==
-						    IPV6_PMTUDISC_PROBE);
+						    orig_mtu);
 
 			skb_prev = skb;
 
@@ -1545,8 +1561,8 @@
 	if (proto == IPPROTO_ICMPV6) {
 		struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
 
-		ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type);
-		ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
+		ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type);
+		ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
 	}
 
 	err = ip6_local_out(skb);
diff -ruw linux-3.11.10/net/ipv6/mcast.c linux-3.11.10-fbx/net/ipv6/mcast.c
--- linux-3.11.10/net/ipv6/mcast.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/mcast.c	2014-07-01 16:22:13.218330008 +0200
@@ -1448,11 +1448,12 @@
 		      dst_output);
 out:
 	if (!err) {
-		ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT);
-		ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
-		IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
-	} else
-		IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS);
+		ICMP6MSGOUT_INC_STATS(net, idev, ICMPV6_MLD2_REPORT);
+		ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
+		IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
+	} else {
+		IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
+	}
 
 	rcu_read_unlock();
 	return;
diff -ruw linux-3.11.10/net/ipv6/netfilter/ip6_tables.c linux-3.11.10-fbx/net/ipv6/netfilter/ip6_tables.c
--- linux-3.11.10/net/ipv6/netfilter/ip6_tables.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/netfilter/ip6_tables.c	2014-07-01 16:22:13.222330025 +0200
@@ -1236,8 +1236,10 @@
 
 	xt_free_table_info(oldinfo);
 	if (copy_to_user(counters_ptr, counters,
-			 sizeof(struct xt_counters) * num_counters) != 0)
-		ret = -EFAULT;
+			 sizeof(struct xt_counters) * num_counters) != 0) {
+		/* Silent error, can't fail, new table is already in place */
+		net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n");
+	}
 	vfree(counters);
 	xt_table_unlock(t);
 	return ret;
diff -ruw linux-3.11.10/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c linux-3.11.10-fbx/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
--- linux-3.11.10/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c	2014-01-17 19:14:18.814220810 +0100
@@ -172,63 +172,13 @@
 	return nf_conntrack_confirm(skb);
 }
 
-static unsigned int __ipv6_conntrack_in(struct net *net,
-					unsigned int hooknum,
-					struct sk_buff *skb,
-					const struct net_device *in,
-					const struct net_device *out,
-					int (*okfn)(struct sk_buff *))
-{
-	struct sk_buff *reasm = skb->nfct_reasm;
-	const struct nf_conn_help *help;
-	struct nf_conn *ct;
-	enum ip_conntrack_info ctinfo;
-
-	/* This packet is fragmented and has reassembled packet. */
-	if (reasm) {
-		/* Reassembled packet isn't parsed yet ? */
-		if (!reasm->nfct) {
-			unsigned int ret;
-
-			ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm);
-			if (ret != NF_ACCEPT)
-				return ret;
-		}
-
-		/* Conntrack helpers need the entire reassembled packet in the
-		 * POST_ROUTING hook. In case of unconfirmed connections NAT
-		 * might reassign a helper, so the entire packet is also
-		 * required.
-		 */
-		ct = nf_ct_get(reasm, &ctinfo);
-		if (ct != NULL && !nf_ct_is_untracked(ct)) {
-			help = nfct_help(ct);
-			if ((help && help->helper) || !nf_ct_is_confirmed(ct)) {
-				nf_conntrack_get_reasm(reasm);
-				NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm,
-					       (struct net_device *)in,
-					       (struct net_device *)out,
-					       okfn, NF_IP6_PRI_CONNTRACK + 1);
-				return NF_DROP_ERR(-ECANCELED);
-			}
-		}
-
-		nf_conntrack_get(reasm->nfct);
-		skb->nfct = reasm->nfct;
-		skb->nfctinfo = reasm->nfctinfo;
-		return NF_ACCEPT;
-	}
-
-	return nf_conntrack_in(net, PF_INET6, hooknum, skb);
-}
-
 static unsigned int ipv6_conntrack_in(unsigned int hooknum,
 				      struct sk_buff *skb,
 				      const struct net_device *in,
 				      const struct net_device *out,
 				      int (*okfn)(struct sk_buff *))
 {
-	return __ipv6_conntrack_in(dev_net(in), hooknum, skb, in, out, okfn);
+	return nf_conntrack_in(dev_net(in), PF_INET6, hooknum, skb);
 }
 
 static unsigned int ipv6_conntrack_local(unsigned int hooknum,
@@ -242,7 +192,7 @@
 		net_notice_ratelimited("ipv6_conntrack_local: packet too short\n");
 		return NF_ACCEPT;
 	}
-	return __ipv6_conntrack_in(dev_net(out), hooknum, skb, in, out, okfn);
+	return nf_conntrack_in(dev_net(out), PF_INET6, hooknum, skb);
 }
 
 static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
diff -ruw linux-3.11.10/net/ipv6/netfilter/nf_conntrack_reasm.c linux-3.11.10-fbx/net/ipv6/netfilter/nf_conntrack_reasm.c
--- linux-3.11.10/net/ipv6/netfilter/nf_conntrack_reasm.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/netfilter/nf_conntrack_reasm.c	2014-01-17 19:14:18.814220810 +0100
@@ -621,31 +621,16 @@
 	return skb;
 }
 
-void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
-			struct net_device *in, struct net_device *out,
-			int (*okfn)(struct sk_buff *))
+void nf_ct_frag6_consume_orig(struct sk_buff *skb)
 {
 	struct sk_buff *s, *s2;
-	unsigned int ret = 0;
 
 	for (s = NFCT_FRAG6_CB(skb)->orig; s;) {
-		nf_conntrack_put_reasm(s->nfct_reasm);
-		nf_conntrack_get_reasm(skb);
-		s->nfct_reasm = skb;
-
 		s2 = s->next;
 		s->next = NULL;
-
-		if (ret != -ECANCELED)
-			ret = NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s,
-					     in, out, okfn,
-					     NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
-		else
-			kfree_skb(s);
-
+		consume_skb(s);
 		s = s2;
 	}
-	nf_conntrack_put_reasm(skb);
 }
 
 static int nf_ct_net_init(struct net *net)
diff -ruw linux-3.11.10/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c linux-3.11.10-fbx/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
--- linux-3.11.10/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c	2014-01-17 19:14:18.814220810 +0100
@@ -75,8 +75,11 @@
 	if (reasm == skb)
 		return NF_ACCEPT;
 
-	nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
-			   (struct net_device *)out, okfn);
+	nf_ct_frag6_consume_orig(reasm);
+
+	NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm,
+		       (struct net_device *) in, (struct net_device *) out,
+		       okfn, NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
 
 	return NF_STOLEN;
 }
diff -ruw linux-3.11.10/net/ipv6/netfilter.c linux-3.11.10-fbx/net/ipv6/netfilter.c
--- linux-3.11.10/net/ipv6/netfilter.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/netfilter.c	2014-07-01 16:22:13.222330025 +0200
@@ -30,13 +30,15 @@
 		.daddr = iph->daddr,
 		.saddr = iph->saddr,
 	};
+	int err;
 
 	dst = ip6_route_output(net, skb->sk, &fl6);
-	if (dst->error) {
+	err = dst->error;
+	if (err) {
 		IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
 		LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
 		dst_release(dst);
-		return dst->error;
+		return err;
 	}
 
 	/* Drop old route. */
diff -ruw linux-3.11.10/net/ipv6/output_core.c linux-3.11.10-fbx/net/ipv6/output_core.c
--- linux-3.11.10/net/ipv6/output_core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/output_core.c	2014-08-22 15:47:22.160063265 +0200
@@ -9,7 +9,7 @@
 void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
 {
 	static atomic_t ipv6_fragmentation_id;
-	int old, new;
+	int ident;
 
 #if IS_ENABLED(CONFIG_IPV6)
 	if (rt && !(rt->dst.flags & DST_NOPEER)) {
@@ -25,13 +25,8 @@
 		}
 	}
 #endif
-	do {
-		old = atomic_read(&ipv6_fragmentation_id);
-		new = old + 1;
-		if (!new)
-			new = 1;
-	} while (atomic_cmpxchg(&ipv6_fragmentation_id, old, new) != old);
-	fhdr->identification = htonl(new);
+	ident = atomic_inc_return(&ipv6_fragmentation_id);
+	fhdr->identification = htonl(ident);
 }
 EXPORT_SYMBOL(ipv6_select_ident);
 
diff -ruw linux-3.11.10/net/ipv6/ping.c linux-3.11.10-fbx/net/ipv6/ping.c
--- linux-3.11.10/net/ipv6/ping.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/ping.c	2014-07-01 16:22:13.222330025 +0200
@@ -57,7 +57,8 @@
 
 
 /* Compatibility glue so we can support IPv6 when it's compiled as a module */
-static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
+static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
+				 int *addr_len)
 {
 	return -EAFNOSUPPORT;
 }
@@ -181,7 +182,7 @@
 			      MSG_DONTWAIT, np->dontfrag);
 
 	if (err) {
-		ICMP6_INC_STATS_BH(sock_net(sk), rt->rt6i_idev,
+		ICMP6_INC_STATS(sock_net(sk), rt->rt6i_idev,
 				   ICMP6_MIB_OUTERRORS);
 		ip6_flush_pending_frames(sk);
 	} else {
diff -ruw linux-3.11.10/net/ipv6/raw.c linux-3.11.10-fbx/net/ipv6/raw.c
--- linux-3.11.10/net/ipv6/raw.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/raw.c	2014-01-17 19:14:18.814220810 +0100
@@ -459,14 +459,11 @@
 	if (flags & MSG_OOB)
 		return -EOPNOTSUPP;
 
-	if (addr_len)
-		*addr_len=sizeof(*sin6);
-
 	if (flags & MSG_ERRQUEUE)
-		return ipv6_recv_error(sk, msg, len);
+		return ipv6_recv_error(sk, msg, len, addr_len);
 
 	if (np->rxpmtu && np->rxopt.bits.rxpmtu)
-		return ipv6_recv_rxpmtu(sk, msg, len);
+		return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
 
 	skb = skb_recv_datagram(sk, flags, noblock, &err);
 	if (!skb)
@@ -500,6 +497,7 @@
 		sin6->sin6_flowinfo = 0;
 		sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
 							  IP6CB(skb)->iif);
+		*addr_len = sizeof(*sin6);
 	}
 
 	sock_recv_ts_and_drops(msg, sk, skb);
diff -ruw linux-3.11.10/net/ipv6/route.c linux-3.11.10-fbx/net/ipv6/route.c
--- linux-3.11.10/net/ipv6/route.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/route.c	2014-07-01 16:22:13.222330025 +0200
@@ -84,6 +84,8 @@
 
 static int		ip6_pkt_discard(struct sk_buff *skb);
 static int		ip6_pkt_discard_out(struct sk_buff *skb);
+static int		ip6_pkt_prohibit(struct sk_buff *skb);
+static int		ip6_pkt_prohibit_out(struct sk_buff *skb);
 static void		ip6_link_failure(struct sk_buff *skb);
 static void		ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
 					   struct sk_buff *skb, u32 mtu);
@@ -234,9 +236,6 @@
 
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 
-static int ip6_pkt_prohibit(struct sk_buff *skb);
-static int ip6_pkt_prohibit_out(struct sk_buff *skb);
-
 static const struct rt6_info ip6_prohibit_entry_template = {
 	.dst = {
 		.__refcnt	= ATOMIC_INIT(1),
@@ -732,8 +731,11 @@
 		prefix = &prefix_buf;
 	}
 
-	rt = rt6_get_route_info(net, prefix, rinfo->prefix_len, gwaddr,
-				dev->ifindex);
+	if (rinfo->prefix_len == 0)
+		rt = rt6_get_dflt_router(gwaddr, dev);
+	else
+		rt = rt6_get_route_info(net, prefix, rinfo->prefix_len,
+					gwaddr, dev->ifindex);
 
 	if (rt && !lifetime) {
 		ip6_del_rt(rt);
@@ -1259,7 +1261,7 @@
 	unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
 
 	if (mtu)
-		return mtu;
+		goto out;
 
 	mtu = IPV6_MIN_MTU;
 
@@ -1269,7 +1271,8 @@
 		mtu = idev->cnf.mtu6;
 	rcu_read_unlock();
 
-	return mtu;
+out:
+	return min_t(unsigned int, mtu, IP6_MAX_MTU);
 }
 
 static struct dst_entry *icmp6_dst_gc_list;
@@ -1449,7 +1452,7 @@
 	if (!table)
 		goto out;
 
-	rt = ip6_dst_alloc(net, NULL, DST_NOCOUNT, table);
+	rt = ip6_dst_alloc(net, NULL, (cfg->fc_flags & RTF_ADDRCONF) ? 0 : DST_NOCOUNT, table);
 
 	if (!rt) {
 		err = -ENOMEM;
@@ -1518,21 +1521,24 @@
 				goto out;
 			}
 		}
-		rt->dst.output = ip6_pkt_discard_out;
-		rt->dst.input = ip6_pkt_discard;
 		rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
 		switch (cfg->fc_type) {
 		case RTN_BLACKHOLE:
 			rt->dst.error = -EINVAL;
+			rt->dst.output = dst_discard;
+			rt->dst.input = dst_discard;
 			break;
 		case RTN_PROHIBIT:
 			rt->dst.error = -EACCES;
+			rt->dst.output = ip6_pkt_prohibit_out;
+			rt->dst.input = ip6_pkt_prohibit;
 			break;
 		case RTN_THROW:
-			rt->dst.error = -EAGAIN;
-			break;
 		default:
-			rt->dst.error = -ENETUNREACH;
+			rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN
+					: -ENETUNREACH;
+			rt->dst.output = ip6_pkt_discard_out;
+			rt->dst.input = ip6_pkt_discard;
 			break;
 		}
 		goto install_route;
@@ -1856,8 +1862,6 @@
 		else
 			rt->rt6i_gateway = *dest;
 		rt->rt6i_flags = ort->rt6i_flags;
-		if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ==
-		    (RTF_DEFAULT | RTF_ADDRCONF))
 			rt6_set_from(rt, ort);
 		rt->rt6i_metric = 0;
 
@@ -2097,8 +2101,6 @@
 	return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
 }
 
-#ifdef CONFIG_IPV6_MULTIPLE_TABLES
-
 static int ip6_pkt_prohibit(struct sk_buff *skb)
 {
 	return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES);
@@ -2110,8 +2112,6 @@
 	return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
 }
 
-#endif
-
 /*
  *	Allocate a dst for local (unicast / anycast) address.
  */
@@ -2121,12 +2121,10 @@
 				    bool anycast)
 {
 	struct net *net = dev_net(idev->dev);
-	struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL);
-
-	if (!rt) {
-		net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n");
+	struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev,
+					    DST_NOCOUNT, NULL);
+	if (!rt)
 		return ERR_PTR(-ENOMEM);
-	}
 
 	in6_dev_hold(idev);
 
diff -ruw linux-3.11.10/net/ipv6/tcpv6_offload.c linux-3.11.10-fbx/net/ipv6/tcpv6_offload.c
--- linux-3.11.10/net/ipv6/tcpv6_offload.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/tcpv6_offload.c	2014-01-17 19:14:18.818220810 +0100
@@ -37,34 +37,32 @@
 {
 	const struct ipv6hdr *iph = skb_gro_network_header(skb);
 	__wsum wsum;
-	__sum16 sum;
+
+	/* Don't bother verifying checksum if we're going to flush anyway. */
+	if (NAPI_GRO_CB(skb)->flush)
+		goto skip_csum;
+
+	wsum = skb->csum;
 
 	switch (skb->ip_summed) {
+	case CHECKSUM_NONE:
+		wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
+				    wsum);
+
+		/* fall through */
+
 	case CHECKSUM_COMPLETE:
 		if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr,
-				  skb->csum)) {
+				  wsum)) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			break;
 		}
-flush:
+
 		NAPI_GRO_CB(skb)->flush = 1;
 		return NULL;
-
-	case CHECKSUM_NONE:
-		wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr,
-						    skb_gro_len(skb),
-						    IPPROTO_TCP, 0));
-		sum = csum_fold(skb_checksum(skb,
-					     skb_gro_offset(skb),
-					     skb_gro_len(skb),
-					     wsum));
-		if (sum)
-			goto flush;
-
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
-		break;
 	}
 
+skip_csum:
 	return tcp_gro_receive(head, skb);
 }
 
diff -ruw linux-3.11.10/net/ipv6/udp.c linux-3.11.10-fbx/net/ipv6/udp.c
--- linux-3.11.10/net/ipv6/udp.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/udp.c	2014-01-17 19:14:18.818220810 +0100
@@ -374,14 +374,11 @@
 	int is_udp4;
 	bool slow;
 
-	if (addr_len)
-		*addr_len = sizeof(struct sockaddr_in6);
-
 	if (flags & MSG_ERRQUEUE)
-		return ipv6_recv_error(sk, msg, len);
+		return ipv6_recv_error(sk, msg, len, addr_len);
 
 	if (np->rxpmtu && np->rxopt.bits.rxpmtu)
-		return ipv6_recv_rxpmtu(sk, msg, len);
+		return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
 
 try_again:
 	skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
@@ -462,7 +459,7 @@
 				ipv6_iface_scope_id(&sin6->sin6_addr,
 						    IP6CB(skb)->iif);
 		}
-
+		*addr_len = sizeof(*sin6);
 	}
 	if (is_udp4) {
 		if (inet->cmsg_flags)
@@ -785,6 +782,60 @@
 	return 0;
 }
 
+/*
+ * Note: called only from the BH handler context,
+ * so we don't need to lock the hashes.
+ */
+static int __udp6_lib_uc_conflict_deliver(struct net *net, struct sk_buff *skb,
+		const struct in6_addr *saddr, const struct in6_addr *daddr,
+		struct udp_table *udptable)
+{
+	struct sock *sk, *stack[256 / sizeof(struct sock *)];
+	const struct udphdr *uh = udp_hdr(skb);
+	struct udp_hslot *hslot = udp_hashslot(udptable, net, ntohs(uh->dest));
+	int dif;
+	unsigned int i, count = 0, non_dup_count = 0;
+
+	spin_lock(&hslot->lock);
+	sk = sk_nulls_head(&hslot->head);
+	dif = inet6_iif(skb);
+	sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif);
+	while (sk) {
+		if (!sock_flag(sk, SOCK_UDP_DUP_UNICAST)) {
+			if (!non_dup_count)
+				stack[count++] = sk;
+			non_dup_count = 1;
+		} else
+			stack[count++] = sk;
+
+		sk = udp_v6_mcast_next(net, sk_nulls_next(sk), uh->dest, daddr,
+				       uh->source, saddr, dif);
+		if (unlikely(count == ARRAY_SIZE(stack))) {
+			if (!sk)
+				break;
+			flush_stack(stack, count, skb, ~0);
+			count = 0;
+		}
+	}
+	/*
+	 * before releasing the lock, we must take reference on sockets
+	 */
+	for (i = 0; i < count; i++)
+		sock_hold(stack[i]);
+
+	spin_unlock(&hslot->lock);
+
+	if (count) {
+		flush_stack(stack, count, skb, count - 1);
+
+		for (i = 0; i < count; i++)
+			sock_put(stack[i]);
+	} else {
+		kfree_skb(skb);
+	}
+	return 0;
+}
+
 int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		   int proto)
 {
@@ -845,6 +896,13 @@
 		int ret;
 
 		sk_mark_napi_id(sk, skb);
+		if (sk->sk_reuse_conflict) {
+			sock_put(sk);
+			return __udp6_lib_uc_conflict_deliver(net, skb,
+							      saddr, daddr,
+							      udptable);
+		}
+
 		ret = udpv6_queue_rcv_skb(sk, skb);
 		sock_put(sk);
 
diff -ruw linux-3.11.10/net/ipv6/udp_offload.c linux-3.11.10-fbx/net/ipv6/udp_offload.c
--- linux-3.11.10/net/ipv6/udp_offload.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/ipv6/udp_offload.c	2014-07-01 16:22:13.222330025 +0200
@@ -86,7 +86,7 @@
 
 	/* Check if there is enough headroom to insert fragment header. */
 	tnl_hlen = skb_tnl_header_len(skb);
-	if (skb_headroom(skb) < (tnl_hlen + frag_hdr_sz)) {
+	if (skb_mac_header(skb) < skb->head + tnl_hlen + frag_hdr_sz) {
 		if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz))
 			goto out;
 	}
@@ -109,7 +109,7 @@
 	fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen);
 	fptr->nexthdr = nexthdr;
 	fptr->reserved = 0;
-	ipv6_select_ident(fptr, (struct rt6_info *)skb_dst(skb));
+	fptr->identification = skb_shinfo(skb)->ip6_frag_id;
 
 	/* Fragment the skb. ipv6 header and the remaining fields of the
 	 * fragment header are updated in ipv6_gso_segment()
diff -ruw linux-3.11.10/net/Kconfig linux-3.11.10-fbx/net/Kconfig
--- linux-3.11.10/net/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/Kconfig	2013-12-04 14:33:29.463479140 +0100
@@ -46,6 +46,18 @@
 
 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
+
 source "net/packet/Kconfig"
 source "net/unix/Kconfig"
 source "net/xfrm/Kconfig"
@@ -199,6 +211,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.11.10/net/key/af_key.c linux-3.11.10-fbx/net/key/af_key.c
--- linux-3.11.10/net/key/af_key.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/key/af_key.c	2014-01-17 19:14:18.818220810 +0100
@@ -3623,7 +3623,6 @@
 	if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
 		goto out;
 
-	msg->msg_namelen = 0;
 	skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
 	if (skb == NULL)
 		goto out;
diff -ruw linux-3.11.10/net/mac80211/Kconfig linux-3.11.10-fbx/net/mac80211/Kconfig
--- linux-3.11.10/net/mac80211/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/mac80211/Kconfig	2013-12-17 18:03:43.099570858 +0100
@@ -4,6 +4,7 @@
 	select CRYPTO
 	select CRYPTO_ARC4
 	select CRYPTO_AES
+	select CRYPTO_CCM
 	select CRC32
 	select AVERAGE
 	---help---
@@ -257,6 +258,17 @@
 	  mesh network).
 
 	  Do not select this option.
+
+config MAC80211_MESH_CSA_DEBUG
+	bool "Verbose mesh channel switch debugging"
+	depends on MAC80211_DEBUG_MENU
+	depends on MAC80211_MESH
+	---help---
+	  Selecting this option causes mac80211 to print out very verbose mesh
+	  channel switch debugging messages (when mac80211 is taking part in a
+	  mesh network).
+
+	  Do not select this option.
 
 config MAC80211_MESH_PS_DEBUG
 	bool "Verbose mesh powersave debugging"
diff -ruw linux-3.11.10/net/Makefile linux-3.11.10-fbx/net/Makefile
--- linux-3.11.10/net/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/Makefile	2013-12-04 14:33:29.463479140 +0100
@@ -38,6 +38,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_PHONET)		+= phonet/
 ifneq ($(CONFIG_VLAN_8021Q),)
diff -ruw linux-3.11.10/net/netfilter/core.c linux-3.11.10-fbx/net/netfilter/core.c
--- linux-3.11.10/net/netfilter/core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/netfilter/core.c	2013-12-04 14:33:32.243479185 +0100
@@ -163,7 +163,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.11.10/net/netfilter/nf_conntrack_core.c linux-3.11.10-fbx/net/netfilter/nf_conntrack_core.c
--- linux-3.11.10/net/netfilter/nf_conntrack_core.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/netfilter/nf_conntrack_core.c	2013-12-04 14:33:32.531479189 +0100
@@ -196,6 +196,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)
 {
@@ -207,6 +211,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.11.10/net/netfilter/nf_conntrack_proto_tcp.c linux-3.11.10-fbx/net/netfilter/nf_conntrack_proto_tcp.c
--- linux-3.11.10/net/netfilter/nf_conntrack_proto_tcp.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/netfilter/nf_conntrack_proto_tcp.c	2013-12-04 14:33:32.651479191 +0100
@@ -1068,6 +1068,18 @@
 	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,
+			  tcp_get_timeouts(nf_ct_net(ct)));
+}
+#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, unsigned int *timeouts)
diff -ruw linux-3.11.10/net/netfilter/nf_conntrack_proto_udp.c linux-3.11.10-fbx/net/netfilter/nf_conntrack_proto_udp.c
--- linux-3.11.10/net/netfilter/nf_conntrack_proto_udp.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/netfilter/nf_conntrack_proto_udp.c	2013-12-04 14:33:32.651479191 +0100
@@ -100,6 +100,17 @@
 	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,
+			  udp_get_timeouts(nf_ct_net(ct)));
+}
+#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, unsigned int *timeouts)
diff -ruw linux-3.11.10/net/netfilter/xt_owner.c linux-3.11.10-fbx/net/netfilter/xt_owner.c
--- linux-3.11.10/net/netfilter/xt_owner.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/netfilter/xt_owner.c	2013-12-04 14:33:32.887479195 +0100
@@ -28,6 +28,63 @@
 	return 0;
 }
 
+static int __owner_match_simple_gid(gid_t gid, kgid_t gid_min, kgid_t gid_max)
+{
+	if (gid_gte(gid, gid_min) && gid_lte(gid, 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,
+				       kgid_t gid_min, kgid_t gid_max)
+{
+	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],
+					     gid_min, gid_max)) {
+				return 1;
+			}
+			count -= cp_count;
+		}
+	}
+	return 0;
+}
+
+static int owner_match_gid(const struct file *filp,
+			   const struct xt_owner_match_info *info)
+{
+	kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min);
+	kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max);
+
+	/*
+	 * 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, gid_min, gid_max))
+		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,
+					gid_min, gid_max))
+		return 1;
+
+	return 0;
+}
+
 static bool
 owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
 {
@@ -58,10 +115,7 @@
 	}
 
 	if (info->match & XT_OWNER_GID) {
-		kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min);
-		kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max);
-		if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
-		     gid_lte(filp->f_cred->fsgid, gid_max)) ^
+		if (owner_match_gid(filp, info) ^
 		    !(info->invert & XT_OWNER_GID))
 			return false;
 	}
diff -ruw linux-3.11.10/net/netlink/af_netlink.c linux-3.11.10-fbx/net/netlink/af_netlink.c
--- linux-3.11.10/net/netlink/af_netlink.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/netlink/af_netlink.c	2014-08-22 15:47:22.164063285 +0200
@@ -1334,7 +1334,74 @@
 	return err;
 }
 
-static inline int netlink_capable(const struct socket *sock, unsigned int flag)
+/**
+ * __netlink_ns_capable - General netlink message capability test
+ * @nsp: NETLINK_CB of the socket buffer holding a netlink command from userspace.
+ * @user_ns: The user namespace of the capability to use
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket we received the message
+ * from had when the netlink socket was created and the sender of the
+ * message has has the capability @cap in the user namespace @user_ns.
+ */
+bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
+			struct user_namespace *user_ns, int cap)
+{
+	return ((nsp->flags & NETLINK_SKB_DST) ||
+		file_ns_capable(nsp->sk->sk_socket->file, user_ns, cap)) &&
+		ns_capable(user_ns, cap);
+}
+EXPORT_SYMBOL(__netlink_ns_capable);
+
+/**
+ * netlink_ns_capable - General netlink message capability test
+ * @skb: socket buffer holding a netlink command from userspace
+ * @user_ns: The user namespace of the capability to use
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket we received the message
+ * from had when the netlink socket was created and the sender of the
+ * message has has the capability @cap in the user namespace @user_ns.
+ */
+bool netlink_ns_capable(const struct sk_buff *skb,
+			struct user_namespace *user_ns, int cap)
+{
+	return __netlink_ns_capable(&NETLINK_CB(skb), user_ns, cap);
+}
+EXPORT_SYMBOL(netlink_ns_capable);
+
+/**
+ * netlink_capable - Netlink global message capability test
+ * @skb: socket buffer holding a netlink command from userspace
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket we received the message
+ * from had when the netlink socket was created and the sender of the
+ * message has has the capability @cap in all user namespaces.
+ */
+bool netlink_capable(const struct sk_buff *skb, int cap)
+{
+	return netlink_ns_capable(skb, &init_user_ns, cap);
+}
+EXPORT_SYMBOL(netlink_capable);
+
+/**
+ * netlink_net_capable - Netlink network namespace message capability test
+ * @skb: socket buffer holding a netlink command from userspace
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket we received the message
+ * from had when the netlink socket was created and the sender of the
+ * message has has the capability @cap over the network namespace of
+ * the socket we received the message from.
+ */
+bool netlink_net_capable(const struct sk_buff *skb, int cap)
+{
+	return netlink_ns_capable(skb, sock_net(skb->sk)->user_ns, cap);
+}
+EXPORT_SYMBOL(netlink_net_capable);
+
+static inline int netlink_allowed(const struct socket *sock, unsigned int flag)
 {
 	return (nl_table[sock->sk->sk_protocol].flags & flag) ||
 		ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN);
@@ -1402,7 +1469,7 @@
 
 	/* Only superuser is allowed to listen multicasts */
 	if (nladdr->nl_groups) {
-		if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV))
+		if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV))
 			return -EPERM;
 		err = netlink_realloc_groups(sk);
 		if (err)
@@ -1464,7 +1531,7 @@
 		return -EINVAL;
 
 	/* Only superuser is allowed to send multicasts */
-	if (nladdr->nl_groups && !netlink_capable(sock, NL_CFG_F_NONROOT_SEND))
+	if (nladdr->nl_groups && !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
 		return -EPERM;
 
 	if (!nlk->portid)
@@ -2070,7 +2137,7 @@
 		break;
 	case NETLINK_ADD_MEMBERSHIP:
 	case NETLINK_DROP_MEMBERSHIP: {
-		if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV))
+		if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV))
 			return -EPERM;
 		err = netlink_realloc_groups(sk);
 		if (err)
@@ -2202,6 +2269,7 @@
 	struct sk_buff *skb;
 	int err;
 	struct scm_cookie scm;
+	u32 netlink_skb_flags = 0;
 
 	if (msg->msg_flags&MSG_OOB)
 		return -EOPNOTSUPP;
@@ -2221,8 +2289,9 @@
 		dst_group = ffs(addr->nl_groups);
 		err =  -EPERM;
 		if ((dst_group || dst_portid) &&
-		    !netlink_capable(sock, NL_CFG_F_NONROOT_SEND))
+		    !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
 			goto out;
+		netlink_skb_flags |= NETLINK_SKB_DST;
 	} else {
 		dst_portid = nlk->dst_portid;
 		dst_group = nlk->dst_group;
@@ -2252,6 +2321,7 @@
 	NETLINK_CB(skb).portid	= nlk->portid;
 	NETLINK_CB(skb).dst_group = dst_group;
 	NETLINK_CB(skb).creds	= siocb->scm->creds;
+	NETLINK_CB(skb).flags	= netlink_skb_flags;
 
 	err = -EFAULT;
 	if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
@@ -2317,8 +2387,6 @@
 	}
 #endif
 
-	msg->msg_namelen = 0;
-
 	copied = data_skb->len;
 	if (len < copied) {
 		msg->msg_flags |= MSG_TRUNC;
diff -ruw linux-3.11.10/net/netlink/genetlink.c linux-3.11.10-fbx/net/netlink/genetlink.c
--- linux-3.11.10/net/netlink/genetlink.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/netlink/genetlink.c	2014-08-22 15:47:22.164063285 +0200
@@ -592,7 +592,7 @@
 		return -EOPNOTSUPP;
 
 	if ((ops->flags & GENL_ADMIN_PERM) &&
-	    !capable(CAP_NET_ADMIN))
+	    !netlink_capable(skb, CAP_NET_ADMIN))
 		return -EPERM;
 
 	if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) {
diff -ruw linux-3.11.10/net/packet/af_packet.c linux-3.11.10-fbx/net/packet/af_packet.c
--- linux-3.11.10/net/packet/af_packet.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/packet/af_packet.c	2014-01-17 19:14:18.826220810 +0100
@@ -237,6 +237,30 @@
 static void __fanout_unlink(struct sock *sk, struct packet_sock *po);
 static void __fanout_link(struct sock *sk, struct packet_sock *po);
 
+static struct net_device *packet_cached_dev_get(struct packet_sock *po)
+{
+	struct net_device *dev;
+
+	rcu_read_lock();
+	dev = rcu_dereference(po->cached_dev);
+	if (likely(dev))
+		dev_hold(dev);
+	rcu_read_unlock();
+
+	return dev;
+}
+
+static void packet_cached_dev_assign(struct packet_sock *po,
+				     struct net_device *dev)
+{
+	rcu_assign_pointer(po->cached_dev, dev);
+}
+
+static void packet_cached_dev_reset(struct packet_sock *po)
+{
+	RCU_INIT_POINTER(po->cached_dev, NULL);
+}
+
 /* register_prot_hook must be invoked with the po->bind_lock held,
  * or from a context in which asynchronous accesses to the packet
  * socket is not possible (packet_create()).
@@ -244,11 +268,13 @@
 static void register_prot_hook(struct sock *sk)
 {
 	struct packet_sock *po = pkt_sk(sk);
+
 	if (!po->running) {
 		if (po->fanout)
 			__fanout_link(sk, po);
 		else
 			dev_add_pack(&po->prot_hook);
+
 		sock_hold(sk);
 		po->running = 1;
 	}
@@ -266,10 +292,12 @@
 	struct packet_sock *po = pkt_sk(sk);
 
 	po->running = 0;
+
 	if (po->fanout)
 		__fanout_unlink(sk, po);
 	else
 		__dev_remove_pack(&po->prot_hook);
+
 	__sock_put(sk);
 
 	if (sync) {
@@ -432,9 +460,9 @@
 
 	pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc;
 
-	spin_lock(&rb_queue->lock);
+	spin_lock_bh(&rb_queue->lock);
 	pkc->delete_blk_timer = 1;
-	spin_unlock(&rb_queue->lock);
+	spin_unlock_bh(&rb_queue->lock);
 
 	prb_del_retire_blk_timer(pkc);
 }
@@ -2046,7 +2074,6 @@
 	struct sk_buff *skb;
 	struct net_device *dev;
 	__be16 proto;
-	bool need_rls_dev = false;
 	int err, reserve = 0;
 	void *ph;
 	struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
@@ -2058,8 +2085,8 @@
 
 	mutex_lock(&po->pg_vec_lock);
 
-	if (saddr == NULL) {
-		dev = po->prot_hook.dev;
+	if (likely(saddr == NULL)) {
+		dev	= packet_cached_dev_get(po);
 		proto	= po->num;
 		addr	= NULL;
 	} else {
@@ -2073,19 +2100,17 @@
 		proto	= saddr->sll_protocol;
 		addr	= saddr->sll_addr;
 		dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex);
-		need_rls_dev = true;
 	}
 
 	err = -ENXIO;
 	if (unlikely(dev == NULL))
 		goto out;
-
-	reserve = dev->hard_header_len;
-
 	err = -ENETDOWN;
 	if (unlikely(!(dev->flags & IFF_UP)))
 		goto out_put;
 
+	reserve = dev->hard_header_len;
+
 	size_max = po->tx_ring.frame_size
 		- (po->tp_hdrlen - sizeof(struct sockaddr_ll));
 
@@ -2162,7 +2187,6 @@
 	__packet_set_status(po, ph, status);
 	kfree_skb(skb);
 out_put:
-	if (need_rls_dev)
 		dev_put(dev);
 out:
 	mutex_unlock(&po->pg_vec_lock);
@@ -2201,7 +2225,6 @@
 	struct sk_buff *skb;
 	struct net_device *dev;
 	__be16 proto;
-	bool need_rls_dev = false;
 	unsigned char *addr;
 	int err, reserve = 0;
 	struct virtio_net_hdr vnet_hdr = { 0 };
@@ -2216,8 +2239,8 @@
 	 *	Get and verify the address.
 	 */
 
-	if (saddr == NULL) {
-		dev = po->prot_hook.dev;
+	if (likely(saddr == NULL)) {
+		dev	= packet_cached_dev_get(po);
 		proto	= po->num;
 		addr	= NULL;
 	} else {
@@ -2229,19 +2252,17 @@
 		proto	= saddr->sll_protocol;
 		addr	= saddr->sll_addr;
 		dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex);
-		need_rls_dev = true;
 	}
 
 	err = -ENXIO;
-	if (dev == NULL)
+	if (unlikely(dev == NULL))
 		goto out_unlock;
-	if (sock->type == SOCK_RAW)
-		reserve = dev->hard_header_len;
-
 	err = -ENETDOWN;
-	if (!(dev->flags & IFF_UP))
+	if (unlikely(!(dev->flags & IFF_UP)))
 		goto out_unlock;
 
+	if (sock->type == SOCK_RAW)
+		reserve = dev->hard_header_len;
 	if (po->has_vnet_hdr) {
 		vnet_hdr_len = sizeof(vnet_hdr);
 
@@ -2375,7 +2396,6 @@
 	if (err > 0 && (err = net_xmit_errno(err)) != 0)
 		goto out_unlock;
 
-	if (need_rls_dev)
 		dev_put(dev);
 
 	return len;
@@ -2383,7 +2403,7 @@
 out_free:
 	kfree_skb(skb);
 out_unlock:
-	if (dev && need_rls_dev)
+	if (dev)
 		dev_put(dev);
 out:
 	return err;
@@ -2428,6 +2448,8 @@
 
 	spin_lock(&po->bind_lock);
 	unregister_prot_hook(sk, false);
+	packet_cached_dev_reset(po);
+
 	if (po->prot_hook.dev) {
 		dev_put(po->prot_hook.dev);
 		po->prot_hook.dev = NULL;
@@ -2483,14 +2505,17 @@
 
 	spin_lock(&po->bind_lock);
 	unregister_prot_hook(sk, true);
+
 	po->num = protocol;
 	po->prot_hook.type = protocol;
 	if (po->prot_hook.dev)
 		dev_put(po->prot_hook.dev);
-	po->prot_hook.dev = dev;
 
+	po->prot_hook.dev = dev;
 	po->ifindex = dev ? dev->ifindex : 0;
 
+	packet_cached_dev_assign(po, dev);
+
 	if (protocol == 0)
 		goto out_unlock;
 
@@ -2604,6 +2629,8 @@
 	sk->sk_family = PF_PACKET;
 	po->num = proto;
 
+	packet_cached_dev_reset(po);
+
 	sk->sk_destruct = packet_sock_destruct;
 	sk_refcnt_debug_inc(sk);
 
@@ -2694,7 +2721,6 @@
 	struct sock *sk = sock->sk;
 	struct sk_buff *skb;
 	int copied, err;
-	struct sockaddr_ll *sll;
 	int vnet_hdr_len = 0;
 
 	err = -EINVAL;
@@ -2777,22 +2803,10 @@
 			goto out_free;
 	}
 
-	/*
-	 *	If the address length field is there to be filled in, we fill
-	 *	it in now.
+	/* You lose any data beyond the buffer you gave. If it worries
+	 * a user program they can ask the device for its MTU
+	 * anyway.
 	 */
-
-	sll = &PACKET_SKB_CB(skb)->sa.ll;
-	if (sock->type == SOCK_PACKET)
-		msg->msg_namelen = sizeof(struct sockaddr_pkt);
-	else
-		msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
-
-	/*
-	 *	You lose any data beyond the buffer you gave. If it worries a
-	 *	user program they can ask the device for its MTU anyway.
-	 */
-
 	copied = skb->len;
 	if (copied > len) {
 		copied = len;
@@ -2805,9 +2819,20 @@
 
 	sock_recv_ts_and_drops(msg, sk, skb);
 
-	if (msg->msg_name)
+	if (msg->msg_name) {
+		/* If the address length field is there to be filled
+		 * in, we fill it in now.
+		 */
+		if (sock->type == SOCK_PACKET) {
+			msg->msg_namelen = sizeof(struct sockaddr_pkt);
+		} else {
+			struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll;
+			msg->msg_namelen = sll->sll_halen +
+				offsetof(struct sockaddr_ll, sll_addr);
+		}
 		memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa,
 		       msg->msg_namelen);
+	}
 
 	if (pkt_sk(sk)->auxdata) {
 		struct tpacket_auxdata aux;
@@ -3359,6 +3384,7 @@
 						sk->sk_error_report(sk);
 				}
 				if (msg == NETDEV_UNREGISTER) {
+					packet_cached_dev_reset(po);
 					po->ifindex = -1;
 					if (po->prot_hook.dev)
 						dev_put(po->prot_hook.dev);
diff -ruw linux-3.11.10/net/packet/internal.h linux-3.11.10-fbx/net/packet/internal.h
--- linux-3.11.10/net/packet/internal.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/packet/internal.h	2014-01-17 19:14:18.826220810 +0100
@@ -113,6 +113,7 @@
 	unsigned int		tp_loss:1;
 	unsigned int		tp_tx_has_off:1;
 	unsigned int		tp_tstamp;
+	struct net_device __rcu	*cached_dev;
 	struct packet_type	prot_hook ____cacheline_aligned_in_smp;
 };
 
diff -ruw linux-3.11.10/net/socket.c linux-3.11.10-fbx/net/socket.c
--- linux-3.11.10/net/socket.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/socket.c	2014-07-01 16:22:13.230330072 +0200
@@ -221,12 +221,13 @@
 	int err;
 	int len;
 
+	BUG_ON(klen > sizeof(struct sockaddr_storage));
 	err = get_user(len, ulen);
 	if (err)
 		return err;
 	if (len > klen)
 		len = klen;
-	if (len < 0 || len > sizeof(struct sockaddr_storage))
+	if (len < 0)
 		return -EINVAL;
 	if (len) {
 		if (audit_sockaddr(klen, kaddr))
@@ -1036,6 +1037,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.
@@ -1108,6 +1134,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;
@@ -1849,8 +1897,10 @@
 	msg.msg_iov = &iov;
 	iov.iov_len = size;
 	iov.iov_base = ubuf;
-	msg.msg_name = (struct sockaddr *)&address;
-	msg.msg_namelen = sizeof(address);
+	/* Save some cycles and don't copy the address if not needed */
+	msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
+	/* We assume all kernel code knows the size of sockaddr_storage */
+	msg.msg_namelen = 0;
 	if (sock->file->f_flags & O_NONBLOCK)
 		flags |= MSG_DONTWAIT;
 	err = sock_recvmsg(sock, &msg, size, flags);
@@ -1978,8 +2028,12 @@
 {
 	if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
 		return -EFAULT;
-	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
+
+	if (kmsg->msg_namelen < 0)
 		return -EINVAL;
+
+	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
+		kmsg->msg_namelen = sizeof(struct sockaddr_storage);
 	return 0;
 }
 
@@ -2230,16 +2284,14 @@
 			goto out;
 	}
 
-	/*
-	 *      Save the user-mode address (verify_iovec will change the
+	/* Save the user-mode address (verify_iovec will change the
 	 *      kernel msghdr to use the kernel address space)
 	 */
-
 	uaddr = (__force void __user *)msg_sys->msg_name;
 	uaddr_len = COMPAT_NAMELEN(msg);
-	if (MSG_CMSG_COMPAT & flags) {
+	if (MSG_CMSG_COMPAT & flags)
 		err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
-	} else
+	else
 		err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
 	if (err < 0)
 		goto out_freeiov;
@@ -2248,6 +2300,9 @@
 	cmsg_ptr = (unsigned long)msg_sys->msg_control;
 	msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
 
+	/* We assume all kernel code knows the size of sockaddr_storage */
+	msg_sys->msg_namelen = 0;
+
 	if (sock->file->f_flags & O_NONBLOCK)
 		flags |= MSG_DONTWAIT;
 	err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
diff -ruw linux-3.11.10/net/sunrpc/auth_gss/gss_rpc_upcall.c linux-3.11.10-fbx/net/sunrpc/auth_gss/gss_rpc_upcall.c
--- linux-3.11.10/net/sunrpc/auth_gss/gss_rpc_upcall.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/sunrpc/auth_gss/gss_rpc_upcall.c	2014-05-09 14:12:54.468546162 +0200
@@ -137,7 +137,6 @@
 {
 	mutex_init(&sn->gssp_lock);
 	sn->gssp_clnt = NULL;
-	init_waitqueue_head(&sn->gssp_wq);
 }
 
 int set_gssp_clnt(struct net *net)
@@ -154,7 +153,6 @@
 		sn->gssp_clnt = clnt;
 	}
 	mutex_unlock(&sn->gssp_lock);
-	wake_up(&sn->gssp_wq);
 	return ret;
 }
 
diff -ruw linux-3.11.10/net/sunrpc/auth_gss/svcauth_gss.c linux-3.11.10-fbx/net/sunrpc/auth_gss/svcauth_gss.c
--- linux-3.11.10/net/sunrpc/auth_gss/svcauth_gss.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/sunrpc/auth_gss/svcauth_gss.c	2014-05-09 14:12:54.468546162 +0200
@@ -1295,34 +1295,9 @@
 	else
 		ret = -EBUSY;
 	spin_unlock(&use_gssp_lock);
-	wake_up(&sn->gssp_wq);
 	return ret;
 }
 
-static inline bool gssp_ready(struct sunrpc_net *sn)
-{
-	switch (sn->use_gss_proxy) {
-		case -1:
-			return false;
-		case 0:
-			return true;
-		case 1:
-			return sn->gssp_clnt;
-	}
-	WARN_ON_ONCE(1);
-	return false;
-}
-
-static int wait_for_gss_proxy(struct net *net, struct file *file)
-{
-	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
-
-	if (file->f_flags & O_NONBLOCK && !gssp_ready(sn))
-		return -EAGAIN;
-	return wait_event_interruptible(sn->gssp_wq, gssp_ready(sn));
-}
-
-
 static ssize_t write_gssp(struct file *file, const char __user *buf,
 			 size_t count, loff_t *ppos)
 {
@@ -1355,16 +1330,12 @@
 			 size_t count, loff_t *ppos)
 {
 	struct net *net = PDE_DATA(file_inode(file));
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 	unsigned long p = *ppos;
 	char tbuf[10];
 	size_t len;
-	int ret;
-
-	ret = wait_for_gss_proxy(net, file);
-	if (ret)
-		return ret;
 
-	snprintf(tbuf, sizeof(tbuf), "%d\n", use_gss_proxy(net));
+	snprintf(tbuf, sizeof(tbuf), "%d\n", sn->use_gss_proxy);
 	len = strlen(tbuf);
 	if (p >= len)
 		return 0;
diff -ruw linux-3.11.10/net/sunrpc/clnt.c linux-3.11.10-fbx/net/sunrpc/clnt.c
--- linux-3.11.10/net/sunrpc/clnt.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/sunrpc/clnt.c	2014-05-09 14:12:54.468546162 +0200
@@ -645,14 +645,16 @@
 /*
  * Free an RPC client
  */
-static void
+static struct rpc_clnt *
 rpc_free_client(struct rpc_clnt *clnt)
 {
+	struct rpc_clnt *parent = NULL;
+
 	dprintk_rcu("RPC:       destroying %s client for %s\n",
 			clnt->cl_protname,
 			rcu_dereference(clnt->cl_xprt)->servername);
 	if (clnt->cl_parent != clnt)
-		rpc_release_client(clnt->cl_parent);
+		parent = clnt->cl_parent;
 	rpc_clnt_remove_pipedir(clnt);
 	rpc_unregister_client(clnt);
 	rpc_free_iostats(clnt->cl_metrics);
@@ -661,18 +663,17 @@
 	xprt_put(rcu_dereference_raw(clnt->cl_xprt));
 	rpciod_down();
 	kfree(clnt);
+	return parent;
 }
 
 /*
  * Free an RPC client
  */
-static void
+static struct rpc_clnt * 
 rpc_free_auth(struct rpc_clnt *clnt)
 {
-	if (clnt->cl_auth == NULL) {
-		rpc_free_client(clnt);
-		return;
-	}
+	if (clnt->cl_auth == NULL)
+		return rpc_free_client(clnt);
 
 	/*
 	 * Note: RPCSEC_GSS may need to send NULL RPC calls in order to
@@ -683,7 +684,8 @@
 	rpcauth_release(clnt->cl_auth);
 	clnt->cl_auth = NULL;
 	if (atomic_dec_and_test(&clnt->cl_count))
-		rpc_free_client(clnt);
+		return rpc_free_client(clnt);
+	return NULL;
 }
 
 /*
@@ -694,10 +696,13 @@
 {
 	dprintk("RPC:       rpc_release_client(%p)\n", clnt);
 
+	do {
 	if (list_empty(&clnt->cl_tasks))
 		wake_up(&destroy_wait);
-	if (atomic_dec_and_test(&clnt->cl_count))
-		rpc_free_auth(clnt);
+		if (!atomic_dec_and_test(&clnt->cl_count))
+			break;
+		clnt = rpc_free_auth(clnt);
+	} while (clnt != NULL);
 }
 EXPORT_SYMBOL_GPL(rpc_release_client);
 
@@ -1418,9 +1423,13 @@
 	task->tk_action = call_refresh;
 	switch (status) {
 	case 0:
-		if (rpcauth_uptodatecred(task))
+		if (rpcauth_uptodatecred(task)) {
 			task->tk_action = call_allocate;
 		return;
+		}
+		/* Use rate-limiting and a max number of retries if refresh
+		 * had status 0 but failed to update the cred.
+		 */
 	case -ETIMEDOUT:
 		rpc_delay(task, 3*HZ);
 	case -EAGAIN:
diff -ruw linux-3.11.10/net/sunrpc/netns.h linux-3.11.10-fbx/net/sunrpc/netns.h
--- linux-3.11.10/net/sunrpc/netns.h	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/sunrpc/netns.h	2014-05-09 14:12:54.468546162 +0200
@@ -26,7 +26,6 @@
 	unsigned int rpcb_is_af_local : 1;
 
 	struct mutex gssp_lock;
-	wait_queue_head_t gssp_wq;
 	struct rpc_clnt *gssp_clnt;
 	int use_gss_proxy;
 	int pipe_version;
diff -ruw linux-3.11.10/net/sunrpc/svcsock.c linux-3.11.10-fbx/net/sunrpc/svcsock.c
--- linux-3.11.10/net/sunrpc/svcsock.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/sunrpc/svcsock.c	2014-07-01 16:22:13.230330072 +0200
@@ -1395,6 +1395,22 @@
 	return svsk;
 }
 
+bool svc_alien_sock(struct net *net, int fd)
+{
+	int err;
+	struct socket *sock = sockfd_lookup(fd, &err);
+	bool ret = false;
+
+	if (!sock)
+		goto out;
+	if (sock_net(sock->sk) != net)
+		ret = true;
+	sockfd_put(sock);
+out:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(svc_alien_sock);
+
 /**
  * svc_addsock - add a listener socket to an RPC service
  * @serv: pointer to RPC service to which to add a new listener
diff -ruw linux-3.11.10/net/sunrpc/svc_xprt.c linux-3.11.10-fbx/net/sunrpc/svc_xprt.c
--- linux-3.11.10/net/sunrpc/svc_xprt.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/sunrpc/svc_xprt.c	2014-08-22 15:47:22.168063305 +0200
@@ -730,6 +730,8 @@
 		newxpt = xprt->xpt_ops->xpo_accept(xprt);
 		if (newxpt)
 			svc_add_new_temp_xprt(serv, newxpt);
+		else
+			module_put(xprt->xpt_class->xcl_owner);
 	} else if (xprt->xpt_ops->xpo_has_wspace(xprt)) {
 		/* XPT_DATA|XPT_DEFERRED case: */
 		dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
diff -ruw linux-3.11.10/net/sunrpc/xprtsock.c linux-3.11.10-fbx/net/sunrpc/xprtsock.c
--- linux-3.11.10/net/sunrpc/xprtsock.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/sunrpc/xprtsock.c	2014-07-01 16:22:13.230330072 +0200
@@ -391,8 +391,10 @@
 	return kernel_sendmsg(sock, &msg, NULL, 0, 0);
 }
 
-static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more)
+static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more, bool zerocopy)
 {
+	ssize_t (*do_sendpage)(struct socket *sock, struct page *page,
+			int offset, size_t size, int flags);
 	struct page **ppage;
 	unsigned int remainder;
 	int err, sent = 0;
@@ -401,6 +403,9 @@
 	base += xdr->page_base;
 	ppage = xdr->pages + (base >> PAGE_SHIFT);
 	base &= ~PAGE_MASK;
+	do_sendpage = sock->ops->sendpage;
+	if (!zerocopy)
+		do_sendpage = sock_no_sendpage;
 	for(;;) {
 		unsigned int len = min_t(unsigned int, PAGE_SIZE - base, remainder);
 		int flags = XS_SENDMSG_FLAGS;
@@ -408,7 +413,7 @@
 		remainder -= len;
 		if (remainder != 0 || more)
 			flags |= MSG_MORE;
-		err = sock->ops->sendpage(sock, *ppage, base, len, flags);
+		err = do_sendpage(sock, *ppage, base, len, flags);
 		if (remainder == 0 || err != len)
 			break;
 		sent += err;
@@ -429,9 +434,10 @@
  * @addrlen: UDP only -- length of destination address
  * @xdr: buffer containing this request
  * @base: starting position in the buffer
+ * @zerocopy: true if it is safe to use sendpage()
  *
  */
-static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base)
+static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, bool zerocopy)
 {
 	unsigned int remainder = xdr->len - base;
 	int err, sent = 0;
@@ -459,7 +465,7 @@
 	if (base < xdr->page_len) {
 		unsigned int len = xdr->page_len - base;
 		remainder -= len;
-		err = xs_send_pagedata(sock, xdr, base, remainder != 0);
+		err = xs_send_pagedata(sock, xdr, base, remainder != 0, zerocopy);
 		if (remainder == 0 || err != len)
 			goto out;
 		sent += err;
@@ -496,6 +502,7 @@
 	struct rpc_rqst *req = task->tk_rqstp;
 	struct rpc_xprt *xprt = req->rq_xprt;
 	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
+	struct sock *sk = transport->inet;
 	int ret = -EAGAIN;
 
 	dprintk("RPC: %5u xmit incomplete (%u left of %u)\n",
@@ -513,7 +520,7 @@
 			 * window size
 			 */
 			set_bit(SOCK_NOSPACE, &transport->sock->flags);
-			transport->inet->sk_write_pending++;
+			sk->sk_write_pending++;
 			/* ...and wait for more buffer space */
 			xprt_wait_for_buffer_space(task, xs_nospace_callback);
 		}
@@ -523,6 +530,9 @@
 	}
 
 	spin_unlock_bh(&xprt->transport_lock);
+
+	/* Race breaker in case memory is freed before above code is called */
+	sk->sk_write_space(sk);
 	return ret;
 }
 
@@ -562,7 +572,7 @@
 			req->rq_svec->iov_base, req->rq_svec->iov_len);
 
 	status = xs_sendpages(transport->sock, NULL, 0,
-						xdr, req->rq_bytes_sent);
+						xdr, req->rq_bytes_sent, true);
 	dprintk("RPC:       %s(%u) = %d\n",
 			__func__, xdr->len - req->rq_bytes_sent, status);
 	if (likely(status >= 0)) {
@@ -618,7 +628,7 @@
 	status = xs_sendpages(transport->sock,
 			      xs_addr(xprt),
 			      xprt->addrlen, xdr,
-			      req->rq_bytes_sent);
+			      req->rq_bytes_sent, true);
 
 	dprintk("RPC:       xs_udp_send_request(%u) = %d\n",
 			xdr->len - req->rq_bytes_sent, status);
@@ -689,6 +699,7 @@
 	struct rpc_xprt *xprt = req->rq_xprt;
 	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
 	struct xdr_buf *xdr = &req->rq_snd_buf;
+	bool zerocopy = true;
 	int status;
 
 	xs_encode_stream_record_marker(&req->rq_snd_buf);
@@ -696,13 +707,20 @@
 	xs_pktdump("packet data:",
 				req->rq_svec->iov_base,
 				req->rq_svec->iov_len);
+	/* Don't use zero copy if this is a resend. If the RPC call
+	 * completes while the socket holds a reference to the pages,
+	 * then we may end up resending corrupted data.
+	 */
+	if (task->tk_flags & RPC_TASK_SENT)
+		zerocopy = false;
 
 	/* Continue transmitting the packet/record. We must be careful
 	 * to cope with writespace callbacks arriving _after_ we have
 	 * called sendmsg(). */
 	while (1) {
 		status = xs_sendpages(transport->sock,
-					NULL, 0, xdr, req->rq_bytes_sent);
+					NULL, 0, xdr, req->rq_bytes_sent,
+					zerocopy);
 
 		dprintk("RPC:       xs_tcp_send_request(%u) = %d\n",
 				xdr->len - req->rq_bytes_sent, status);
diff -ruw linux-3.11.10/net/unix/af_unix.c linux-3.11.10-fbx/net/unix/af_unix.c
--- linux-3.11.10/net/unix/af_unix.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/unix/af_unix.c	2014-07-01 16:22:13.234330084 +0200
@@ -161,9 +161,8 @@
 
 static inline unsigned int unix_hash_fold(__wsum n)
 {
-	unsigned int hash = (__force unsigned int)n;
+	unsigned int hash = (__force unsigned int)csum_fold(n);
 
-	hash ^= hash>>16;
 	hash ^= hash>>8;
 	return hash&(UNIX_HASH_SIZE-1);
 }
@@ -268,8 +267,10 @@
 	sk_for_each(s, &unix_socket_table[hash ^ type]) {
 		struct unix_sock *u = unix_sk(s);
 
+#ifdef UNIX_ABSTRACT_IGNORE_NETNS
 		if (!net_eq(sock_net(s), net))
 			continue;
+#endif
 
 		if (u->addr->len == len &&
 		    !memcmp(u->addr->name, sunname, len))
@@ -530,13 +531,17 @@
 static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *,
 				  struct msghdr *, size_t, int);
 
-static void unix_set_peek_off(struct sock *sk, int val)
+static int unix_set_peek_off(struct sock *sk, int val)
 {
 	struct unix_sock *u = unix_sk(sk);
 
-	mutex_lock(&u->readlock);
+	if (mutex_lock_interruptible(&u->readlock))
+		return -EINTR;
+
 	sk->sk_peek_off = val;
 	mutex_unlock(&u->readlock);
+
+	return 0;
 }
 
 
@@ -714,7 +719,9 @@
 	int err;
 	unsigned int retries = 0;
 
-	mutex_lock(&u->readlock);
+	err = mutex_lock_interruptible(&u->readlock);
+	if (err)
+		return err;
 
 	err = 0;
 	if (u->addr)
@@ -873,7 +880,9 @@
 		goto out;
 	addr_len = err;
 
-	mutex_lock(&u->readlock);
+	err = mutex_lock_interruptible(&u->readlock);
+	if (err)
+		goto out;
 
 	err = -EINVAL;
 	if (u->addr)
@@ -1762,7 +1771,6 @@
 {
 	struct unix_sock *u = unix_sk(sk);
 
-	msg->msg_namelen = 0;
 	if (u->addr) {
 		msg->msg_namelen = u->addr->len;
 		memcpy(msg->msg_name, u->addr->name, u->addr->len);
@@ -1786,11 +1794,12 @@
 	if (flags&MSG_OOB)
 		goto out;
 
-	msg->msg_namelen = 0;
-
 	err = mutex_lock_interruptible(&u->readlock);
-	if (err) {
-		err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
+	if (unlikely(err)) {
+		/* recvmsg() in non blocking mode is supposed to return -EAGAIN
+		 * sk_rcvtimeo is not honored by mutex_lock_interruptible()
+		 */
+		err = noblock ? -EAGAIN : -ERESTARTSYS;
 		goto out;
 	}
 
@@ -1910,6 +1919,7 @@
 	struct unix_sock *u = unix_sk(sk);
 	struct sockaddr_un *sunaddr = msg->msg_name;
 	int copied = 0;
+	int noblock = flags & MSG_DONTWAIT;
 	int check_creds = 0;
 	int target;
 	int err = 0;
@@ -1925,9 +1935,7 @@
 		goto out;
 
 	target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
-	timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
-
-	msg->msg_namelen = 0;
+	timeo = sock_rcvtimeo(sk, noblock);
 
 	/* Lock the socket to prevent queue disordering
 	 * while sleeps in memcpy_tomsg
@@ -1939,8 +1947,11 @@
 	}
 
 	err = mutex_lock_interruptible(&u->readlock);
-	if (err) {
-		err = sock_intr_errno(timeo);
+	if (unlikely(err)) {
+		/* recvmsg() in non blocking mode is supposed to return -EAGAIN
+		 * sk_rcvtimeo is not honored by mutex_lock_interruptible()
+		 */
+		err = noblock ? -EAGAIN : -ERESTARTSYS;
 		goto out;
 	}
 
diff -ruw linux-3.11.10/net/unix/Kconfig linux-3.11.10-fbx/net/unix/Kconfig
--- linux-3.11.10/net/unix/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/unix/Kconfig	2014-05-09 14:12:54.468546162 +0200
@@ -19,6 +19,9 @@
 
 	  Say Y unless you know what you are doing.
 
+config UNIX_ABSTRACT_IGNORE_NETNS
+	bool "make abstract namespace global to all network namespaces"
+
 config UNIX_DIAG
 	tristate "UNIX: socket monitoring interface"
 	depends on UNIX
diff -ruw linux-3.11.10/net/xfrm/xfrm_user.c linux-3.11.10-fbx/net/xfrm/xfrm_user.c
--- linux-3.11.10/net/xfrm/xfrm_user.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/net/xfrm/xfrm_user.c	2014-08-22 15:47:22.168063305 +0200
@@ -2362,7 +2362,7 @@
 	link = &xfrm_dispatch[type];
 
 	/* All operations require privileges, even GET */
-	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
+	if (!netlink_net_capable(skb, CAP_NET_ADMIN))
 		return -EPERM;
 
 	if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
diff -ruw linux-3.11.10/scripts/link-vmlinux.sh linux-3.11.10-fbx/scripts/link-vmlinux.sh
--- linux-3.11.10/scripts/link-vmlinux.sh	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/scripts/link-vmlinux.sh	2014-01-17 19:14:18.834220810 +0100
@@ -82,7 +82,9 @@
 		kallsymopt="${kallsymopt} --all-symbols"
 	fi
 
+	if [ -n "${CONFIG_ARM}" ] && [ -n "${CONFIG_PAGE_OFFSET}" ]; then
 	kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET"
+	fi
 
 	local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL}               \
 		      ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}"
diff -ruw linux-3.11.10/scripts/mod/file2alias.c linux-3.11.10-fbx/scripts/mod/file2alias.c
--- linux-3.11.10/scripts/mod/file2alias.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/scripts/mod/file2alias.c	2014-05-09 14:12:54.504546163 +0200
@@ -210,8 +210,8 @@
 				range_lo < 0x9 ? "[%X-9" : "[%X",
 				range_lo);
 			sprintf(alias + strlen(alias),
-				range_hi > 0xA ? "a-%X]" : "%X]",
-				range_lo);
+				range_hi > 0xA ? "A-%X]" : "%X]",
+				range_hi);
 		}
 	}
 	if (bcdDevice_initial_digits < (sizeof(bcdDevice_lo) * 2 - 1))
diff -ruw linux-3.11.10/scripts/mod/modpost.c linux-3.11.10-fbx/scripts/mod/modpost.c
--- linux-3.11.10/scripts/mod/modpost.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/scripts/mod/modpost.c	2014-07-01 16:22:13.234330084 +0200
@@ -573,12 +573,16 @@
 		if (strncmp(symname, "_restgpr_", sizeof("_restgpr_") - 1) == 0 ||
 		    strncmp(symname, "_savegpr_", sizeof("_savegpr_") - 1) == 0 ||
 		    strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 ||
-		    strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0)
+		    strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0 ||
+		    strncmp(symname, "_restvr_", sizeof("_restvr_") - 1) == 0 ||
+		    strncmp(symname, "_savevr_", sizeof("_savevr_") - 1) == 0)
 			return 1;
 	if (info->hdr->e_machine == EM_PPC64)
 		/* Special register function linked on all modules during final link of .ko */
 		if (strncmp(symname, "_restgpr0_", sizeof("_restgpr0_") - 1) == 0 ||
-		    strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0)
+		    strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0 ||
+		    strncmp(symname, "_restvr_", sizeof("_restvr_") - 1) == 0 ||
+		    strncmp(symname, "_savevr_", sizeof("_savevr_") - 1) == 0)
 			return 1;
 	/* Do not ignore this symbol */
 	return 0;
diff -ruw linux-3.11.10/security/Kconfig linux-3.11.10-fbx/security/Kconfig
--- linux-3.11.10/security/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/security/Kconfig	2013-12-04 14:33:33.719479208 +0100
@@ -122,6 +122,7 @@
 source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
 source security/yama/Kconfig
+source security/fbxlsmjail/Kconfig
 
 source security/integrity/Kconfig
 
diff -ruw linux-3.11.10/security/Makefile linux-3.11.10-fbx/security/Makefile
--- linux-3.11.10/security/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/security/Makefile	2013-12-04 14:33:33.719479208 +0100
@@ -8,6 +8,7 @@
 subdir-$(CONFIG_SECURITY_TOMOYO)        += tomoyo
 subdir-$(CONFIG_SECURITY_APPARMOR)	+= apparmor
 subdir-$(CONFIG_SECURITY_YAMA)		+= yama
+subdir-$(CONFIG_SECURITY_FBXLSMJAIL)	+= fbxlsmjail
 
 # always enable default capabilities
 obj-y					+= commoncap.o
@@ -23,6 +24,7 @@
 obj-$(CONFIG_SECURITY_TOMOYO)		+= tomoyo/built-in.o
 obj-$(CONFIG_SECURITY_APPARMOR)		+= apparmor/built-in.o
 obj-$(CONFIG_SECURITY_YAMA)		+= yama/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.11.10/sound/core/control.c linux-3.11.10-fbx/sound/core/control.c
--- linux-3.11.10/sound/core/control.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/sound/core/control.c	2014-08-22 15:47:22.168063305 +0200
@@ -289,6 +289,10 @@
 {
 	struct snd_kcontrol *kctl;
 
+	/* Make sure that the ids assigned to the control do not wrap around */
+	if (card->last_numid >= UINT_MAX - count)
+		card->last_numid = 0;
+
 	list_for_each_entry(kctl, &card->controls, list) {
 		if (kctl->id.numid < card->last_numid + 1 + count &&
 		    kctl->id.numid + kctl->count > card->last_numid + 1) {
@@ -331,6 +335,7 @@
 {
 	struct snd_ctl_elem_id id;
 	unsigned int idx;
+	unsigned int count;
 	int err = -EINVAL;
 
 	if (! kcontrol)
@@ -338,6 +343,9 @@
 	if (snd_BUG_ON(!card || !kcontrol->info))
 		goto error;
 	id = kcontrol->id;
+	if (id.index > UINT_MAX - kcontrol->count)
+		goto error;
+
 	down_write(&card->controls_rwsem);
 	if (snd_ctl_find_id(card, &id)) {
 		up_write(&card->controls_rwsem);
@@ -359,8 +367,9 @@
 	card->controls_count += kcontrol->count;
 	kcontrol->id.numid = card->last_numid + 1;
 	card->last_numid += kcontrol->count;
+	count = kcontrol->count;
 	up_write(&card->controls_rwsem);
-	for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
+	for (idx = 0; idx < count; idx++, id.index++, id.numid++)
 		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
 	return 0;
 
@@ -389,6 +398,7 @@
 		    bool add_on_replace)
 {
 	struct snd_ctl_elem_id id;
+	unsigned int count;
 	unsigned int idx;
 	struct snd_kcontrol *old;
 	int ret;
@@ -424,8 +434,9 @@
 	card->controls_count += kcontrol->count;
 	kcontrol->id.numid = card->last_numid + 1;
 	card->last_numid += kcontrol->count;
+	count = kcontrol->count;
 	up_write(&card->controls_rwsem);
-	for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
+	for (idx = 0; idx < count; idx++, id.index++, id.numid++)
 		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
 	return 0;
 
@@ -898,9 +909,9 @@
 			result = kctl->put(kctl, control);
 		}
 		if (result > 0) {
+			struct snd_ctl_elem_id id = control->id;
 			up_read(&card->controls_rwsem);
-			snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
-				       &control->id);
+			snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
 			return 0;
 		}
 	}
@@ -992,6 +1003,7 @@
 
 struct user_element {
 	struct snd_ctl_elem_info info;
+	struct snd_card *card;
 	void *elem_data;		/* element data */
 	unsigned long elem_data_size;	/* size of element data in bytes */
 	void *tlv_data;			/* TLV data */
@@ -1035,7 +1047,9 @@
 {
 	struct user_element *ue = kcontrol->private_data;
 
+	mutex_lock(&ue->card->user_ctl_lock);
 	memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size);
+	mutex_unlock(&ue->card->user_ctl_lock);
 	return 0;
 }
 
@@ -1045,9 +1059,11 @@
 	int change;
 	struct user_element *ue = kcontrol->private_data;
 	
+	mutex_lock(&ue->card->user_ctl_lock);
 	change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0;
 	if (change)
 		memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size);
+	mutex_unlock(&ue->card->user_ctl_lock);
 	return change;
 }
 
@@ -1067,19 +1083,32 @@
 		new_data = memdup_user(tlv, size);
 		if (IS_ERR(new_data))
 			return PTR_ERR(new_data);
+		mutex_lock(&ue->card->user_ctl_lock);
 		change = ue->tlv_data_size != size;
 		if (!change)
 			change = memcmp(ue->tlv_data, new_data, size);
 		kfree(ue->tlv_data);
 		ue->tlv_data = new_data;
 		ue->tlv_data_size = size;
+		mutex_unlock(&ue->card->user_ctl_lock);
 	} else {
-		if (! ue->tlv_data_size || ! ue->tlv_data)
-			return -ENXIO;
-		if (size < ue->tlv_data_size)
-			return -ENOSPC;
+		int ret = 0;
+
+		mutex_lock(&ue->card->user_ctl_lock);
+		if (!ue->tlv_data_size || !ue->tlv_data) {
+			ret = -ENXIO;
+			goto err_unlock;
+		}
+		if (size < ue->tlv_data_size) {
+			ret = -ENOSPC;
+			goto err_unlock;
+		}
 		if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
-			return -EFAULT;
+			ret = -EFAULT;
+err_unlock:
+		mutex_unlock(&ue->card->user_ctl_lock);
+		if (ret)
+			return ret;
 	}
 	return change;
 }
@@ -1137,8 +1166,6 @@
 	struct user_element *ue;
 	int idx, err;
 
-	if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
-		return -ENOMEM;
 	if (info->count < 1)
 		return -EINVAL;
 	access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
@@ -1147,21 +1174,16 @@
 				 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE));
 	info->id.numid = 0;
 	memset(&kctl, 0, sizeof(kctl));
-	down_write(&card->controls_rwsem);
-	_kctl = snd_ctl_find_id(card, &info->id);
-	err = 0;
-	if (_kctl) {
-		if (replace)
-			err = snd_ctl_remove(card, _kctl);
-		else
-			err = -EBUSY;
-	} else {
-		if (replace)
-			err = -ENOENT;
-	}
-	up_write(&card->controls_rwsem);
-	if (err < 0)
+
+	if (replace) {
+		err = snd_ctl_remove_user_ctl(file, &info->id);
+		if (err)
 		return err;
+	}
+
+	if (card->user_ctl_count >= MAX_USER_CONTROLS)
+		return -ENOMEM;
+
 	memcpy(&kctl.id, &info->id, sizeof(info->id));
 	kctl.count = info->owner ? info->owner : 1;
 	access |= SNDRV_CTL_ELEM_ACCESS_USER;
@@ -1211,6 +1233,7 @@
 	ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL);
 	if (ue == NULL)
 		return -ENOMEM;
+	ue->card = card;
 	ue->info = *info;
 	ue->info.access = 0;
 	ue->elem_data = (char *)ue + sizeof(*ue);
@@ -1322,8 +1345,9 @@
 		}
 		err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv);
 		if (err > 0) {
+			struct snd_ctl_elem_id id = kctl->id;
 			up_read(&card->controls_rwsem);
-			snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id);
+			snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id);
 			return 0;
 		}
 	} else {
diff -ruw linux-3.11.10/sound/core/init.c linux-3.11.10-fbx/sound/core/init.c
--- linux-3.11.10/sound/core/init.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/sound/core/init.c	2014-08-22 15:47:22.168063305 +0200
@@ -170,7 +170,7 @@
 	if (idx < 0) {
 		for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) {
 			/* idx == -1 == 0xffff means: take any free slot */
-			if (idx2 < sizeof(int) && !(idx & (1U << idx2)))
+			if (idx2 < 32 && !(idx & (1U << idx2)))
 				continue;
 			if (!test_bit(idx2, snd_cards_lock)) {
 				if (module_slot_match(module, idx2)) {
@@ -183,7 +183,7 @@
 	if (idx < 0) {
 		for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) {
 			/* idx == -1 == 0xffff means: take any free slot */
-			if (idx2 < sizeof(int) && !(idx & (1U << idx2)))
+			if (idx2 < 32 && !(idx & (1U << idx2)))
 				continue;
 			if (!test_bit(idx2, snd_cards_lock)) {
 				if (!slots[idx2] || !*slots[idx2]) {
@@ -215,6 +215,7 @@
 	INIT_LIST_HEAD(&card->devices);
 	init_rwsem(&card->controls_rwsem);
 	rwlock_init(&card->ctl_files_rwlock);
+	mutex_init(&card->user_ctl_lock);
 	INIT_LIST_HEAD(&card->controls);
 	INIT_LIST_HEAD(&card->ctl_files);
 	spin_lock_init(&card->files_lock);
diff -ruw linux-3.11.10/sound/core/pcm_lib.c linux-3.11.10-fbx/sound/core/pcm_lib.c
--- linux-3.11.10/sound/core/pcm_lib.c	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/sound/core/pcm_lib.c	2014-01-17 19:14:18.834220810 +0100
@@ -1937,6 +1937,8 @@
 		case SNDRV_PCM_STATE_DISCONNECTED:
 			err = -EBADFD;
 			goto _endloop;
+		case SNDRV_PCM_STATE_PAUSED:
+			continue;
 		}
 		if (!tout) {
 			snd_printd("%s write error (DMA or IRQ trouble?)\n",
diff -ruw linux-3.11.10/sound/pci/Kconfig linux-3.11.10-fbx/sound/pci/Kconfig
--- linux-3.11.10/sound/pci/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/sound/pci/Kconfig	2014-05-09 14:12:54.508546163 +0200
@@ -30,6 +30,7 @@
 	select SND_PCM
 	select SND_AC97_CODEC
 	select SND_OPL3_LIB
+	select ZONE_DMA
 	help
 	  Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+
 
@@ -54,6 +55,7 @@
 	tristate "ALi M5451 PCI Audio Controller"
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
+	select ZONE_DMA
 	help
 	  Say Y here to include support for the integrated AC97 sound
 	  device on motherboards using the ALi M5451 Audio Controller
@@ -158,6 +160,7 @@
 	select SND_PCM
 	select SND_RAWMIDI
 	select SND_AC97_CODEC
+	select ZONE_DMA
 	help
 	  Say Y here to include support for Aztech AZF3328 (PCI168)
 	  soundcards.
@@ -463,6 +466,7 @@
 	select SND_HWDEP
 	select SND_RAWMIDI
 	select SND_AC97_CODEC
+	select ZONE_DMA
 	help
 	  Say Y to include support for Sound Blaster PCI 512, Live!,
 	  Audigy and E-mu APS (partially supported) soundcards.
@@ -478,6 +482,7 @@
 	tristate "Emu10k1X (Dell OEM Version)"
 	select SND_AC97_CODEC
 	select SND_RAWMIDI
+	select ZONE_DMA
 	help
 	  Say Y here to include support for the Dell OEM version of the
 	  Sound Blaster Live!.
@@ -511,6 +516,7 @@
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
+	select ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on ESS Solo-1
 	  (ES1938, ES1946, ES1969) chips.
@@ -522,6 +528,7 @@
 	tristate "ESS ES1968/1978 (Maestro-1/2/2E)"
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
+	select ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on ESS Maestro
 	  1/2/2E chips.
@@ -603,6 +610,7 @@
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	select BITREVERSE
+	select ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on the
 	  ICE1712 (Envy24) chip.
@@ -690,6 +698,7 @@
 config SND_MAESTRO3
 	tristate "ESS Allegro/Maestro3"
 	select SND_AC97_CODEC
+	select ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on ESS Maestro 3
 	  (Allegro) chips.
@@ -786,6 +795,7 @@
 	tristate "SiS 7019 Audio Accelerator"
 	depends on X86 && !X86_64
 	select SND_AC97_CODEC
+	select ZONE_DMA
 	help
 	  Say Y here to include support for the SiS 7019 Audio Accelerator.
 
@@ -797,6 +807,7 @@
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
+	select ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on the S3
 	  SonicVibes chip.
@@ -808,6 +819,7 @@
 	tristate "Trident 4D-Wave DX/NX; SiS 7018"
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
+	select ZONE_DMA
 	help
 	  Say Y here to include support for soundcards based on Trident
 	  4D-Wave DX/NX or SiS 7018 chips.
diff -ruw linux-3.11.10/sound/soc/kirkwood/Kconfig linux-3.11.10-fbx/sound/soc/kirkwood/Kconfig
--- linux-3.11.10/sound/soc/kirkwood/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/sound/soc/kirkwood/Kconfig	2013-12-04 14:33:34.979479228 +0100
@@ -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.11.10/sound/soc/kirkwood/Makefile linux-3.11.10-fbx/sound/soc/kirkwood/Makefile
--- linux-3.11.10/sound/soc/kirkwood/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/sound/soc/kirkwood/Makefile	2013-12-04 14:33:34.983479228 +0100
@@ -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
diff -ruw linux-3.11.10/sound/usb/Kconfig linux-3.11.10-fbx/sound/usb/Kconfig
--- linux-3.11.10/sound/usb/Kconfig	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/sound/usb/Kconfig	2014-05-09 14:12:54.520546163 +0200
@@ -14,6 +14,7 @@
 	select SND_HWDEP
 	select SND_RAWMIDI
 	select SND_PCM
+	select BITREVERSE
 	help
 	  Say Y here to include support for USB audio and USB MIDI
 	  devices.
diff -ruw linux-3.11.10/usr/Makefile linux-3.11.10-fbx/usr/Makefile
--- linux-3.11.10/usr/Makefile	2013-11-29 19:42:37.000000000 +0100
+++ linux-3.11.10-fbx/usr/Makefile	2013-12-04 14:33:36.239479248 +0100
@@ -46,8 +46,10 @@
 # in initramfs and to detect if any files are added/removed.
 # Removed files are identified by directory timestamp being updated
 # The dependency list is generated by gen_initramfs.sh -l
-ifneq ($(wildcard $(obj)/.initramfs_data.cpio.d),)
-	include $(obj)/.initramfs_data.cpio.d
+ifneq ($(wildcard $(obj)/.initramfs_data.cpio$(suffix_y).d),)
+	include $(obj)/.initramfs_data.cpio$(suffix_y).d
+else
+	deps_initramfs := FORCE
 endif
 
 quiet_cmd_initfs = GEN     $@
@@ -64,6 +66,6 @@
 # 3) If gen_init_cpio are newer than initramfs_data.cpio
 # 4) arguments to gen_initramfs.sh changes
 $(obj)/initramfs_data.cpio$(suffix_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs
-	$(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.d
+	$(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio$(suffix_y).d
 	$(call if_changed,initfs)
 
--- /dev/null	2015-07-28 12:46:09.152032985 +0200
+++ linux-3.11.10-fbx/arch/x86/kernel/fbxbootinfo.c	2013-12-17 18:03:42.371570846 +0100
@@ -0,0 +1,46 @@
+#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(u64 phys_addr, u32 data_len)
+{
+	struct setup_data *data;
+
+	data = early_memremap(phys_addr, data_len);
+	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);
+	early_iounmap(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	2015-07-28 12:46:09.152032985 +0200
+++ linux-3.11.10-fbx/arch/x86/kernel/fbxserial.c	2013-12-17 18:03:42.371570846 +0100
@@ -0,0 +1,56 @@
+
+#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(u64 phys_addr, u32 data_len)
+{
+	struct setup_data *data;
+
+	data = early_memremap(phys_addr, data_len);
+	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);
+	early_iounmap(data, data_len);
+	add_device_randomness(&serial_info, sizeof (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	2015-07-28 12:46:09.152032985 +0200
+++ linux-3.11.10-fbx/arch/x86/platform/ce4100/fbx6hd.dts	2013-12-04 14:33:18.619478968 +0100
@@ -0,0 +1,454 @@
+/*
+ * 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>;
+				};
+			};
+		};
+	};
+};
--- /dev/null	2015-07-28 12:46:09.152032985 +0200
+++ linux-3.11.10-fbx/arch/x86/platform/ce4100/i2c-intelce.c	2013-12-04 14:33:18.619478968 +0100
@@ -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	2015-07-28 12:46:09.152032985 +0200
+++ linux-3.11.10-fbx/config	2015-07-29 11:26:29.760331829 +0200
@@ -0,0 +1,3020 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/x86 3.11.10.14 Kernel Configuration
+#
+# CONFIG_64BIT is not set
+CONFIG_X86_32=y
+CONFIG_X86=y
+CONFIG_INSTRUCTION_DECODER=y
+CONFIG_OUTPUT_FORMAT="elf32-i386"
+CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_MMU=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_HAS_CPU_RELAX=y
+CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
+CONFIG_ARCH_HAS_CPU_AUTOPROBE=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_ARCH_WANT_HUGE_PMD_SHARE=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+# CONFIG_ZONE_DMA32 is not set
+# 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_ARCH_SUPPORTS_UPROBES=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE="/opt/toolchains/atom-glibc-2.21-gcc-4.9.2-binutils-2.25-gdb-7.8.2/bin/i686-fbx-linux-gnu-"
+# CONFIG_COMPILE_TEST is not set
+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_HAVE_KERNEL_LZ4=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_KERNEL_LZ4 is not set
+CONFIG_DEFAULT_HOSTNAME="fbx6hd"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_FHANDLE is not set
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_AUDIT_WATCH=y
+CONFIG_AUDIT_TREE=y
+# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_IRQ_DOMAIN=y
+# CONFIG_IRQ_DOMAIN_DEBUG is not set
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+# CONFIG_TICK_CPU_ACCOUNTING is not set
+CONFIG_IRQ_TIME_ACCOUNTING=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_RCU_FANOUT=32
+CONFIG_RCU_FANOUT_LEAF=16
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+# CONFIG_RCU_NOCB_CPU is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
+CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
+CONFIG_ARCH_WANTS_PROT_NUMA_PROT_NONE=y
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+# CONFIG_CPUSETS is not set
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_MEMCG=y
+# CONFIG_MEMCG_KMEM is not set
+CONFIG_CGROUP_PERF=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+# CONFIG_SCHED_AUTOGROUP is not set
+CONFIG_MM_OWNER=y
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_HAVE_UID16=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_HAVE_PCSPKR_PLATFORM=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_SLUB_CPU_PARTIAL is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_OPROFILE_NMI_TIMER=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_OPTPROBES=y
+CONFIG_HAVE_KPROBES_ON_FTRACE=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=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_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
+CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
+CONFIG_HAVE_CMPXCHG_LOCAL=y
+CONFIG_HAVE_CMPXCHG_DOUBLE=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_SECCOMP_FILTER=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
+CONFIG_HAVE_ARCH_SOFT_DIRTY=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OLD_SIGACTION=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_MODULE_SIG 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
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_AIX_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
+
+#
+# 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_UNINLINE_SPIN_UNLOCK=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_FREEZER=y
+
+#
+# Processor type and features
+#
+# CONFIG_ZONE_DMA is not set
+CONFIG_SMP=y
+CONFIG_X86_MPPARSE=y
+# CONFIG_X86_BIGSMP is not set
+CONFIG_X86_EXTENDED_PLATFORM=y
+# CONFIG_X86_GOLDFISH is not set
+CONFIG_X86_INTEL_CE=y
+CONFIG_FBX6HD=y
+# CONFIG_X86_WANT_INTEL_MID is not set
+# CONFIG_X86_INTEL_LPSS 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_HYPERVISOR_GUEST is not set
+CONFIG_NO_BOOTMEM=y
+# CONFIG_MEMTEST 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_L1_CACHE_SHIFT=6
+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_NR_CPUS=2
+CONFIG_SCHED_SMT=y
+# CONFIG_SCHED_MC 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_MICROCODE_INTEL_EARLY is not set
+# CONFIG_MICROCODE_AMD_EARLY 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_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_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_ARCH_DISCARD_MEMBLOCK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+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_CROSS_MEMORY_ATTACH is not set
+# CONFIG_CLEANCACHE is not set
+# CONFIG_ZBUD 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_X86_SMAP is not set
+# CONFIG_EFI is not set
+CONFIG_SECCOMP=y
+# 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=656M"
+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_I2C=y
+# 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_MULTIPLE_DRIVERS is not set
+# CONFIG_CPU_IDLE_GOV_LADDER is not set
+CONFIG_CPU_IDLE_GOV_MENU=y
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+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_REALLOC_ENABLE_AUTO 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
+
+#
+# PCI host controller drivers
+#
+CONFIG_ISA_DMA_API=y
+# CONFIG_ISA is not set
+# CONFIG_SCx200 is not set
+# CONFIG_ALIX is not set
+# CONFIG_NET5501 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_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+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_PACKET_DIAG is not set
+CONFIG_UNIX=y
+# CONFIG_UNIX_ABSTRACT_IGNORE_NETNS is not set
+# CONFIG_UNIX_DIAG is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=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_NET_IP_TUNNEL is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+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_GC_THRESH=1024
+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_GRE 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_ACCT is not set
+# 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_PROCFS=y
+# CONFIG_NF_CONNTRACK_EVENTS is not set
+# CONFIG_NF_CONNTRACK_TIMEOUT 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_NF_CT_NETLINK_TIMEOUT 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_AUDIT is not set
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+# CONFIG_NETFILTER_XT_TARGET_LED is not set
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+# 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_BPF 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_CONNLABEL 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_ECN 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_NFACCT 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_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_ULOG is not set
+# CONFIG_NF_NAT_IPV4 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=y
+CONFIG_NF_CONNTRACK_IPV6=y
+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_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+# CONFIG_IP6_NF_MANGLE is not set
+# CONFIG_IP6_NF_RAW is not set
+# CONFIG_NF_NAT_IPV6 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_FBXBRIDGE is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+CONFIG_VLAN_8021Q=y
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_VLAN_8021Q_MVRP 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_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_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_NET_MPLS_GSO is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+# CONFIG_NETPRIO_CGROUP is not set
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_BQL=y
+CONFIG_NET_FLOW_LIMIT=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=y
+# CONFIG_BT_RFCOMM is not set
+# CONFIG_BT_BNEP is not set
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=y
+# CONFIG_BT_HCIUART is not set
+CONFIG_BT_HCIBCM203X=y
+CONFIG_BT_HCIBPA10X=y
+CONFIG_BT_HCIBFUSB=y
+# CONFIG_BT_HCIVHCI is not set
+CONFIG_BT_MRVL=y
+CONFIG_BT_ATH3K=y
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# 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=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_FW_LOADER_USER_HELPER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_CMA is not set
+
+#
+# Bus devices
+#
+# 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_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_DOCG3 is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON 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_DOCG4 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_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI 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_SELFTEST is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_I2C=y
+CONFIG_OF_NET=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_MTD=y
+# CONFIG_PARPORT is not set
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG_MESSAGES is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX 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
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_NVME is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_BLK_DEV_RSXX is not set
+
+#
+# Misc devices
+#
+# CONFIG_WINTEGRA_MMAP is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_IBM_ASM is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ATMEL_SSC 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_INTELCE_PIC16PMU=y
+# CONFIG_BMP085_I2C is not set
+# CONFIG_PCH_PHUB is not set
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+# CONFIG_VMWARE_VMCI 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
+
+#
+# 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_ZPODD is not set
+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_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN 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_NLMON is not set
+# CONFIG_ARCNET is not set
+
+#
+# CAIF transport drivers
+#
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+CONFIG_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_ARC=y
+# CONFIG_ARC_EMAC is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_CALXEDA_XGMAC 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_SH_ETH 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_NET_VENDOR_WIZNET 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
+
+#
+# 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_RTL8152 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
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_POLLDEV=y
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP 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_GP2A is not set
+# CONFIG_INPUT_GPIO_TILT_POLLED 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_IMS_PCU 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_TTY=y
+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_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ 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_SCCNXP 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_SERIAL_ARC is not set
+# CONFIG_SERIAL_RP2 is not set
+# CONFIG_SERIAL_FSL_LPUART 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_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_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_ISMT 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_CBUS_GPIO is not set
+# CONFIG_I2C_DESIGNWARE_PCI is not set
+# CONFIG_I2C_EG20T is not set
+# CONFIG_I2C_GPIO 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
+
+#
+# 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_SCx200_ACB is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_SPI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+# CONFIG_PTP_1588_CLOCK_PCH is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+CONFIG_GPIO_ACPI=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_TS5500 is not set
+# CONFIG_GPIO_SCH is not set
+# CONFIG_GPIO_ICH is not set
+# CONFIG_GPIO_VX855 is not set
+# CONFIG_GPIO_LYNXPOINT is not set
+# CONFIG_GPIO_GRGPIO 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
+# CONFIG_GPIO_ADNP is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_AMD8111 is not set
+# CONFIG_GPIO_LANGWELL is not set
+# CONFIG_GPIO_PCH is not set
+# CONFIG_GPIO_ML_IOH is not set
+# CONFIG_GPIO_SODAVILLE is not set
+# CONFIG_GPIO_RDC321X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MCP23S08 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+
+#
+# USB 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_DS2781 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_SBS 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_LP8727 is not set
+# CONFIG_CHARGER_GPIO is not set
+# CONFIG_CHARGER_BQ2415X is not set
+# CONFIG_CHARGER_SMB347 is not set
+# CONFIG_BATTERY_GOLDFISH is not set
+# CONFIG_POWER_RESET is not set
+# CONFIG_POWER_AVS 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_ADT7410 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_G762 is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_HIH6130 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_LM95234 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_MAX197 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_MAX6697 is not set
+# CONFIG_SENSORS_MCP3021 is not set
+# CONFIG_SENSORS_NCT6775 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_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_INA209 is not set
+# CONFIG_SENSORS_INA2XX 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_THERMAL_DEFAULT_GOV_STEP_WISE=y
+# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
+# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
+# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+# CONFIG_THERMAL_EMULATION is not set
+# CONFIG_INTEL_POWERCLAMP is not set
+CONFIG_X86_PKG_TEMP_THERMAL=y
+
+#
+# Texas Instruments thermal drivers
+#
+# 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_CS5535 is not set
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_LPC_ICH is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_KEMPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_VIPERBOARD is not set
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_RTSX_PCI is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_SI476X_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SMSC is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TPS65217 is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS80031 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_MFD_ARIZONA_I2C 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_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CAMERA_SUPPORT is not set
+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+# CONFIG_MEDIA_RADIO_SUPPORT is not set
+CONFIG_MEDIA_RC_SUPPORT=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_DVB_CORE=y
+# CONFIG_DVB_NET is not set
+# CONFIG_TTPCI_EEPROM is not set
+CONFIG_DVB_MAX_ADAPTERS=8
+# CONFIG_DVB_DYNAMIC_MINORS is not set
+
+#
+# Media drivers
+#
+CONFIG_RC_CORE=y
+CONFIG_RC_MAP=y
+CONFIG_RC_DECODERS=y
+# CONFIG_LIRC is not set
+# 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_SANYO_DECODER is not set
+CONFIG_IR_MCE_KBD_DECODER=y
+CONFIG_RC_DEVICES=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_IR_IGUANA is not set
+# CONFIG_IR_TTUSBIR is not set
+# CONFIG_RC_LOOPBACK is not set
+# CONFIG_IR_GPIO_CIR is not set
+CONFIG_MEDIA_USB_SUPPORT=y
+
+#
+# Analog/digital TV USB devices
+#
+# CONFIG_VIDEO_AU0828 is not set
+
+#
+# Digital TV USB devices
+#
+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_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_DTV5100 is not set
+# CONFIG_DVB_USB_FRIIO is not set
+# CONFIG_DVB_USB_AZ6027 is not set
+# CONFIG_DVB_USB_TECHNISAT_USB2 is not set
+CONFIG_DVB_USB_V2=y
+# CONFIG_DVB_USB_AF9015 is not set
+CONFIG_DVB_USB_AF9035=m
+# CONFIG_DVB_USB_ANYSEE is not set
+# CONFIG_DVB_USB_AU6610 is not set
+# CONFIG_DVB_USB_AZ6007 is not set
+# CONFIG_DVB_USB_CE6230 is not set
+# CONFIG_DVB_USB_EC168 is not set
+# CONFIG_DVB_USB_GL861 is not set
+# CONFIG_DVB_USB_IT913X is not set
+# CONFIG_DVB_USB_LME2510 is not set
+# CONFIG_DVB_USB_MXL111SF is not set
+# CONFIG_DVB_USB_RTL28XXU is not set
+# CONFIG_DVB_TTUSB_BUDGET is not set
+# CONFIG_DVB_TTUSB_DEC is not set
+# CONFIG_SMS_USB_DRV is not set
+# CONFIG_DVB_B2C2_FLEXCOP_USB is not set
+
+#
+# Webcam, TV (analog/digital) USB devices
+#
+# CONFIG_MEDIA_PCI_SUPPORT is not set
+
+#
+# Supported MMC/SDIO adapters
+#
+# CONFIG_CYPRESS_FIRMWARE is not set
+
+#
+# Media ancillary drivers (tuners, sensors, i2c, frontends)
+#
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+CONFIG_MEDIA_ATTACH=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_MT2063 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_FC0011 is not set
+# CONFIG_MEDIA_TUNER_FC0012 is not set
+# CONFIG_MEDIA_TUNER_FC0013 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
+# CONFIG_MEDIA_TUNER_E4000 is not set
+# CONFIG_MEDIA_TUNER_FC2580 is not set
+# CONFIG_MEDIA_TUNER_TUA9001 is not set
+CONFIG_MEDIA_TUNER_IT913X=m
+# CONFIG_MEDIA_TUNER_R820T is not set
+
+#
+# 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_TS2020 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_HD29L2 is not set
+# CONFIG_DVB_STV0367 is not set
+# CONFIG_DVB_CXD2820R is not set
+# CONFIG_DVB_RTL2830 is not set
+# CONFIG_DVB_RTL2832 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_LG2160 is not set
+# CONFIG_DVB_S5H1409 is not set
+# CONFIG_DVB_AU8522_DTV 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
+# CONFIG_DVB_M88RS2000 is not set
+CONFIG_DVB_AF9033=m
+
+#
+# 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_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_EXYNOS_VIDEO is not set
+# CONFIG_BACKLIGHT_LCD_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_USB_HIFACE is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HID_BATTERY_STRENGTH is not set
+CONFIG_HIDRAW=y
+CONFIG_UHID=y
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=y
+# CONFIG_HID_APPLEIR is not set
+# CONFIG_HID_AUREAL is not set
+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_ELECOM is not set
+# CONFIG_HID_ELO is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_HOLTEK is not set
+# CONFIG_HID_HUION 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_FBX_REMOTE_AUDIO is not set
+CONFIG_HID_GYRATION=y
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=y
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO_TPKBD 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_MAGICMOUSE 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_ROCCAT is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+CONFIG_HID_SONY=y
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+CONFIG_HID_SUNPLUS=y
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+CONFIG_HID_TOPSEED=y
+# CONFIG_HID_THINGM is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_WIIMOTE is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEFAULT_PERSIST 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_MON 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_EHCI_PCI=m
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_FUSBH200_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
+
+#
+# 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
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_CHIPIDEA 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_EZUSB_FX2 is not set
+# CONFIG_USB_HSIC_USB3503 is not set
+# CONFIG_USB_PHY is not set
+# CONFIG_USB_GADGET 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_LM3642 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_LP5562 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_PCA9633 is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+# CONFIG_LEDS_TCA6507 is not set
+# CONFIG_LEDS_LM355x is not set
+# CONFIG_LEDS_OT200 is not set
+# CONFIG_LEDS_BLINKM is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+# CONFIG_LEDS_TRIGGER_ONESHOT is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_CPU 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_LEDS_TRIGGER_TRANSIENT is not set
+# CONFIG_LEDS_TRIGGER_CAMERA is not set
+# CONFIG_FREEBOX_PANEL is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_PCI is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# 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_MAILBOX is not set
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+
+#
+# Rpmsg drivers
+#
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+# CONFIG_VME_BUS is not set
+# CONFIG_PWM is not set
+CONFIG_IRQCHIP=y
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+# CONFIG_FMC 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_GOOGLE_FIRMWARE is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+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_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_WARN 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
+CONFIG_EXFAT_FS=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_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_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# 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_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_PSTORE=y
+# CONFIG_PSTORE_CONSOLE is not set
+CONFIG_PSTORE_RAM=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_SWAP is not set
+# 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_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_DEBUG is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+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_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+
+#
+# printk and dmesg options
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+
+#
+# Compile-time checks and compiler options
+#
+# CONFIG_DEBUG_INFO is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=0
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM 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_ARCH_WANT_FRAME_POINTERS=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+
+#
+# Memory Debugging
+#
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_VIRTUAL is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+CONFIG_HAVE_ARCH_KMEMCHECK=y
+# CONFIG_DEBUG_SHIRQ is not set
+
+#
+# Debug Lockups and Hangs
+#
+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_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_TIMER_STATS is not set
+CONFIG_DEBUG_PREEMPT=y
+
+#
+# Lock Debugging (spinlocks, mutexes, etc...)
+#
+# 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_WW_MUTEX_SLOWPATH is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING 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_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_PROVE_RCU_DELAY is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS 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_DYNAMIC_FTRACE_WITH_REGS=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
+
+#
+# Runtime Testing
+#
+# CONFIG_LKDTM is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_INTERVAL_TREE_TEST is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_X86_VERBOSE_BOOTUP=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_EARLY_PRINTK_DBGP 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_DEBUG_TLBFLUSH is not set
+# 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_NMI_SELFTEST is not set
+# CONFIG_X86_DEBUG_STATIC_CPU_HAS 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=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_CMAC is not set
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32C_INTEL is not set
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_CRC32_PCLMUL 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_SERPENT_SSE2_586 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
+# CONFIG_CRYPTO_LZ4 is not set
+# CONFIG_CRYPTO_LZ4HC is not set
+
+#
+# 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_ASYMMETRIC_KEY_TYPE 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_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IO=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_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+# CONFIG_CRC8 is not set
+CONFIG_AUDIT_GENERIC=y
+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_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_ENC8=y
+CONFIG_REED_SOLOMON_DEC8=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+CONFIG_OID_REGISTRY=y
+CONFIG_FBXSERIAL=y
diff -Nruw linux-3.11.10-fbx/drivers/fbxgpio./Kconfig linux-3.11.10-fbx/drivers/fbxgpio/Kconfig
--- linux-3.11.10-fbx/drivers/fbxgpio./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxgpio/Kconfig	2010-02-25 15:41:07.511150361 +0100
@@ -0,0 +1,3 @@
+config FREEBOX_GPIO
+	tristate "Freebox GPIO control interface"
+	default n
diff -Nruw linux-3.11.10-fbx/drivers/fbxgpio./Makefile linux-3.11.10-fbx/drivers/fbxgpio/Makefile
--- linux-3.11.10-fbx/drivers/fbxgpio./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxgpio/Makefile	2010-02-25 15:41:07.511150361 +0100
@@ -0,0 +1 @@
+obj-$(CONFIG_FREEBOX_GPIO)	+= fbxgpio_core.o
diff -Nruw linux-3.11.10-fbx/drivers/fbxjtag./Kconfig linux-3.11.10-fbx/drivers/fbxjtag/Kconfig
--- linux-3.11.10-fbx/drivers/fbxjtag./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxjtag/Kconfig	2010-02-25 15:41:07.511150361 +0100
@@ -0,0 +1,3 @@
+config FREEBOX_JTAG
+	tristate "Freebox JTAG control interface"
+	default n
diff -Nruw linux-3.11.10-fbx/drivers/fbxjtag./Makefile linux-3.11.10-fbx/drivers/fbxjtag/Makefile
--- linux-3.11.10-fbx/drivers/fbxjtag./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxjtag/Makefile	2010-02-25 15:41:07.511150361 +0100
@@ -0,0 +1 @@
+obj-$(CONFIG_FREEBOX_JTAG)	+= fbxjtag.o
diff -Nruw linux-3.11.10-fbx/drivers/fbxmtd./Kconfig linux-3.11.10-fbx/drivers/fbxmtd/Kconfig
--- linux-3.11.10-fbx/drivers/fbxmtd./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxmtd/Kconfig	2010-02-25 15:41:07.511150361 +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.11.10-fbx/drivers/fbxmtd./Makefile linux-3.11.10-fbx/drivers/fbxmtd/Makefile
--- linux-3.11.10-fbx/drivers/fbxmtd./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxmtd/Makefile	2010-02-25 15:41:07.511150361 +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.11.10-fbx/drivers/fbxpanel./Kconfig linux-3.11.10-fbx/drivers/fbxpanel/Kconfig
--- linux-3.11.10-fbx/drivers/fbxpanel./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxpanel/Kconfig	2010-02-25 15:41:07.511150361 +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.11.10-fbx/drivers/fbxpanel./Makefile linux-3.11.10-fbx/drivers/fbxpanel/Makefile
--- linux-3.11.10-fbx/drivers/fbxpanel./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxpanel/Makefile	2010-02-25 15:41:07.511150361 +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.11.10-fbx/drivers/fbxprocfs./fbxprocfs.c linux-3.11.10-fbx/drivers/fbxprocfs/fbxprocfs.c
--- linux-3.11.10-fbx/drivers/fbxprocfs./fbxprocfs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxprocfs/fbxprocfs.c	2013-12-04 14:33:18.903478972 +0100
@@ -0,0 +1,299 @@
+/*
+ * Freebox ProcFs interface
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+#include <linux/sizes.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_desc *ro_desc,
+		 const struct fbxprocfs_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;
+}
+
+/*
+ * replacement for NULL rfunc.
+ */
+static int bad_rfunc(struct seq_file *m, void *ptr)
+{
+	return -EACCES;
+}
+
+/*
+ * fbxprocfs write path is now handled by seq_file code. this
+ * simplifies client code greatly.
+ */
+static int fbxprocfs_open(struct inode *inode, struct file *file)
+{
+	const struct fbxprocfs_desc *desc = PDE_DATA(inode);
+
+	return single_open(file, desc->rfunc ? desc->rfunc : bad_rfunc,
+			   (void*)desc->id);
+}
+
+/*
+ * no particular help from kernel in the write path, fetch user buffer
+ * in a kernel buffer and call write func.
+ */
+static int fbxprocfs_write(struct file *file, const char __user *ubuf,
+			   size_t len, loff_t *off)
+{
+	/*
+	 * get fbxprocfs desc via the proc_dir_entry in file inode
+	 */
+	struct fbxprocfs_desc *d = PDE_DATA(file_inode(file));
+	char *kbuf;
+	int ret;
+
+	/*
+	 * must have a wfunc callback.
+	 */
+	if (!d->wfunc)
+		return -EACCES;
+
+	/*
+	 * allow up to SZ_4K bytes to be written.
+	 */
+	if (len > SZ_4K)
+		return -EOVERFLOW;
+
+	/*
+	 * alloc and fetch kernel buffer containing user data.
+	 */
+	kbuf = kmalloc(SZ_4K, GFP_KERNEL);
+	if (!kbuf)
+		return -ENOMEM;
+
+	ret = -EFAULT;
+	if (copy_from_user(kbuf, ubuf, len))
+		goto kfree;
+
+	ret = d->wfunc(file, kbuf, len, (void*)d->id);
+
+kfree:
+	kfree(kbuf);
+	return ret;
+}
+
+/*
+ * fbxprocfs file operations, read stuff is handled by seq_file code.
+ */
+static const struct file_operations fbxprocfs_fops = {
+	.open		= fbxprocfs_open,
+	.llseek		= seq_lseek,
+	.read		= seq_read,
+	.release	= seq_release,
+	.write		= fbxprocfs_write,
+};
+
+/*
+ * replaces create_proc_read_entry removed in latest kernels.
+ */
+static struct proc_dir_entry *__create_proc_read_entry(
+				       const struct fbxprocfs_desc *desc,
+				       struct proc_dir_entry *base)
+{
+	return proc_create_data(desc->name, 0, base, &fbxprocfs_fops,
+				(void*)desc);
+}
+
+/*
+ * replaces create_proc_entry removed in latest kernels.
+ */
+static struct proc_dir_entry *__create_proc_entry(
+					const struct fbxprocfs_desc *desc,
+					struct proc_dir_entry *base)
+{
+	return proc_create_data(desc->name, S_IFREG | S_IWUSR | S_IRUGO,
+				base, &fbxprocfs_fops, (void*)desc);
+}
+
+/*
+ * create given entries in client directory
+ */
+static int
+__create_entries(struct fbxprocfs_client *client,
+		 const struct fbxprocfs_desc *ro_desc,
+		 const struct fbxprocfs_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],
+						      client->dir))) {
+			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], client->dir))) {
+			printk(KERN_ERR PFX "can't create %s/%s entry\n",
+			       client->dirname, ro_desc[i].name);
+			goto err;
+		}
+		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_desc *ro_desc,
+			 const struct fbxprocfs_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_desc *ro_desc,
+			 const struct fbxprocfs_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.11.10-fbx/drivers/fbxprocfs./Kconfig linux-3.11.10-fbx/drivers/fbxprocfs/Kconfig
--- linux-3.11.10-fbx/drivers/fbxprocfs./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxprocfs/Kconfig	2010-02-25 15:41:07.519542884 +0100
@@ -0,0 +1,2 @@
+config FREEBOX_PROCFS
+	tristate "Freebox procfs interface"
diff -Nruw linux-3.11.10-fbx/drivers/fbxprocfs./Makefile linux-3.11.10-fbx/drivers/fbxprocfs/Makefile
--- linux-3.11.10-fbx/drivers/fbxprocfs./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxprocfs/Makefile	2010-02-25 15:41:07.519542884 +0100
@@ -0,0 +1 @@
+obj-$(CONFIG_FREEBOX_PROCFS) += fbxprocfs.o
diff -Nruw linux-3.11.10-fbx/drivers/fbxwatchdog./Kconfig linux-3.11.10-fbx/drivers/fbxwatchdog/Kconfig
--- linux-3.11.10-fbx/drivers/fbxwatchdog./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxwatchdog/Kconfig	2013-12-04 14:33:18.903478972 +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.11.10-fbx/drivers/fbxwatchdog./Makefile linux-3.11.10-fbx/drivers/fbxwatchdog/Makefile
--- linux-3.11.10-fbx/drivers/fbxwatchdog./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/fbxwatchdog/Makefile	2013-12-04 14:33:18.903478972 +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.11.10-fbx/drivers/media/platform/tango2./Kconfig linux-3.11.10-fbx/drivers/media/platform/tango2/Kconfig
--- linux-3.11.10-fbx/drivers/media/platform/tango2./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/platform/tango2/Kconfig	2013-12-04 14:33:19.559478983 +0100
@@ -0,0 +1,11 @@
+config DVB_TANGO2
+	tristate "Tango2 DVB adapter"
+	depends on 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.11.10-fbx/drivers/media/platform/tango2./Makefile linux-3.11.10-fbx/drivers/media/platform/tango2/Makefile
--- linux-3.11.10-fbx/drivers/media/platform/tango2./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/media/platform/tango2/Makefile	2013-12-04 14:33:19.559478983 +0100
@@ -0,0 +1,5 @@
+obj-$(CONFIG_DVB_TANGO2) = tango2_dvb.o
+
+tango2_dvb-objs := tango2.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
--- /dev/null	2015-07-28 12:46:09.152032985 +0200
+++ linux-3.11.10-fbx/drivers/media/rc/keymaps/rc-rc6-freebox.c	2013-12-04 14:33:19.575478983 +0100
@@ -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_MCE,
+		.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>");
diff -Nruw linux-3.11.10-fbx/drivers/misc/hdmi-cec./core.c linux-3.11.10-fbx/drivers/misc/hdmi-cec/core.c
--- linux-3.11.10-fbx/drivers/misc/hdmi-cec./core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/hdmi-cec/core.c	2013-12-20 15:48:08.931562434 +0100
@@ -0,0 +1,580 @@
+/*
+ * 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);
+
+	adapter->tx_timeout_timer.expires = jiffies + HZ * 5;
+	add_timer(&adapter->tx_timeout_timer);
+
+out:
+	mutex_unlock(&adapter->lock);
+	return ret;
+}
+
+/**
+ * adapter_tx_done() - called by adapter when tx is complete
+ * @adapter:	adapter pointer
+ *
+ */
+static 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);
+}
+
+void adapter_tx_done(struct cec_adapter *adapter, bool success,
+		     u8 flags, u8 tries)
+{
+	del_timer_sync(&adapter->tx_timeout_timer);
+	__adapter_tx_done(adapter, success, flags, tries);
+}
+
+EXPORT_SYMBOL(adapter_tx_done);
+
+/*
+ *
+ */
+static void adapter_tx_timeout(unsigned long data)
+{
+	struct cec_adapter *adapter = (struct cec_adapter *)data;
+	dev_err(&adapter->dev, "tx timeout\n");
+	__adapter_tx_done(adapter, false, CEC_TX_F_UNKNOWN_ERROR, 0);
+}
+
+/**
+ * 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;
+
+	init_timer(&adapter->tx_timeout_timer);
+	adapter->tx_timeout_timer.function = adapter_tx_timeout;
+	adapter->tx_timeout_timer.data = (unsigned long)adapter;
+
+	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);
+
+	del_timer_sync(&adapter->tx_timeout_timer);
+
+	/* 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);
+	/* let sysfs release the device */
+	dev_info(&adapter->dev, "unregistering cec adapter\n");
+	device_unregister(&adapter->dev);
+}
+
+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.11.10-fbx/drivers/misc/hdmi-cec./dev.c linux-3.11.10-fbx/drivers/misc/hdmi-cec/dev.c
--- linux-3.11.10-fbx/drivers/misc/hdmi-cec./dev.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/hdmi-cec/dev.c	2013-12-04 14:33:19.703478985 +0100
@@ -0,0 +1,293 @@
+/*
+ * 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 cec_adapter *adapter = f->private_data;
+
+	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.11.10-fbx/drivers/misc/hdmi-cec./hdmi-cec-priv.h linux-3.11.10-fbx/drivers/misc/hdmi-cec/hdmi-cec-priv.h
--- linux-3.11.10-fbx/drivers/misc/hdmi-cec./hdmi-cec-priv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/hdmi-cec/hdmi-cec-priv.h	2013-12-04 14:33:19.703478985 +0100
@@ -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.11.10-fbx/drivers/misc/hdmi-cec./Kconfig linux-3.11.10-fbx/drivers/misc/hdmi-cec/Kconfig
--- linux-3.11.10-fbx/drivers/misc/hdmi-cec./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/hdmi-cec/Kconfig	2013-12-04 14:33:19.703478985 +0100
@@ -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.11.10-fbx/drivers/misc/hdmi-cec./Makefile linux-3.11.10-fbx/drivers/misc/hdmi-cec/Makefile
--- linux-3.11.10-fbx/drivers/misc/hdmi-cec./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/hdmi-cec/Makefile	2013-12-04 14:33:19.703478985 +0100
@@ -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.11.10-fbx/drivers/misc/hdmi-cec./remoti.c linux-3.11.10-fbx/drivers/misc/hdmi-cec/remoti.c
--- linux-3.11.10-fbx/drivers/misc/hdmi-cec./remoti.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/hdmi-cec/remoti.c	2013-12-04 14:33:19.703478985 +0100
@@ -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 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 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	= 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	2015-07-28 12:46:09.152032985 +0200
+++ linux-3.11.10-fbx/drivers/misc/pic16-pmu.c	2013-12-04 14:33:19.711478985 +0100
@@ -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 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 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		= 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.11.10-fbx/drivers/misc/remoti./core.c linux-3.11.10-fbx/drivers/misc/remoti/core.c
--- linux-3.11.10-fbx/drivers/misc/remoti./core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/remoti/core.c	2013-12-04 14:33:19.711478985 +0100
@@ -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 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		= 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.11.10-fbx/drivers/misc/remoti./core-priv.h linux-3.11.10-fbx/drivers/misc/remoti/core-priv.h
--- linux-3.11.10-fbx/drivers/misc/remoti./core-priv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/remoti/core-priv.h	2013-12-04 14:33:19.711478985 +0100
@@ -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.11.10-fbx/drivers/misc/remoti./core-sysfs.c linux-3.11.10-fbx/drivers/misc/remoti/core-sysfs.c
--- linux-3.11.10-fbx/drivers/misc/remoti./core-sysfs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/remoti/core-sysfs.c	2013-12-04 14:33:19.711478985 +0100
@@ -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.11.10-fbx/drivers/misc/remoti./Kconfig linux-3.11.10-fbx/drivers/misc/remoti/Kconfig
--- linux-3.11.10-fbx/drivers/misc/remoti./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/remoti/Kconfig	2013-12-04 14:33:19.711478985 +0100
@@ -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.11.10-fbx/drivers/misc/remoti./leds.c linux-3.11.10-fbx/drivers/misc/remoti/leds.c
--- linux-3.11.10-fbx/drivers/misc/remoti./leds.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/remoti/leds.c	2013-12-04 14:33:19.711478985 +0100
@@ -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 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 = 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.11.10-fbx/drivers/misc/remoti./Makefile linux-3.11.10-fbx/drivers/misc/remoti/Makefile
--- linux-3.11.10-fbx/drivers/misc/remoti./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/remoti/Makefile	2013-12-04 14:33:19.711478985 +0100
@@ -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.11.10-fbx/drivers/misc/remoti./user.c linux-3.11.10-fbx/drivers/misc/remoti/user.c
--- linux-3.11.10-fbx/drivers/misc/remoti./user.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.11.10-fbx/drivers/misc/remoti/user.c	2013-12-04 14:33:19.711478985 +0100
@@ -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	2015-07-28 12:46:09.152032985 +0200
+++ linux-3.11.10-fbx/drivers/mtd/fbx6hd-mtdparts.c	2013-12-04 14:33:19.747478986 +0100
@@ -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_BANK