diff -ruw linux-2.6.31.7/arch/mips/include/asm/cpu.h linux-2.6.31.7-fbx/arch/mips/include/asm/cpu.h
--- linux-2.6.31.7/arch/mips/include/asm/cpu.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/cpu.h	2011-05-23 16:08:41.753678754 +0200
@@ -113,6 +113,12 @@
 
 #define PRID_IMP_BCM4710	0x4000
 #define PRID_IMP_BCM3302	0x9000
+#define PRID_IMP_BCM6338	0x9000
+#define PRID_IMP_BCM6345	0x8000
+#define PRID_IMP_BCM6348	0x9100
+#define PRID_IMP_BCM4350	0xA000
+#define PRID_REV_BCM6358	0x0010
+#define PRID_REV_BCM6368	0x0030
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_CAVIUM
@@ -210,6 +216,7 @@
 	 */
 	CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
 	CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
+	CPU_BCM6338, CPU_BCM6345, CPU_BCM6348, CPU_BCM6358,
 
 	/*
 	 * MIPS64 class processors
diff -ruw linux-2.6.31.7/arch/mips/include/asm/fixmap.h linux-2.6.31.7-fbx/arch/mips/include/asm/fixmap.h
--- linux-2.6.31.7/arch/mips/include/asm/fixmap.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/fixmap.h	2010-10-25 13:43:55.971490607 +0200
@@ -67,11 +67,15 @@
  * the start of the fixmap, and leave one page empty
  * at the top of mem..
  */
+#ifdef CONFIG_BCM63XX
+#define FIXADDR_TOP     ((unsigned long)(long)(int)0xff000000)
+#else
 #if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX)
 #define FIXADDR_TOP	((unsigned long)(long)(int)(0xff000000 - 0x20000))
 #else
 #define FIXADDR_TOP	((unsigned long)(long)(int)0xfffe0000)
 #endif
+#endif
 #define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
 #define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
 
diff -ruw linux-2.6.31.7/arch/mips/Kconfig linux-2.6.31.7-fbx/arch/mips/Kconfig
--- linux-2.6.31.7/arch/mips/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/Kconfig	2011-09-09 16:15:47.800298342 +0200
@@ -568,6 +568,23 @@
 	  Technology and now in turn merged with Fujitsu.  Say Y here to
 	  support this machine type.
 
+config TANGO2
+	bool "Sigma Designs SMP863x platform (Tango2)"
+	select CEVT_R4K
+	select CSRC_R4K
+	select HW_HAS_PCI
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select GENERIC_GPIO
+	select SYS_HAS_EARLY_PRINTK
+	select USB_ARCH_HAS_OHCI
+	select USB_ARCH_HAS_EHCI
+	help
+	 Support for Sigma Designs SMP863x platform (Tango2)
+
 config MACH_TX39XX
 	bool "Toshiba TX39 series based machines"
 
@@ -665,6 +682,7 @@
 source "arch/mips/pmc-sierra/Kconfig"
 source "arch/mips/sgi-ip27/Kconfig"
 source "arch/mips/sibyte/Kconfig"
+source "arch/mips/tango2/Kconfig"
 source "arch/mips/txx9/Kconfig"
 source "arch/mips/vr41xx/Kconfig"
 source "arch/mips/cavium-octeon/Kconfig"
@@ -792,7 +810,7 @@
 config EARLY_PRINTK
 	bool "Early printk" if EMBEDDED && DEBUG_KERNEL
 	depends on SYS_HAS_EARLY_PRINTK
-	default y
+	default y if DEBUG_KERNEL
 	help
 	  This option enables special console drivers which allow the kernel
 	  to print messages very early in the bootup process.
@@ -2191,3 +2209,9 @@
 source "crypto/Kconfig"
 
 source "lib/Kconfig"
+
+config CROSS_PATH
+	string "cross path"
+	default "mips-linux-" if CPU_BIG_ENDIAN
+	default "mipsel-linux-" if CPU_LITTLE_ENDIAN
+
diff -ruw linux-2.6.31.7/arch/mips/kernel/cpu-probe.c linux-2.6.31.7-fbx/arch/mips/kernel/cpu-probe.c
--- linux-2.6.31.7/arch/mips/kernel/cpu-probe.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/kernel/cpu-probe.c	2011-05-23 16:08:41.753678754 +0200
@@ -160,6 +160,10 @@
 	case CPU_PR4450:
 	case CPU_BCM3302:
 	case CPU_CAVIUM_OCTEON:
+	case CPU_BCM6338:
+	case CPU_BCM6345:
+	case CPU_BCM6348:
+	case CPU_BCM6358:
 		cpu_wait = r4k_wait;
 		break;
 
@@ -857,6 +861,7 @@
 	decode_configs(c);
 	switch (c->processor_id & 0xff00) {
 	case PRID_IMP_BCM3302:
+	/* same as PRID_IMP_BCM6338 */
 		c->cputype = CPU_BCM3302;
 		__cpu_name[cpu] = "Broadcom BCM3302";
 		break;
@@ -864,6 +869,28 @@
 		c->cputype = CPU_BCM4710;
 		__cpu_name[cpu] = "Broadcom BCM4710";
 		break;
+	case PRID_IMP_BCM6345:
+		c->cputype = CPU_BCM6345;
+		__cpu_name[cpu] = "Broadcom BCM6345";
+		break;
+	case PRID_IMP_BCM6348:
+		c->cputype = CPU_BCM6348;
+		__cpu_name[cpu] = "Broadcom BCM6348";
+		break;
+	case PRID_IMP_BCM4350:
+		switch (c->processor_id & 0xf0) {
+		case PRID_REV_BCM6358:
+			c->cputype = CPU_BCM6358;
+			__cpu_name[cpu] = "Broadcom BCM6358";
+			break;
+		default:
+			c->cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
+	default:
+		c->cputype = CPU_UNKNOWN;
+		break;
 	}
 }
 
diff -ruw linux-2.6.31.7/arch/mips/kernel/Makefile linux-2.6.31.7-fbx/arch/mips/kernel/Makefile
--- linux-2.6.31.7/arch/mips/kernel/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/kernel/Makefile	2010-10-25 13:43:55.981506139 +0200
@@ -2,7 +2,7 @@
 # Makefile for the Linux/MIPS kernel.
 #
 
-CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
+CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS) $(EXTRA_LDSFLAGS)
 
 extra-y		:= head.o init_task.o vmlinux.lds
 
diff -ruw linux-2.6.31.7/arch/mips/kernel/traps.c linux-2.6.31.7-fbx/arch/mips/kernel/traps.c
--- linux-2.6.31.7/arch/mips/kernel/traps.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/kernel/traps.c	2010-10-25 13:43:55.991442951 +0200
@@ -1537,7 +1537,12 @@
 	 *  o read IntCtl.IPPCI to determine the performance counter interrupt
 	 */
 	if (cpu_has_mips_r2) {
+#ifndef CONFIG_TANGO2
 		cp0_compare_irq = (read_c0_intctl() >> 29) & 7;
+#else
+		/* buggy CPU */
+		cp0_compare_irq = 7;
+#endif
 		cp0_perfcount_irq = (read_c0_intctl() >> 26) & 7;
 		if (cp0_perfcount_irq == cp0_compare_irq)
 			cp0_perfcount_irq = -1;
diff -ruw linux-2.6.31.7/arch/mips/Makefile linux-2.6.31.7-fbx/arch/mips/Makefile
--- linux-2.6.31.7/arch/mips/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/Makefile	2011-05-23 16:08:41.753678754 +0200
@@ -43,12 +43,12 @@
 endif
 
 ifneq ($(SUBARCH),$(ARCH))
-  ifeq ($(CROSS_COMPILE),)
-    CROSS_COMPILE := $(call cc-cross-prefix, $(tool-archpref)-linux-  $(tool-archpref)-linux-gnu-  $(tool-archpref)-unknown-linux-gnu-)
+  ifneq ($(CONFIG_CROSS_PATH),)
+    CROSS_COMPILE := $(patsubst "%",%,$(CONFIG_CROSS_PATH))
   endif
 endif
 
-cflags-y := -ffunction-sections
+# cflags-y := -ffunction-sections
 cflags-y += $(call cc-option, -mno-check-zero-division)
 
 ifdef CONFIG_32BIT
@@ -572,6 +572,13 @@
 all-$(CONFIG_SNI_RM)		:= vmlinux.ecoff
 
 #
+# SigmaDesigns Tango2 arch
+#
+core-$(CONFIG_TANGO2)		+= arch/mips/tango2/
+cflags-$(CONFIG_TANGO2)		+= -I$(srctree)/arch/mips/include/asm/mach-tango2/
+load-$(CONFIG_TANGO2)		:= 0xffffffff90020000
+
+#
 # Common TXx9
 #
 core-$(CONFIG_MACH_TX39XX)	+= arch/mips/txx9/generic/
diff -ruw linux-2.6.31.7/arch/mips/mm/fault.c linux-2.6.31.7-fbx/arch/mips/mm/fault.c
--- linux-2.6.31.7/arch/mips/mm/fault.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/mm/fault.c	2010-10-25 13:43:55.991442951 +0200
@@ -130,10 +130,10 @@
 	if (user_mode(regs)) {
 		tsk->thread.cp0_badvaddr = address;
 		tsk->thread.error_code = write;
-#if 0
-		printk("do_page_fault() #2: sending SIGSEGV to %s for "
+#if 1
+		printk("do_page_fault() #2: sending SIGSEGV to %s[%d] for "
 		       "invalid %s\n%0*lx (epc == %0*lx, ra == %0*lx)\n",
-		       tsk->comm,
+		       tsk->comm, tsk->pid,
 		       write ? "write access to" : "read access from",
 		       field, address,
 		       field, (unsigned long) regs->cp0_epc,
diff -ruw linux-2.6.31.7/arch/mips/mm/tlbex.c linux-2.6.31.7-fbx/arch/mips/mm/tlbex.c
--- linux-2.6.31.7/arch/mips/mm/tlbex.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/mm/tlbex.c	2010-10-25 13:43:55.991442951 +0200
@@ -322,6 +322,10 @@
 	case CPU_BCM4710:
 	case CPU_LOONGSON2:
 	case CPU_R5500:
+	case CPU_BCM6338:
+	case CPU_BCM6345:
+	case CPU_BCM6348:
+	case CPU_BCM6358:
 		if (m4kc_tlbp_war())
 			uasm_i_nop(p);
 	case CPU_ALCHEMY:
diff -ruw linux-2.6.31.7/arch/mips/pci/Makefile linux-2.6.31.7-fbx/arch/mips/pci/Makefile
--- linux-2.6.31.7/arch/mips/pci/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/pci/Makefile	2011-05-23 16:08:41.753678754 +0200
@@ -16,6 +16,8 @@
 obj-$(CONFIG_NEC_MARKEINS)	+= ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
 obj-$(CONFIG_PCI_TX4927)	+= ops-tx4927.o
 obj-$(CONFIG_BCM47XX)		+= pci-bcm47xx.o
+obj-$(CONFIG_BCM63XX)		+= pci-bcm63xx.o fixup-bcm63xx.o \
+					ops-bcm63xx.o
 
 #
 # These are still pretty much in the old state, watch, go blind.
@@ -57,3 +59,5 @@
 ifdef CONFIG_PCI_MSI
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= msi-octeon.o
 endif
+
+obj-$(CONFIG_TANGO2)		+= pci-tango2.o ops-tango2.o fixup-tango2.o
diff -ruw linux-2.6.31.7/block/blk-core.c linux-2.6.31.7-fbx/block/blk-core.c
--- linux-2.6.31.7/block/blk-core.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/block/blk-core.c	2010-10-25 13:43:56.231445651 +0200
@@ -1111,17 +1111,13 @@
 	req->cmd_type = REQ_TYPE_FS;
 
 	/*
-	 * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST)
+	 * Inherit FAILFAST from bio (for read-ahead, and explicit
+	 * FAILFAST).  FAILFAST flags are identical for req and bio.
 	 */
 	if (bio_rw_ahead(bio))
-		req->cmd_flags |= (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
-				   REQ_FAILFAST_DRIVER);
-	if (bio_failfast_dev(bio))
-		req->cmd_flags |= REQ_FAILFAST_DEV;
-	if (bio_failfast_transport(bio))
-		req->cmd_flags |= REQ_FAILFAST_TRANSPORT;
-	if (bio_failfast_driver(bio))
-		req->cmd_flags |= REQ_FAILFAST_DRIVER;
+		req->cmd_flags |= REQ_FAILFAST_MASK;
+	else
+		req->cmd_flags |= bio->bi_rw & REQ_FAILFAST_MASK;
 
 	if (unlikely(bio_discard(bio))) {
 		req->cmd_flags |= REQ_DISCARD;
@@ -2239,9 +2235,8 @@
 void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
 		     struct bio *bio)
 {
-	/* Bit 0 (R/W) is identical in rq->cmd_flags and bio->bi_rw, and
-	   we want BIO_RW_AHEAD (bit 1) to imply REQ_FAILFAST (bit 1). */
-	rq->cmd_flags |= (bio->bi_rw & 3);
+	/* Bit 0 (R/W) is identical in rq->cmd_flags and bio->bi_rw */
+	rq->cmd_flags |= bio->bi_rw & REQ_RW;
 
 	if (bio_has_data(bio)) {
 		rq->nr_phys_segments = bio_phys_segments(q, bio);
diff -ruw linux-2.6.31.7/crypto/algboss.c linux-2.6.31.7-fbx/crypto/algboss.c
--- linux-2.6.31.7/crypto/algboss.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/crypto/algboss.c	2010-10-25 13:43:56.241443311 +0200
@@ -209,7 +209,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-2.6.31.7/crypto/Kconfig linux-2.6.31.7-fbx/crypto/Kconfig
--- linux-2.6.31.7/crypto/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/crypto/Kconfig	2010-10-25 13:43:56.241443311 +0200
@@ -80,6 +80,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-2.6.31.7/crypto/Makefile linux-2.6.31.7-fbx/crypto/Makefile
--- linux-2.6.31.7/crypto/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/crypto/Makefile	2010-10-25 13:43:56.241443311 +0200
@@ -29,7 +29,10 @@
 
 obj-$(CONFIG_CRYPTO_PCOMP) += pcompress.o
 
-cryptomgr-objs := algboss.o testmgr.o
+cryptomgr-objs := algboss.o
+ifeq ($(CONFIG_CRYPTO_BUILTIN_TEST),y)
+cryptomgr-objs += testmgr.o
+endif
 
 obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
diff -ruw linux-2.6.31.7/drivers/hwmon/Kconfig linux-2.6.31.7-fbx/drivers/hwmon/Kconfig
--- linux-2.6.31.7/drivers/hwmon/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/hwmon/Kconfig	2010-10-25 13:43:56.411443585 +0200
@@ -402,12 +402,12 @@
 	  will be called gl520sm.
 
 config SENSORS_CORETEMP
-	tristate "Intel Core (2) Duo/Solo temperature sensor"
+	tristate "Intel Core/Core2/Atom temperature sensor"
 	depends on X86 && EXPERIMENTAL
 	help
 	  If you say yes here you get support for the temperature
-	  sensor inside your CPU. Supported all are all known variants
-	  of Intel Core family.
+	  sensor inside your CPU. Most of the family 6 CPUs
+	  are supported. Check documentation/driver for details.
 
 config SENSORS_IBMAEM
 	tristate "IBM Active Energy Manager temperature/power sensors and control"
diff -ruw linux-2.6.31.7/drivers/i2c/busses/Kconfig linux-2.6.31.7-fbx/drivers/i2c/busses/Kconfig
--- linux-2.6.31.7/drivers/i2c/busses/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/i2c/busses/Kconfig	2010-10-25 13:43:56.441447728 +0200
@@ -461,7 +461,7 @@
 
 config I2C_PXA
 	tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && ARCH_PXA
+	depends on EXPERIMENTAL && (ARCH_PXA || PCI)
 	help
 	  If you have devices in the PXA I2C bus, say yes to this option.
 	  This driver can also be built as a module.  If so, the module
diff -ruw linux-2.6.31.7/drivers/ide/ide-disk.c linux-2.6.31.7-fbx/drivers/ide/ide-disk.c
--- linux-2.6.31.7/drivers/ide/ide-disk.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/ide/ide-disk.c	2010-10-25 13:43:56.451445421 +0200
@@ -452,6 +452,7 @@
 	cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
 	cmd->tf_flags = IDE_TFLAG_DYN;
 	cmd->protocol = ATA_PROT_NODATA;
+	cmd->rq = rq;
 
 	rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
 	rq->special = cmd;
diff -ruw linux-2.6.31.7/drivers/ide/ide-probe.c linux-2.6.31.7-fbx/drivers/ide/ide-probe.c
--- linux-2.6.31.7/drivers/ide/ide-probe.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/ide/ide-probe.c	2010-10-25 13:43:56.451445421 +0200
@@ -759,7 +759,12 @@
 		return 1;
 
 	q->queuedata = drive;
+
+#ifdef CONFIG_BLK_DEV_IDE_TANGO2
 	blk_queue_segment_boundary(q, 0xffff);
+#else
+	blk_queue_segment_boundary(q, 0xffffffff);
+#endif
 
 	if (hwif->rqsize < max_sectors)
 		max_sectors = hwif->rqsize;
diff -ruw linux-2.6.31.7/drivers/ide/Kconfig linux-2.6.31.7-fbx/drivers/ide/Kconfig
--- linux-2.6.31.7/drivers/ide/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/ide/Kconfig	2010-03-18 18:28:49.282986858 +0100
@@ -717,6 +717,11 @@
        depends on SOC_AU1200 && 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-2.6.31.7/drivers/ide/Makefile linux-2.6.31.7-fbx/drivers/ide/Makefile
--- linux-2.6.31.7/drivers/ide/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/ide/Makefile	2010-03-18 18:28:49.282986858 +0100
@@ -117,3 +117,4 @@
 obj-$(CONFIG_BLK_DEV_IDE_TX4938)	+= tx4938ide.o
 obj-$(CONFIG_BLK_DEV_IDE_TX4939)	+= tx4939ide.o
 obj-$(CONFIG_BLK_DEV_IDE_AT91)		+= at91_ide.o
+obj-$(CONFIG_BLK_DEV_IDE_TANGO2)	+= tango2ide.o
diff -ruw linux-2.6.31.7/drivers/input/misc/Kconfig linux-2.6.31.7-fbx/drivers/input/misc/Kconfig
--- linux-2.6.31.7/drivers/input/misc/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/input/misc/Kconfig	2010-10-25 13:43:56.491443075 +0200
@@ -269,4 +269,15 @@
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called dm355evm_keys.
+
+config INPUT_SMSC_CAP1014
+	tristate "SMSC CAP1014 capacitive sensor driver"
+	select I2C
+	select INPUT_POLLDEV
+
+config INPUT_SMSC_CAP1066
+	tristate "SMSC CAP1066 capacitive sensor driver"
+	select I2C
+	select INPUT_POLLDEV
+
 endif
diff -ruw linux-2.6.31.7/drivers/input/misc/Makefile linux-2.6.31.7-fbx/drivers/input/misc/Makefile
--- linux-2.6.31.7/drivers/input/misc/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/input/misc/Makefile	2010-10-25 13:43:56.491443075 +0200
@@ -26,3 +26,5 @@
 obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
 obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
+obj-$(CONFIG_INPUT_SMSC_CAP1014)	+= smsc_cap1014.o
+obj-$(CONFIG_INPUT_SMSC_CAP1066)	+= smsc_cap1066.o
diff -ruw linux-2.6.31.7/drivers/Kconfig linux-2.6.31.7-fbx/drivers/Kconfig
--- linux-2.6.31.7/drivers/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/Kconfig	2010-03-18 18:28:49.042817945 +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"
@@ -56,6 +60,10 @@
 
 source "drivers/gpio/Kconfig"
 
+source "drivers/fbxgpio/Kconfig"
+
+source "drivers/fbxjtag/Kconfig"
+
 source "drivers/w1/Kconfig"
 
 source "drivers/power/Kconfig"
@@ -64,6 +72,8 @@
 
 source "drivers/thermal/Kconfig"
 
+source "drivers/fbxwatchdog/Kconfig"
+
 source "drivers/watchdog/Kconfig"
 
 source "drivers/ssb/Kconfig"
@@ -90,6 +100,8 @@
 
 source "drivers/leds/Kconfig"
 
+source "drivers/fbxpanel/Kconfig"
+
 source "drivers/accessibility/Kconfig"
 
 source "drivers/infiniband/Kconfig"
@@ -100,6 +112,8 @@
 
 source "drivers/dma/Kconfig"
 
+source "drivers/fbxdmamux/Kconfig"
+
 source "drivers/dca/Kconfig"
 
 source "drivers/auxdisplay/Kconfig"
@@ -113,4 +127,5 @@
 source "drivers/staging/Kconfig"
 
 source "drivers/platform/Kconfig"
+
 endmenu
diff -ruw linux-2.6.31.7/drivers/leds/Kconfig linux-2.6.31.7-fbx/drivers/leds/Kconfig
--- linux-2.6.31.7/drivers/leds/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/leds/Kconfig	2010-10-25 13:43:56.531447957 +0200
@@ -297,4 +297,11 @@
 comment "iptables trigger is under Netfilter config (LED target)"
 	depends on LEDS_TRIGGERS
 
+config LEDS_TRIGGER_NETDEV
+	tristate "LED Network Device Trigger"
+	depends on LEDS_TRIGGERS
+	help
+	  This allows LEDs to be controlled by Network Device activity.
+	  If unsure, say Y.
+	  
 endif # NEW_LEDS
diff -ruw linux-2.6.31.7/drivers/leds/Makefile linux-2.6.31.7-fbx/drivers/leds/Makefile
--- linux-2.6.31.7/drivers/leds/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/leds/Makefile	2010-10-25 13:43:56.531447957 +0200
@@ -36,6 +36,7 @@
 obj-$(CONFIG_LEDS_TRIGGER_TIMER)	+= ledtrig-timer.o
 obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK)	+= ledtrig-ide-disk.o
 obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT)	+= ledtrig-heartbeat.o
+obj-$(CONFIG_LEDS_TRIGGER_NETDEV)	+= ledtrig-netdev.o
 obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)	+= ledtrig-backlight.o
 obj-$(CONFIG_LEDS_TRIGGER_GPIO)		+= ledtrig-gpio.o
 obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)	+= ledtrig-default-on.o
diff -ruw linux-2.6.31.7/drivers/Makefile linux-2.6.31.7-fbx/drivers/Makefile
--- linux-2.6.31.7/drivers/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/Makefile	2010-10-25 13:43:56.261444538 +0200
@@ -6,6 +6,8 @@
 #
 
 obj-y				+= gpio/
+obj-$(CONFIG_FREEBOX_GPIO)	+= fbxgpio/
+obj-$(CONFIG_FREEBOX_JTAG)	+= fbxjtag/
 obj-$(CONFIG_PCI)		+= pci/
 obj-$(CONFIG_PARISC)		+= parisc/
 obj-$(CONFIG_RAPIDIO)		+= rapidio/
@@ -50,7 +52,9 @@
 obj-$(CONFIG_UIO)		+= uio/
 obj-y				+= cdrom/
 obj-y				+= auxdisplay/
+obj-$(CONFIG_FREEBOX_PROCFS)	+= fbxprocfs/
 obj-$(CONFIG_MTD)		+= mtd/
+obj-$(CONFIG_FREEBOX_MTD)	+= fbxmtd/
 obj-$(CONFIG_SPI)		+= spi/
 obj-$(CONFIG_PCCARD)		+= pcmcia/
 obj-$(CONFIG_DIO)		+= dio/
@@ -77,6 +81,7 @@
 obj-$(CONFIG_POWER_SUPPLY)	+= power/
 obj-$(CONFIG_HWMON)		+= hwmon/
 obj-$(CONFIG_THERMAL)		+= thermal/
+obj-$(CONFIG_FREEBOX_WATCHDOG)	+= fbxwatchdog/
 obj-$(CONFIG_WATCHDOG)		+= watchdog/
 obj-$(CONFIG_PHONE)		+= telephony/
 obj-$(CONFIG_MD)		+= md/
@@ -93,6 +98,7 @@
 obj-$(CONFIG_MMC)		+= mmc/
 obj-$(CONFIG_MEMSTICK)		+= memstick/
 obj-$(CONFIG_NEW_LEDS)		+= leds/
+obj-$(CONFIG_FREEBOX_PANEL)	+= fbxpanel/
 obj-$(CONFIG_INFINIBAND)	+= infiniband/
 obj-$(CONFIG_SGI_SN)		+= sn/
 obj-y				+= firmware/
@@ -100,6 +106,7 @@
 obj-$(CONFIG_SUPERH)		+= sh/
 obj-$(CONFIG_GENERIC_TIME)	+= clocksource/
 obj-$(CONFIG_DMA_ENGINE)	+= dma/
+obj-$(CONFIG_FREEBOX_DMAMUX)	+= fbxdmamux/
 obj-$(CONFIG_DCA)		+= dca/
 obj-$(CONFIG_HID)		+= hid/
 obj-$(CONFIG_PPC_PS3)		+= ps3/
diff -ruw linux-2.6.31.7/drivers/md/dm-ioctl.c linux-2.6.31.7-fbx/drivers/md/dm-ioctl.c
--- linux-2.6.31.7/drivers/md/dm-ioctl.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/md/dm-ioctl.c	2010-10-25 13:43:56.541546114 +0200
@@ -1509,7 +1509,10 @@
 	return r;
 }
 
-static long dm_ctl_ioctl(struct file *file, uint command, ulong u)
+#ifndef CONFIG_DMCRYPTATBOOT
+static
+#endif
+long dm_ctl_ioctl(struct file *file, uint command, ulong u)
 {
 	return (long)ctl_ioctl(command, (struct dm_ioctl __user *)u);
 }
diff -ruw linux-2.6.31.7/drivers/media/dvb/dvb-core/dmxdev.c linux-2.6.31.7-fbx/drivers/media/dvb/dvb-core/dmxdev.c
--- linux-2.6.31.7/drivers/media/dvb/dvb-core/dmxdev.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/dvb-core/dmxdev.c	2010-10-25 13:43:56.551443309 +0200
@@ -430,6 +430,8 @@
 /* stop feed but only mark the specified filter as stopped (state set) */
 static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
 {
+	struct dmxdev_feed *feed;
+
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
 
 	switch (dmxdevfilter->type) {
@@ -438,7 +440,8 @@
 		dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);
 		break;
 	case DMXDEV_TYPE_PES:
-		dmxdevfilter->feed.ts->stop_filtering(dmxdevfilter->feed.ts);
+		list_for_each_entry(feed, &dmxdevfilter->feed.ts, next)
+			feed->ts->stop_filtering(feed->ts);
 		break;
 	default:
 		return -EINVAL;
@@ -449,13 +452,23 @@
 /* start feed associated with the specified filter */
 static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter)
 {
+	struct dmxdev_feed *feed;
+	int ret;
+
 	dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
 
 	switch (filter->type) {
 	case DMXDEV_TYPE_SEC:
 		return filter->feed.sec->start_filtering(filter->feed.sec);
 	case DMXDEV_TYPE_PES:
-		return filter->feed.ts->start_filtering(filter->feed.ts);
+		list_for_each_entry(feed, &filter->feed.ts, next) {
+			ret = feed->ts->start_filtering(feed->ts);
+			if (ret < 0) {
+				dvb_dmxdev_feed_stop(filter);
+				return ret;
+			}
+		}
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -487,6 +500,9 @@
 
 static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
 {
+	struct dmxdev_feed *feed;
+	struct dmx_demux *demux;
+
 	if (dmxdevfilter->state < DMXDEV_STATE_GO)
 		return 0;
 
@@ -503,13 +519,12 @@
 		dmxdevfilter->feed.sec = NULL;
 		break;
 	case DMXDEV_TYPE_PES:
-		if (!dmxdevfilter->feed.ts)
-			break;
 		dvb_dmxdev_feed_stop(dmxdevfilter);
-		dmxdevfilter->dev->demux->
-		    release_ts_feed(dmxdevfilter->dev->demux,
-				    dmxdevfilter->feed.ts);
-		dmxdevfilter->feed.ts = NULL;
+		demux = dmxdevfilter->dev->demux;
+		list_for_each_entry(feed, &dmxdevfilter->feed.ts, next) {
+			demux->release_ts_feed(demux, feed->ts);
+			feed->ts = NULL;
+		}
 		break;
 	default:
 		if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED)
@@ -521,19 +536,88 @@
 	return 0;
 }
 
+static void dvb_dmxdev_delete_pids(struct dmxdev_filter *dmxdevfilter)
+{
+	struct dmxdev_feed *feed, *tmp;
+
+	/* delete all PIDs */
+	list_for_each_entry_safe(feed, tmp, &dmxdevfilter->feed.ts, next) {
+		list_del(&feed->next);
+		kfree(feed);
+	}
+
+	BUG_ON(!list_empty(&dmxdevfilter->feed.ts));
+}
+
 static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter)
 {
 	if (dmxdevfilter->state < DMXDEV_STATE_SET)
 		return 0;
 
+	if (dmxdevfilter->type == DMXDEV_TYPE_PES)
+		dvb_dmxdev_delete_pids(dmxdevfilter);
+
 	dmxdevfilter->type = DMXDEV_TYPE_NONE;
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
 	return 0;
 }
 
+static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
+				 struct dmxdev_filter *filter,
+				 struct dmxdev_feed *feed)
+{
+	struct timespec timeout = { 0 };
+	struct dmx_pes_filter_params *para = &filter->params.pes;
+	dmx_output_t otype;
+	int ret;
+	int ts_type;
+	enum dmx_ts_pes ts_pes;
+	struct dmx_ts_feed *tsfeed;
+
+	feed->ts = NULL;
+	otype = para->output;
+
+	ts_pes = (enum dmx_ts_pes)para->pes_type;
+
+	if (ts_pes < DMX_PES_OTHER)
+		ts_type = TS_DECODER;
+	else
+		ts_type = 0;
+
+	if (otype == DMX_OUT_TS_TAP)
+		ts_type |= TS_PACKET;
+	else if (otype == DMX_OUT_TSDEMUX_TAP)
+		ts_type |= TS_PACKET | TS_DEMUX;
+	else if (otype == DMX_OUT_TAP)
+		ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;
+
+	ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux, &feed->ts,
+					      dvb_dmxdev_ts_callback);
+	if (ret < 0)
+		return ret;
+
+	tsfeed = feed->ts;
+	tsfeed->priv = filter;
+
+	ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, 32768, timeout);
+	if (ret < 0) {
+		dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
+		return ret;
+	}
+
+	ret = tsfeed->start_filtering(tsfeed);
+	if (ret < 0) {
+		dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
 {
 	struct dmxdev *dmxdev = filter->dev;
+	struct dmxdev_feed *feed;
 	void *mem;
 	int ret, i;
 
@@ -631,56 +715,14 @@
 		break;
 	}
 	case DMXDEV_TYPE_PES:
-	{
-		struct timespec timeout = { 0 };
-		struct dmx_pes_filter_params *para = &filter->params.pes;
-		dmx_output_t otype;
-		int ts_type;
-		enum dmx_ts_pes ts_pes;
-		struct dmx_ts_feed **tsfeed = &filter->feed.ts;
-
-		filter->feed.ts = NULL;
-		otype = para->output;
-
-		ts_pes = (enum dmx_ts_pes)para->pes_type;
-
-		if (ts_pes < DMX_PES_OTHER)
-			ts_type = TS_DECODER;
-		else
-			ts_type = 0;
-
-		if (otype == DMX_OUT_TS_TAP)
-			ts_type |= TS_PACKET;
-		else if (otype == DMX_OUT_TSDEMUX_TAP)
-			ts_type |= TS_PACKET | TS_DEMUX;
-		else if (otype == DMX_OUT_TAP)
-			ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;
-
-		ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux,
-						      tsfeed,
-						      dvb_dmxdev_ts_callback);
-		if (ret < 0)
-			return ret;
-
-		(*tsfeed)->priv = filter;
-
-		ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
-				     32768, timeout);
+		list_for_each_entry(feed, &filter->feed.ts, next) {
+			ret = dvb_dmxdev_start_feed(dmxdev, filter, feed);
 		if (ret < 0) {
-			dmxdev->demux->release_ts_feed(dmxdev->demux,
-						       *tsfeed);
+				dvb_dmxdev_filter_stop(filter);
 			return ret;
 		}
-
-		ret = filter->feed.ts->start_filtering(filter->feed.ts);
-		if (ret < 0) {
-			dmxdev->demux->release_ts_feed(dmxdev->demux,
-						       *tsfeed);
-			return ret;
 		}
-
 		break;
-	}
 	default:
 		return -EINVAL;
 	}
@@ -718,7 +760,7 @@
 	dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
 	dmxdevfilter->type = DMXDEV_TYPE_NONE;
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
-	dmxdevfilter->feed.ts = NULL;
+	INIT_LIST_HEAD(&dmxdevfilter->feed.ts);
 	init_timer(&dmxdevfilter->timer);
 
 	dvbdev->users++;
@@ -760,6 +802,55 @@
 		filter->mode[i] ^= 0xff;
 }
 
+static int dvb_dmxdev_add_pid(struct dmxdev *dmxdev,
+			      struct dmxdev_filter *filter, u16 pid)
+{
+	struct dmxdev_feed *feed;
+
+	if ((filter->type != DMXDEV_TYPE_PES) ||
+	    (filter->state < DMXDEV_STATE_SET))
+		return -EINVAL;
+
+	/* only TS packet filters may have multiple PIDs */
+	if ((filter->params.pes.output != DMX_OUT_TSDEMUX_TAP) &&
+	    (!list_empty(&filter->feed.ts)))
+		return -EINVAL;
+
+	feed = kzalloc(sizeof(struct dmxdev_feed), GFP_KERNEL);
+	if (feed == NULL)
+		return -ENOMEM;
+
+	feed->pid = pid;
+	list_add(&feed->next, &filter->feed.ts);
+
+	if (filter->state >= DMXDEV_STATE_GO)
+		return dvb_dmxdev_start_feed(dmxdev, filter, feed);
+
+	return 0;
+}
+
+static int dvb_dmxdev_remove_pid(struct dmxdev *dmxdev,
+				  struct dmxdev_filter *filter, u16 pid)
+{
+	struct dmxdev_feed *feed, *tmp;
+
+	if ((filter->type != DMXDEV_TYPE_PES) ||
+	    (filter->state < DMXDEV_STATE_SET))
+		return -EINVAL;
+
+	list_for_each_entry_safe(feed, tmp, &filter->feed.ts, next) {
+		if ((feed->pid == pid) && (feed->ts != NULL)) {
+			feed->ts->stop_filtering(feed->ts);
+			filter->dev->demux->release_ts_feed(filter->dev->demux,
+							    feed->ts);
+			list_del(&feed->next);
+			kfree(feed);
+		}
+	}
+
+	return 0;
+}
+
 static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
 				 struct dmxdev_filter *dmxdevfilter,
 				 struct dmx_sct_filter_params *params)
@@ -784,7 +875,10 @@
 				     struct dmxdev_filter *dmxdevfilter,
 				     struct dmx_pes_filter_params *params)
 {
+	int ret;
+
 	dvb_dmxdev_filter_stop(dmxdevfilter);
+	dvb_dmxdev_filter_reset(dmxdevfilter);
 
 	if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0)
 		return -EINVAL;
@@ -795,6 +889,11 @@
 
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
 
+	ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter,
+				 dmxdevfilter->params.pes.pid);
+	if (ret < 0)
+		return ret;
+
 	if (params->flags & DMX_IMMEDIATE_START)
 		return dvb_dmxdev_filter_start(dmxdevfilter);
 
@@ -958,6 +1057,24 @@
 					     &((struct dmx_stc *)parg)->base);
 		break;
 
+	case DMX_ADD_PID:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+		ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+
+	case DMX_REMOVE_PID:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+		ret = dvb_dmxdev_remove_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+
 	default:
 		ret = -EINVAL;
 		break;
diff -ruw linux-2.6.31.7/drivers/media/dvb/dvb-core/dmxdev.h linux-2.6.31.7-fbx/drivers/media/dvb/dvb-core/dmxdev.h
--- linux-2.6.31.7/drivers/media/dvb/dvb-core/dmxdev.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/dvb-core/dmxdev.h	2010-03-18 18:28:49.832796658 +0100
@@ -53,13 +53,20 @@
 	DMXDEV_STATE_TIMEDOUT
 };
 
+struct dmxdev_feed {
+	u16 pid;
+	struct dmx_ts_feed *ts;
+	struct list_head next;
+};
+
 struct dmxdev_filter {
 	union {
 		struct dmx_section_filter *sec;
 	} filter;
 
 	union {
-		struct dmx_ts_feed *ts;
+		/* list of TS and PES feeds (struct dmxdev_feed) */
+		struct list_head ts;
 		struct dmx_section_feed *sec;
 	} feed;
 
diff -ruw linux-2.6.31.7/drivers/media/dvb/dvb-core/dvb_frontend.c linux-2.6.31.7-fbx/drivers/media/dvb/dvb-core/dvb_frontend.c
--- linux-2.6.31.7/drivers/media/dvb/dvb-core/dvb_frontend.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/dvb-core/dvb_frontend.c	2010-10-25 13:43:56.551443309 +0200
@@ -657,7 +657,6 @@
 	}
 
 	fepriv->thread = NULL;
-	fepriv->exit = 0;
 	mb();
 
 	dvb_frontend_wakeup(fe);
@@ -672,6 +671,7 @@
 
 	fepriv->exit = 1;
 	mb();
+	wake_up_all(&fepriv->events.wait_queue);
 
 	if (!fepriv->thread)
 		return;
@@ -1758,6 +1758,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-2.6.31.7/drivers/media/dvb/dvb-usb/dib0700_devices.c linux-2.6.31.7-fbx/drivers/media/dvb/dvb-usb/dib0700_devices.c
--- linux-2.6.31.7/drivers/media/dvb/dvb-usb/dib0700_devices.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/dvb-usb/dib0700_devices.c	2010-11-18 19:12:23.981656337 +0100
@@ -1120,6 +1120,15 @@
 	}
 };
 
+static struct dib0070_config dib7770p_dib0070_config = {
+	.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+	.reset = dib7070_tuner_reset,
+	.sleep = dib7070_tuner_sleep,
+	.clock_khz = 12000,
+	.clock_pad_drive = 0,
+	.flip_chip = 1,
+};
+
 static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
 {
 	struct dvb_usb_adapter *adap = fe->dvb->priv;
@@ -1137,6 +1146,44 @@
 	return state->set_param_save(fe, fep);
 }
 
+static int dib7770_set_param_override(struct dvb_frontend *fe,
+				      struct dvb_frontend_parameters *fep)
+{
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	struct dib0700_adapter_state *state = adap->priv;
+
+	u16 offset;
+	u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
+	switch (band) {
+	case BAND_VHF:
+		dib7000p_set_gpio(fe, 0, 0, 1);
+		offset = 850;
+		break;
+	case BAND_UHF:
+	default:
+		dib7000p_set_gpio(fe, 0, 0, 0);
+		offset = 250;
+		break;
+	}
+	deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
+	dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
+	return state->set_param_save(fe, fep);
+}
+
+static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	struct dib0700_adapter_state *st = adap->priv;
+	struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+
+	if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7770p_dib0070_config) == NULL)
+		return -ENODEV;
+
+	st->set_param_save = adap->fe->ops.tuner_ops.set_params;
+	adap->fe->ops.tuner_ops.set_params = dib7770_set_param_override;
+	return 0;
+}
+
+
 static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
 {
 	struct dib0700_adapter_state *st = adap->priv;
@@ -1155,6 +1202,17 @@
 	return 0;
 }
 
+static int stk7070p_pid_filter(struct dvb_usb_adapter *adapter, int index,
+			       u16 pid, int onoff)
+{
+	return dib7000p_pid_filter(adapter->fe, index, pid, onoff);
+}
+
+static int stk7070p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
+{
+	return dib7000p_pid_filter_ctrl(adapter->fe, onoff);
+}
+
 static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
 	60000, 15000, // internal, sampling
 	1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
@@ -1281,6 +1339,58 @@
 	return adap->fe == NULL ? -ENODEV : 0;
 }
 
+/* STK7770P */
+static struct dib7000p_config dib7770p_dib7000p_config = {
+	.output_mpeg2_in_188_bytes = 1,
+
+	.agc_config_count = 1,
+	.agc = &dib7070_agc_config,
+	.bw  = &dib7070_bw_config_12_mhz,
+	.tuner_is_baseband = 1,
+	.spur_protect = 1,
+
+	.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+	.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+	.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+	.hostbus_diversity = 1,
+	.enable_current_mirror = 1,
+	.disable_sample_and_hold = 0,
+};
+
+static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
+	if (p->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
+	    p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
+		dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+	else
+		dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+	dib0700_ctrl_clock(adap->dev, 72, 1);
+
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+	if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+				     &dib7770p_dib7000p_config) != 0) {
+		err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+		    __func__);
+		return -ENODEV;
+	}
+
+	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+			      &dib7770p_dib7000p_config);
+	return adap->fe == NULL ? -ENODEV : 0;
+}
+
 /* S5H1411 */
 static struct s5h1411_config pinnacle_801e_config = {
 	.output_mode   = S5H1411_PARALLEL_OUTPUT,
@@ -1497,6 +1607,7 @@
 	{ USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_H) },
 	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_T3) },
 	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_T5) },
+	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7770P) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1916,6 +2027,33 @@
 				{ NULL },
 			},
 		},
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+		.num_adapters = 1,
+		.adapter = {
+			{
+				.caps = DVB_USB_ADAP_HAS_PID_FILTER |
+				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+				.pid_filter_count = 32,
+				.pid_filter = stk7070p_pid_filter,
+				.pid_filter_ctrl = stk7070p_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",
+				{ &dib0700_usb_id_table[54], NULL },
+				{ NULL },
+			},
+		},
 	},
 };
 
diff -ruw linux-2.6.31.7/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c linux-2.6.31.7-fbx/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
--- linux-2.6.31.7/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c	2010-03-18 18:28:49.832796658 +0100
@@ -177,6 +177,9 @@
 	if (adap->props.frontend_attach(adap) == 0 && adap->fe != NULL) {
 		adap->fe_init  = adap->fe->ops.init;  adap->fe->ops.init  = dvb_usb_fe_wakeup;
 		adap->fe_sleep = adap->fe->ops.sleep; adap->fe->ops.sleep = dvb_usb_fe_sleep;
+		/* only attach the tuner if the demod is there */
+		if (adap->props.tuner_attach != NULL)
+			adap->props.tuner_attach(adap);
 
 		if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
 			err("Frontend registration failed.");
@@ -185,9 +188,6 @@
 			return -ENODEV;
 		}
 
-		/* only attach the tuner if the demod is there */
-		if (adap->props.tuner_attach != NULL)
-			adap->props.tuner_attach(adap);
 	} else
 		err("no frontend was attached by '%s'",adap->dev->desc->name);
 
diff -ruw linux-2.6.31.7/drivers/media/dvb/dvb-usb/dvb-usb.h linux-2.6.31.7-fbx/drivers/media/dvb/dvb-usb/dvb-usb.h
--- linux-2.6.31.7/drivers/media/dvb/dvb-usb/dvb-usb.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/dvb-usb/dvb-usb.h	2010-10-25 13:43:56.551443309 +0200
@@ -223,7 +223,7 @@
 	int generic_bulk_ctrl_endpoint;
 
 	int num_device_descs;
-	struct dvb_usb_device_description devices[12];
+	struct dvb_usb_device_description devices[32];
 };
 
 /**
diff -ruw linux-2.6.31.7/drivers/media/dvb/dvb-usb/dvb-usb-ids.h linux-2.6.31.7-fbx/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
--- linux-2.6.31.7/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2010-10-25 13:43:56.551443309 +0200
@@ -90,6 +90,7 @@
 #define USB_PID_DIBCOM_MOD3001_WARM			0x0bc7
 #define USB_PID_DIBCOM_STK7700P				0x1e14
 #define USB_PID_DIBCOM_STK7700P_PC			0x1e78
+#define USB_PID_DIBCOM_STK7770P				0x1e80
 #define USB_PID_DIBCOM_STK7700D				0x1ef0
 #define USB_PID_DIBCOM_STK7700_U7000			0x7001
 #define USB_PID_DIBCOM_STK7070P				0x1ebc
diff -ruw linux-2.6.31.7/drivers/media/dvb/dvb-usb/dvb-usb-init.c linux-2.6.31.7-fbx/drivers/media/dvb/dvb-usb/dvb-usb-init.c
--- linux-2.6.31.7/drivers/media/dvb/dvb-usb/dvb-usb-init.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/dvb-usb/dvb-usb-init.c	2010-10-25 13:43:56.551443309 +0200
@@ -18,7 +18,7 @@
 module_param_named(debug,dvb_usb_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64,mem=128,uxfer=256  (or-able))." DVB_USB_DEBUG_STATUS);
 
-int dvb_usb_disable_rc_polling;
+int dvb_usb_disable_rc_polling = 1;
 module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
 MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
 
diff -ruw linux-2.6.31.7/drivers/media/dvb/frontends/dib7000p.c linux-2.6.31.7-fbx/drivers/media/dvb/frontends/dib7000p.c
--- linux-2.6.31.7/drivers/media/dvb/frontends/dib7000p.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/frontends/dib7000p.c	2010-11-18 19:12:23.981656337 +0100
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 
+#include "dvb_math.h"
 #include "dvb_frontend.h"
 
 #include "dib7000p.h"
@@ -257,6 +258,9 @@
 
 //	dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
 
+	reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
+	reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
+
 	dib7000p_write_word(state, 908, reg_908);
 	dib7000p_write_word(state, 909, reg_909);
 }
@@ -775,7 +779,10 @@
 		default:
 		case GUARD_INTERVAL_1_32: value *= 1; break;
 	}
-	state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
+	if (state->cfg.diversity_delay == 0)
+		state->div_sync_wait = (value * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
+	else
+		state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for one DVSY-fifo
 
 	/* deactive the possibility of diversity reception if extended interleaver */
 	state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
@@ -1217,7 +1224,34 @@
 
 static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
 {
-	*snr = 0x0000;
+	struct dib7000p_state *state = fe->demodulator_priv;
+	u16 val;
+	s32 signal_mant, signal_exp, noise_mant, noise_exp;
+	u32 result = 0;
+
+	val = dib7000p_read_word(state, 479);
+	noise_mant = (val >> 4) & 0xff;
+	noise_exp = ((val & 0xf) << 2);
+	val = dib7000p_read_word(state, 480);
+	noise_exp += ((val >> 14) & 0x3);
+	if ((noise_exp & 0x20) != 0)
+		noise_exp -= 0x40;
+
+	signal_mant = (val >> 6) & 0xFF;
+	signal_exp  = (val & 0x3F);
+	if ((signal_exp & 0x20) != 0)
+		signal_exp -= 0x40;
+
+	if (signal_mant != 0)
+		result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
+	else
+		result = intlog10(2) * 10 * signal_exp - 100;
+	if (noise_mant != 0)
+		result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
+	else
+		result -= intlog10(2) * 10 * noise_exp - 100;
+	*snr = result / (1 << 24);
+
 	return 0;
 }
 
@@ -1271,6 +1305,22 @@
 }
 EXPORT_SYMBOL(dib7000p_get_i2c_master);
 
+int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
+{
+	struct dib7000p_state *state = fe->demodulator_priv;
+	uint16_t val = dib7000p_read_word(state, 235) & 0xffef;
+	val |= (onoff & 0x1) << 4;
+	return dib7000p_write_word(state, 235, val);
+}
+EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
+
+int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+{
+	struct dib7000p_state *state = fe->demodulator_priv;
+	return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
+}
+EXPORT_SYMBOL(dib7000p_pid_filter);
+
 int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
 {
 	struct dib7000p_state st = { .i2c_adap = i2c };
diff -ruw linux-2.6.31.7/drivers/media/dvb/frontends/dib7000p.h linux-2.6.31.7-fbx/drivers/media/dvb/frontends/dib7000p.h
--- linux-2.6.31.7/drivers/media/dvb/frontends/dib7000p.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/frontends/dib7000p.h	2010-11-18 19:12:23.981656337 +0100
@@ -33,6 +33,11 @@
 	int (*agc_control) (struct dvb_frontend *, u8 before);
 
 	u8 output_mode;
+	u8 disable_sample_and_hold : 1;
+
+	u8 enable_current_mirror : 1;
+	u8 diversity_delay;
+
 };
 
 #define DEFAULT_DIB7000P_I2C_ADDRESS 18
@@ -51,6 +56,8 @@
 extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
 extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
 extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
+extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
+extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff);
 #else
 static inline
 struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
@@ -95,6 +102,19 @@
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
 }
+
+static inline int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
+static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
 #endif
 
 #endif
diff -ruw linux-2.6.31.7/drivers/media/dvb/frontends/tda1004x.c linux-2.6.31.7-fbx/drivers/media/dvb/frontends/tda1004x.c
--- linux-2.6.31.7/drivers/media/dvb/frontends/tda1004x.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/frontends/tda1004x.c	2010-03-18 18:28:49.853437676 +0100
@@ -522,6 +522,7 @@
 	   goes into an instable state. So, proper locking are needed
 	   at the i2c bus master.
 	 */
+	if (!state->config->no_eeprom) {
 	printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
 	tda1004x_write_byteI(state, TDA1004X_CONFC4, 4);
 	msleep(300);
@@ -530,6 +531,7 @@
 	/* Checks if eeprom firmware went without troubles */
 	if (tda1004x_check_upload_ok(state) == 0)
 		return 0;
+	}
 
 	/* eeprom firmware didn't work. Load one manually. */
 
@@ -682,21 +684,97 @@
 		tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x10,
 							state->config->invert_oclk << 4);
 	}
-	tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
-	tda1004x_write_mask (state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x38); // Turn IF AGC output on
+	/* Start Freebox altered code */
+	tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x34);
+	tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x20); // Turn both AGC outputs on
+	/* End Freebox altered code */
 	tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0);	  // }
 	tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
 	tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0);	  // }
 	tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff);  // }
-	tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1
+	/* Start Freebox altered code */
+	tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x01);
+	/* End Freebox altered code */
 	tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
 	tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
 	tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
-	// tda1004x_write_mask(state, 0x50, 0x80, 0x80);         // handle out of guard echoes
+	/* Start Freebox altered code */
+	tda1004x_write_mask(state, 0x50, 0x80, 0x80);         // handle out of guard echoes
+	tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xa9);
+	tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc);
+	tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 0x0a);
+	/* End Freebox altered code */
 
 	return 0;
 }
 
+/* Start Freebox added code */
+static int tda1004x_find_offset(struct dvb_frontend* fe,
+				struct dvb_frontend_parameters *fe_params)
+{
+	struct tda1004x_state* state = fe->demodulator_priv;
+	int status, conf1, conf2, offset_f;
+	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+
+	dprintk("%s\n", __func__);
+
+	while (time_before(jiffies, timeout)) {
+		msleep(10);
+		status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
+		conf1 = tda1004x_read_byte(state, TDA1004X_OUT_CONF1);
+		conf2 = tda1004x_read_byte(state, TDA1004X_OUT_CONF2);
+		if (status == -1 || conf1 == -1 || conf2 == -1)
+			return -EIO;
+		if ((status & 0x8)) /* lock */
+			goto out_offset;
+		offset_f = ((conf1 & 0x80) >> 5) | ((conf2 & 0xC0) >> 6);
+		if (offset_f != 0)
+			break;
+	}
+	if (time_after(jiffies, timeout)) {
+		goto out_offset;
+	}
+
+	if (!offset_f) {
+		// no signal found
+		goto out_offset;
+	}
+
+	// offset found, re-tune
+	switch (offset_f) {
+		default: // to keep gcc happy
+		case 1: fe_params->frequency += 166666; break;
+		case 2: fe_params->frequency -= 166666; break;
+		case 3: fe_params->frequency += 166666 * 2; break;
+		case 4: fe_params->frequency -= 166666 * 2; break;
+		case 5: fe_params->frequency += 166666 * 3; break;
+		case 6: fe_params->frequency -= 166666 * 3; break;
+	}
+
+	// set frequency
+	if (fe->ops.tuner_ops.set_params) {
+		fe->ops.tuner_ops.set_params(fe, fe_params);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+	}
+
+	// reset auto offset
+	tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x0);
+
+	// set offset
+	tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, conf1 & 0x80);
+	tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, conf2 & 0xC0);
+
+	// start lock
+	tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
+	msleep(1);
+	tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 4);
+
+out_offset:
+	return 0;
+}
+/* End Freebox added code */
+
 static int tda1004x_set_fe(struct dvb_frontend* fe,
 			   struct dvb_frontend_parameters *fe_params)
 {
@@ -709,8 +787,10 @@
 	if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
 		// setup auto offset
 		tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10);
-		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0);
-		tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0);
+		/* Start Freebox altered code */
+		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0x80);
+		tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0xC0);
+		/* End Freebox altered code */
 
 		// disable agc_conf[2]
 		tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 0);
@@ -886,7 +966,14 @@
 	case TDA1004X_DEMOD_TDA10046:
 		tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
 		msleep(1);
-		tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1);
+		/* Start Freebox altered code */
+		tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 4);
+		/* End Freebox altered code */
+		/* Start Freebox added code */
+		tmp = tda1004x_find_offset(fe, fe_params);
+		if (tmp)
+			return tmp;
+		/* End Freebox added code */
 		break;
 	}
 
@@ -1094,7 +1181,14 @@
 	if (tmp < 0)
 		return -EIO;
 
-	*signal = (tmp << 8) | tmp;
+	/* Start Freebox added code */
+	*signal = tmp;
+	tmp = tda1004x_read_byte(state, TDA10046H_AGC_TUN_LEVEL);
+	if (tmp < 0)
+		return -EIO;
+	*signal = (*signal << 8) | tmp;
+	/* End Freebox added code */
+
 	dprintk("%s: signal=0x%x\n", __func__, *signal);
 	return 0;
 }
diff -ruw linux-2.6.31.7/drivers/media/dvb/frontends/tda1004x.h linux-2.6.31.7-fbx/drivers/media/dvb/frontends/tda1004x.h
--- linux-2.6.31.7/drivers/media/dvb/frontends/tda1004x.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/frontends/tda1004x.h	2010-03-18 18:28:49.853437676 +0100
@@ -77,6 +77,9 @@
 	/* Does the OCLK signal need inverted? */
 	u8 invert_oclk;
 
+	/* don't boot from eeprom */
+	u8 no_eeprom;
+
 	/* parallel or serial transport stream */
 	enum tda10046_tsout ts_mode;
 
diff -ruw linux-2.6.31.7/drivers/media/dvb/Kconfig linux-2.6.31.7-fbx/drivers/media/dvb/Kconfig
--- linux-2.6.31.7/drivers/media/dvb/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/Kconfig	2010-10-25 13:43:56.551443309 +0200
@@ -51,6 +51,10 @@
 	depends on DVB_CORE && PCI && I2C
 source "drivers/media/dvb/dm1105/Kconfig"
 
+comment "Supported Tango2 Adapters"
+	depends on DVB_CORE && ARCH_FBX5_B
+source "drivers/media/dvb/tango2/Kconfig"
+
 comment "Supported FireWire (IEEE 1394) Adapters"
 	depends on DVB_CORE && IEEE1394
 source "drivers/media/dvb/firewire/Kconfig"
diff -ruw linux-2.6.31.7/drivers/media/dvb/Makefile linux-2.6.31.7-fbx/drivers/media/dvb/Makefile
--- linux-2.6.31.7/drivers/media/dvb/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/Makefile	2010-10-25 13:43:56.551443309 +0200
@@ -2,6 +2,6 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/
+obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ tango2/
 
 obj-$(CONFIG_DVB_FIREDTV)	+= firewire/
diff -ruw linux-2.6.31.7/drivers/misc/Kconfig linux-2.6.31.7-fbx/drivers/misc/Kconfig
--- linux-2.6.31.7/drivers/misc/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/misc/Kconfig	2010-10-25 13:43:56.651449504 +0200
@@ -233,6 +233,14 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called isl29003.
 
+config PI7C9X
+	tristate "Pericom PI7C9X packet switch driver"
+	select I2C
+	select BITREVERSE
+
+config CRASHZONE
+	bool "crashzone support"
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff -ruw linux-2.6.31.7/drivers/misc/Makefile linux-2.6.31.7-fbx/drivers/misc/Makefile
--- linux-2.6.31.7/drivers/misc/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/misc/Makefile	2010-10-25 13:43:56.651449504 +0200
@@ -19,6 +19,8 @@
 obj-$(CONFIG_SGI_GRU)		+= sgi-gru/
 obj-$(CONFIG_HP_ILO)		+= hpilo.o
 obj-$(CONFIG_ISL29003)		+= isl29003.o
+obj-$(CONFIG_PI7C9X)		+= pi7c9x.o
 obj-$(CONFIG_C2PORT)		+= c2port/
+obj-$(CONFIG_CRASHZONE)		+= crash_zone.o
 obj-y				+= eeprom/
 obj-y				+= cb710/
diff -ruw linux-2.6.31.7/drivers/mtd/Kconfig linux-2.6.31.7-fbx/drivers/mtd/Kconfig
--- linux-2.6.31.7/drivers/mtd/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/mtd/Kconfig	2010-10-25 13:43:56.661441337 +0200
@@ -25,6 +25,9 @@
 	help
 	  Determines the verbosity level of the MTD debugging messages.
 
+config MTD_ERASE_PRINTK
+	bool "write to kernel log when a block is erased"
+
 config MTD_CONCAT
 	tristate "MTD concatenating support"
 	help
@@ -171,6 +174,19 @@
 	---help---
 	  TI AR7 partitioning support
 
+config MTD_FBX6HD_PARTS
+	tristate "Freebox V6 HD partitioning support"
+	depends on MTD_PARTITIONS
+	help
+	  Freebox V6 HD partitioning support
+
+config MTD_FBX6HD_PARTS_WRITE_ALL
+	bool "make all partitions writeable"
+	default n
+	depends on MTD_FBX6HD_PARTS
+	help
+	  Freebox V6 HD partitions support
+
 comment "User Modules And Translation Layers"
 
 config MTD_CHAR
diff -ruw linux-2.6.31.7/drivers/mtd/Makefile linux-2.6.31.7-fbx/drivers/mtd/Makefile
--- linux-2.6.31.7/drivers/mtd/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/mtd/Makefile	2010-03-18 18:28:50.013636346 +0100
@@ -13,6 +13,7 @@
 obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
 obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
 obj-$(CONFIG_MTD_OF_PARTS)      += ofpart.o
+obj-$(CONFIG_MTD_FBX6HD_PARTS)	+= fbx6hd-mtdparts.o
 
 # 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_CHAR)		+= mtdchar.o
diff -ruw linux-2.6.31.7/drivers/mtd/nand/Kconfig linux-2.6.31.7-fbx/drivers/mtd/nand/Kconfig
--- linux-2.6.31.7/drivers/mtd/nand/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/mtd/nand/Kconfig	2010-10-25 13:43:56.671441602 +0200
@@ -452,4 +452,9 @@
 	help
 	  Enables support for NAND Flash chips wired onto Socrates board.
 
+config MTD_NAND_DENALI
+	tristate "NAND Denali controller support"
+	depends on MTD_NAND && PCI
+	default n
+
 endif # MTD_NAND
diff -ruw linux-2.6.31.7/drivers/mtd/nand/Makefile linux-2.6.31.7-fbx/drivers/mtd/nand/Makefile
--- linux-2.6.31.7/drivers/mtd/nand/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/mtd/nand/Makefile	2010-10-25 13:43:56.671441602 +0200
@@ -40,5 +40,6 @@
 obj-$(CONFIG_MTD_NAND_MXC)		+= mxc_nand.o
 obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socrates_nand.o
 obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o
+obj-$(CONFIG_MTD_NAND_DENALI)		+= denali_nand.o
 
 nand-objs := nand_base.o nand_bbt.o
diff -ruw linux-2.6.31.7/drivers/net/Kconfig linux-2.6.31.7-fbx/drivers/net/Kconfig
--- linux-2.6.31.7/drivers/net/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/net/Kconfig	2010-10-25 13:43:56.701469669 +0200
@@ -553,6 +553,21 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called sunhme.
 
+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
+
+
 config SUNBMAC
 	tristate "Sun BigMAC 10/100baseT support (EXPERIMENTAL)"
 	depends on SBUS && EXPERIMENTAL
@@ -1928,6 +1943,15 @@
 	  To compile this driver as a module, choose M here.  The module
 	  will be called atl2.
 
+config BCM63XX_ENET
+	tristate "Broadcom 63xx internal mac support"
+	depends on BCM63XX
+	select MII
+	select PHYLIB
+	help
+	  This driver supports the ethernet MACs in the Broadcom 63xx
+	  MIPS chipset family (BCM63XX).
+
 source "drivers/net/fs_enet/Kconfig"
 
 endif # NET_ETHERNET
@@ -2382,6 +2406,7 @@
 	depends on MV64X60 || PPC32 || PLAT_ORION
 	select INET_LRO
 	select PHYLIB
+	select MII
 	help
 	  This driver supports the gigabit ethernet MACs in the
 	  Marvell Discovery PPC/MIPS chipset family (MV643XX) and
diff -ruw linux-2.6.31.7/drivers/net/Makefile linux-2.6.31.7-fbx/drivers/net/Makefile
--- linux-2.6.31.7/drivers/net/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/net/Makefile	2010-10-25 13:43:56.701469669 +0200
@@ -47,6 +47,8 @@
 obj-$(CONFIG_SUNLANCE) += sunlance.o
 obj-$(CONFIG_SUNQE) += sunqe.o
 obj-$(CONFIG_SUNBMAC) += sunbmac.o
+obj-$(CONFIG_TANGO2_ENET) += tango2_enet.o
+obj-$(CONFIG_TANGO2_PCINET_H) += tango2_pcinet_h.o
 obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o
 obj-$(CONFIG_SUNGEM) += sungem.o sungem_phy.o
 obj-$(CONFIG_CASSINI) += cassini.o
@@ -136,6 +138,7 @@
 obj-$(CONFIG_B44) += b44.o
 obj-$(CONFIG_FORCEDETH) += forcedeth.o
 obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o
+obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
 obj-$(CONFIG_AX88796) += ax88796.o
 
 obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
diff -ruw linux-2.6.31.7/drivers/net/phy/Kconfig linux-2.6.31.7-fbx/drivers/net/phy/Kconfig
--- linux-2.6.31.7/drivers/net/phy/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/net/phy/Kconfig	2010-03-18 18:28:50.173105810 +0100
@@ -56,6 +56,12 @@
 	  Currently supports the BCM5411, BCM5421, BCM5461, BCM5464, BCM5481
 	  and BCM5482 PHYs.
 
+config BCM63XX_PHY
+	tristate "Drivers for Broadcom 63xx SOCs internal PHY"
+	depends on BCM63XX
+	---help---
+	  Currently supports the 6348 and 6358 PHYs.
+
 config ICPLUS_PHY
 	tristate "Drivers for ICPlus PHYs"
 	---help---
diff -ruw linux-2.6.31.7/drivers/net/phy/Makefile linux-2.6.31.7-fbx/drivers/net/phy/Makefile
--- linux-2.6.31.7/drivers/net/phy/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/net/phy/Makefile	2010-03-18 18:28:50.173105810 +0100
@@ -11,6 +11,7 @@
 obj-$(CONFIG_SMSC_PHY)		+= smsc.o
 obj-$(CONFIG_VITESSE_PHY)	+= vitesse.o
 obj-$(CONFIG_BROADCOM_PHY)	+= broadcom.o
+obj-$(CONFIG_BCM63XX_PHY)	+= bcm63xx.o
 obj-$(CONFIG_ICPLUS_PHY)	+= icplus.o
 obj-$(CONFIG_REALTEK_PHY)	+= realtek.o
 obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
diff -ruw linux-2.6.31.7/drivers/net/wireless/hostap/Kconfig linux-2.6.31.7-fbx/drivers/net/wireless/hostap/Kconfig
--- linux-2.6.31.7/drivers/net/wireless/hostap/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/net/wireless/hostap/Kconfig	2010-03-18 18:28:50.303103370 +0100
@@ -95,3 +95,7 @@
 
 	The driver can be compiled as a module and will be named
 	hostap_cs.
+
+config HOSTAP_CS_FBXDMAMUX
+	bool "use fbxdmamux for data transfer"
+	depends on HOSTAP_CS
diff -ruw linux-2.6.31.7/drivers/pcmcia/Kconfig linux-2.6.31.7-fbx/drivers/pcmcia/Kconfig
--- linux-2.6.31.7/drivers/pcmcia/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/pcmcia/Kconfig	2010-03-18 18:28:50.812835107 +0100
@@ -192,6 +192,10 @@
 	tristate "Au1x00 pcmcia support"
 	depends on SOC_AU1X00 && PCMCIA
 
+config PCMCIA_BCM63XX
+	tristate "bcm63xx pcmcia support"
+	depends on BCM63XX && PCMCIA
+
 config PCMCIA_SA1100
 	tristate "SA1100 support"
 	depends on ARM && ARCH_SA1100 && PCMCIA
diff -ruw linux-2.6.31.7/drivers/pcmcia/Makefile linux-2.6.31.7-fbx/drivers/pcmcia/Makefile
--- linux-2.6.31.7/drivers/pcmcia/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/pcmcia/Makefile	2010-10-25 13:43:57.011447041 +0200
@@ -27,6 +27,7 @@
 obj-$(CONFIG_M32R_PCC)				+= m32r_pcc.o
 obj-$(CONFIG_M32R_CFC)				+= m32r_cfc.o
 obj-$(CONFIG_PCMCIA_AU1X00)			+= au1x00_ss.o
+obj-$(CONFIG_PCMCIA_BCM63XX)			+= bcm63xx_pcmcia.o
 obj-$(CONFIG_PCMCIA_VRC4171)			+= vrc4171_card.o
 obj-$(CONFIG_PCMCIA_VRC4173)			+= vrc4173_cardu.o
 obj-$(CONFIG_OMAP_CF)				+= omap_cf.o
diff -ruw linux-2.6.31.7/drivers/platform/Kconfig linux-2.6.31.7-fbx/drivers/platform/Kconfig
--- linux-2.6.31.7/drivers/platform/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/Kconfig	2010-03-18 18:28:50.822832587 +0100
@@ -3,3 +3,11 @@
 if X86
 source "drivers/platform/x86/Kconfig"
 endif
+
+if TANGO2
+source "drivers/platform/tango2/Kconfig"
+endif
+
+if ARCH_GEN3
+source "drivers/platform/intelce/Kconfig"
+endif
diff -ruw linux-2.6.31.7/drivers/platform/Makefile linux-2.6.31.7-fbx/drivers/platform/Makefile
--- linux-2.6.31.7/drivers/platform/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/Makefile	2010-03-18 18:28:50.822832587 +0100
@@ -3,3 +3,5 @@
 #
 
 obj-$(CONFIG_X86)		+= x86/
+obj-$(CONFIG_TANGO2)		+= tango2/
+obj-$(CONFIG_INTELCE)		+= intelce/
diff -ruw linux-2.6.31.7/drivers/serial/8250.c linux-2.6.31.7-fbx/drivers/serial/8250.c
--- linux-2.6.31.7/drivers/serial/8250.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/serial/8250.c	2010-10-25 13:43:57.131442147 +0200
@@ -39,6 +39,12 @@
 #include <linux/nmi.h>
 #include <linux/mutex.h>
 
+#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>
 
@@ -294,6 +300,13 @@
 		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
 		.flags		= UART_CAP_FIFO | UART_CAP_AFE,
 	},
+	[PORT_INTELCE] = {
+		.name		= "IntelCE",
+		.fifo_size	= 32,
+		.tx_loadsz	= 32,
+		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+		.flags		= UART_CAP_FIFO | UART_CAP_UUE,
+	},
 };
 
 #if defined (CONFIG_SERIAL_8250_AU1X00)
@@ -394,14 +407,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 = map_8250_in_reg(p, offset) << p->regshift;
 	return readb(p->membase + offset);
+#endif
 }
 
 static void mem_serial_out(struct uart_port *p, int offset, int value)
 {
+#ifdef CONFIG_TANGO2
+	/*
+	 * we add a special case for UART_DL register, since
+	 * register content has a different meaning for us.
+	 */
+	if (offset == UART_DL) {
+		/* select right clock source */
+		value = (em8xxx_sys_frequency / p->uartclk);
+	}
+
+	/* no EFR on tango2 */
+	if (offset != UART_EFR) {
+		offset = offset << p->regshift;
+		gbus_writel((unsigned long)p->membase + offset,
+			    value);
+	}
+#else
 	offset = map_8250_out_reg(p, offset) << p->regshift;
 	writeb(value, p->membase + offset);
+#endif
 }
 
 static void mem32_serial_out(struct uart_port *p, int offset, int value)
@@ -554,6 +597,7 @@
 #define serial_inp(up, offset)		serial_in(up, offset)
 #define serial_outp(up, offset, value)	serial_out(up, offset, value)
 
+#ifndef CONFIG_TANGO2
 /* Uart divisor latch read */
 static inline int _serial_dl_read(struct uart_8250_port *up)
 {
@@ -606,6 +650,7 @@
 #define serial_dl_read(up) _serial_dl_read(up)
 #define serial_dl_write(up, value) _serial_dl_write(up, value)
 #endif
+#endif
 
 /*
  * For the 16C950
@@ -739,7 +784,11 @@
 static int size_fifo(struct uart_8250_port *up)
 {
 	unsigned char old_fcr, old_mcr, old_lcr;
+#ifdef CONFIG_TANGO2
+	unsigned short old_dll, old_dlm;
+#else
 	unsigned short old_dl;
+#endif
 	int count;
 
 	old_lcr = serial_inp(up, UART_LCR);
@@ -750,8 +799,14 @@
 		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
 	serial_outp(up, UART_MCR, UART_MCR_LOOP);
 	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+#ifdef CONFIG_TANGO2
+	old_dll = serial_inp(up, UART_DL) & 0xff;
+	old_dlm = serial_inp(up, UART_DL) >> 8;
+	serial_outp(up, UART_DL, 0x01);
+#else
 	old_dl = serial_dl_read(up);
 	serial_dl_write(up, 0x0001);
+#endif
 	serial_outp(up, UART_LCR, 0x03);
 	for (count = 0; count < 256; count++)
 		serial_outp(up, UART_TX, count);
@@ -762,7 +817,11 @@
 	serial_outp(up, UART_FCR, old_fcr);
 	serial_outp(up, UART_MCR, old_mcr);
 	serial_outp(up, UART_LCR, UART_LCR_DLAB);
+#ifdef CONFIG_TANGO2
+	serial_outp(up, UART_DL, (old_dlm << 8) | old_dll);
+#else
 	serial_dl_write(up, old_dl);
+#endif
 	serial_outp(up, UART_LCR, old_lcr);
 
 	return count;
@@ -781,6 +840,16 @@
 	old_lcr = serial_inp(p, UART_LCR);
 	serial_outp(p, UART_LCR, UART_LCR_DLAB);
 
+#ifdef CONFIG_TANGO2
+	old_dll = serial_inp(p, UART_DL) & 0xff;
+	old_dlm = serial_inp(p, UART_DL) >> 8;
+
+	serial_outp(p, UART_DL, 0);
+
+	id = serial_inp(p, UART_DL);
+
+	serial_outp(p, UART_DL, (old_dlm << 8) | old_dll);
+#else
 	old_dll = serial_inp(p, UART_DLL);
 	old_dlm = serial_inp(p, UART_DLM);
 
@@ -791,6 +860,7 @@
 
 	serial_outp(p, UART_DLL, old_dll);
 	serial_outp(p, UART_DLM, old_dlm);
+#endif
 	serial_outp(p, UART_LCR, old_lcr);
 
 	return id;
@@ -992,7 +1062,11 @@
 
 			serial_outp(up, UART_LCR, 0xE0);
 
+#ifdef CONFIG_TANGO2
+			quot = serial_inp(up, UART_DL);
+#else
 			quot = serial_dl_read(up);
+#endif
 			quot <<= 3;
 
 			status1 = serial_in(up, 0x04); /* EXCR2 */
@@ -1000,8 +1074,11 @@
 			status1 |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
 			serial_outp(up, 0x04, status1);
 
+#ifdef CONFIG_TANGO2
+			serial_outp(up, UART_DL, quot);
+#else
 			serial_dl_write(up, quot);
-
+#endif
 			serial_outp(up, UART_LCR, 0);
 
 			up->port.uartclk = 921600*16;
@@ -1053,11 +1130,15 @@
 		serial_outp(up, UART_IER, iersave | UART_IER_UUE);
 		if (serial_in(up, UART_IER) & UART_IER_UUE) {
 			/*
-			 * It's an Xscale.
+			 * It's an Xscale or an Intel Gen3/4 SoC
 			 * We'll leave the UART_IER_UUE bit set to 1 (enabled).
 			 */
 			DEBUG_AUTOCONF("Xscale ");
+#ifndef __i386__
 			up->port.type = PORT_XSCALE;
+#else
+			up->port.type = PORT_INTELCE;
+#endif
 			up->capabilities |= UART_CAP_UUE;
 			return;
 		}
@@ -1540,6 +1621,15 @@
 }
 
 /*
+ * The UART Tx interrupts are not set under some conditions and therefore serial
+ * transmission hangs. This is a silicon issue and has not been root caused. The
+ * workaround for this silicon issue checks UART_LSR_THRE bit and UART_LSR_TEMT
+ * bit of LSR register in interrupt handler to see whether at least one of these
+ * two bits is set, if so then process the transmit request. If this workaround
+ * is not applied, then the serial transmission may hang. This workaround is for
+ * errata number 9 in Errata - B step.
+*/
+/*
  * This is the serial driver's interrupt routine.
  *
  * Arjan thinks the old way was overly complex, so it got simplified.
@@ -1558,6 +1648,7 @@
 	struct irq_info *i = dev_id;
 	struct list_head *l, *end = NULL;
 	int pass_counter = 0, handled = 0;
+	unsigned int flag;
 
 	DEBUG_INTR("serial8250_interrupt(%d)...", irq);
 
@@ -1573,6 +1664,7 @@
 		iir = serial_in(up, UART_IIR);
 		if (!(iir & UART_IIR_NO_INT)) {
 			serial8250_handle_port(up);
+			flag |= 0x01;
 
 			handled = 1;
 
@@ -1590,7 +1682,8 @@
 			handled = 1;
 
 			end = NULL;
-		} else if (end == NULL)
+		}
+		else if (end == NULL)
 			end = l;
 
 		l = l->next;
@@ -2385,7 +2478,11 @@
 		serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
 	}
 
+#ifdef CONFIG_TANGO2
+	serial_outp(up, UART_DL, quot);
+#else
 	serial_dl_write(up, quot);
+#endif
 
 	/*
 	 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
@@ -2742,11 +2839,15 @@
 	 *	First save the IER then disable the interrupts
 	 */
 	ier = serial_in(up, UART_IER);
-
+#ifdef CONFIG_GEN3_UART
+	/* Should enable UUE (Uart Unit Enable) bit. */
+	serial_out(up, UART_IER, UART_IER_UUE);
+#else
 	if (up->capabilities & UART_CAP_UUE)
 		serial_out(up, UART_IER, UART_IER_UUE);
 	else
 		serial_out(up, UART_IER, 0);
+#endif
 
 	uart_console_write(&up->port, s, count, serial8250_console_putchar);
 
diff -ruw linux-2.6.31.7/drivers/serial/8250_early.c linux-2.6.31.7-fbx/drivers/serial/8250_early.c
--- linux-2.6.31.7/drivers/serial/8250_early.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/serial/8250_early.c	2010-03-18 18:28:51.032814874 +0100
@@ -106,8 +106,13 @@
 
 	lcr = serial_in(port, UART_LCR);
 	serial_out(port, UART_LCR, lcr | UART_LCR_DLAB);
+#ifdef CONFIG_TANGO2
+	dll = serial_in(port, UART_DL) & 0xff;
+	dlm = serial_in(port, UART_DL) >> 8;
+#else
 	dll = serial_in(port, UART_DLL);
 	dlm = serial_in(port, UART_DLM);
+#endif
 	serial_out(port, UART_LCR, lcr);
 
 	quot = (dlm << 8) | dll;
@@ -128,8 +133,13 @@
 	divisor = port->uartclk / (16 * device->baud);
 	c = serial_in(port, UART_LCR);
 	serial_out(port, UART_LCR, c | UART_LCR_DLAB);
+
+#ifdef CONFIG_TANGO2
+	serial_out(port, UART_DL, divisor & 0xffff);
+#else
 	serial_out(port, UART_DLL, divisor & 0xff);
 	serial_out(port, UART_DLM, (divisor >> 8) & 0xff);
+#endif
 	serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
 }
 
diff -ruw linux-2.6.31.7/drivers/serial/Kconfig linux-2.6.31.7-fbx/drivers/serial/Kconfig
--- linux-2.6.31.7/drivers/serial/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/serial/Kconfig	2010-10-25 13:43:57.131442147 +0200
@@ -37,6 +37,13 @@
 	  Most people will say Y or M here, so that they can use serial mice,
 	  modems and similar devices connecting to the standard serial ports.
 
+config GEN3_UART
+	bool "Intel Media SOC Gen3 UART support"
+	depends on SERIAL_8250 && ARCH_GEN3 
+	default y
+	help
+	  This option enables Intel Media SOC Gen3 UART support. 
+
 config SERIAL_8250_CONSOLE
 	bool "Console on 8250/16550 and compatible serial port"
 	depends on SERIAL_8250=y
@@ -1451,4 +1458,23 @@
 	---help---
 	Add support for UART controller on timberdale.
 
+config SERIAL_BCM63XX
+	tristate "bcm63xx serial port support"
+	select SERIAL_CORE
+	depends on BCM63XX
+	help
+	  If you have a bcm63xx CPU, you can enable its onboard
+	  serial port by enabling this options.
+
+          To compile this driver as a module, choose M here: the
+          module will be called bcm963xx_uart.
+
+config SERIAL_BCM63XX_CONSOLE
+	bool "Console on bcm63xx serial port"
+	depends on SERIAL_BCM63XX
+	select SERIAL_CORE_CONSOLE
+	help
+	  If you have enabled the serial port on the bcm63xx CPU
+	  you can make it the console by answering Y to this option.
+
 endmenu
diff -ruw linux-2.6.31.7/drivers/serial/Makefile linux-2.6.31.7-fbx/drivers/serial/Makefile
--- linux-2.6.31.7/drivers/serial/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/serial/Makefile	2010-10-25 13:43:57.131442147 +0200
@@ -34,6 +34,7 @@
 obj-$(CONFIG_SERIAL_PXA) += pxa.o
 obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
 obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
+obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
 obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o
 obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
 obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
diff -ruw linux-2.6.31.7/drivers/spi/Kconfig linux-2.6.31.7-fbx/drivers/spi/Kconfig
--- linux-2.6.31.7/drivers/spi/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/spi/Kconfig	2010-10-25 13:43:57.141443424 +0200
@@ -178,6 +178,12 @@
 	  controller. If you have an embedded system with an AMBA(R)
 	  bus and a PL022 controller, say Y or M here.
 
+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 && EXPERIMENTAL
diff -ruw linux-2.6.31.7/drivers/spi/Makefile linux-2.6.31.7-fbx/drivers/spi/Makefile
--- linux-2.6.31.7/drivers/spi/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/spi/Makefile	2010-10-25 13:43:57.141443424 +0200
@@ -24,6 +24,7 @@
 obj-$(CONFIG_SPI_OMAP24XX)		+= omap2_mcspi.o
 obj-$(CONFIG_SPI_ORION)			+= orion_spi.o
 obj-$(CONFIG_SPI_PL022)			+= amba-pl022.o
+obj-$(CONFIG_SPI_TDM_ORION)		+= orion_tdm_spi.o
 obj-$(CONFIG_SPI_MPC52xx_PSC)		+= mpc52xx_psc_spi.o
 obj-$(CONFIG_SPI_MPC8xxx)		+= spi_mpc8xxx.o
 obj-$(CONFIG_SPI_S3C24XX_GPIO)		+= spi_s3c24xx_gpio.o
diff -ruw linux-2.6.31.7/drivers/usb/gadget/Kconfig linux-2.6.31.7-fbx/drivers/usb/gadget/Kconfig
--- linux-2.6.31.7/drivers/usb/gadget/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/usb/gadget/Kconfig	2010-10-25 13:43:57.381500900 +0200
@@ -121,6 +121,17 @@
 #
 # Integrated controllers
 #
+config USB_GADGET_VOX160
+	boolean "IKANOS VX160"
+	help
+	   This driver provides USB Device Controller driver for IKanos's VX160
+
+config USB_VOX160
+	tristate
+	depends on USB_GADGET_VOX160
+	default USB_GADGET
+	select USB_GADGET_SELECTED
+
 
 config USB_GADGET_AT91
 	boolean "Atmel AT91 USB Device Port"
diff -ruw linux-2.6.31.7/drivers/usb/gadget/Makefile linux-2.6.31.7-fbx/drivers/usb/gadget/Makefile
--- linux-2.6.31.7/drivers/usb/gadget/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/usb/gadget/Makefile	2010-10-25 13:43:57.381500900 +0200
@@ -27,6 +27,7 @@
 obj-$(CONFIG_USB_CI13XXX)	+= ci13xxx_udc.o
 obj-$(CONFIG_USB_S3C_HSOTG)	+= s3c-hsotg.o
 obj-$(CONFIG_USB_LANGWELL)	+= langwell_udc.o
+obj-$(CONFIG_USB_VOX160)	+= vox160_udc.o
 
 #
 # USB gadget drivers
diff -ruw linux-2.6.31.7/drivers/usb/host/ehci.h linux-2.6.31.7-fbx/drivers/usb/host/ehci.h
--- linux-2.6.31.7/drivers/usb/host/ehci.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/usb/host/ehci.h	2010-10-25 13:43:57.391451589 +0200
@@ -602,6 +602,11 @@
 #define writel_be(val, addr)	__raw_writel(val, (__force unsigned *)addr)
 #endif
 
+#if defined(CONFIG_MIPS) && defined(CONFIG_BCM63XX)
+#define readl_be(addr)		__raw_readl((__force unsigned *)addr)
+#define writel_be(val, addr)	__raw_writel(val, (__force unsigned *)addr)
+#endif
+
 static inline unsigned int ehci_readl(const struct ehci_hcd *ehci,
 		__u32 __iomem * regs)
 {
diff -ruw linux-2.6.31.7/drivers/usb/host/ehci-hcd.c linux-2.6.31.7-fbx/drivers/usb/host/ehci-hcd.c
--- linux-2.6.31.7/drivers/usb/host/ehci-hcd.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/usb/host/ehci-hcd.c	2010-10-25 13:43:57.391451589 +0200
@@ -1119,6 +1119,16 @@
 #define	PLATFORM_DRIVER		ixp4xx_ehci_driver
 #endif
 
+#ifdef CONFIG_TANGO2
+#include "ehci-tango2.c"
+#define	PLATFORM_DRIVER		ehci_hcd_tango2_driver
+#endif
+
+#ifdef CONFIG_BCM63XX
+#include "ehci-bcm63xx.c"
+#define	PLATFORM_DRIVER		ehci_hcd_bcm63xx_driver
+#endif
+
 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER)
 #error "missing bus glue for ehci-hcd"
diff -ruw linux-2.6.31.7/drivers/usb/host/ehci-hub.c linux-2.6.31.7-fbx/drivers/usb/host/ehci-hub.c
--- linux-2.6.31.7/drivers/usb/host/ehci-hub.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/usb/host/ehci-hub.c	2010-10-25 13:43:57.391451589 +0200
@@ -681,11 +681,13 @@
 			 * power switching; they're allowed to just limit the
 			 * current.  khubd will turn the power back on.
 			 */
+#ifndef CONFIG_BCM63XX
 			if (HCS_PPC (ehci->hcs_params)){
 				ehci_writel(ehci,
 					temp & ~(PORT_RWC_BITS | PORT_POWER),
 					status_reg);
 			}
+#endif
 		}
 
 		/* whoever resumes must GetPortStatus to complete it!! */
diff -ruw linux-2.6.31.7/drivers/usb/host/ehci-q.c linux-2.6.31.7-fbx/drivers/usb/host/ehci-q.c
--- linux-2.6.31.7/drivers/usb/host/ehci-q.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/usb/host/ehci-q.c	2010-10-25 13:43:57.391451589 +0200
@@ -1100,6 +1100,33 @@
 	return rc;
 }
 
+#ifdef CONFIG_TANGO2
+/*-------------------------------------------------------------------------*/
+
+/* The TangoX USB2.0 core has a bug related async qh unlinking. */
+static void tango2_unlink_async_fix(struct ehci_hcd *ehci)
+{
+	struct ehci_qh *next    =NULL;
+	int async_list		= 0;
+	int cmd = readl (&ehci->regs->command);
+
+	/* Disable ASYNC */
+	writel (cmd & ~CMD_ASE, &ehci->regs->command);
+	udelay(250);
+	async_list =(u32)phys_to_virt(readl (&ehci->regs->async_next));
+	next = (struct ehci_qh *) async_list;
+	if(next->qh_next.qh)
+		writel(next->hw_next, &ehci->regs->async_next);
+	else
+		writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next);
+	wmb();
+
+	/* Enable ASYNC */
+	writel (cmd | CMD_ASE, &ehci->regs->command);
+	(void) readl (&ehci->regs->command);
+}
+#endif
+
 /*-------------------------------------------------------------------------*/
 
 /* the async qh for the qtds being reclaimed are now unlinked from the HC */
@@ -1159,6 +1186,10 @@
 		BUG ();
 #endif
 
+#ifdef CONFIG_TANGO2
+	tango2_unlink_async_fix(ehci);
+#endif
+
 	/* stop async schedule right now? */
 	if (unlikely (qh == ehci->async)) {
 		/* can't get here without STS_ASS set */
@@ -1232,6 +1263,7 @@
 				}
 			}
 
+#ifndef CONFIG_TANGO2
 			/* unlink idle entries, reducing DMA usage as well
 			 * as HCD schedule-scanning costs.  delay for any qh
 			 * we just scanned, there's a not-unusual case that it
@@ -1247,6 +1279,7 @@
 				else
 					action = TIMER_ASYNC_SHRINK;
 			}
+#endif
 
 			qh = qh->qh_next.qh;
 		} while (qh);
diff -ruw linux-2.6.31.7/drivers/usb/host/ehci-sched.c linux-2.6.31.7-fbx/drivers/usb/host/ehci-sched.c
--- linux-2.6.31.7/drivers/usb/host/ehci-sched.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/usb/host/ehci-sched.c	2010-10-25 13:43:57.391451589 +0200
@@ -2259,9 +2259,13 @@
 				 * No need to check for activity unless the
 				 * frame is current.
 				 */
+#ifdef CONFIG_ARCH_GEN3
+				if (live && (q.sitd->hw_results & SITD_ACTIVE(ehci))) {
+#else
 				if (frame == clock_frame && live &&
 						(q.sitd->hw_results &
 							SITD_ACTIVE(ehci))) {
+#endif
 					incomplete = true;
 					q_p = &q.sitd->sitd_next;
 					hw_p = &q.sitd->hw_next;
diff -ruw linux-2.6.31.7/drivers/usb/host/ohci.h linux-2.6.31.7-fbx/drivers/usb/host/ohci.h
--- linux-2.6.31.7/drivers/usb/host/ohci.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/usb/host/ohci.h	2010-10-25 13:43:57.401447536 +0200
@@ -550,6 +550,11 @@
  * Other arches can be added if/when they're needed.
  *
  */
+#if defined(CONFIG_MIPS) && defined(CONFIG_BCM63XX)
+#define readl_be(addr)		__raw_readl((__force unsigned *)addr)
+#define writel_be(val, addr)	__raw_writel(val, (__force unsigned *)addr)
+#endif
+
 static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci,
 					__hc32 __iomem * regs)
 {
@@ -655,7 +660,7 @@
  * some big-endian SOC implementations.  Same thing happens with PSW access.
  */
 
-#ifdef CONFIG_PPC_MPC52xx
+#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_BCM63XX)
 #define big_endian_frame_no_quirk(ohci)	(ohci->flags & OHCI_QUIRK_FRAME_NO)
 #else
 #define big_endian_frame_no_quirk(ohci)	0
diff -ruw linux-2.6.31.7/drivers/usb/host/ohci-hcd.c linux-2.6.31.7-fbx/drivers/usb/host/ohci-hcd.c
--- linux-2.6.31.7/drivers/usb/host/ohci-hcd.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/usb/host/ohci-hcd.c	2010-10-25 13:43:57.401447536 +0200
@@ -133,6 +133,15 @@
 module_param (no_handshake, bool, 0);
 MODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake");
 
+
+#ifdef CONFIG_TANGO2
+static struct timer_list ohci_timer;
+static int polling_scale = 1;
+static int polling_interval_min = 1;
+static int polling_interval_max = HZ;
+static unsigned int polling_interval = 1;
+#endif
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -775,8 +784,19 @@
 	ints &= ohci_readl(ohci, &regs->intrenable);
 
 	/* interrupt for some other device? */
-	if (ints == 0)
+	if (ints == 0) {
+#ifdef CONFIG_TANGO2
+		polling_interval <<= polling_scale;
+		/* Poll at least once per second */
+		if (polling_interval > polling_interval_max)
+			polling_interval = polling_interval_max;
+#endif
 		return IRQ_NOTMINE;
+	}
+
+#ifdef CONFIG_TANGO2
+	polling_interval = polling_interval_min;
+#endif
 
 	if (ints & OHCI_INTR_UE) {
 		// e.g. due to PCI Master/Target Abort
@@ -890,6 +910,24 @@
 
 /*-------------------------------------------------------------------------*/
 
+#ifdef CONFIG_TANGO2
+static void ohci_polling (unsigned long data)
+{
+	unsigned long flags;
+	struct usb_hcd *hcd = (struct usb_hcd *)data;
+
+	local_save_flags(flags);
+	ohci_irq (hcd);
+	local_irq_restore(flags);
+
+	/* poll using variable delay */
+	mod_timer(&ohci_timer, jiffies + polling_interval);
+       return;
+}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
 static void ohci_stop (struct usb_hcd *hcd)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
@@ -1052,6 +1090,11 @@
 #define PLATFORM_DRIVER		usb_hcd_pnx4008_driver
 #endif
 
+#ifdef CONFIG_BCM63XX
+#include "ohci-bcm63xx.c"
+#define PLATFORM_DRIVER		ohci_hcd_bcm63xx_driver
+#endif
+
 #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
     defined(CONFIG_CPU_SUBTYPE_SH7721) || \
     defined(CONFIG_CPU_SUBTYPE_SH7763) || \
@@ -1060,6 +1103,10 @@
 #define PLATFORM_DRIVER		ohci_hcd_sh_driver
 #endif
 
+#ifdef CONFIG_TANGO2
+#include "ohci-tango2.c"
+#define PLATFORM_DRIVER		ohci_hcd_tango2_driver
+#endif
 
 #ifdef CONFIG_USB_OHCI_HCD_PPC_OF
 #include "ohci-ppc-of.c"
diff -ruw linux-2.6.31.7/drivers/usb/serial/cp210x.c linux-2.6.31.7-fbx/drivers/usb/serial/cp210x.c
--- linux-2.6.31.7/drivers/usb/serial/cp210x.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/usb/serial/cp210x.c	2010-10-25 13:43:57.411439677 +0200
@@ -60,6 +60,7 @@
 	{ USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */
 	{ USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
 	{ USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */
+	{ USB_DEVICE(0x0489, 0xE003) }, /* Pirelli wifi/GSM phone */
 	{ USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
 	{ USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */
 	{ USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */
diff -ruw linux-2.6.31.7/drivers/video/Kconfig linux-2.6.31.7-fbx/drivers/video/Kconfig
--- linux-2.6.31.7/drivers/video/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/video/Kconfig	2010-10-25 13:43:57.431453697 +0200
@@ -491,6 +491,28 @@
 	  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_SSD1305
+	tristate "SSD1305 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_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-2.6.31.7/drivers/video/Makefile linux-2.6.31.7-fbx/drivers/video/Makefile
--- linux-2.6.31.7/drivers/video/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/video/Makefile	2010-10-25 13:43:57.431453697 +0200
@@ -30,6 +30,8 @@
 # Hardware specific drivers go first
 obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
 obj-$(CONFIG_FB_ARC)              += arcfb.o
+obj-$(CONFIG_FB_SSD1305)          += ssd1305.o
+obj-$(CONFIG_FB_SSD1327)          += ssd1327.o
 obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
diff -ruw linux-2.6.31.7/firmware/Makefile linux-2.6.31.7-fbx/firmware/Makefile
--- linux-2.6.31.7/firmware/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/firmware/Makefile	2010-10-25 13:43:57.961437931 +0200
@@ -46,6 +46,9 @@
 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_8687.fw mwl8k/fmimage_8687.fw
+fw-shipped-$(CONFIG_MWL8K) += mwl8k/helper_8366.fw mwl8k/fmimage_8366.fw
+fw-shipped-$(CONFIG_MWL8K) += mwl8k/mfg_fmimage_8366.fw
 fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
 fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis
 fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis
diff -ruw linux-2.6.31.7/fs/exec.c linux-2.6.31.7-fbx/fs/exec.c
--- linux-2.6.31.7/fs/exec.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/exec.c	2010-10-25 13:43:58.041441342 +0200
@@ -61,6 +61,14 @@
 #include <asm/tlb.h>
 #include "internal.h"
 
+enum {
+	CORE_ENV_PID,
+	CORE_ENV_SIGNAL,
+	CORE_ENV_EXECUTABLE,
+	CORE_ENV_TIME,
+	CORE_ENV_NR,
+};
+
 int core_uses_pid;
 char core_pattern[CORENAME_MAX_SIZE] = "core";
 int suid_dumpable = 0;
@@ -1737,9 +1745,13 @@
 	int flag = 0;
 	int ispipe = 0;
 	unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
+	char *helper_envp[CORE_ENV_NR + 1];
 	char **helper_argv = NULL;
 	int helper_argc = 0;
 	char *delimit;
+	int i;
+
+	memset(helper_envp, 0, sizeof (helper_envp));
 
 	audit_core_dumps(signr);
 
@@ -1806,6 +1818,8 @@
 		goto fail_unlock;
 
  	if (ispipe) {
+		struct timeval tv;
+
 		helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
 		if (!helper_argv) {
 			printk(KERN_WARNING "%s failed to allocate memory\n",
@@ -1829,9 +1843,22 @@
 
 		core_limit = RLIM_INFINITY;
 
+		/* Set pipe helper environment */
+		do_gettimeofday(&tv);
+
+		helper_envp[CORE_ENV_PID] = kasprintf(GFP_KERNEL,
+			"CORE_PID=%d", current->tgid);
+		helper_envp[CORE_ENV_SIGNAL] = kasprintf(GFP_KERNEL,
+			"CORE_SIGNAL=%ld", signr);
+		helper_envp[CORE_ENV_EXECUTABLE] = kasprintf(GFP_KERNEL,
+			"CORE_EXECUTABLE=%s", current->comm);
+		helper_envp[CORE_ENV_TIME] = kasprintf(GFP_KERNEL,
+			"CORE_TIME=%lu", tv.tv_sec);
+		helper_envp[CORE_ENV_NR] = NULL;
+
 		/* SIGPIPE can happen, but it's just never processed */
- 		if (call_usermodehelper_pipe(corename+1, helper_argv, NULL,
-				&file)) {
+		if (call_usermodehelper_pipe(corename+1, helper_argv,
+				helper_envp, &file)) {
  			printk(KERN_INFO "Core dump to %s pipe failed\n",
 			       corename);
  			goto fail_unlock;
@@ -1874,6 +1901,8 @@
 fail_unlock:
 	if (helper_argv)
 		argv_free(helper_argv);
+	for (i = 0; i < CORE_ENV_NR; i++)
+		kfree(helper_envp[i]);
 
 	revert_creds(old_cred);
 	put_cred(cred);
diff -ruw linux-2.6.31.7/fs/Kconfig linux-2.6.31.7-fbx/fs/Kconfig
--- linux-2.6.31.7/fs/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/Kconfig	2010-10-25 13:43:58.001441438 +0200
@@ -145,6 +145,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-2.6.31.7/fs/ramfs/file-mmu.c linux-2.6.31.7-fbx/fs/ramfs/file-mmu.c
--- linux-2.6.31.7/fs/ramfs/file-mmu.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/ramfs/file-mmu.c	2010-03-18 18:28:52.302922419 +0100
@@ -27,6 +27,7 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/ramfs.h>
+#include <linux/xattr.h>
 
 #include "internal.h"
 
@@ -51,4 +52,11 @@
 
 const struct inode_operations ramfs_file_inode_operations = {
 	.getattr	= simple_getattr,
+#ifdef CONFIG_RAMFS_XATTR
+	.setxattr	= generic_setxattr,
+	.getxattr	= generic_getxattr,
+	.listxattr	= generic_listxattr,
+	.removexattr	= generic_removexattr,
+#endif
 };
+
diff -ruw linux-2.6.31.7/fs/ramfs/inode.c linux-2.6.31.7-fbx/fs/ramfs/inode.c
--- linux-2.6.31.7/fs/ramfs/inode.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/ramfs/inode.c	2010-10-25 13:43:58.141447691 +0200
@@ -35,6 +35,7 @@
 #include <linux/sched.h>
 #include <linux/parser.h>
 #include <asm/uaccess.h>
+#include <linux/xattr.h>
 #include "internal.h"
 
 /* some random number */
@@ -44,6 +45,7 @@
 
 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 = {
 	.ra_pages	= 0,	/* No readahead */
@@ -52,6 +54,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, int mode, dev_t dev)
 {
 	struct inode * inode = new_inode(sb);
@@ -156,9 +180,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,
@@ -240,6 +272,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, S_IFDIR | fsi->mount_opts.mode, 0);
 	if (!inode) {
@@ -292,6 +327,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);
@@ -313,10 +358,19 @@
 	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-2.6.31.7/fs/ramfs/internal.h linux-2.6.31.7-fbx/fs/ramfs/internal.h
--- linux-2.6.31.7/fs/ramfs/internal.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/ramfs/internal.h	2010-03-18 18:28:52.302922419 +0100
@@ -9,6 +9,42 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#ifndef RAMFS_INTERNAL_H
+# define RAMFS_INTERNALH
+
+/* 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 struct xattr_handler *ramfs_xattr_handlers[];
+#endif
+
+
+#endif /* !RAMFS_INTERNAL_H */
diff -ruw linux-2.6.31.7/fs/ramfs/Makefile linux-2.6.31.7-fbx/fs/ramfs/Makefile
--- linux-2.6.31.7/fs/ramfs/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/ramfs/Makefile	2010-03-18 18:28:52.302922419 +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-2.6.31.7/fs/squashfs/block.c linux-2.6.31.7-fbx/fs/squashfs/block.c
--- linux-2.6.31.7/fs/squashfs/block.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/squashfs/block.c	2010-03-18 18:28:52.312910069 +0100
@@ -33,6 +33,8 @@
 #include <linux/string.h>
 #include <linux/buffer_head.h>
 #include <linux/zlib.h>
+#include <linux/vmalloc.h>
+#include <linux/LzmaDec.h>
 
 #include "squashfs_fs.h"
 #include "squashfs_fs_sb.h"
@@ -70,6 +72,296 @@
 	return bh;
 }
 
+#ifdef CONFIG_SQUASHFS_SUPPORT_ZLIB
+static int decompress_block_zlib(struct squashfs_sb_info *msblk,
+				 struct buffer_head **bh, int b,
+				 int *length, int offset, int pages,
+				 void **buffer, int srclength)
+{
+	int zlib_err = 0, zlib_init = 0;
+	int bytes, page = 0, avail, k = 0;
+
+	mutex_lock(&msblk->read_data_mutex);
+
+	msblk->stream.avail_out = 0;
+	msblk->stream.avail_in = 0;
+
+	bytes = *length;
+	do {
+		if (msblk->stream.avail_in == 0 && k < b) {
+			avail = min(bytes, msblk->devblksize - offset);
+			bytes -= avail;
+			wait_on_buffer(bh[k]);
+			if (!buffer_uptodate(bh[k]))
+				goto release_mutex;
+
+			if (avail == 0) {
+				offset = 0;
+				put_bh(bh[k++]);
+				continue;
+			}
+
+			msblk->stream.next_in = bh[k]->b_data + offset;
+			msblk->stream.avail_in = avail;
+			offset = 0;
+		}
+
+		if (msblk->stream.avail_out == 0 && page < pages) {
+			msblk->stream.next_out = buffer[page++];
+			msblk->stream.avail_out = PAGE_CACHE_SIZE;
+		}
+
+		if (!zlib_init) {
+			zlib_err = zlib_inflateInit(&msblk->stream);
+			if (zlib_err != Z_OK) {
+				ERROR("zlib_inflateInit returned"
+				      " unexpected result 0x%x,"
+				      " srclength %d\n", zlib_err,
+				      srclength);
+				goto release_mutex;
+			}
+			zlib_init = 1;
+		}
+
+		zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH);
+
+		if (msblk->stream.avail_in == 0 && k < b)
+			put_bh(bh[k++]);
+	} while (zlib_err == Z_OK);
+
+	if (zlib_err != Z_STREAM_END) {
+		ERROR("zlib_inflate error, data probably corrupt\n");
+		goto release_mutex;
+	}
+
+	zlib_err = zlib_inflateEnd(&msblk->stream);
+	if (zlib_err != Z_OK) {
+		ERROR("zlib_inflate error, data probably corrupt\n");
+		goto release_mutex;
+	}
+	*length = msblk->stream.total_out;
+	mutex_unlock(&msblk->read_data_mutex);
+
+	return 0;
+
+release_mutex:
+	mutex_unlock(&msblk->read_data_mutex);
+
+	for (; k < b; k++)
+		put_bh(bh[k]);
+	return 1;
+}
+#endif
+
+#ifdef CONFIG_SQUASHFS_SUPPORT_LZMA
+static int decompress_block_lzma(struct squashfs_sb_info *msblk,
+				 struct buffer_head **bh, int b,
+				 int *length, int in_offset, int pages,
+				 void **buffer, int srclength)
+{
+	int bytes, prob_size;
+	int out_page, out_avail;
+	int in_avail = 0, in_bh;
+	char *out_ptr, *in_ptr;
+	CLzmaDec dec;
+	CLzmaProps *prop;
+	ELzmaStatus status;
+	char prop_buf[LZMA_PROPS_SIZE];
+	static char junk_buf[128];
+
+/* 	printk("decompress_block_lzma: len:%u srclen:%u in_offset:%d\n", */
+/* 	       *length, srclength, in_offset); */
+
+	/* make sure data is bigger than fixed lzma properties */
+	if (*length < LZMA_PROPS_SIZE)
+		return 1;
+
+	/* fetch props */
+	out_ptr = prop_buf;
+	out_avail = LZMA_PROPS_SIZE;
+
+	for (in_bh = 0; in_bh < b; in_bh++) {
+
+		wait_on_buffer(bh[in_bh]);
+
+		if (!buffer_uptodate(bh[in_bh]))
+			goto put_all_bh;
+
+		in_avail = msblk->devblksize - in_offset;
+		if (in_avail > out_avail)
+			in_avail = out_avail;
+		memcpy(out_ptr, bh[in_bh]->b_data + in_offset, in_avail);
+		out_ptr += in_avail;
+		out_avail -= in_avail;
+
+		/* break when we have all props */
+		if (!out_avail)
+			break;
+
+		in_offset = 0;
+		put_bh(bh[in_bh]);
+	}
+
+	if (out_avail) {
+		ERROR("LZMA: unable to read props\n");
+		goto put_all_bh;
+	}
+
+	/* restore length & in_offset */
+	*length -= LZMA_PROPS_SIZE;
+	in_offset += in_avail;
+
+	prop = &dec.prop;
+	if (LzmaProps_Decode(prop, prop_buf, LZMA_PROPS_SIZE) != SZ_OK) {
+		ERROR("LZMA: decode props failed\n");
+		goto put_all_bh;
+	}
+
+	/* from this point, we're using global workspace, so lock */
+	mutex_lock(&msblk->read_data_mutex);
+
+	/* check if the current workspace is big enough */
+	if (prop->dicSize > srclength)
+		prop->dicSize = srclength;
+
+	if (prop->dicSize > msblk->lzma_dict_size) {
+		vfree(msblk->lzma_dict_buffer);
+		msblk->lzma_dict_buffer = NULL;
+		msblk->lzma_dict_size = prop->dicSize;
+	}
+
+	if (!msblk->lzma_dict_buffer) {
+		msblk->lzma_dict_buffer = vmalloc(msblk->lzma_dict_size);
+		if (!msblk->lzma_dict_buffer)
+			goto release_mutex;
+	}
+
+	/* check if the current workspace is big enough */
+	prob_size = LzmaProps_GetNumProbs(prop) * sizeof (CLzmaProb);
+	if (prob_size > msblk->lzma_prob_size) {
+		vfree(msblk->lzma_prob_buffer);
+		msblk->lzma_prob_buffer = NULL;
+		msblk->lzma_prob_size = prob_size;
+	}
+
+	if (!msblk->lzma_prob_buffer) {
+		msblk->lzma_prob_buffer = vmalloc(msblk->lzma_prob_size);
+		if (!msblk->lzma_prob_buffer)
+			goto release_mutex;
+	}
+
+	/* init lzma decoder */
+	dec.numProbs = LzmaProps_GetNumProbs(prop);
+	dec.probs = msblk->lzma_prob_buffer;
+	dec.dic = msblk->lzma_dict_buffer;
+	dec.dicBufSize = prop->dicSize;
+	LzmaDec_Init(&dec);
+
+	in_avail = min(*length, msblk->devblksize - in_offset);
+	in_ptr = bh[in_bh]->b_data + in_offset;
+
+	bytes = *length - in_avail;
+	*length = 0;
+
+	out_page = 0;
+	out_avail = PAGE_SIZE;
+	out_ptr = buffer[0];
+
+	do {
+		SRes res;
+		int in_consumed, out_written;
+
+		/* read one block of data */
+		if (in_avail == 0) {
+
+			if (in_bh == b - 1) {
+				ERROR("LZMA: ran out of input data\n");
+				goto release_mutex;
+			}
+
+			put_bh(bh[in_bh]);
+			in_bh++;
+
+			wait_on_buffer(bh[in_bh]);
+			if (!buffer_uptodate(bh[in_bh]))
+				goto release_mutex;
+
+			in_avail = min(msblk->devblksize, bytes);
+			in_ptr = bh[in_bh]->b_data;
+			bytes -= in_avail;
+		}
+
+		/* switch to next out page if needed */
+		if (out_avail == 0) {
+			if (out_page == pages - 1) {
+				out_ptr = junk_buf;
+				out_avail = sizeof (junk_buf);
+			} else {
+				out_page++;
+				out_ptr = buffer[out_page];
+				out_avail = PAGE_SIZE;
+			}
+		}
+
+		in_consumed = in_avail;
+		out_written = out_avail;
+
+/* 		printk("decodetobuf: out_avail:%u in_avail:%u\n", */
+/* 		       out_avail, in_avail); */
+
+		res = LzmaDec_DecodeToBuf(&dec,
+					  out_ptr, &out_written,
+					  in_ptr, &in_consumed,
+					  LZMA_FINISH_ANY, &status);
+
+		if (res != SZ_OK) {
+			ERROR("LZMA: invalid compressed data\n");
+			goto release_mutex;
+		}
+
+/* 		printk("decodetobuf: out_written:%u in_consumed:%u\n", */
+/* 		       out_written, in_consumed); */
+
+		if (!in_consumed && !out_written) {
+			ERROR("LZMA: no data consumed\n");
+			goto release_mutex;
+		}
+
+		*length += out_written;
+		out_ptr += out_written;
+		out_avail -= out_written;
+
+		in_ptr += in_consumed;
+		in_avail -= in_consumed;
+
+	} while (in_avail || bytes);
+
+	put_bh(bh[in_bh]);
+
+	switch (status) {
+	case LZMA_STATUS_NOT_FINISHED:
+	case LZMA_STATUS_NEEDS_MORE_INPUT:
+	default:
+		ERROR("LZMA: decompression is not done\n");
+		goto release_mutex;
+	case LZMA_STATUS_FINISHED_WITH_MARK:
+	case LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK:
+		break;
+	}
+
+	mutex_unlock(&msblk->read_data_mutex);
+
+	return 0;
+
+release_mutex:
+	mutex_unlock(&msblk->read_data_mutex);
+
+put_all_bh:
+	for (; in_bh < b; in_bh++)
+		put_bh(bh[in_bh]);
+	return 1;
+}
+#endif
 
 /*
  * Read and decompress a metadata block or datablock.  Length is non-zero
@@ -86,8 +378,7 @@
 	struct buffer_head **bh;
 	int offset = index & ((1 << msblk->devblksize_log2) - 1);
 	u64 cur_index = index >> msblk->devblksize_log2;
-	int bytes, compressed, b = 0, k = 0, page = 0, avail;
-
+	int bytes, compressed, b = 0, k = 0;
 
 	bh = kcalloc((msblk->block_size >> msblk->devblksize_log2) + 1,
 				sizeof(*bh), GFP_KERNEL);
@@ -153,77 +444,42 @@
 	}
 
 	if (compressed) {
-		int zlib_err = 0, zlib_init = 0;
+		int ret;
 
 		/*
 		 * Uncompress block.
 		 */
-
-		mutex_lock(&msblk->read_data_mutex);
-
-		msblk->stream.avail_out = 0;
-		msblk->stream.avail_in = 0;
-
-		bytes = length;
-		do {
-			if (msblk->stream.avail_in == 0 && k < b) {
-				avail = min(bytes, msblk->devblksize - offset);
-				bytes -= avail;
-				wait_on_buffer(bh[k]);
-				if (!buffer_uptodate(bh[k]))
-					goto release_mutex;
-
-				if (avail == 0) {
-					offset = 0;
-					put_bh(bh[k++]);
-					continue;
+		switch (msblk->compression) {
+#ifdef CONFIG_SQUASHFS_SUPPORT_ZLIB
+		case ZLIB_COMPRESSION:
+			ret = decompress_block_zlib(msblk, bh, b,
+						    &length, offset,
+						    pages, buffer, srclength);
+			break;
+#endif
+
+#ifdef CONFIG_SQUASHFS_SUPPORT_LZMA
+		case LZMA_COMPRESSION:
+			ret = decompress_block_lzma(msblk, bh, b,
+						    &length, offset,
+						    pages, buffer, srclength);
+			break;
+#endif
+
+		default:
+			ret = 0;
+			break;
 				}
 
-				msblk->stream.next_in = bh[k]->b_data + offset;
-				msblk->stream.avail_in = avail;
-				offset = 0;
-			}
-
-			if (msblk->stream.avail_out == 0 && page < pages) {
-				msblk->stream.next_out = buffer[page++];
-				msblk->stream.avail_out = PAGE_CACHE_SIZE;
-			}
-
-			if (!zlib_init) {
-				zlib_err = zlib_inflateInit(&msblk->stream);
-				if (zlib_err != Z_OK) {
-					ERROR("zlib_inflateInit returned"
-						" unexpected result 0x%x,"
-						" srclength %d\n", zlib_err,
-						srclength);
-					goto release_mutex;
-				}
-				zlib_init = 1;
-			}
-
-			zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH);
-
-			if (msblk->stream.avail_in == 0 && k < b)
-				put_bh(bh[k++]);
-		} while (zlib_err == Z_OK);
-
-		if (zlib_err != Z_STREAM_END) {
-			ERROR("zlib_inflate error, data probably corrupt\n");
-			goto release_mutex;
-		}
+		if (ret)
+			goto read_failure;
 
-		zlib_err = zlib_inflateEnd(&msblk->stream);
-		if (zlib_err != Z_OK) {
-			ERROR("zlib_inflate error, data probably corrupt\n");
-			goto release_mutex;
-		}
-		length = msblk->stream.total_out;
-		mutex_unlock(&msblk->read_data_mutex);
 	} else {
 		/*
 		 * Block is uncompressed.
 		 */
-		int i, in, pg_offset = 0;
+		int i, k = 0, in, pg_offset = 0;
+		int page = 0, avail;
 
 		for (i = 0; i < b; i++) {
 			wait_on_buffer(bh[i]);
@@ -255,9 +511,6 @@
 	kfree(bh);
 	return length;
 
-release_mutex:
-	mutex_unlock(&msblk->read_data_mutex);
-
 block_release:
 	for (; k < b; k++)
 		put_bh(bh[k]);
diff -ruw linux-2.6.31.7/fs/squashfs/Kconfig linux-2.6.31.7-fbx/fs/squashfs/Kconfig
--- linux-2.6.31.7/fs/squashfs/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/squashfs/Kconfig	2010-03-18 18:28:52.312910069 +0100
@@ -1,7 +1,6 @@
 config SQUASHFS
 	tristate "SquashFS 4.0 - Squashed file system support"
 	depends on BLOCK
-	select ZLIB_INFLATE
 	help
 	  Saying Y here includes support for SquashFS 4.0 (a Compressed
 	  Read-Only File System).  Squashfs is a highly compressed read-only
@@ -26,6 +25,18 @@
 
 	  If unsure, say N.
 
+config SQUASHFS_SUPPORT_ZLIB
+	bool
+	prompt "Support ZLIB compression" if SQUASHFS_SUPPORT_LZMA
+	select ZLIB_INFLATE
+	depends on SQUASHFS
+	default y
+
+config SQUASHFS_SUPPORT_LZMA
+	bool "Support LZMA compression"
+	depends on SQUASHFS
+	select DECOMPRESS_LZMASDK
+
 config SQUASHFS_EMBEDDED
 
 	bool "Additional option for memory-constrained systems" 
diff -ruw linux-2.6.31.7/fs/squashfs/squashfs_fs.h linux-2.6.31.7-fbx/fs/squashfs/squashfs_fs.h
--- linux-2.6.31.7/fs/squashfs/squashfs_fs.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/squashfs/squashfs_fs.h	2010-03-18 18:28:52.312910069 +0100
@@ -212,6 +212,7 @@
  * definitions for structures on disk
  */
 #define ZLIB_COMPRESSION	 1
+#define LZMA_COMPRESSION	 2
 
 struct squashfs_super_block {
 	__le32			s_magic;
diff -ruw linux-2.6.31.7/fs/squashfs/squashfs_fs_sb.h linux-2.6.31.7-fbx/fs/squashfs/squashfs_fs_sb.h
--- linux-2.6.31.7/fs/squashfs/squashfs_fs_sb.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/squashfs/squashfs_fs_sb.h	2010-03-18 18:28:52.312910069 +0100
@@ -52,6 +52,7 @@
 };
 
 struct squashfs_sb_info {
+	int			compression;
 	int			devblksize;
 	int			devblksize_log2;
 	struct squashfs_cache	*block_cache;
@@ -64,7 +65,15 @@
 	struct mutex		read_data_mutex;
 	struct mutex		meta_index_mutex;
 	struct meta_index	*meta_index;
+#ifdef CONFIG_SQUASHFS_SUPPORT_ZLIB
 	z_stream		stream;
+#endif
+#ifdef CONFIG_SQUASHFS_SUPPORT_LZMA
+	char			*lzma_dict_buffer;
+	unsigned int		lzma_dict_size;
+	void			*lzma_prob_buffer;
+	unsigned int		lzma_prob_size;
+#endif
 	__le64			*inode_lookup_table;
 	u64			inode_table;
 	u64			directory_table;
diff -ruw linux-2.6.31.7/fs/squashfs/squashfs.h linux-2.6.31.7-fbx/fs/squashfs/squashfs.h
--- linux-2.6.31.7/fs/squashfs/squashfs.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/squashfs/squashfs.h	2010-03-18 18:28:52.312910069 +0100
@@ -20,7 +20,6 @@
  *
  * squashfs.h
  */
-
 #define TRACE(s, args...)	pr_debug("SQUASHFS: "s, ## args)
 
 #define ERROR(s, args...)	pr_err("SQUASHFS error: "s, ## args)
diff -ruw linux-2.6.31.7/fs/squashfs/super.c linux-2.6.31.7-fbx/fs/squashfs/super.c
--- linux-2.6.31.7/fs/squashfs/super.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/squashfs/super.c	2010-10-25 13:43:58.141447691 +0200
@@ -37,6 +37,7 @@
 #include <linux/module.h>
 #include <linux/zlib.h>
 #include <linux/magic.h>
+#include <linux/vmalloc.h>
 
 #include "squashfs_fs.h"
 #include "squashfs_fs_sb.h"
@@ -48,6 +49,8 @@
 
 static int supported_squashfs_filesystem(short major, short minor, short comp)
 {
+	int unsupported;
+
 	if (major < SQUASHFS_MAJOR) {
 		ERROR("Major/Minor mismatch, older Squashfs %d.%d "
 			"filesystems are unsupported\n", major, minor);
@@ -59,8 +62,26 @@
 		return -EINVAL;
 	}
 
-	if (comp != ZLIB_COMPRESSION)
+	unsupported = 0;
+	switch (comp) {
+	case ZLIB_COMPRESSION:
+#ifndef CONFIG_SQUASHFS_SUPPORT_ZLIB
+		unsupported = 1;
+#endif
+		break;
+	case LZMA_COMPRESSION:
+#ifndef CONFIG_SQUASHFS_SUPPORT_LZMA
+		unsupported = 1;
+#endif
+		break;
+	default:
 		return -EINVAL;
+	}
+
+	if (unsupported) {
+		ERROR("Unsupported compression scheme\n");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -87,13 +108,6 @@
 	}
 	msblk = sb->s_fs_info;
 
-	msblk->stream.workspace = kmalloc(zlib_inflate_workspacesize(),
-		GFP_KERNEL);
-	if (msblk->stream.workspace == NULL) {
-		ERROR("Failed to allocate zlib workspace\n");
-		goto failure;
-	}
-
 	sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
 	if (sblk == NULL) {
 		ERROR("Failed to allocate squashfs_super_block\n");
@@ -136,6 +150,28 @@
 			le16_to_cpu(sblk->compression));
 	if (err < 0)
 		goto failed_mount;
+	msblk->compression = le16_to_cpu(sblk->compression);
+
+	err = -ENOMEM;
+
+	switch (msblk->compression) {
+#ifdef CONFIG_SQUASHFS_SUPPORT_ZLIB
+	case ZLIB_COMPRESSION:
+		msblk->stream.workspace = kmalloc(zlib_inflate_workspacesize(),
+						  GFP_KERNEL);
+		if (msblk->stream.workspace == NULL) {
+			ERROR("Failed to allocate zlib workspace\n");
+			goto failed_mount;
+		}
+		break;
+#endif
+
+	case LZMA_COMPRESSION:
+		break;
+
+	default:
+		break;
+	}
 
 	err = -EINVAL;
 
@@ -183,6 +219,8 @@
 	flags = le16_to_cpu(sblk->flags);
 
 	TRACE("Found valid superblock on %s\n", bdevname(sb->s_bdev, b));
+	TRACE("Compression: %s\n",
+	      (msblk->compression == LZMA_COMPRESSION) ? "LZMA" : "ZLIB");
 	TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(flags)
 				? "un" : "");
 	TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(flags)
@@ -295,14 +333,15 @@
 	kfree(msblk->inode_lookup_table);
 	kfree(msblk->fragment_index);
 	kfree(msblk->id_table);
+#ifdef CONFIG_SQUASHFS_SUPPORT_ZLIB
 	kfree(msblk->stream.workspace);
+#endif
 	kfree(sb->s_fs_info);
 	sb->s_fs_info = NULL;
 	kfree(sblk);
 	return err;
 
 failure:
-	kfree(msblk->stream.workspace);
 	kfree(sb->s_fs_info);
 	sb->s_fs_info = NULL;
 	return -ENOMEM;
@@ -349,7 +388,13 @@
 		kfree(sbi->id_table);
 		kfree(sbi->fragment_index);
 		kfree(sbi->meta_index);
+#ifdef CONFIG_SQUASHFS_SUPPORT_ZLIB
 		kfree(sbi->stream.workspace);
+#endif
+#ifdef CONFIG_SQUASHFS_SUPPORT_LZMA
+		vfree(sbi->lzma_dict_buffer);
+		vfree(sbi->lzma_prob_buffer);
+#endif
 		kfree(sb->s_fs_info);
 		sb->s_fs_info = NULL;
 	}
diff -ruw linux-2.6.31.7/fs/xfs/linux-2.6/xfs_buf.c linux-2.6.31.7-fbx/fs/xfs/linux-2.6/xfs_buf.c
--- linux-2.6.31.7/fs/xfs/linux-2.6/xfs_buf.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/xfs/linux-2.6/xfs_buf.c	2010-03-18 18:28:52.332914134 +0100
@@ -449,6 +449,40 @@
 	return error;
 }
 
+#ifdef CONFIG_MIPS
+static void cache_flush_buf_page(xfs_buf_t *bp, int page_id)
+{
+	struct page *page;
+	void *vmaddr, *addr;
+
+	if (!(bp->b_flags & XBF_MAPPED))
+		return;
+
+	if (bp->b_page_count <= 1)
+		return;
+
+	page = bp->b_pages[page_id];
+	vmaddr = bp->b_addr - bp->b_offset + (page_id * PAGE_CACHE_SIZE);
+	addr = page_address(page);
+
+	if (pages_do_alias((unsigned long)addr, (unsigned long)vmaddr)) {
+		local_flush_data_cache_page(vmaddr);
+		local_flush_data_cache_page(addr);
+	}
+}
+
+static void cache_flush_buf(xfs_buf_t *bp)
+{
+	unsigned int i;
+
+	for (i = 0; i < bp->b_page_count; i++)
+		cache_flush_buf_page(bp, i);
+}
+#else
+static inline void cache_flush_buf_page(xfs_buf_t *bp, int page_id) { }
+static inline void cache_flush_buf(xfs_buf_t *bp) { }
+#endif
+
 /*
  *	Map buffer into kernel address-space if nessecary.
  */
@@ -470,6 +504,7 @@
 			return -ENOMEM;
 		bp->b_addr += bp->b_offset;
 		bp->b_flags |= XBF_MAPPED;
+		cache_flush_buf(bp);
 	}
 
 	return 0;
@@ -1202,6 +1237,7 @@
 		bio->bi_end_io = xfs_buf_bio_end_io;
 		bio->bi_private = bp;
 
+		cache_flush_buf_page(bp, 0);
 		bio_add_page(bio, bp->b_pages[0], PAGE_CACHE_SIZE, 0);
 		size = 0;
 
@@ -1228,6 +1264,7 @@
 		if (nbytes > size)
 			nbytes = size;
 
+		cache_flush_buf_page(bp, map_i);
 		rbytes = bio_add_page(bio, bp->b_pages[map_i], nbytes, offset);
 		if (rbytes < nbytes)
 			break;
diff -ruw linux-2.6.31.7/fs/xfs/xfs_dir2_block.c linux-2.6.31.7-fbx/fs/xfs/xfs_dir2_block.c
--- linux-2.6.31.7/fs/xfs/xfs_dir2_block.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/xfs/xfs_dir2_block.c	2010-03-18 18:28:52.352918293 +0100
@@ -485,6 +485,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.
@@ -509,11 +512,18 @@
 		cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
 					    (char *)dep - (char *)block);
 
+		if (xfs_iget(mp, NULL, be64_to_cpu(dep->inumber), 0, 0,
+			     &inode, 0) == 0) {
+			type = (inode->i_d.di_mode >> 12) & 0xf;
+			xfs_iput(inode, 0);
+		} else
+			type = DT_UNKNOWN;
+
 		/*
 		 * If it didn't fit, set the final offset to here & return.
 		 */
 		if (filldir(dirent, dep->name, dep->namelen, cook & 0x7fffffff,
-			    be64_to_cpu(dep->inumber), DT_UNKNOWN)) {
+			    be64_to_cpu(dep->inumber), type)) {
 			*offset = cook & 0x7fffffff;
 			xfs_da_brelse(NULL, bp);
 			return 0;
diff -ruw linux-2.6.31.7/fs/xfs/xfs_dir2_leaf.c linux-2.6.31.7-fbx/fs/xfs/xfs_dir2_leaf.c
--- linux-2.6.31.7/fs/xfs/xfs_dir2_leaf.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/xfs/xfs_dir2_leaf.c	2010-10-25 13:43:58.171446892 +0200
@@ -816,6 +816,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.
@@ -1078,9 +1081,16 @@
 		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) == 0) {
+			type = (inode->i_d.di_mode >> 12) & 0xf;
+			xfs_iput(inode, 0);
+		} else
+			type = DT_UNKNOWN;
+
 		if (filldir(dirent, dep->name, dep->namelen,
 			    xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff,
-			    be64_to_cpu(dep->inumber), DT_UNKNOWN))
+			    be64_to_cpu(dep->inumber), type))
 			break;
 
 		/*
diff -ruw linux-2.6.31.7/fs/xfs/xfs_dir2_sf.c linux-2.6.31.7-fbx/fs/xfs/xfs_dir2_sf.c
--- linux-2.6.31.7/fs/xfs/xfs_dir2_sf.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/fs/xfs/xfs_dir2_sf.c	2010-03-18 18:28:52.352918293 +0100
@@ -770,6 +770,9 @@
 	 */
 	sfep = xfs_dir2_sf_firstentry(sfp);
 	for (i = 0; i < sfp->hdr.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));
 
@@ -779,8 +782,15 @@
 		}
 
 		ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep));
+
+		if (xfs_iget(mp, NULL, ino, 0, 0, &inode, 0) == 0) {
+			type = (inode->i_d.di_mode >> 12) & 0xf;
+			xfs_iput(inode, 0);
+		} else
+			type = DT_UNKNOWN;
+
 		if (filldir(dirent, sfep->name, sfep->namelen,
-			    off & 0x7fffffff, ino, DT_UNKNOWN)) {
+			    off & 0x7fffffff, ino, type)) {
 			*offset = off & 0x7fffffff;
 			return 0;
 		}
diff -ruw linux-2.6.31.7/include/linux/bio.h linux-2.6.31.7-fbx/include/linux/bio.h
--- linux-2.6.31.7/include/linux/bio.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/bio.h	2010-10-25 13:43:58.191443310 +0200
@@ -142,37 +142,40 @@
  *
  * bit 0 -- data direction
  *	If not set, bio is a read from device. If set, it's a write to device.
- * bit 1 -- rw-ahead when set
- * bit 2 -- barrier
+ * bit 1 -- fail fast device errors
+ * bit 2 -- fail fast transport errors
+ * bit 3 -- fail fast driver errors
+ * bit 4 -- rw-ahead when set
+ * bit 5 -- barrier
  *	Insert a serialization point in the IO queue, forcing previously
  *	submitted IO to be completed before this one is issued.
- * bit 3 -- synchronous I/O hint.
- * bit 4 -- Unplug the device immediately after submitting this bio.
- * bit 5 -- metadata request
+ * bit 6 -- synchronous I/O hint.
+ * bit 7 -- Unplug the device immediately after submitting this bio.
+ * bit 8 -- metadata request
  *	Used for tracing to differentiate metadata and data IO. May also
  *	get some preferential treatment in the IO scheduler
- * bit 6 -- discard sectors
+ * bit 9 -- discard sectors
  *	Informs the lower level device that this range of sectors is no longer
  *	used by the file system and may thus be freed by the device. Used
  *	for flash based storage.
- * bit 7 -- fail fast device errors
- * bit 8 -- fail fast transport errors
- * bit 9 -- fail fast driver errors
  *	Don't want driver retries for any fast fail whatever the reason.
  * bit 10 -- Tell the IO scheduler not to wait for more requests after this
 	one has been submitted, even if it is a SYNC request.
  */
-#define BIO_RW		0	/* Must match RW in req flags (blkdev.h) */
-#define BIO_RW_AHEAD	1	/* Must match FAILFAST in req flags */
-#define BIO_RW_BARRIER	2
-#define BIO_RW_SYNCIO	3
-#define BIO_RW_UNPLUG	4
-#define BIO_RW_META	5
-#define BIO_RW_DISCARD	6
-#define BIO_RW_FAILFAST_DEV		7
-#define BIO_RW_FAILFAST_TRANSPORT	8
-#define BIO_RW_FAILFAST_DRIVER		9
-#define BIO_RW_NOIDLE	10
+enum bio_rw_flags {
+	BIO_RW,
+	BIO_RW_FAILFAST_DEV,
+	BIO_RW_FAILFAST_TRANSPORT,
+	BIO_RW_FAILFAST_DRIVER,
+	/* above flags must match REQ_* */
+	BIO_RW_AHEAD,
+	BIO_RW_BARRIER,
+	BIO_RW_SYNCIO,
+	BIO_RW_UNPLUG,
+	BIO_RW_META,
+	BIO_RW_DISCARD,
+	BIO_RW_NOIDLE,
+};
 
 #define bio_rw_flagged(bio, flag)	((bio)->bi_rw & (1 << (flag)))
 
diff -ruw linux-2.6.31.7/include/linux/blkdev.h linux-2.6.31.7-fbx/include/linux/blkdev.h
--- linux-2.6.31.7/include/linux/blkdev.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/blkdev.h	2010-10-25 13:43:58.191443310 +0200
@@ -93,6 +93,7 @@
 	__REQ_FAILFAST_DEV,	/* no driver retries of device errors */
 	__REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */
 	__REQ_FAILFAST_DRIVER,	/* no driver retries of driver errors */
+	/* above flags must match BIO_RW_* */
 	__REQ_DISCARD,		/* request to discard sectors */
 	__REQ_SORTED,		/* elevator knows about this request */
 	__REQ_SOFTBARRIER,	/* may not be passed by ioscheduler */
@@ -143,6 +144,9 @@
 #define REQ_NOIDLE	(1 << __REQ_NOIDLE)
 #define REQ_IO_STAT	(1 << __REQ_IO_STAT)
 
+#define REQ_FAILFAST_MASK	(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | \
+				 REQ_FAILFAST_DRIVER)
+
 #define BLK_MAX_CDB	16
 
 /*
diff -ruw linux-2.6.31.7/include/linux/dvb/dmx.h linux-2.6.31.7-fbx/include/linux/dvb/dmx.h
--- linux-2.6.31.7/include/linux/dvb/dmx.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/dvb/dmx.h	2010-03-18 18:28:52.392910033 +0100
@@ -151,5 +151,7 @@
 #define DMX_GET_CAPS             _IOR('o', 48, dmx_caps_t)
 #define DMX_SET_SOURCE           _IOW('o', 49, dmx_source_t)
 #define DMX_GET_STC              _IOWR('o', 50, struct dmx_stc)
+#define DMX_ADD_PID              _IOW('o', 51, __u16)
+#define DMX_REMOVE_PID           _IOW('o', 52, __u16)
 
 #endif /*_DVBDMX_H_*/
diff -ruw linux-2.6.31.7/include/linux/ide.h linux-2.6.31.7-fbx/include/linux/ide.h
--- linux-2.6.31.7/include/linux/ide.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/ide.h	2010-10-25 13:43:58.211442780 +0200
@@ -164,7 +164,7 @@
 		ide_cmd640,	ide_dtc2278,	ide_ali14xx,
 		ide_qd65xx,	ide_umc8672,	ide_ht6560b,
 		ide_4drives,	ide_pmac,	ide_acorn,
-		ide_au1xxx,	ide_palm3710
+		ide_au1xxx,	ide_palm3710,	ide_tango2,
 };
 
 typedef u8 hwif_chipset_t;
diff -ruw linux-2.6.31.7/include/linux/if_tunnel.h linux-2.6.31.7-fbx/include/linux/if_tunnel.h
--- linux-2.6.31.7/include/linux/if_tunnel.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/if_tunnel.h	2010-10-25 13:43:58.211442780 +0200
@@ -33,6 +33,11 @@
 	__be16			o_flags;
 	__be32			i_key;
 	__be32			o_key;
+
+	/* this is the first bits to match on ipv6 address */
+	struct in6_addr		fbx6to4_zone;
+	__u8			fbx6to4_prefix;
+
 	struct iphdr		iph;
 };
 
diff -ruw linux-2.6.31.7/include/linux/Kbuild linux-2.6.31.7-fbx/include/linux/Kbuild
--- linux-2.6.31.7/include/linux/Kbuild	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/Kbuild	2010-10-25 13:43:58.191443310 +0200
@@ -65,6 +65,8 @@
 header-y += elf-em.h
 header-y += fadvise.h
 header-y += falloc.h
+header-y += fbxatm.h
+header-y += fbxmtd_map_ioctl.h
 header-y += fd.h
 header-y += fdreg.h
 header-y += fib_rules.h
diff -ruw linux-2.6.31.7/include/linux/kernel.h linux-2.6.31.7-fbx/include/linux/kernel.h
--- linux-2.6.31.7/include/linux/kernel.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/kernel.h	2010-10-25 13:43:58.211442780 +0200
@@ -245,6 +245,8 @@
 extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
 				   unsigned int interval_msec);
 
+extern void console_emergency_dump(char *buf, int *len);
+
 /*
  * Print a one-time message (analogous to WARN_ONCE() et al):
  */
@@ -276,6 +278,9 @@
 static inline void log_buf_kexec_setup(void)
 {
 }
+
+static inline void console_emergency_dump(char *buf, int *len) { }
+
 #endif
 
 extern int printk_needs_cpu(int cpu);
diff -ruw linux-2.6.31.7/include/linux/netdevice.h linux-2.6.31.7-fbx/include/linux/netdevice.h
--- linux-2.6.31.7/include/linux/netdevice.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/netdevice.h	2010-10-25 13:43:58.221441236 +0200
@@ -886,6 +886,11 @@
 	/* GARP */
 	struct garp_port	*garp_port;
 
+#if defined(CONFIG_FREEBOX_BRIDGE) || defined(CONFIG_FREEBOX_BRIDGE_MODULE)
+	struct fbxbridge	*fbx_bridge;
+	struct fbxbridge	*fbx_bridge_port;
+#endif
+
 	/* class/net/name entry */
 	struct device		dev;
 	/* space for optional statistics and wireless sysfs groups */
diff -ruw linux-2.6.31.7/include/linux/netfilter/nf_conntrack_ftp.h linux-2.6.31.7-fbx/include/linux/netfilter/nf_conntrack_ftp.h
--- linux-2.6.31.7/include/linux/netfilter/nf_conntrack_ftp.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/netfilter/nf_conntrack_ftp.h	2010-03-18 18:28:52.442910030 +0100
@@ -26,6 +26,11 @@
 	u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
 	/* 0 means seq_match_aft_nl not set */
 	int seq_aft_nl_num[IP_CT_DIR_MAX];
+#if defined(CONFIG_FREEBOX_BRIDGE) || defined(CONFIG_FREEBOX_BRIDGE_MODULE)
+	unsigned int is_fbxbridge;
+	unsigned long fbxbridge_remote;
+	unsigned long fbxbridge_wan;
+#endif
 };
 
 struct nf_conntrack_expect;
diff -ruw linux-2.6.31.7/include/linux/pci_ids.h linux-2.6.31.7-fbx/include/linux/pci_ids.h
--- linux-2.6.31.7/include/linux/pci_ids.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/pci_ids.h	2010-10-25 13:43:58.231437793 +0200
@@ -2493,6 +2493,7 @@
 #define PCI_DEVICE_ID_INTEL_ICH9_6	0x2930
 #define PCI_DEVICE_ID_INTEL_ICH9_7	0x2916
 #define PCI_DEVICE_ID_INTEL_ICH9_8	0x2918
+#define PCI_DEVICE_ID_INTEL_SODAVILLE	0x2e52
 #define PCI_DEVICE_ID_INTEL_82855PM_HB	0x3340
 #define PCI_DEVICE_ID_INTEL_IOAT_TBG4	0x3429
 #define PCI_DEVICE_ID_INTEL_IOAT_TBG5	0x342a
diff -ruw linux-2.6.31.7/include/linux/serial_core.h linux-2.6.31.7-fbx/include/linux/serial_core.h
--- linux-2.6.31.7/include/linux/serial_core.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/serial_core.h	2010-10-25 13:43:58.241445423 +0200
@@ -42,7 +42,8 @@
 #define PORT_RM9000	16	/* PMC-Sierra RM9xxx internal UART */
 #define PORT_OCTEON	17	/* Cavium OCTEON internal UART */
 #define PORT_AR7	18	/* Texas Instruments AR7 internal UART */
-#define PORT_MAX_8250	18	/* max port ID */
+#define PORT_INTELCE	19	/* Intel CE3100/4100 SoC internal UART */
+#define PORT_MAX_8250	19	/* max port ID */
 
 /*
  * ARM specific type numbers.  These are not currently guaranteed
@@ -174,6 +175,9 @@
 /* Qualcomm MSM SoCs */
 #define PORT_MSM	88
 
+/* Broadcom 63xx */
+#define PORT_BCM63XX	89
+
 #ifdef __KERNEL__
 
 #include <linux/compiler.h>
diff -ruw linux-2.6.31.7/include/linux/serial_reg.h linux-2.6.31.7-fbx/include/linux/serial_reg.h
--- linux-2.6.31.7/include/linux/serial_reg.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/serial_reg.h	2010-03-18 18:28:52.462918501 +0100
@@ -18,9 +18,18 @@
  * DLAB=0
  */
 #define UART_RX		0	/* In:  Receive buffer */
+#ifdef CONFIG_TANGO2
+#define UART_TX		1	/* Out: Transmit buffer */
+#else
 #define UART_TX		0	/* Out: Transmit buffer */
+#endif
 
+#ifdef CONFIG_TANGO2
+#define UART_IER	2	/* Out: Interrupt Enable Register */
+#else
 #define UART_IER	1	/* Out: Interrupt Enable Register */
+#endif
+
 #define UART_IER_MSI		0x08 /* Enable Modem status interrupt */
 #define UART_IER_RLSI		0x04 /* Enable receiver line status interrupt */
 #define UART_IER_THRI		0x02 /* Enable Transmitter holding register int. */
@@ -30,7 +39,12 @@
  */
 #define UART_IERX_SLEEP		0x10 /* Enable sleep mode */
 
+#ifdef CONFIG_TANGO2
+#define UART_IIR	3	/* In:  Interrupt ID Register */
+#else
 #define UART_IIR	2	/* In:  Interrupt ID Register */
+#endif
+
 #define UART_IIR_NO_INT		0x01 /* No interrupts pending */
 #define UART_IIR_ID		0x06 /* Mask for the interrupt ID */
 #define UART_IIR_MSI		0x00 /* Modem status interrupt */
@@ -40,7 +54,12 @@
 
 #define UART_IIR_BUSY		0x07 /* DesignWare APB Busy Detect */
 
+#ifdef CONFIG_TANGO2
+#define UART_FCR	4	/* Out: FIFO Control Register */
+#else
 #define UART_FCR	2	/* Out: FIFO Control Register */
+#endif
+
 #define UART_FCR_ENABLE_FIFO	0x01 /* Enable the FIFO */
 #define UART_FCR_CLEAR_RCVR	0x02 /* Clear the RCVR FIFO */
 #define UART_FCR_CLEAR_XMIT	0x04 /* Clear the XMIT FIFO */
@@ -83,7 +102,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.
@@ -99,7 +123,11 @@
 #define UART_LCR_WLEN7		0x02 /* Wordlength: 7 bits */
 #define UART_LCR_WLEN8		0x03 /* Wordlength: 8 bits */
 
+#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) */
@@ -110,7 +138,12 @@
 #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_TEMT		0x40 /* Transmitter empty */
 #define UART_LSR_THRE		0x20 /* Transmit-hold-register empty */
 #define UART_LSR_BI		0x10 /* Break interrupt indicator */
@@ -120,7 +153,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 */
@@ -131,18 +168,36 @@
 #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_EFR_CTS		0x80 /* CTS flow control */
 #define UART_EFR_RTS		0x40 /* RTS flow control */
 #define UART_EFR_SCD		0x20 /* Special character detect */
diff -ruw linux-2.6.31.7/include/linux/skbuff.h linux-2.6.31.7-fbx/include/linux/skbuff.h
--- linux-2.6.31.7/include/linux/skbuff.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/skbuff.h	2011-05-23 16:08:41.783678775 +0200
@@ -255,6 +255,13 @@
 typedef unsigned char *sk_buff_data_t;
 #endif
 
+enum {
+	FFN_STATE_INIT = 0,
+	FFN_STATE_FORWARDABLE,
+	FFN_STATE_FAST_FORWARDED,
+	FFN_STATE_INCOMPATIBLE,
+};
+
 /** 
  *	struct sk_buff - socket buffer
  *	@next: Next buffer in list
@@ -362,6 +369,9 @@
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 	struct nf_conntrack	*nfct;
 	struct sk_buff		*nfct_reasm;
+#ifdef CONFIG_IP_FFN
+	int			ffn_state;
+#endif
 #endif
 #ifdef CONFIG_BRIDGE_NETFILTER
 	struct nf_bridge_info	*nf_bridge;
@@ -394,6 +404,7 @@
 	__u32			secmark;
 #endif
 
+	__u32			rx_class;
 	__u32			mark;
 
 	__u16			vlan_tci;
@@ -401,6 +412,15 @@
 	sk_buff_data_t		transport_header;
 	sk_buff_data_t		network_header;
 	sk_buff_data_t		mac_header;
+
+#ifdef CONFIG_SKB_RECYCLE
+	/* callback just before skb header memory is about to be
+	 * released, memory is not freed if callback returns 1 */
+	int			(*recycle)(void *recycle_data,
+					   struct sk_buff *skb);
+	void			*recycle_data;
+#endif
+
 	/* These elements must be at the end, see alloc_skb() for details.  */
 	sk_buff_data_t		tail;
 	sk_buff_data_t		end;
@@ -1370,6 +1390,10 @@
  * Various parts of the networking layer expect at least 32 bytes of
  * headroom, you should not reduce this.
  */
+#ifdef CONFIG_NETSKBPAD
+#define NET_SKB_PAD	CONFIG_NETSKBPAD
+#endif
+
 #ifndef NET_SKB_PAD
 #define NET_SKB_PAD	32
 #endif
@@ -2057,6 +2081,11 @@
 }
 #endif
 
+#ifdef CONFIG_SKB_RECYCLE
+extern void kfree_recycled_skbmem(struct sk_buff *skb);
+void skb_clean_state(struct sk_buff *skb);
+#endif
+
 static inline int skb_is_gso(const struct sk_buff *skb)
 {
 	return skb_shinfo(skb)->gso_size;
diff -ruw linux-2.6.31.7/include/linux/sockios.h linux-2.6.31.7-fbx/include/linux/sockios.h
--- linux-2.6.31.7/include/linux/sockios.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/linux/sockios.h	2010-03-18 18:28:52.472910092 +0100
@@ -125,6 +125,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-2.6.31.7/include/net/ip.h linux-2.6.31.7-fbx/include/net/ip.h
--- linux-2.6.31.7/include/net/ip.h	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/include/net/ip.h	2010-10-25 13:43:58.261441193 +0200
@@ -352,6 +352,14 @@
 int ip_frag_nqueues(struct net *net);
 
 /*
+ *     Functions provided by ip_ffn.c
+ */
+extern void ip_ffn_init(void);
+extern int ip_ffn_process(struct sk_buff *skb);
+extern void ip_ffn_add(struct sk_buff *skb);
+extern void ip_ffn_flush_all(void);
+
+/*
  *	Functions provided by ip_forward.c
  */
  
diff -ruw linux-2.6.31.7/init/do_mounts.c linux-2.6.31.7-fbx/init/do_mounts.c
--- linux-2.6.31.7/init/do_mounts.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/init/do_mounts.c	2011-05-23 16:08:41.783678775 +0200
@@ -16,6 +16,10 @@
 #include <linux/async.h>
 #include <linux/fs_struct.h>
 
+#ifdef CONFIG_DMCRYPTATBOOT
+#include <linux/dm-ioctl.h>
+#endif
+
 #include <linux/nfs_fs.h>
 #include <linux/nfs_fs_sb.h>
 #include <linux/nfs_mount.h>
@@ -359,6 +363,121 @@
 #endif
 }
 
+#ifdef CONFIG_DMCRYPTATBOOT
+/*
+ * Create dm device
+ */
+long dm_ctl_ioctl(struct file *file, uint command, ulong u);
+
+static int dm_run_setup(void)
+{
+	struct dm_ioctl dm, *dmp;
+	struct dm_target_spec *spec;
+	uint64_t size;
+	char *data, *tmp, *major, *minor;
+	uint8_t *target_info;
+	dev_t tomap;
+	int ret, fd;
+	uint8_t key[128];
+
+	/* read config */
+	ret = -EINVAL;
+	tmp = CONFIG_DMCRYPTATBOOT_DEVICE;
+	major = minor = NULL;
+	if (tmp)
+		major = strsep(&tmp, ":");
+	if (tmp)
+		minor = strsep(&tmp, ":");
+	if (!major || !minor)
+		goto end;
+
+	/* create device to map */
+	tomap = MKDEV(simple_strtoul(major, NULL, 10),
+		      simple_strtoul(minor, NULL, 10));
+	if (create_dev("/dev/tomap", tomap))
+		goto end;
+
+	fd = sys_open("/dev/tomap", 0, 0);
+	if (fd < 0)
+		goto end;
+
+	/* fetch its size */
+	if (sys_ioctl(fd, BLKGETSIZE64, (unsigned long)&size)) {
+		sys_close(fd);
+		goto end;
+	}
+	sys_close(fd);
+	size /= 512;
+
+	/* create dm device */
+	memset(&dm, 0, sizeof (dm));
+	dm.version[0] = DM_VERSION_MAJOR;
+	dm.version[1] = DM_VERSION_MINOR;
+	dm.version[2] = DM_VERSION_PATCHLEVEL;
+	dm.data_size = sizeof (dm);
+	strcpy(dm.name, "root");
+
+	ret = dm_ctl_ioctl(NULL, DM_DEV_CREATE, (ulong)&dm);
+	if (ret < 0) {
+		printk("dm_ctl_ioctl create failed\n");
+		goto end;
+	}
+
+	/* create table */
+	data = kmalloc(sizeof (*dmp) + sizeof (*spec) + 128, GFP_KERNEL);
+	if (!data)
+		goto end;
+	dmp = (struct dm_ioctl *)data;
+	spec = (struct dm_target_spec *)(dmp + 1);
+	target_info = (uint8_t *)(spec + 1);
+
+	memset(dmp, 0, sizeof (*dmp));
+	dmp->version[0] = DM_VERSION_MAJOR;
+	dmp->version[1] = DM_VERSION_MINOR;
+	dmp->version[2] = DM_VERSION_PATCHLEVEL;
+	dmp->data_size = sizeof (*dmp) + sizeof (*spec) + 128;
+	dmp->data_start = sizeof (*dmp);
+	dmp->target_count = 1;
+	strcpy(dmp->name, "root");
+
+	memset(spec, 0, sizeof (*spec));
+	spec->sector_start = 0;
+	spec->length = size;
+	strcpy(spec->target_type, "crypt");
+
+	strcpy(key, CONFIG_DMCRYPTATBOOT_KEY);
+
+	memset(target_info, 0, 128);
+	snprintf((char *)target_info, 128, "%s %s 0 /dev/tomap 0",
+		 CONFIG_DMCRYPTATBOOT_CIPHER, key);
+	target_info[127] = 0;
+
+	ret = dm_ctl_ioctl(NULL, DM_TABLE_LOAD, (ulong)data);
+	if (ret < 0) {
+		printk("dm_ctl_ioctl table load failed\n");
+		goto end;
+	}
+
+	/* resume device */
+	memset(&dm, 0, sizeof (dm));
+	dm.version[0] = DM_VERSION_MAJOR;
+	dm.version[1] = DM_VERSION_MINOR;
+	dm.version[2] = DM_VERSION_PATCHLEVEL;
+	dm.data_size = sizeof (dm);
+	strcpy(dm.name, "root");
+
+	ret = dm_ctl_ioctl(NULL, DM_DEV_SUSPEND, (ulong)&dm);
+	if (ret < 0) {
+		printk("dm_ctl_ioctl resume failed\n");
+		goto end;
+	}
+
+	strcpy(saved_root_name, "/dev/dm-0");
+end:
+	return ret;
+}
+#endif
+
 /*
  * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
  */
@@ -383,6 +502,16 @@
 
 	md_run_setup();
 
+#ifdef CONFIG_DMCRYPTATBOOT
+#ifdef CONFIG_DMCRYPTATBOOT_ONLY
+	if (dm_run_setup() != 0)
+		/* disallow other root= value */
+		saved_root_name[0] = 0;
+#else
+	dm_run_setup();
+#endif
+#endif
+
 	if (saved_root_name[0]) {
 		root_device_name = saved_root_name;
 		if (!strncmp(root_device_name, "mtd", 3) ||
diff -ruw linux-2.6.31.7/init/Kconfig linux-2.6.31.7-fbx/init/Kconfig
--- linux-2.6.31.7/init/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/init/Kconfig	2010-10-25 13:43:58.281449475 +0200
@@ -435,6 +435,41 @@
 		     13 =>  8 KB
 		     12 =>  4 KB
 
+
+config DMCRYPTATBOOT
+	bool "Create device-mapper crypt target before root"
+	depends on DM_CRYPT
+	default n
+
+config DMCRYPTATBOOT_DEVICE
+	string "Device major:minor"
+	depends on DMCRYPTATBOOT
+
+config DMCRYPTATBOOT_CIPHER
+	string "Cipher"
+	depends on DMCRYPTATBOOT
+
+config DMCRYPTATBOOT_KEY
+	string "Key"
+	depends on DMCRYPTATBOOT
+
+config DMCRYPTATBOOT_KEY_DECRYPT
+	string "Decryption key"
+	depends on DMCRYPTATBOOT
+
+config DMCRYPTATBOOT_ONLY
+	bool "Refuse to mount something else"
+	depends on DMCRYPTATBOOT
+
+config FBX_DECRYPT_INITRD
+	bool "Decrypt initrd at boot"
+	depends on BLK_DEV_RAM
+	default n
+
+config FBX_DECRYPT_INITRD_KEY
+	string "Decryption key"
+	depends on FBX_DECRYPT_INITRD
+
 #
 # Architectures with an unreliable sched_clock() should select this:
 #
diff -ruw linux-2.6.31.7/init/Makefile linux-2.6.31.7-fbx/init/Makefile
--- linux-2.6.31.7/init/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/init/Makefile	2011-05-23 16:08:41.783678775 +0200
@@ -10,13 +10,16 @@
 endif
 obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
 
+obj-$(CONFIG_FBX_DECRYPT_INITRD)+= fbx_decrypt_initrd.o rc4.o
+
 mounts-y			:= do_mounts.o
 mounts-$(CONFIG_BLK_DEV_RAM)	+= do_mounts_rd.o
 mounts-$(CONFIG_BLK_DEV_INITRD)	+= do_mounts_initrd.o
 mounts-$(CONFIG_BLK_DEV_MD)	+= do_mounts_md.o
 
+
 # files to be removed upon make clean
-clean-files := ../include/linux/compile.h
+clean-files := ../include/linux/compile.h dmcryptatboot_decrypt.c
 
 # dependencies on generated files need to be listed explicitly
 
diff -ruw linux-2.6.31.7/kernel/pid.c linux-2.6.31.7-fbx/kernel/pid.c
--- linux-2.6.31.7/kernel/pid.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/kernel/pid.c	2010-10-25 13:43:58.301445325 +0200
@@ -79,7 +79,7 @@
 	.level = 0,
 	.child_reaper = &init_task,
 };
-EXPORT_SYMBOL_GPL(init_pid_ns);
+EXPORT_SYMBOL(init_pid_ns);
 
 int is_container_init(struct task_struct *tsk)
 {
diff -ruw linux-2.6.31.7/kernel/printk.c linux-2.6.31.7-fbx/kernel/printk.c
--- linux-2.6.31.7/kernel/printk.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/kernel/printk.c	2010-10-25 13:43:58.301445325 +0200
@@ -45,6 +45,10 @@
 
 #define __LOG_BUF_LEN	(1 << CONFIG_LOG_BUF_SHIFT)
 
+#ifdef CONFIG_DEBUG_LL
+extern void printascii(char *);
+#endif
+
 /* printk's without a loglevel use this.. */
 #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
 
@@ -251,6 +255,29 @@
 #endif
 
 /*
+ * dump log buffer content in given buffer
+ */
+void console_emergency_dump(char *buf, int *len)
+{
+	int i, limit;
+
+	if (*len > log_buf_len)
+		*len = log_buf_len;
+	if (*len > logged_chars)
+		*len = logged_chars;
+	limit = log_end;
+
+	for (i = 0; i < *len; i++) {
+		int j;
+
+		j = limit - 1 -i;
+		if (j + log_buf_len < log_end)
+			break;
+		buf[*len - 1 - i] = LOG_BUF(j);
+	}
+}
+
+/*
  * Commands to do_syslog:
  *
  * 	0 -- Close the log.  Currently a NOP.
@@ -686,6 +713,9 @@
 	printed_len += vscnprintf(printk_buf + printed_len,
 				  sizeof(printk_buf) - printed_len, fmt, args);
 
+#ifdef CONFIG_DEBUG_LL
+	printascii(printk_buf);
+#endif
 
 	p = printk_buf;
 
diff -ruw linux-2.6.31.7/lib/Kconfig linux-2.6.31.7-fbx/lib/Kconfig
--- linux-2.6.31.7/lib/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/lib/Kconfig	2010-03-18 18:28:52.582926504 +0100
@@ -118,6 +118,12 @@
 	tristate
 
 #
+# lzma decompressor from lzma sdk
+#
+config DECOMPRESS_LZMASDK
+	tristate
+
+#
 # Generic allocator support is selected if needed
 #
 config GENERIC_ALLOCATOR
@@ -200,4 +206,7 @@
 config GENERIC_ATOMIC64
        bool
 
+config FBXSERIAL
+	bool
+
 endmenu
diff -ruw linux-2.6.31.7/lib/Makefile linux-2.6.31.7-fbx/lib/Makefile
--- linux-2.6.31.7/lib/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/lib/Makefile	2010-03-18 18:28:52.582926504 +0100
@@ -70,6 +70,8 @@
 lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
 lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
 
+lib-$(CONFIG_DECOMPRESS_LZMASDK) += LzmaDec.o
+
 obj-$(CONFIG_TEXTSEARCH) += textsearch.o
 obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
 obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o
@@ -77,6 +79,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-2.6.31.7/net/8021q/vlan.c linux-2.6.31.7-fbx/net/8021q/vlan.c
--- linux-2.6.31.7/net/8021q/vlan.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/8021q/vlan.c	2010-10-25 13:43:58.351442850 +0200
@@ -295,7 +295,7 @@
 /*  Attach a VLAN device to a mac address (ie Ethernet Card).
  *  Returns 0 if the device was created or a negative error code otherwise.
  */
-static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
+int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
 {
 	struct net_device *new_dev;
 	struct net *net = dev_net(real_dev);
diff -ruw linux-2.6.31.7/net/core/dev.c linux-2.6.31.7-fbx/net/core/dev.c
--- linux-2.6.31.7/net/core/dev.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/core/dev.c	2010-10-25 13:43:58.361437288 +0200
@@ -127,6 +127,7 @@
 #include <linux/jhash.h>
 #include <linux/random.h>
 #include <trace/events/napi.h>
+#include <linux/kthread.h>
 
 #include "net-sysfs.h"
 
@@ -171,6 +172,17 @@
 static struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
 static struct list_head ptype_all __read_mostly;	/* Taps */
 
+#ifdef CONFIG_NETRXTHREAD
+
+#define RXTHREAD_MAX_PROCESS    CONFIG_NETRXTHREAD_MAX_PROCESS
+#define RXTHREAD_MAX_PKTS       128
+
+static struct task_struct *krxd;
+static struct sk_buff_head krxd_pkt_queue[CONFIG_NETRXTHREAD_RX_QUEUE];
+static 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.
@@ -1937,6 +1949,23 @@
 DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, };
 
 
+/* 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
@@ -2108,6 +2137,37 @@
 #define handle_bridge(skb, pt_prev, ret, orig_dev)	(skb)
 #endif
 
+#if defined(CONFIG_FREEBOX_BRIDGE) || defined(CONFIG_FREEBOX_BRIDGE_MODULE)
+struct sk_buff *(*fbxbridge_handle_frame_hook)(struct fbxbridge *p, struct sk_buff *skb);
+
+struct fbxbridge;
+
+static inline struct sk_buff *handle_fbxbridge(struct sk_buff *skb,
+					       struct packet_type **pt_prev, int *ret,
+					       struct net_device *orig_dev)
+{
+	struct fbxbridge *fbxbr;
+
+	if (skb->pkt_type == PACKET_LOOPBACK ||
+	    (fbxbr = skb->dev->fbx_bridge_port) == NULL)
+		return skb;
+
+	if (skb->protocol != __constant_htons(ETH_P_IP) &&
+	    skb->protocol != __constant_htons(ETH_P_ARP))
+		return skb;
+
+	if (*pt_prev) {
+		*ret = deliver_skb(skb, *pt_prev, orig_dev);
+		*pt_prev = NULL;
+	}
+
+	return fbxbridge_handle_frame_hook(fbxbr, skb);
+}
+#else
+#define handle_fbxbridge(skb, pt_prev, ret, orig_dev)   (skb)
+#endif
+
+
 #if defined(CONFIG_MACVLAN) || defined(CONFIG_MACVLAN_MODULE)
 struct sk_buff *(*macvlan_handle_frame_hook)(struct sk_buff *skb) __read_mostly;
 EXPORT_SYMBOL_GPL(macvlan_handle_frame_hook);
@@ -2225,22 +2285,7 @@
 	rcu_read_unlock();
 }
 
-/**
- *	netif_receive_skb - process receive buffer from network
- *	@skb: buffer to process
- *
- *	netif_receive_skb() is the main receive data processing function.
- *	It always succeeds. The buffer may be dropped during processing
- *	for congestion control or by the protocol layers.
- *
- *	This function may only be called from softirq context and interrupts
- *	should be enabled.
- *
- *	Return values (usually ignored):
- *	NET_RX_SUCCESS: no congestion
- *	NET_RX_DROP: packet was dropped
- */
-int netif_receive_skb(struct sk_buff *skb)
+static int netif_receive_skb_end(struct sk_buff *skb)
 {
 	struct packet_type *ptype, *pt_prev;
 	struct net_device *orig_dev;
@@ -2270,12 +2315,6 @@
 			skb->dev = orig_dev->master;
 	}
 
-	__get_cpu_var(netdev_rx_stat).total++;
-
-	skb_reset_network_header(skb);
-	skb_reset_transport_header(skb);
-	skb->mac_len = skb->network_header - skb->mac_header;
-
 	pt_prev = NULL;
 
 	rcu_read_lock();
@@ -2296,6 +2335,10 @@
 		}
 	}
 
+	skb = handle_fbxbridge(skb, &pt_prev, &ret, orig_dev);
+	if (!skb)
+		goto out;
+
 #ifdef CONFIG_NET_CLS_ACT
 	skb = handle_ing(skb, &pt_prev, &ret, orig_dev);
 	if (!skb)
@@ -2337,6 +2380,123 @@
 	return ret;
 }
 
+#ifdef CONFIG_NETRXTHREAD
+static int krxd_action(void *unused)
+{
+	struct sk_buff *skb;
+	unsigned int maxpkt_in_loop;
+
+	set_user_nice(current, -5);
+	current->flags |= PF_NOFREEZE;
+	__set_current_state(TASK_RUNNING);
+
+	maxpkt_in_loop = RXTHREAD_MAX_PROCESS;
+	while (1) {
+		unsigned int i, queue, count;
+
+		local_bh_disable();
+		count = CONFIG_NETRXTHREAD_RX_QUEUE;
+		for (i = 0; i < count; i++) {
+			queue = count - i - 1;
+			skb = skb_dequeue(&krxd_pkt_queue[queue]);
+			if (!skb)
+				continue;
+			krxd_pkts_count--;
+			break;
+		}
+
+		if (!skb) {
+			local_bh_enable();
+			wait_event_interruptible(krxd_wq,
+						 krxd_pkts_count != 0);
+			set_current_state(TASK_RUNNING);
+			maxpkt_in_loop = RXTHREAD_MAX_PROCESS;
+			continue;
+		}
+
+		netif_receive_skb_end(skb);
+		local_bh_enable();
+
+		/* only schedule when working on lowest prio queue */
+		if (queue == 0) {
+			if (--maxpkt_in_loop == 0) {
+				maxpkt_in_loop = RXTHREAD_MAX_PROCESS;
+				schedule();
+			}
+		}
+	}
+	return 0;
+}
+#endif
+
+/**
+ *	netif_receive_skb - process receive buffer from network
+ *	@skb: buffer to process
+ *
+ *	netif_receive_skb() is the main receive data processing function.
+ *	It always succeeds. The buffer may be dropped during processing
+ *	for congestion control or by the protocol layers.
+ *
+ *	This function may only be called from softirq context and interrupts
+ *	should be enabled.
+ *
+ *	Return values (usually ignored):
+ *	NET_RX_SUCCESS: no congestion
+ *	NET_RX_DROP: packet was dropped
+ */
+int netif_receive_skb(struct sk_buff *skb)
+{
+#ifdef CONFIG_NETRXTHREAD
+	unsigned int len, queue;
+#endif
+
+	if (skb->vlan_tci && vlan_hwaccel_do_receive(skb))
+		return NET_RX_SUCCESS;
+
+	/* if we've gotten here through NAPI, check netpoll */
+	if (netpoll_receive_skb(skb))
+		return NET_RX_DROP;
+
+	if (!skb->tstamp.tv64)
+		net_timestamp(skb);
+
+	if (!skb->iif)
+		skb->iif = skb->dev->ifindex;
+
+	__get_cpu_var(netdev_rx_stat).total++;
+
+	skb_reset_network_header(skb);
+	skb_reset_transport_header(skb);
+	skb->mac_len = skb->network_header - skb->mac_header;
+
+#if defined(CONFIG_FREEBOX_DIVERTER) || defined(CONFIG_FREEBOX_DIVERTER_MODULE)
+	if (handle_fbxdiverter(skb))
+		return NET_RX_SUCCESS;
+#endif
+
+#ifndef CONFIG_NETRXTHREAD
+	return netif_receive_skb_end(skb);
+#else
+	queue = skb->rx_class;
+	if (queue >= CONFIG_NETRXTHREAD_RX_QUEUE)
+		queue = CONFIG_NETRXTHREAD_RX_QUEUE - 1;
+
+	/* queue the packet to the rx thread */
+	local_bh_disable();
+	len = skb_queue_len(&krxd_pkt_queue[queue]);
+	if (len < RXTHREAD_MAX_PKTS) {
+		__skb_queue_tail(&krxd_pkt_queue[queue], skb);
+		krxd_pkts_count++;
+		if (!len)
+			wake_up(&krxd_wq);
+	} else {
+		dev_kfree_skb(skb);
+	}
+	local_bh_enable();
+	return NET_RX_SUCCESS;
+#endif
+}
+
 /* Network device is going away, flush any packets still pending  */
 static void flush_backlog(void *arg)
 {
@@ -5615,6 +5775,19 @@
 	open_softirq(NET_TX_SOFTIRQ, net_tx_action);
 	open_softirq(NET_RX_SOFTIRQ, net_rx_action);
 
+#ifdef CONFIG_NETRXTHREAD
+	for (i = 0; i < CONFIG_NETRXTHREAD_RX_QUEUE; i++)
+		skb_queue_head_init(&krxd_pkt_queue[i]);
+	krxd_pkts_count = 0;
+	init_waitqueue_head(&krxd_wq);
+	krxd = kthread_create(krxd_action, NULL, "krxthread");
+	if (IS_ERR(krxd)) {
+		printk(KERN_ERR "unable to create krxd\n");
+		return -ENOMEM;
+	}
+	wake_up_process(krxd);
+#endif
+
 	hotcpu_notifier(dev_cpu_callback, 0);
 	dst_init();
 	dev_mcast_init();
@@ -5668,6 +5841,11 @@
 EXPORT_SYMBOL(net_disable_timestamp);
 EXPORT_SYMBOL(dev_get_flags);
 
+
+#if defined(CONFIG_FREEBOX_BRIDGE_MODULE)
+EXPORT_SYMBOL(fbxbridge_handle_frame_hook);
+#endif
+
 EXPORT_SYMBOL(dev_load);
 
 EXPORT_PER_CPU_SYMBOL(softnet_data);
diff -ruw linux-2.6.31.7/net/core/skbuff.c linux-2.6.31.7-fbx/net/core/skbuff.c
--- linux-2.6.31.7/net/core/skbuff.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/core/skbuff.c	2010-10-25 13:43:58.371445476 +0200
@@ -336,7 +336,19 @@
 		skb_get(list);
 }
 
+#ifdef CONFIG_SKB_RECYCLE
+void kfree_recycled_skbmem(struct sk_buff *skb)
+{
+	kfree(skb->head);
+	kmem_cache_free(skbuff_head_cache, skb);
+}
+
+EXPORT_SYMBOL(kfree_recycled_skbmem);
+
+static int skb_release_data(struct sk_buff *skb, int may_recycle)
+#else
 static void skb_release_data(struct sk_buff *skb)
+#endif
 {
 	if (!skb->cloned ||
 	    !atomic_sub_return(skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1,
@@ -350,8 +362,16 @@
 		if (skb_has_frags(skb))
 			skb_drop_fraglist(skb);
 
+#ifdef CONFIG_SKB_RECYCLE
+		if (may_recycle && skb->recycle(skb->recycle_data, skb))
+				return 1;
+#endif
 		kfree(skb->head);
 	}
+
+#ifdef CONFIG_SKB_RECYCLE
+	return 0;
+#endif
 }
 
 /*
@@ -415,10 +435,25 @@
 }
 
 /* Free everything but the sk_buff shell. */
+#ifdef CONFIG_SKB_RECYCLE
+static int skb_release_all(struct sk_buff *skb, int may_recycle)
+#else
 static void skb_release_all(struct sk_buff *skb)
+#endif
 {
 	skb_release_head_state(skb);
+#ifdef CONFIG_SKB_RECYCLE
+	if (skb->fclone == SKB_FCLONE_UNAVAILABLE &&
+	    skb->recycle &&
+	    may_recycle) {
+		if (skb_release_data(skb, 1))
+			return 1;
+	} else
+		skb_release_data(skb, 0);
+	return 0;
+#else
 	skb_release_data(skb);
+#endif
 }
 
 /**
@@ -432,8 +467,13 @@
 
 void __kfree_skb(struct sk_buff *skb)
 {
+#ifdef CONFIG_SKB_RECYCLE
+	if (!skb_release_all(skb, 1))
+		kfree_skbmem(skb);
+#else
 	skb_release_all(skb);
 	kfree_skbmem(skb);
+#endif
 }
 EXPORT_SYMBOL(__kfree_skb);
 
@@ -477,6 +517,29 @@
 }
 EXPORT_SYMBOL(consume_skb);
 
+#ifdef CONFIG_SKB_RECYCLE
+void skb_clean_state(struct sk_buff *skb)
+{
+	struct skb_shared_info *shinfo;
+
+	shinfo = skb_shinfo(skb);
+	atomic_set(&shinfo->dataref, 1);
+	shinfo->nr_frags = 0;
+	shinfo->gso_size = 0;
+	shinfo->gso_segs = 0;
+	shinfo->gso_type = 0;
+	shinfo->ip6_frag_id = 0;
+	shinfo->tx_flags.flags = 0;
+	shinfo->frag_list = NULL;
+	memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps));
+
+	memset(skb, 0, offsetof(struct sk_buff, recycle));
+	skb->data = skb->head;
+	skb_reset_tail_pointer(skb);
+	skb->truesize = skb->end - skb->head + sizeof(struct sk_buff);
+}
+#endif
+
 /**
  *	skb_recycle_check - check if skb can be reused for receive
  *	@skb: buffer
@@ -544,7 +607,11 @@
 #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
 	new->ipvs_property	= old->ipvs_property;
 #endif
+#ifdef CONFIG_IP_FFN
+	new->ffn_state		= FFN_STATE_INIT;
+#endif
 	new->protocol		= old->protocol;
+	new->rx_class		= old->rx_class;
 	new->mark		= old->mark;
 	new->iif		= old->iif;
 	__nf_copy(new, old);
@@ -563,6 +630,9 @@
 	new->do_not_encrypt	= old->do_not_encrypt;
 #endif
 
+#ifdef CONFIG_SKB_RECYCLE
+	new->recycle		= NULL;
+#endif
 	skb_copy_secmark(new, old);
 }
 
@@ -590,6 +660,10 @@
 	C(head);
 	C(data);
 	C(truesize);
+#ifdef CONFIG_SKB_RECYCLE
+	C(recycle);
+	C(recycle_data);
+#endif
 	atomic_set(&n->users, 1);
 
 	atomic_inc(&(skb_shinfo(skb)->dataref));
@@ -611,7 +685,11 @@
  */
 struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src)
 {
+#ifdef CONFIG_SKB_RECYCLE
+	skb_release_all(dst, 0);
+#else
 	skb_release_all(dst);
+#endif
 	return __skb_clone(dst, src);
 }
 EXPORT_SYMBOL_GPL(skb_morph);
@@ -836,7 +914,12 @@
 	if (skb_has_frags(skb))
 		skb_clone_fraglist(skb);
 
+#ifdef CONFIG_SKB_RECYCLE
+	skb_release_data(skb, 0);
+	skb->recycle = NULL;
+#else
 	skb_release_data(skb);
+#endif
 
 	off = (data + nhead) - skb->head;
 
diff -ruw linux-2.6.31.7/net/ipv4/ipconfig.c linux-2.6.31.7-fbx/net/ipv4/ipconfig.c
--- linux-2.6.31.7/net/ipv4/ipconfig.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/ipv4/ipconfig.c	2010-03-18 18:28:52.652914180 +0100
@@ -187,6 +187,37 @@
 static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
 static struct net_device *ic_dev __initdata = NULL;	/* Selected device */
 
+#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)
 {
 	struct ic_device *d, **last;
@@ -204,6 +235,11 @@
 			printk(KERN_ERR "IP-Config: Failed to open %s\n", dev->name);
 	}
 
+#ifdef CONFIG_VLAN_8021Q
+	/* register vlan device if needed */
+	prepare_vlan();
+#endif
+
 	for_each_netdev(&init_net, dev) {
 		if (dev->flags & IFF_LOOPBACK)
 			continue;
@@ -658,8 +694,10 @@
 		e += sizeof(ic_req_params);
 
 		if (*vendor_class_identifier) {
+#ifdef IPCONFIG_DEBUG
 			printk(KERN_INFO "DHCP: sending class identifier \"%s\"\n",
 			       vendor_class_identifier);
+#endif
 			*e++ = 60;	/* Class-identifier */
 			len = strlen(vendor_class_identifier);
 			*e++ = len;
diff -ruw linux-2.6.31.7/net/ipv4/ip_input.c linux-2.6.31.7-fbx/net/ipv4/ip_input.c
--- linux-2.6.31.7/net/ipv4/ip_input.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/ipv4/ip_input.c	2010-10-25 13:43:58.381443306 +0200
@@ -437,6 +437,11 @@
 		goto drop;
 	}
 
+#ifdef CONFIG_IP_FFN
+	if (!ip_ffn_process(skb))
+		return NET_RX_SUCCESS;
+#endif
+
 	/* Remove any debris in the socket control block */
 	memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
 
diff -ruw linux-2.6.31.7/net/ipv4/ip_output.c linux-2.6.31.7-fbx/net/ipv4/ip_output.c
--- linux-2.6.31.7/net/ipv4/ip_output.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/ipv4/ip_output.c	2010-10-25 13:43:58.381443306 +0200
@@ -166,6 +166,7 @@
 	}
 
 	skb->priority = sk->sk_priority;
+	skb->rx_class = 1;
 	skb->mark = sk->sk_mark;
 
 	/* Send it out. */
@@ -201,6 +202,11 @@
 		skb = skb2;
 	}
 
+#ifdef CONFIG_IP_FFN
+	if (skb->ffn_state == FFN_STATE_FORWARDABLE)
+		ip_ffn_add(skb);
+#endif
+
 	if (dst->hh)
 		return neigh_hh_output(dst->hh, skb);
 	else if (dst->neighbour)
@@ -303,6 +309,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(PF_INET, NF_INET_POST_ROUTING, skb, NULL, dev,
 			    ip_finish_output,
 			    !(IPCB(skb)->flags & IPSKB_REROUTED));
@@ -385,6 +396,7 @@
 			     (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 
 	skb->priority = sk->sk_priority;
+	skb->rx_class = 1;
 	skb->mark = sk->sk_mark;
 
 	return ip_local_out(skb);
@@ -1288,6 +1300,7 @@
 	iph->daddr = rt->rt_dst;
 
 	skb->priority = sk->sk_priority;
+	skb->rx_class = 1;
 	skb->mark = sk->sk_mark;
 	/*
 	 * Steal rt from cork.dst to avoid a pair of atomic_inc/atomic_dec
@@ -1430,6 +1443,9 @@
 #if defined(CONFIG_IP_MULTICAST) && defined(CONFIG_PROC_FS)
 	igmp_mc_proc_init();
 #endif
+#ifdef CONFIG_IP_FFN
+	ip_ffn_init();
+#endif
 }
 
 EXPORT_SYMBOL(ip_generic_getfrag);
diff -ruw linux-2.6.31.7/net/ipv4/Kconfig linux-2.6.31.7-fbx/net/ipv4/Kconfig
--- linux-2.6.31.7/net/ipv4/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/ipv4/Kconfig	2010-03-18 18:28:52.652914180 +0100
@@ -324,6 +324,11 @@
 
 	  If unsure, say N.
 
+config INET_XFRM_GC_THRESH
+	int "IP: xfrm garbage collect threshold"
+	depends on XFRM
+	default 1024
+
 config INET_AH
 	tristate "IP: AH transformation"
 	select XFRM
diff -ruw linux-2.6.31.7/net/ipv4/Makefile linux-2.6.31.7-fbx/net/ipv4/Makefile
--- linux-2.6.31.7/net/ipv4/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/ipv4/Makefile	2010-03-18 18:28:52.652914180 +0100
@@ -14,6 +14,7 @@
 	     inet_fragment.o
 
 obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
+obj-$(CONFIG_IP_FFN) += ip_ffn.o
 obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o
 obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o
 obj-$(CONFIG_PROC_FS) += proc.o
diff -ruw linux-2.6.31.7/net/ipv4/netfilter/ip_tables.c linux-2.6.31.7-fbx/net/ipv4/netfilter/ip_tables.c
--- linux-2.6.31.7/net/ipv4/netfilter/ip_tables.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/ipv4/netfilter/ip_tables.c	2010-10-25 13:43:58.381443306 +0200
@@ -1301,6 +1301,10 @@
 			   tmp.num_counters, tmp.counters);
 	if (ret)
 		goto free_newinfo_untrans;
+
+#ifdef CONFIG_IP_FFN
+	ip_ffn_flush_all();
+#endif
 	return 0;
 
  free_newinfo_untrans:
diff -ruw linux-2.6.31.7/net/ipv4/netfilter/Kconfig linux-2.6.31.7-fbx/net/ipv4/netfilter/Kconfig
--- linux-2.6.31.7/net/ipv4/netfilter/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/ipv4/netfilter/Kconfig	2010-03-18 18:28:52.662918410 +0100
@@ -5,6 +5,9 @@
 menu "IP: Netfilter Configuration"
 	depends on INET && NETFILTER
 
+config IP_FFN
+	bool "IP: Fast forwarding and NAT"
+
 config NF_DEFRAG_IPV4
 	tristate
 	default n
diff -ruw linux-2.6.31.7/net/ipv4/xfrm4_policy.c linux-2.6.31.7-fbx/net/ipv4/xfrm4_policy.c
--- linux-2.6.31.7/net/ipv4/xfrm4_policy.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/ipv4/xfrm4_policy.c	2010-10-25 13:43:58.391447028 +0200
@@ -248,7 +248,7 @@
 	.destroy =		xfrm4_dst_destroy,
 	.ifdown =		xfrm4_dst_ifdown,
 	.local_out =		__ip_local_out,
-	.gc_thresh =		1024,
+	.gc_thresh =		CONFIG_INET_XFRM_GC_THRESH,
 	.entries =		ATOMIC_INIT(0),
 };
 
diff -ruw linux-2.6.31.7/net/ipv6/addrconf.c linux-2.6.31.7-fbx/net/ipv6/addrconf.c
--- linux-2.6.31.7/net/ipv6/addrconf.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/ipv6/addrconf.c	2010-10-25 13:43:58.391447028 +0200
@@ -4055,7 +4055,7 @@
 		return 0;
 
 	if (!rtnl_trylock())
-		return restart_syscall();
+		return -ERESTARTSYS;
 
 	if (p == &net->ipv6.devconf_all->disable_ipv6) {
 		__s32 newf = net->ipv6.devconf_all->disable_ipv6;
diff -ruw linux-2.6.31.7/net/ipv6/Kconfig linux-2.6.31.7-fbx/net/ipv6/Kconfig
--- linux-2.6.31.7/net/ipv6/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/ipv6/Kconfig	2010-03-18 18:28:52.672922242 +0100
@@ -173,6 +173,11 @@
 config IPV6_NDISC_NODETYPE
 	bool
 
+config IPV6_SIT_FBX6TO4
+	bool "sit support Freebox 6to4 scheme"
+	depends on IPV6_SIT
+	default n
+
 config IPV6_TUNNEL
 	tristate "IPv6: IP-in-IPv6 tunnel (RFC2473)"
 	select INET6_TUNNEL
diff -ruw linux-2.6.31.7/net/Kconfig linux-2.6.31.7-fbx/net/Kconfig
--- linux-2.6.31.7/net/Kconfig	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/Kconfig	2010-10-25 13:43:58.351442850 +0200
@@ -25,6 +25,26 @@
 
 menu "Networking options"
 
+config NETSKBPAD
+	int "Size reserved by dev_alloc_skb"
+	default 16
+
+config NETRXTHREAD
+	bool "Do rx network processing in kernel thread"
+
+config NETRXTHREAD_RX_QUEUE
+	int "Number of rx queues"
+	default 1
+	depends on NETRXTHREAD
+
+config NETRXTHREAD_MAX_PROCESS
+	int "Maximum number of packet to process before schedule"
+	default 4
+	depends on NETRXTHREAD
+
+config SKB_RECYCLE
+	bool "Skb recycling support"
+
 source "net/packet/Kconfig"
 source "net/unix/Kconfig"
 source "net/xfrm/Kconfig"
@@ -166,6 +186,7 @@
 source "net/rds/Kconfig"
 source "net/tipc/Kconfig"
 source "net/atm/Kconfig"
+source "net/fbxatm/Kconfig"
 source "net/802/Kconfig"
 source "net/bridge/Kconfig"
 source "net/dsa/Kconfig"
diff -ruw linux-2.6.31.7/net/Makefile linux-2.6.31.7-fbx/net/Makefile
--- linux-2.6.31.7/net/Makefile	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/Makefile	2010-10-25 13:43:58.351442850 +0200
@@ -41,6 +41,9 @@
 obj-$(CONFIG_SUNRPC)		+= sunrpc/
 obj-$(CONFIG_AF_RXRPC)		+= rxrpc/
 obj-$(CONFIG_ATM)		+= atm/
+ifneq ($(CONFIG_FBXATM),)
+obj-y				+= fbxatm/
+endif
 obj-$(CONFIG_DECNET)		+= decnet/
 obj-$(CONFIG_ECONET)		+= econet/
 obj-$(CONFIG_PHONET)		+= phonet/
diff -ruw linux-2.6.31.7/net/socket.c linux-2.6.31.7-fbx/net/socket.c
--- linux-2.6.31.7/net/socket.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/socket.c	2010-10-25 13:43:58.451453455 +0200
@@ -886,6 +886,31 @@
 
 EXPORT_SYMBOL(dlci_ioctl_set);
 
+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.
@@ -958,6 +983,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->ops->ioctl(sock, cmd, arg);
 
diff -ruw linux-2.6.31.7/net/wireless/wext.c linux-2.6.31.7-fbx/net/wireless/wext.c
--- linux-2.6.31.7/net/wireless/wext.c	2009-12-08 20:13:50.000000000 +0100
+++ linux-2.6.31.7-fbx/net/wireless/wext.c	2010-10-25 13:43:58.461445051 +0200
@@ -310,6 +310,7 @@
 		.header_type	= IW_HEADER_TYPE_POINT,
 		.token_size	= 1,
 		.max_tokens	= IW_GENERIC_IE_MAX,
+		.flags      = IW_DESCR_FLAG_NOMAX,
 	},
 	[SIOCSIWAUTH	- SIOCIWFIRST] = {
 		.header_type	= IW_HEADER_TYPE_PARAM,
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./board-fbx5b.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/board-fbx5b.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./board-fbx5b.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/board-fbx5b.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,69 @@
+#ifndef BOARD_FBX5B_H_
+#define BOARD_FBX5B_H_
+
+/* gpio above 32 are uart0 gpio */
+/* gpio above 64 are uart1 gpio */
+
+#define GPIO_DEMOD_I2C_CLK		0
+#define GPIO_DEMOD_I2C_DATA		1
+#define GPIO_FIP_DIN			2
+#define GPIO_FIP_DOUT			3
+#define GPIO_FIP_STB			4
+#define GPIO_FIP_CLK			5 /* fbx5bx */
+#define GPIO_MARVELL_INT		5 /* fbxo1_b */
+#define GPIO_IDE_RESET			6
+#define GPIO_IDE_T7			7
+#define GPIO_PCI_INTA			8
+#define GPIO_PCI_INTB			9
+#define GPIO_USB_PWR_FLT0		10
+#define GPIO_USB_PWR_FLT1		11
+#define GPIO_IR				12
+#define GPIO_DEMOD_IRQ			13 /* fbx5b1 */
+#define GPIO_BOARD_RESET_2		13 /* fbx5b2 and fbxo1_b */
+#define GPIO_DEMOD_RESET		14
+#define GPIO_DEMOD_SLEEP		15
+#define GPIO_DEMOD_STATUS		16
+#define GPIO_USB_ENABLE			17
+#define GPIO_SEL_HD			18
+#define GPIO_RESET_FIP			19
+#define GPIO_MUTE			20
+#define GPIO_PCI_ACT			21
+#define GPIO_BOARD_RESET_3		21 /* fbxo1_b */
+#define GPIO_PCI_RESET			22
+#define GPIO_ETH_PHY_RESET		23
+#define GPIO_COMMUTATION_LENTE_0	24
+#define GPIO_COMMUTATION_LENTE_1	25
+#define GPIO_COMMUTATION_RAPIDE		26
+#define GPIO_IDCARD0			27
+#define GPIO_IDCARD1			28
+#define GPIO_IDCARD2			29
+#define GPIO_IDCARD3			30
+#define GPIO_BOOT_ETHERNET		31
+
+#define GPIO_PCI_CLK_RUN		(32 + 2)
+#define GPIO_DEMOD_BKERR		(32 + 3)
+#define GPIO_IDE_CSEL			(32 + 5)
+#define GPIO_BOARD_RESET		(32 + 6)
+
+
+#define TANGO2_FBXSERIAL_OFFSET		(0x40000)
+
+extern unsigned int fbx_board_id;
+extern char zboot_version_str[128];
+
+/*
+ * list of known tango2 freebox board id
+ */
+enum {
+	E_FBXBOARDID_FBX5B1		= 0,
+	E_FBXBOARDID_FBX5B2_FIRST	= 1,
+	E_FBXBOARDID_FBX5B2_QIMONDA	= 1,
+	E_FBXBOARDID_FBX5B2_NANYA	= 2,
+	E_FBXBOARDID_FBX5B2_SAMSUNG	= 3,
+	E_FBXBOARDID_FBX5B2_ELPIDA	= 4,
+	E_FBXBOARDID_FBX5B2_LAST	= 4,
+	E_FBXBOARDID_FBXO1B		= 8,
+	E_FBXBOARDID_LAST,
+};
+
+#endif /* ! BOARD_FBX5B_H_ */
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./devices.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/devices.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./devices.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/devices.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,22 @@
+#ifndef __DEVICES_H
+#define __DEVICES_H
+
+#include <linux/if_ether.h>
+
+/*
+ * tango2 ethernet mac platform data. only mac_addr for now.
+ */
+struct tango2_enet_platform_data {
+	uint8_t mac_addr[ETH_ALEN];
+	unsigned int phy_need_reset;
+	unsigned int phy_is_ics1893;
+};
+
+/*
+ * tango2 ide platform data
+ */
+struct tango2_ide_platform_data {
+	void		(*reset_ide)(void);
+};
+
+#endif
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./dma-coherence.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/dma-coherence.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./dma-coherence.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/dma-coherence.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,99 @@
+#ifndef __ASM_MACH_TANGO2_DMA_COHERENCE_H
+#define __ASM_MACH_TANGO2_DMA_COHERENCE_H
+
+#include <linux/pci.h>
+
+struct device;
+
+extern unsigned long g_pcimem_busaddr[2];
+extern unsigned long g_pcimem_busaddr_end[2];
+extern unsigned long g_pcimem_physaddr[2];
+extern unsigned long g_pcimem_physaddr_end[2];
+
+#ifdef CONFIG_PCI
+#define IS_PCIDEV(x)	((x) != NULL && (x)->bus == &pci_bus_type)
+#else
+#define IS_PCIDEV(x)	0
+#endif
+
+static inline unsigned long tango2_pci_virt_to_bus(unsigned long addr)
+{
+	panic("virt2bus: Not a dma-able address: 0x%08lx\n", addr);
+}
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+					  size_t size)
+{
+#ifdef CONFIG_PCI
+	unsigned long bus_addr;
+#endif
+
+	if (!IS_PCIDEV(dev))
+		return virt_to_phys(addr);
+
+#ifdef CONFIG_PCI
+	bus_addr = CPHYSADDR(addr);
+
+	if (bus_addr < g_pcimem_physaddr[0] &&
+	    bus_addr >= g_pcimem_physaddr_end[0])
+		panic("tango2: not a dma-able address: %p\n", addr);
+
+	/* address in first dram controller */
+	return bus_addr - g_pcimem_physaddr[0] + g_pcimem_busaddr[0];
+#endif
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+					       struct page *page)
+{
+	return plat_map_dma_mem(dev, page_address(page), PAGE_SIZE);
+}
+
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+						  dma_addr_t dma_addr)
+{
+#ifdef CONFIG_PCI
+	if (dma_addr >= g_pcimem_busaddr[0] &&
+	    dma_addr < g_pcimem_busaddr_end[0]) {
+		return dma_addr - g_pcimem_busaddr[0] +
+			g_pcimem_physaddr[0];
+	}
+#endif
+	return dma_addr;
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+				      size_t size,
+				      enum dma_data_direction direction)
+{
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+	/*
+	 * we fall back to GFP_DMA when the mask isn't all 1s,
+	 * so we can't guarantee allocations that must be
+	 * within a tighter range than GFP_DMA..
+	 */
+	if (mask < DMA_BIT_MASK(24))
+		return 0;
+
+	return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+	return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+					 dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+	return 0;
+}
+#endif
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./emhwlib_dram.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/emhwlib_dram.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./emhwlib_dram.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/emhwlib_dram.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,55 @@
+/*****************************************
+ Copyright © 2001-2003  
+ Sigma Designs, Inc. All Rights Reserved
+ Proprietary and Confidential
+ *****************************************/
+/**
+  @file   emhwlib_dram.h
+  @brief  
+
+  fm stands for: first megabyte.
+
+  THE CODE USING THESE SYMBOLS ASSUMES THAT THE END BOUNDARY OF AN
+  ENTITY IS THE START BOUNDARY OF THE NEXT ENTITY
+  
+  htoinc.pl emhwlib_dram.h emhwlib_dram.inc
+  
+  @author Emmanuel Michon
+  @date   2004-07-26
+*/
+
+#ifndef __EMHWLIB_DRAM_H__
+#define __EMHWLIB_DRAM_H__
+
+#include <asm/mach-tango2/rmem86xxid.h>
+
+#include "emhwlib_dram_tango2.h"
+
+#define MEMCFG_SIGNATURE	0x6766636d // `m' `c' `f' `g'
+
+#ifndef __ASSEMBLY__
+
+/* This is the memory map data structure, the size is 64 bytes */
+typedef struct {
+	unsigned int signature;
+	unsigned int dram0_size;            /* The size of DRAM0 */
+	unsigned int dram1_size;            /* The size of DRAM1 */
+	unsigned int dram2_size;            /* The size of DRAM2 */
+	unsigned int dram0_removable_topreserved;     /* The size of top reserved in DRAM0 */
+	unsigned int dram1_removable_topreserved;     /* The size of top reserved in DRAM1 */
+	unsigned int dram2_removable_topreserved;     /* The size of top reserved in DRAM2 */
+	unsigned int dram0_fixed_topreserved;     /* The size of top reserved in DRAM0 */
+	unsigned int dram1_fixed_topreserved;     /* The size of top reserved in DRAM1 */
+	unsigned int dram2_fixed_topreserved;     /* The size of top reserved in DRAM2 */
+	unsigned int kernel_end;            /* The end address of kernel */
+	unsigned int checksum;		    /* The checksum */
+	unsigned int linux_cmd;		/* Linux command line */
+	unsigned int curtainA;
+	unsigned int curtainB;
+	unsigned int curtainC;
+} memcfg_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif // __EMHWLIB_DRAM_H__
+ 
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./emhwlib_dram_tango2.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/emhwlib_dram_tango2.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./emhwlib_dram_tango2.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/emhwlib_dram_tango2.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,49 @@
+/*****************************************
+ Copyright © 2004-2005
+ Sigma Designs, Inc. All Rights Reserved
+ Proprietary and Confidential
+ *****************************************/
+/**
+  @file   emhwlib_dram_tango2.h
+  @brief  
+
+  Addresses appear in increasing order. It is assumed that computing
+  FM_Y-FM_X is a proper way to access the max usable size for FM_X.
+
+  See SMP8630 software spec 3.3
+
+  @author Emmanuel Michon, YH Lin, Julien Soulier
+  @date   2005-04-06
+*/
+
+#ifndef __EMHWLIB_DRAM_TANGO2_H__
+#define __EMHWLIB_DRAM_TANGO2_H__
+
+/* Spec 3.3.5: stage (S4) [fully functional player memory map] */
+#define FM_GNET                    0x00000000
+#define FM_SCRATCH                 0x00000f08 /* 184 bytes */
+#define FM_MEMCFG                  0x00000fc0
+#define FM_IRQHANDLER_API          0x00001000
+#define FM_XTASK_API               0x00009e00 /* 512 bytes */
+#define FM_XOSDBG                  0x0000a000
+#define FM_XTASK1DBG               0x0000c000
+#define FM_XTASK2DBG               0x0000d000
+#define FM_XTASK3DBG               0x0000e000
+#define FM_XTASK4DBG               0x0000f000
+#define FM_SCRATCH2                0x00010000
+#define FM_DRAMCALIBRATION         0x0001f000
+#define FM_RESERVED                0x00020000
+
+/*
+  Spec 3.3.5: stage (S0) [bootstrap memory map]
+
+  Because you will use zboot/yamon to download linux/CE
+  at start of DRAM, the former are away from beginning.
+*/
+#define FM_ZBOOT                   0x01000000
+#define FM_YAMON_text_ram          0x01000000
+#define FM_YAMON__ftext_init       0x01100000
+#define FM_yamon_appl__ftext       0x01110000
+#define FM_linuxmips__ftext        0x00020000
+
+#endif // __EMHWLIB_DRAM_TANGO2_H__
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./emhwlib_lram.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/emhwlib_lram.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./emhwlib_lram.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/emhwlib_lram.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,75 @@
+/*****************************************
+ Copyright © 2004-2005
+ Sigma Designs, Inc. All Rights Reserved
+ Proprietary and Confidential
+ *****************************************/
+/**
+  @file   emhwlib_lram.h
+  @brief  
+
+  Map of the localram (8KBytes)
+
+  Traditionnally the start of localram is used to setup
+  a few kilobytes bootstrap routine code+data
+  (cache init, tlb init, load something bigger to DRAM, jump there).
+
+  Fixed offsets are defined in this file as communication devices
+  between hardware blocks.
+  Even debug locations must be present here.
+
+  The bootstrap routine is expected to preserve these and setup
+  its stack under LR_STACKTOP.
+
+  See emhwlib_resources_shared.h how some resources bw. 0 and 0x100 are used already
+  only when uCLinux is up with irq handler running
+
+  @author Emmanuel Michon
+  @date   2005-03-17
+*/
+
+#ifndef __EMHWLIB_LRAM_H__
+#define __EMHWLIB_LRAM_H__
+
+#define LR_CPU_IDLELOOP          0x00000000 /* CPU uses 0x80 bytes, up to 0x0080 */
+#define LR_UCLINUX_END           0x00000100
+
+#define LR_VSYNC_STRUCT          0x00000200 /* 2KB of data structures */
+#define LR_VSYNC_CODE            0x00000a00 /* 2KB of code */
+#define LR_VSYNC_END             0x00001200
+
+#define LR_STACKTOP              0x000017F4 /* in case a bootstrap routine needs a stack in local ram. Use this boundary */
+
+#define LR_PCI_INTERRUPT_ENABLE  0x000017F4
+#define LR_HOST_INTERRUPT_STATUS 0x000017F8
+#define LR_CPU_BRU_JUMP          0x000017FC /* `bootrom_ucos jump' (debug purpose) */
+
+#define LR_HB_HOST               0x00001cb0
+#define LR_HB_CPU                0x00001cb4
+#define LR_HB_MPEG0              0x00001cb8
+#define LR_HB_MPEG1              0x00001cbc
+#define LR_HB_AUDIO0             0x00001cc0
+#define LR_HB_AUDIO1             0x00001cc4
+#define LR_HB_DEMUX              0x00001cc8
+#define LR_HB_XPU                0x00001ccc
+
+#define LR_IDMA                  0x00001cd0 /* 16bytes. Obsoletizes LR_HMMAD */
+
+#define LR_ETH_MAC_LO            0x00001ce0 /* Ethernet MAC addr low 4 bytes */
+#define LR_ETH_MAC_HI            0x00001ce4 /* Ethernet MAC addr high bytes */
+
+#define LR_HMMAD                 0x00001cf4
+#define LR_KEY_ZONE              0x00001D00 /* 0x200 bytes, up to 0x1F00 */
+#define LR_YAMON_DIGITS          0x00001F00
+#define LR_XPU_DUMP              0x00001F00 /* 0x80 bytes, up to 0x1F80 */
+
+#define LR_VSYNC_PERIOD          0x00001FA0 /* 0x20 bytes, up to 0x1FC0 */
+
+#define LR_RANDOM_SEED           0x00001FC8 /* 0x08 bytes, up to 0x1FD0 */
+#define LR_LOCAL_DEBUG_PROBE     0x00001FD0 /* 0x20 bytes, up to 0x1FF0 */
+
+#define LR_XENV_LOCATION         0x00001FF0 /* Location of XENV, found by XOS */
+#define LR_GNET_MAC              0x00001FF4
+#define LR_ZBOOT_STAGE           0x00001FF8
+#define LR_XPU_STAGE             0x00001FFC
+
+#endif // __EMHWLIB_LRAM_H__
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./emhwlib_registers_tango2.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/emhwlib_registers_tango2.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./emhwlib_registers_tango2.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/emhwlib_registers_tango2.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,1346 @@
+/******************************************************/
+/* This file is generated automatically, DO NOT EDIT! */
+/******************************************************/
+/*
+ * ../emhwlib_hal/include/tango2/emhwlib_registers_tango2.h
+ *
+ * Copyright (c) 2001-2003 Sigma Designs, Inc. 
+ * All Rights Reserved. Proprietary and Confidential.
+ *
+ */
+ 
+/**
+  @file ../emhwlib_hal/include/tango2/emhwlib_registers_tango2.h
+  @brief emhwlib generated file
+   
+  @author Jacques Mahe, Christian Wolff, Julien Soulier, Emmanuel Michon
+  @ingroup hwlproperties
+*/
+
+#ifndef __EMHWLIB_REGISTERS_TANGO2_H__
+#define __EMHWLIB_REGISTERS_TANGO2_H__
+
+/* SystemBlock registers */
+#define REG_BASE_system_block 0x00010000 /* width RMuint32 */
+#define SYS_clkgen0_pll 0x0000 /* width RMuint32 */
+#define SYS_clkgen0_div 0x0004 /* width RMuint32 */
+#define SYS_clkgen1_pll 0x0008 /* width RMuint32 */
+#define SYS_clkgen1_div 0x000C /* width RMuint32 */
+#define SYS_clkgen2_pll 0x0010 /* width RMuint32 */
+#define SYS_clkgen2_div 0x0014 /* width RMuint32 */
+#define SYS_clkgen3_pll 0x0018 /* width RMuint32 */
+#define SYS_clkgen3_div 0x001C /* width RMuint32 */
+#define SYS_avclk_mux 0x0038 /* width RMuint32 */
+#define SYS_sysclk_mux 0x003C /* width RMuint32 */
+#define SYS_clk_cnt 0x0040 /* width RMuint32 */
+#define SYS_xtal_in_cnt 0x0048 /* width RMuint32 */
+#define DRAM_vbus_w0_cfg 0x0300 /* width RMuint32 */
+#define DRAM_vbus_w1_cfg 0x0304 /* width RMuint32 */
+#define DRAM_vbus_w2_cfg 0x0308 /* width RMuint32 */
+#define DRAM_vbus_w3_cfg 0x030c /* width RMuint32 */
+#define DRAM_vbus_r0_cfg 0x0340 /* width RMuint32 */
+#define DRAM_vbus_r1_cfg 0x0344 /* width RMuint32 */
+#define DRAM_vbus_r2_cfg 0x0348 /* width RMuint32 */
+#define DRAM_vbus_r3_cfg 0x034c /* width RMuint32 */
+#define DRAM_vbus_r4_cfg 0x0350 /* width RMuint32 */
+#define DRAM_vbus_r5_cfg 0x0354 /* width RMuint32 */
+#define DRAM_vbus_r6_cfg 0x0358 /* width RMuint32 */
+#define DRAM_vbus_r7_cfg 0x035c /* width RMuint32 */
+#define DRAM_vbus_r8_cfg 0x0360 /* width RMuint32 */
+#define DRAM_vbus_r9_cfg 0x0364 /* width RMuint32 */
+#define DRAM_vbus_r10_cfg 0x0368 /* width RMuint32 */
+#define DRAM_vbus_r11_cfg 0x036c /* width RMuint32 */
+#define DRAM_mbus_w0_cfg 0x0200 /* width RMuint32 */
+#define DRAM_mbus_w1_cfg 0x0204 /* width RMuint32 */
+#define DRAM_mbus_w2_cfg 0x0208 /* width RMuint32 */
+#define DRAM_mbus_w3_cfg 0x020c /* width RMuint32 */
+#define DRAM_mbus_w4_cfg 0x0210 /* width RMuint32 */
+#define DRAM_mbus_w5_cfg 0x0214 /* width RMuint32 */
+#define DRAM_mbus_w6_cfg 0x0218 /* width RMuint32 */
+#define DRAM_mbus_w7_cfg 0x021c /* width RMuint32 */
+#define DRAM_mbus_w8_cfg 0x0220 /* width RMuint32 */
+#define DRAM_mbus_w9_cfg 0x0224 /* width RMuint32 */
+#define DRAM_mbus_w10_cfg 0x0228 /* width RMuint32 */
+#define DRAM_mbus_r0_cfg 0x0240 /* width RMuint32 */
+#define DRAM_mbus_r1_cfg 0x0244 /* width RMuint32 */
+#define DRAM_mbus_r2_cfg 0x0248 /* width RMuint32 */
+#define DRAM_mbus_r3_cfg 0x024c /* width RMuint32 */
+#define DRAM_mbus_r4_cfg 0x0250 /* width RMuint32 */
+#define DRAM_mbus_r5_cfg 0x0254 /* width RMuint32 */
+#define DRAM_mbus_r6_cfg 0x0258 /* width RMuint32 */
+#define DRAM_mbus_r7_cfg 0x025c /* width RMuint32 */
+#define DRAM_mbus_r8_cfg 0x0260 /* width RMuint32 */
+#define DRAM_mbus_r9_cfg 0x0264 /* width RMuint32 */
+#define DRAM_mbus_r10_cfg 0x0268 /* width RMuint32 */
+#define SYS_hostclk_mux 0x0030 /* width RMuint32 */
+#define SYS_sysclk_premux 0x0034 /* width RMuint32 */
+#define SYS_rnd_cnt 0x0044 /* width RMuint32 */
+#define SYS_cnt_cfg 0x004c /* width RMuint32 */
+#define SYS_cfg_cnt0 0x0050 /* width RMuint32 */
+#define SYS_cfg_cnt1 0x0054 /* width RMuint32 */
+#define SYS_cfg_cnt2 0x0058 /* width RMuint32 */
+#define SYS_cfg_cnt3 0x005c /* width RMuint32 */
+#define SYS_cfg_cnt4 0x0060 /* width RMuint32 */
+#define SYS_cleandiv0_div 0x0080 /* width RMuint32 */
+#define SYS_cleandiv1_div 0x0088 /* width RMuint32 */
+#define SYS_cleandiv2_div 0x0090 /* width RMuint32 */
+#define SYS_cleandiv4_div 0x00a0 /* width RMuint32 */
+#define SYS_cleandiv5_div 0x00a8 /* width RMuint32 */
+#define SYS_cleandiv6_div 0x00b0 /* width RMuint32 */
+#define SYS_cleandiv7_div 0x00b8 /* width RMuint32 */
+#define SYS_cleandiv8_div 0x00c0 /* width RMuint32 */
+#define SYS_cleandiv9_div 0x00c8 /* width RMuint32 */
+#define SYS_cleandiv10_div 0x00d0 /* width RMuint32 */
+#define MARB_mid01_cfg 0x0200 /* width RMuint32 */
+#define MARB_mid21_cfg 0x0204 /* width RMuint32 */
+#define MARB_mid02_cfg 0x0208 /* width RMuint32 */
+#define MARB_mid22_cfg 0x020c /* width RMuint32 */
+#define MARB_mid04_cfg 0x0210 /* width RMuint32 */
+#define MARB_mid24_cfg 0x0214 /* width RMuint32 */
+#define MARB_mid25_cfg 0x0218 /* width RMuint32 */
+#define MARB_mid08_cfg 0x021c /* width RMuint32 */
+#define MARB_mid28_cfg 0x0220 /* width RMuint32 */
+#define MARB_mid29_cfg 0x0224 /* width RMuint32 */
+#define MARB_mid0C_cfg 0x0228 /* width RMuint32 */
+#define MARB_mid2C_cfg 0x022c /* width RMuint32 */
+#define MARB_mid10_cfg 0x0230 /* width RMuint32 */
+#define MARB_mid30_cfg 0x0234 /* width RMuint32 */
+#define MARB_mid31_cfg 0x0238 /* width RMuint32 */
+#define MARB_mid12_cfg 0x023c /* width RMuint32 */
+#define MARB_mid32_cfg 0x0240 /* width RMuint32 */
+#define VARB_mid01_cfg 0x0300 /* width RMuint32 */
+#define VARB_mid02_cfg 0x0304 /* width RMuint32 */
+#define VARB_mid21_cfg 0x0308 /* width RMuint32 */
+#define VARB_mid22_cfg 0x030c /* width RMuint32 */
+#define VARB_mid23_cfg 0x0310 /* width RMuint32 */
+#define VARB_mid24_cfg 0x0314 /* width RMuint32 */
+#define VARB_mid25_cfg 0x0318 /* width RMuint32 */
+#define VARB_mid26_cfg 0x031c /* width RMuint32 */
+#define VARB_mid27_cfg 0x0320 /* width RMuint32 */
+#define VARB_mid28_cfg 0x0324 /* width RMuint32 */
+#define VARB_mid29_cfg 0x0328 /* width RMuint32 */
+#define VARB_mid2A_cfg 0x032c /* width RMuint32 */
+#define VARB_mid10_cfg 0x0330 /* width RMuint32 */
+#define VARB_mid30_cfg 0x0334 /* width RMuint32 */
+#define VARB_mid31_cfg 0x0338 /* width RMuint32 */
+#define IARB_mid01_cfg 0x0400 /* width RMuint32 */
+#define IARB_mid02_cfg 0x0404 /* width RMuint32 */
+#define SYS_gpio_dir 0x0500 /* width RMuint32 */
+#define SYS_gpio_data 0x0504 /* width RMuint32 */
+#define SYS_gpio_int 0x0508 /* width RMuint32 */
+#define SYS_gpio15_pwm 0x0510 /* width RMuint32 */
+#define SYS_gpio14_pwm 0x0514 /* width RMuint32 */
+#define REG_BASE_dram_controller_0 0x00030000 /* width RMuint32 */
+#define MEM_BASE_dram_controller_0 0x10000000 /* width RMuint32 */
+#define REG_BASE_dram_controller_1 0x00040000 /* width RMuint32 */
+#define MEM_BASE_dram_controller_1 0x20000000 /* width RMuint32 */
+#define REG_BASE_dram_controller_2 0x00050000 /* width RMuint32 */
+#define MEM_BASE_dram_controller_2 0x30000000 /* width RMuint32 */
+#define DRAM_dunit_cfg 0x0000 /* width RMuint32 */
+#define DRAM_dunit_delay0_ctrl 0x0004 /* width RMuint32 */
+#define DRAM_dunit_delay1_ctrl 0x0008 /* width RMuint32 */
+#define DRAM_dunit_auto_delay 0x000c /* width RMuint32 */
+#define DRAM_dunit_delay_probe 0x0010 /* width RMuint32 */
+#define DRAM_dunit_effective_delay 0x0014 /* width RMuint32 */
+#define DRAM_dunit_bw_probe_cfg 0x0020 /* width RMuint32 */
+#define DRAM_dunit_bw_probe_cnt 0x0024 /* width RMuint32 */
+#define DRAM_dunit_flush_buffer 0x0104 /* width RMuint32 */
+#define REG_BASE_host_interface 0x00020000 /* width RMuint32 */
+#define MEM_BASE_host_interface 0x40000000 /* width RMuint32 */
+#define IDE_data 0x0000 /* width RMuint32 */
+#define IDE_error 0x0004 /* width RMuint32 */
+#define IDE_count 0x0008 /* width RMuint32 */
+#define IDE_start_sector 0x000c /* width RMuint32 */
+#define IDE_cylinder_lo 0x0010 /* width RMuint32 */
+#define IDE_cylinder_hi 0x0014 /* width RMuint32 */
+#define IDE_head_device 0x0018 /* width RMuint32 */
+#define IDE_cmd_stat 0x001c /* width RMuint32 */
+#define IDE_irq_stat 0x0218 /* width RMuint32 */
+#define IDE_cmd_stat__ 0x021c /* width RMuint32 */
+#define PB_timing0 0x0800 /* width RMuint32 */
+#define PB_timing1 0x0804 /* width RMuint32 */
+#define PB_timing2 0x0808 /* width RMuint32 */
+#define PB_timing3 0x080c /* width RMuint32 */
+#define PB_timing4 0x0810 /* width RMuint32 */
+#define PB_timing5 0x0814 /* width RMuint32 */
+#define PB_default_timing 0x0818 /* width RMuint32 */
+#define PB_use_timing0 0x081c /* width RMuint32 */
+#define PB_use_timing1 0x0820 /* width RMuint32 */
+#define PB_use_timing2 0x0824 /* width RMuint32 */
+#define PB_use_timing3 0x0828 /* width RMuint32 */
+#define PB_use_timing4 0x082c /* width RMuint32 */
+#define PB_use_timing5 0x0830 /* width RMuint32 */
+#define PB_CS_config 0x0834 /* width RMuint32 */
+#define PB_automode_start_address 0x0840 /* width RMuint32 */
+#define PB_automode_control 0x0844 /* width RMuint32 */
+#define SFLA_status 0xa000 /* width RMuint32 */
+#define SFLA_read_parameters 0xa008 /* width RMuint32 */
+#define SFLA_drive_pads 0xa00c /* width RMuint32 */
+#define SFLA_driver_speed 0xa010 /* width RMuint32 */
+#define SFLA_N_for_Send_Get 0xa020 /* width RMuint32 */
+#define SFLA_read_data 0xa030 /* width RMuint32 */
+#define SFLA_Send_1 0xa040 /* width RMuint32 */
+#define SFLA_Send_8 0xa044 /* width RMuint32 */
+#define SFLA_Send_16 0xa048 /* width RMuint32 */
+#define SFLA_Send_32 0xa04c /* width RMuint32 */
+#define SFLA_Send_Get_1 0xa050 /* width RMuint32 */
+#define SFLA_Send_Get_8 0xa054 /* width RMuint32 */
+#define SFLA_Send_Get_16 0xa058 /* width RMuint32 */
+#define SFLA_Send_Get_32 0xa05c /* width RMuint32 */
+#define SFLA_Chip_Select 0xa060 /* width RMuint32 */
+#define SFLA_Chip_Deselect 0xa064 /* width RMuint32 */
+#define SFLA_Send_N 0xa068 /* width RMuint32 */
+#define SFLA_Get_SlaveOut 0xa070 /* width RMuint32 */
+#define SFLA_Wait_Timer 0xa074 /* width RMuint32 */
+#define SFLA_Send_Get_N 0xa078 /* width RMuint32 */
+#define EMHWLIB_IS_HOST 0xe000 /* width RMuint32 */
+#define HOST_REG1 0xfed0 /* width RMuint32 */
+#define HOST_REG2 0xfed4 /* width RMuint32 */
+#define READ_ADDRESS 0xfec0 /* width RMuint32 */
+#define READ_COUNTER 0xfec4 /* width RMuint32 */
+#define READ_ENABLE 0xfec8 /* width RMuint32 */
+#define READ_REVERSE 0xfecc /* width RMuint32 */
+#define WRITE_ADDRESS 0xfed8 /* width RMuint32 */
+#define WRITE_COUNTER 0xfedc /* width RMuint32 */
+#define WRITE_ENABLE 0xfee0 /* width RMuint32 */
+#define BURST 0xfee4 /* width RMuint32 */
+#define PCI_TIMEOUT 0x8000 /* width RMuint32 */
+#define PCI_TIMEOUT_STATUS 0x8004 /* width RMuint32 */
+#define PCI_TIMER 0x8008 /* width RMuint32 */
+#define PCI_TIMER_TEST 0x800c /* width RMuint32 */
+#define PCI_WAKEUP 0x8010 /* width RMuint32 */
+#define PCI_REGION_0_BASE 0x9000 /* width RMuint32 */
+#define PCI_REGION_1_BASE 0x9004 /* width RMuint32 */
+#define PCI_REGION_2_BASE 0x9008 /* width RMuint32 */
+#define PCI_REGION_3_BASE 0x900c /* width RMuint32 */
+#define PCI_REGION_4_BASE 0x9010 /* width RMuint32 */
+#define PCI_REGION_5_BASE 0x9014 /* width RMuint32 */
+#define PCI_REGION_6_BASE 0x9018 /* width RMuint32 */
+#define PCI_REGION_7_BASE 0x901c /* width RMuint32 */
+#define PCI_irq_status 0x9020 /* width RMuint32 */
+#define PCI_irq_set 0x9024 /* width RMuint32 */
+#define PCI_irq_clear 0x9028 /* width RMuint32 */
+#define SBOX_FIFO_RESET 0x90a0 /* width RMuint32 */
+#define SBOX_ROUTE 0x90a8 /* width RMuint32 */
+#define output_SBOX_MBUS_W0 0x9080 /* width RMuint32 */
+#define output_SBOX_MBUS_W1 0x9084 /* width RMuint32 */
+#define output_SBOX_PCI_MASTER 0x9088 /* width RMuint32 */
+#define output_SBOX_PCI_SLAVE 0x908c /* width RMuint32 */
+#define output_SBOX_CIPHER 0x9090 /* width RMuint32 */
+#define output_SBOX_IDE_ISA 0x9094 /* width RMuint32 */
+#define output_SBOX_IDE_DVD 0x9098 /* width RMuint32 */
+#define input_keep_SBOX 0 /* width RMuint32 */
+#define input_MBUS_R0_SBOX 1 /* width RMuint32 */
+#define input_MBUS_R1_SBOX 2 /* width RMuint32 */
+#define input_PCI_MASTER_SBOX 3 /* width RMuint32 */
+#define input_PCI_SLAVE_SBOX 4 /* width RMuint32 */
+#define input_CIPHER_SBOX 5 /* width RMuint32 */
+#define input_IDE_DVD_SBOX 6 /* width RMuint32 */
+#define input_IDE_ISA_SBOX 7 /* width RMuint32 */
+#define input_SFLA_SBOX 8 /* width RMuint32 */
+#define input_unconnected_SBOX 0xf /* width RMuint32 */
+#define host_mutex0 0x9040 /* width RMuint32 */
+#define host_mutex1 0x9044 /* width RMuint32 */
+#define host_mutex2 0x9048 /* width RMuint32 */
+#define host_mutex3 0x904c /* width RMuint32 */
+#define host_mutex4 0x9050 /* width RMuint32 */
+#define host_mutex5 0x9054 /* width RMuint32 */
+#define host_mutex6 0x9058 /* width RMuint32 */
+#define host_mutex7 0x905c /* width RMuint32 */
+#define host_mutex8 0x9060 /* width RMuint32 */
+#define host_mutex9 0x9064 /* width RMuint32 */
+#define host_mutex10 0x9068 /* width RMuint32 */
+#define host_mutex11 0x906c /* width RMuint32 */
+#define host_mutex12 0x9070 /* width RMuint32 */
+#define host_mutex13 0x9074 /* width RMuint32 */
+#define host_mutex14 0x9078 /* width RMuint32 */
+#define host_mutex15 0x907c /* width RMuint32 */
+#define PCI_host_reg5 0xfe94 /* width RMuint32 */
+#define PCI_chip_is_host 0xfe90 /* width RMuint32 */
+#define IDECTRL_idesrc 0x20d0 /* width RMuint32 */
+#define IDECTRL_pri_drv1udmatim1 0x20e0 /* width RMuint32 */
+#define IDECTRL_pri_drv1udmatim2 0x20f0 /* width RMuint32 */
+#define IDECTRL_pri_idectl 0x2100 /* width RMuint32 */
+#define IDECTRL_pri_drv0tim 0x2110 /* width RMuint32 */
+#define IDECTRL_pri_drv1tim 0x2120 /* width RMuint32 */
+#define IDECTRL_idemisc 0x2130 /* width RMuint32 */
+#define IDECTRL_idestatus 0x2140 /* width RMuint32 */
+#define IDECTRL_udmactl 0x2150 /* width RMuint32 */
+#define IDECTRL_pri_drv0udmatim1 0x2160 /* width RMuint32 */
+#define IDECTRL_pri_drv0udmatim2 0x2170 /* width RMuint32 */
+#define IDECTRL_pref_st 0x2310 /* width RMuint32 */
+#define IDECTRL_pri_ctrlblock 0x2398 /* width RMuint32 */
+#define IDECTRL_pri_cmdblock 0x23c0 /* width RMuint32 */
+#define IDECTRL_bmic 0x2400 /* width RMuint32 */
+#define IDECTRL_bmis 0x2410 /* width RMuint32 */
+#define IDECTRL_bmidtp 0x2420 /* width RMuint32 */
+#define IDECTRL_ide_dmaptr 0x2780 /* width RMuint32 */
+#define IDECTRL_ide_dmalen 0x2790 /* width RMuint32 */
+#define IDECTRL_pio_prefetch_data 0x27c0 /* width RMuint32 */
+#define MEM_BASE_pfla 0x40000000 /* width RMuint32 */
+#define PB_CS0_OFFSET 0x00000000 /* width RMuint32 */
+#define PB_CS1_OFFSET 0x04000000 /* width RMuint32 */
+#define PB_CS2_OFFSET 0x08000000 /* width RMuint32 */
+#define PB_CS3_OFFSET 0x0c000000 /* width RMuint32 */
+#define ETH_gpio_dir 0x710c /* width RMuint32 */
+#define ETH_gpio_data 0x7110 /* width RMuint32 */
+#define PCI_host_reg1 0xfed0 /* width RMuint32 */
+#define PCI_host_reg2 0xfed4 /* width RMuint32 */
+#define PCI_host_reg3 0xfe80 /* width RMuint32 */
+#define PCI_host_reg4 0xfe84 /* width RMuint32 */
+#define PCI_pcictrl_reg1 0xfe88 /* width RMuint32 */
+#define PCI_pcictrl_reg2 0xfe8c /* width RMuint32 */
+#define PCI_pcictrl_reg3 0xfefc /* width RMuint32 */
+#define PCI_REG0 0xfee8 /* width RMuint32 */
+#define PCI_REG1 0xfeec /* width RMuint32 */
+#define PCI_REG2 0xfef0 /* width RMuint32 */
+#define PCI_REG3 0xfef4 /* width RMuint32 */
+#define PCI_CONFIG 0xfef8 /* width RMuint32 */
+#define MIF_W0_ADD 0xb000 /* width RMuint32 */
+#define MIF_W0_CNT 0xb004 /* width RMuint32 */
+#define MIF_W0_SKIP 0xb008 /* width RMuint32 */
+#define MIF_W0_CMD 0xb00c /* width RMuint32 */
+#define MIF_W1_ADD 0xb040 /* width RMuint32 */
+#define MIF_W1_CNT 0xb044 /* width RMuint32 */
+#define MIF_W1_SKIP 0xb048 /* width RMuint32 */
+#define MIF_W1_CMD 0xb04c /* width RMuint32 */
+#define MIF_R0_ADD 0xb080 /* width RMuint32 */
+#define MIF_R0_CNT 0xb084 /* width RMuint32 */
+#define MIF_R0_SKIP 0xb088 /* width RMuint32 */
+#define MIF_R0_CMD 0xb08c /* width RMuint32 */
+#define MIF_R1_ADD 0xb0c0 /* width RMuint32 */
+#define MIF_R1_CNT 0xb0c4 /* width RMuint32 */
+#define MIF_R1_SKIP 0xb0c8 /* width RMuint32 */
+#define MIF_R1_CMD 0xb0cc /* width RMuint32 */
+#define MBUS_IDLE 0 /* width RMuint32 */
+#define MBUS_LINEAR 1 /* width RMuint32 */
+#define MBUS_DOUBLE 2 /* width RMuint32 */
+#define MBUS_RECTANGLE 3 /* width RMuint32 */
+#define MBUS_VOID 4 /* width RMuint32 */
+#define MBUS_LINEAR_VOID 5 /* width RMuint32 */
+#define MBUS_DOUBLE_VOID 6 /* width RMuint32 */
+#define MBUS_RECTANGLE_VOID 7 /* width RMuint32 */
+#define MBUS_TILED 8 /* width RMuint32 */
+#define GBUS_MUTEX_XPU 0x14 /* width RMuint32 */
+#define GBUS_MUTEX_PT110 0x16 /* width RMuint32 */
+#define GBUS_MUTEX_TDMX 0x19 /* width RMuint32 */
+#define GBUS_MUTEX_AUDIO_0 0x1b /* width RMuint32 */
+#define GBUS_MUTEX_AUDIO_1 0x1c /* width RMuint32 */
+#define GBUS_MUTEX_MPEG_0 0x1d /* width RMuint32 */
+#define GBUS_MUTEX_MPEG_1 0x1e /* width RMuint32 */
+#define GBUS_MUTEX_HOST 0x1f /* width RMuint32 */
+#define GBUS_MUTEX_LOCAL 0x10 /* width RMuint32 */
+/* SystemBlock registers done */
+
+/* CPUBlock registers */
+#define REG_BASE_cpu_block 0x00060000 /* width RMuint32 */
+#define CPU_time0_load 0xc500 /* width RMuint32 */
+#define CPU_time0_value 0xc504 /* width RMuint32 */
+#define CPU_time0_ctrl 0xc508 /* width RMuint32 */
+#define CPU_time0_clr 0xc50c /* width RMuint32 */
+#define CPU_time1_load 0xc600 /* width RMuint32 */
+#define CPU_time1_value 0xc604 /* width RMuint32 */
+#define CPU_time1_ctrl 0xc608 /* width RMuint32 */
+#define CPU_time1_clr 0xc60c /* width RMuint32 */
+#define CPU_rtc_data 0xc800 /* width RMuint32 */
+#define CPU_rtc_match 0xc804 /* width RMuint32 */
+#define CPU_rtc_stat 0xc808 /* width RMuint32 */
+#define CPU_rtc_load 0xc80c /* width RMuint32 */
+#define CPU_rtc_ctrl 0xc810 /* width RMuint32 */
+#define CPU_irq_status 0xe000 /* width RMuint32 */
+#define CPU_irq_rawstat 0xe004 /* width RMuint32 */
+#define CPU_irq_enableset 0xe008 /* width RMuint32 */
+#define CPU_irq_enableclr 0xe00c /* width RMuint32 */
+#define CPU_irq_softset 0xe010 /* width RMuint32 */
+#define CPU_irq_softclr 0xe014 /* width RMuint32 */
+#define CPU_fiq_status 0xe100 /* width RMuint32 */
+#define CPU_fiq_rawstat 0xe104 /* width RMuint32 */
+#define CPU_fiq_enableset 0xe108 /* width RMuint32 */
+#define CPU_fiq_enableclr 0xe10c /* width RMuint32 */
+#define CPU_fiq_softset 0xe110 /* width RMuint32 */
+#define CPU_fiq_softclr 0xe114 /* width RMuint32 */
+#define CPU_edge_status 0xe200 /* width RMuint32 */
+#define CPU_edge_rawstat 0xe204 /* width RMuint32 */
+#define CPU_edge_config_rise 0xe208 /* width RMuint32 */
+#define CPU_edge_config_fall 0xe20c /* width RMuint32 */
+#define CPU_SOFT_INT 0x00000001 /* width RMuint32 */
+#define CPU_UART0_INT 0x00000002 /* width RMuint32 */
+#define CPU_UART1_INT 0x00000004 /* width RMuint32 */
+#define CPU_TIMER0_INT 0x00000020 /* width RMuint32 */
+#define CPU_TIMER1_INT 0x00000040 /* width RMuint32 */
+#define CPU_HOST_MBUS_W0_INT 0x00000200 /* width RMuint32 */
+#define CPU_HOST_MBUS_W1_INT 0x00000400 /* width RMuint32 */
+#define CPU_HOST_MBUS_R0_INT 0x00000800 /* width RMuint32 */
+#define CPU_HOST_MBUS_R1_INT 0x00001000 /* width RMuint32 */
+#define CPU_PCI_INTA 0x00002000 /* width RMuint32 */
+#define CPU_PCI_INTB 0x00004000 /* width RMuint32 */
+#define CPU_PCI_INTC 0x00008000 /* width RMuint32 */
+#define CPU_PCI_INTD 0x00010000 /* width RMuint32 */
+#define CPU_PCI_FAULT_INT 0x00100000 /* width RMuint32 */
+#define CPU_INFRARED_INT 0x00200000 /* width RMuint32 */
+#define CPU_SFLA_INT 0x00000010 /* width RMuint32 */
+#define CPU_DVD_INT 0x00000080 /* width RMuint32 */
+#define CPU_ETH_INT 0x00000100 /* width RMuint32 */
+#define CPU_DMAIDE_INT 0x00020000 /* width RMuint32 */
+#define CPU_IDE_INT 0x00040000 /* width RMuint32 */
+#define CPU_FRONTPANEL_INT 0x00080000 /* width RMuint32 */
+#define CPU_I2C_INT 0x00400000 /* width RMuint32 */
+#define CPU_GFX_ACCEL_INT 0x00800000 /* width RMuint32 */
+#define CPU_VSYNC0_INT 0x01000000 /* width RMuint32 */
+#define CPU_VSYNC1_INT 0x02000000 /* width RMuint32 */
+#define CPU_VSYNC2_INT 0x04000000 /* width RMuint32 */
+#define CPU_VSYNC3_INT 0x08000000 /* width RMuint32 */
+#define CPU_VSYNC4_INT 0x10000000 /* width RMuint32 */
+#define CPU_VSYNC4BKEND_INT 0x20000000 /* width RMuint32 */
+#define CPU_VSYNC5_INT 0x40000000 /* width RMuint32 */
+#define CPU_VSYNC5BKEND_INT 0x80000000 /* width RMuint32 */
+#define CPU_SMARTCARD_HI_INT 0x00000001 /* width RMuint32 */
+#define CPU_HDMI_HI_INT 0x00000002 /* width RMuint32 */
+#define CPU_HDMI_I2C_HI_INT 0x00000004 /* width RMuint32 */
+#define CPU_VBUS_W0_HI_INT 0x00000008 /* width RMuint32 */
+#define CPU_VBUS_W3_HI_INT 0x00000010 /* width RMuint32 */
+#define CPU_ETH_PHY_HI_INT 0x00000020 /* width RMuint32 */
+#define CPU_ETH_MAC_HI_INT 0x00000040 /* width RMuint32 */
+#define CPU_USB_OHCI_MAC_HI_INT 0x00000080 /* width RMuint32 */
+#define CPU_USB_EHCI_MAC_HI_INT 0x00000100 /* width RMuint32 */
+#define LOG2_CPU_SOFT_INT 0 /* width RMuint32 */
+#define LOG2_CPU_UART0_INT 1 /* width RMuint32 */
+#define LOG2_CPU_UART1_INT 2 /* width RMuint32 */
+#define LOG2_CPU_TIMER0_INT 5 /* width RMuint32 */
+#define LOG2_CPU_TIMER1_INT 6 /* width RMuint32 */
+#define LOG2_CPU_DVD_INT 7 /* width RMuint32 */
+#define LOG2_CPU_RTC_INT 8 /* width RMuint32 */
+#define LOG2_CPU_HOST_MBUS_W0_INT 9 /* width RMuint32 */
+#define LOG2_CPU_HOST_MBUS_W1_INT 10 /* width RMuint32 */
+#define LOG2_CPU_HOST_MBUS_R0_INT 11 /* width RMuint32 */
+#define LOG2_CPU_HOST_MBUS_R1_INT 12 /* width RMuint32 */
+#define LOG2_CPU_PCI_INTA 13 /* width RMuint32 */
+#define LOG2_CPU_PCI_INTB 14 /* width RMuint32 */
+#define LOG2_CPU_PCI_INTC 15 /* width RMuint32 */
+#define LOG2_CPU_PCI_INTD 16 /* width RMuint32 */
+#define LOG2_CPU_DMAIDE_INT 17 /* width RMuint32 */
+#define LOG2_CPU_IDE_INT 18 /* width RMuint32 */
+#define LOG2_CPU_FRONTPANEL_INT 19 /* width RMuint32 */
+#define LOG2_CPU_PCI_FAULT_INT 20 /* width RMuint32 */
+#define LOG2_CPU_INFRARED_INT 21 /* width RMuint32 */
+#define LOG2_CPU_I2C_INT 22 /* width RMuint32 */
+#define LOG2_CPU_GFX_ACCEL_INT 23 /* width RMuint32 */
+#define LOG2_CPU_VSYNC0_INT 24 /* width RMuint32 */
+#define LOG2_CPU_VSYNC1_INT 25 /* width RMuint32 */
+#define LOG2_CPU_VSYNC2_INT 26 /* width RMuint32 */
+#define LOG2_CPU_VSYNC3_INT 27 /* width RMuint32 */
+#define LOG2_CPU_VSYNC4_INT 28 /* width RMuint32 */
+#define LOG2_CPU_VSYNC4BKEND_INT 29 /* width RMuint32 */
+#define LOG2_CPU_VSYNC5_INT 30 /* width RMuint32 */
+#define LOG2_CPU_VSYNC5BKEND_INT 31 /* width RMuint32 */
+#define LOG2_CPU_SMARTCARD_INT 32 /* width RMuint32 */
+#define LOG2_CPU_HDMI_INT 33 /* width RMuint32 */
+#define LOG2_CPU_HDMI_I2C_INT 34 /* width RMuint32 */
+#define LOG2_CPU_VBUS_W0_INT 35 /* width RMuint32 */
+#define LOG2_CPU_VBUS_W3_INT 36 /* width RMuint32 */
+#define LOG2_CPU_ETH_PHY_INT 37 /* width RMuint32 */
+#define LOG2_CPU_ETH_MAC_INT 38 /* width RMuint32 */
+#define LOG2_CPU_USB_OHCI_INT 39 /* width RMuint32 */
+#define LOG2_CPU_USB_EHCI_INT 40 /* width RMuint32 */
+#define CPU_edge_status_hi 0xe220 /* width RMuint32 */
+#define CPU_edge_rawstat_hi 0xe224 /* width RMuint32 */
+#define CPU_edge_config_rise_hi 0xe228 /* width RMuint32 */
+#define CPU_edge_config_fall_hi 0xe22c /* width RMuint32 */
+#define CPU_irq_status_hi 0xe018 /* width RMuint32 */
+#define CPU_irq_rawstat_hi 0xe01c /* width RMuint32 */
+#define CPU_irq_enableset_hi 0xe020 /* width RMuint32 */
+#define CPU_irq_enableclr_hi 0xe024 /* width RMuint32 */
+#define CPU_fiq_status_hi 0xe118 /* width RMuint32 */
+#define CPU_fiq_rawstat_hi 0xe11c /* width RMuint32 */
+#define CPU_fiq_enableset_hi 0xe120 /* width RMuint32 */
+#define CPU_fiq_enableclr_hi 0xe124 /* width RMuint32 */
+#define CPU_iiq_status 0xe300 /* width RMuint32 */
+#define CPU_iiq_rawstat 0xe304 /* width RMuint32 */
+#define CPU_iiq_enableset 0xe308 /* width RMuint32 */
+#define CPU_iiq_enableclr 0xe30c /* width RMuint32 */
+#define CPU_iiq_softset 0xe310 /* width RMuint32 */
+#define CPU_iiq_softclr 0xe314 /* width RMuint32 */
+#define CPU_iiq_status_hi 0xe318 /* width RMuint32 */
+#define CPU_iiq_rawstat_hi 0xe31c /* width RMuint32 */
+#define CPU_iiq_enableset_hi 0xe320 /* width RMuint32 */
+#define CPU_iiq_enableclr_hi 0xe324 /* width RMuint32 */
+#define CPU_UART_GPIOMODE 0x38 /* width RMuint32 */
+#define CPU_UART_GPIODIR 0x30 /* width RMuint32 */
+#define CPU_UART_GPIODATA 0x34 /* width RMuint32 */
+#define CPU_edge_config_rise_set 0xe210 /* width RMuint32 */
+#define CPU_edge_config_rise_clr 0xe214 /* width RMuint32 */
+#define CPU_edge_config_fall_set 0xe218 /* width RMuint32 */
+#define CPU_edge_config_fall_clr 0xe21c /* width RMuint32 */
+#define CPU_edge_config_rise_set_hi 0xe230 /* width RMuint32 */
+#define CPU_edge_config_rise_clr_hi 0xe234 /* width RMuint32 */
+#define CPU_edge_config_fall_set_hi 0xe238 /* width RMuint32 */
+#define CPU_edge_config_fall_clr_hi 0xe23c /* width RMuint32 */
+#define CPU_pm_select_0 0xc900 /* width RMuint32 */
+#define CPU_pm_counter_0 0xc904 /* width RMuint32 */
+#define CPU_pm_select_1 0xc908 /* width RMuint32 */
+#define CPU_pm_counter_1 0xc90c /* width RMuint32 */
+#define CPU_remap 0xf000 /* width RMuint32 */
+#define CPU_remap1 0xf004 /* width RMuint32 */
+#define CPU_remap2 0xf008 /* width RMuint32 */
+#define CPU_remap3 0xf00c /* width RMuint32 */
+#define CPU_remap4 0xf010 /* width RMuint32 */
+#define CPU_remap_address 0x1fc00000 /* width RMuint32 */
+#define CPU_remap1_address 0 /* width RMuint32 */
+#define CPU_remap2_address 0x04000000 /* width RMuint32 */
+#define CPU_remap3_address 0x08000000 /* width RMuint32 */
+#define CPU_remap4_address 0x0c000000 /* width RMuint32 */
+#define REG_BASE_xpu_block 0xe0000 /* width RMuint32 */
+#define REG_BASE_irq_handler_block 0xe0000 /* width RMuint32 */
+#define G2L_BIST_BUSY 0xffe0 /* width RMuint32 */
+#define G2L_BIST_PASS 0xffe4 /* width RMuint32 */
+#define G2L_BIST_MASK 0xffe8 /* width RMuint32 */
+#define G2L_RESET_CONTROL 0xfffc /* width RMuint32 */
+#define CPU_UART0_base 0xc100 /* width RMuint32 */
+#define CPU_UART1_base 0xc200 /* width RMuint32 */
+#define CPU_UART_RBR 0x00 /* width RMuint32 */
+#define CPU_UART_THR 0x04 /* width RMuint32 */
+#define CPU_UART_IER 0x08 /* width RMuint32 */
+#define CPU_UART_IIR 0x0c /* width RMuint32 */
+#define CPU_UART_FCR 0x10 /* width RMuint32 */
+#define CPU_UART_LCR 0x14 /* width RMuint32 */
+#define CPU_UART_MCR 0x18 /* width RMuint32 */
+#define CPU_UART_LSR 0x1c /* width RMuint32 */
+#define CPU_UART_MSR 0x20 /* width RMuint32 */
+#define CPU_UART_SCR 0x24 /* width RMuint32 */
+#define CPU_UART_CLKDIV 0x28 /* width RMuint32 */
+#define CPU_UART_CLKSEL 0x2c /* width RMuint32 */
+/* CPUBlock registers done */
+
+/* DisplayBlock registers */
+#define REG_BASE_display_block 0x00070000 /* width RMuint32 */
+#define VO_run 0x0000 /* width RMuint32 */
+#define VO_reset_datapath 0x0004 /* width RMuint32 */
+#define VO_reset_timing 0x0008 /* width RMuint32 */
+#define VO_reset_config 0x000c /* width RMuint32 */
+#define VO_reset_mode_0 0x0014 /* width RMuint32 */
+#define VO_reset_mode_1 0x0018 /* width RMuint32 */
+#define VIF_w0 0x4000 /* width RMuint32 */
+#define VIF_w1 0x4100 /* width RMuint32 */
+#define VIF_w2 0x4200 /* width RMuint32 */
+#define VIF_w3 0x4F00 /* width RMuint32 */
+#define VIF_r0 0x4300 /* width RMuint32 */
+#define VIF_r1 0x4400 /* width RMuint32 */
+#define VIF_r2 0x4500 /* width RMuint32 */
+#define VIF_r3 0x4600 /* width RMuint32 */
+#define VIF_r4 0x4700 /* width RMuint32 */
+#define VIF_r5 0x4800 /* width RMuint32 */
+#define VIF_r6 0x4900 /* width RMuint32 */
+#define VIF_r7 0x4A00 /* width RMuint32 */
+#define VIF_r8 0x4B00 /* width RMuint32 */
+#define VIF_r9 0x4C00 /* width RMuint32 */
+#define VIF_r10 0x4D00 /* width RMuint32 */
+#define VIF_r11 0x4E00 /* width RMuint32 */
+#define VIF_offs 0x0100 /* width RMuint32 */
+#define VIF_add 0x0000 /* width RMuint32 */
+#define VIF_cnt 0x0004 /* width RMuint32 */
+#define VIF_skip 0x0008 /* width RMuint32 */
+#define VIF_cmd 0x000c /* width RMuint32 */
+#define VIF_addB 0x0010 /* width RMuint32 */
+#define VIF_cntB 0x0014 /* width RMuint32 */
+#define VIF_skipB 0x0018 /* width RMuint32 */
+#define VBUS_IDLE 0x0 /* width RMuint32 */
+#define VBUS_LINEAR 0x1 /* width RMuint32 */
+#define VBUS_DOUBLE 0x2 /* width RMuint32 */
+#define VBUS_RECTANGLE 0x3 /* width RMuint32 */
+#define VBUS_DOUBLE_FIELD 0x4 /* width RMuint32 */
+#define VBUS_DOUBLE_RECTANGLE 0x5 /* width RMuint32 */
+#define VBUS_8BYTE_COLUMN 0x6 /* width RMuint32 */
+#define VBUS_VOID 0x8 /* width RMuint32 */
+#define VBUS_LINEAR_VOID 0x9 /* width RMuint32 */
+#define VBUS_DOUBLE_VOID 0xa /* width RMuint32 */
+#define VBUS_RECTANGLE_VOID 0xb /* width RMuint32 */
+#define VBUS_DOUBLE_FIELD_VOID 0xc /* width RMuint32 */
+#define VBUS_DOUBLE_RECTANGLE_VOID 0xd /* width RMuint32 */
+#define VBUS_8BYTE_COLUMN_VOID 0xe /* width RMuint32 */
+#define VO_hdmi_reset_bit 0x17 /* width RMuint32 */
+#define VO_hdmi_config 0x3d00 /* width RMuint32 */
+#define VO_hdmi_i2c 0x3dc0 /* width RMuint32 */
+#define VO_hdmi_keymem 0x3e00 /* width RMuint32 */
+/* DisplayBlock registers done */
+
+/* DispOSDScaler registers */
+#define VO_osd_reset_bit 0x03 /* width RMuint32 */
+#define VO_osd_format_hds 0x0300 /* width RMuint32 */
+#define VO_osd_output_size 0x0304 /* width RMuint32 */
+#define VO_osd_scale_factor 0x0308 /* width RMuint32 */
+#define VO_osd_scale_phase_flicker 0x030c /* width RMuint32 */
+#define VO_osd_alpha_routing 0x0310 /* width RMuint32 */
+#define VO_osd_key_color 0x0314 /* width RMuint32 */
+#define VO_osd_lut 0x9000 /* width RMuint32 */
+#define VO_osd_lut0 0x9000 /* width RMuint32 */
+/* DispOSDScaler registers done */
+
+/* DispHardwareCursor registers */
+#define VO_cursor_reset_bit 0x01 /* width RMuint32 */
+#define VO_cursor_size_ctrl 0x0100 /* width RMuint32 */
+#define VO_cursor_lut 0x0140 /* width RMuint32 */
+#define VO_cursor_lut0 0x0140 /* width RMuint32 */
+#define VO_cursor_lut1 0x0144 /* width RMuint32 */
+#define VO_cursor_lut2 0x0148 /* width RMuint32 */
+#define VO_cursor_lut3 0x014c /* width RMuint32 */
+#define VO_cursor_lut4 0x0150 /* width RMuint32 */
+#define VO_cursor_lut5 0x0154 /* width RMuint32 */
+#define VO_cursor_lut6 0x0158 /* width RMuint32 */
+#define VO_cursor_lut7 0x015c /* width RMuint32 */
+#define VO_cursor_lut8 0x0160 /* width RMuint32 */
+#define VO_cursor_lut9 0x0164 /* width RMuint32 */
+#define VO_cursor_lut10 0x0168 /* width RMuint32 */
+#define VO_cursor_lut11 0x016c /* width RMuint32 */
+#define VO_cursor_lut12 0x0170 /* width RMuint32 */
+#define VO_cursor_lut13 0x0174 /* width RMuint32 */
+#define VO_cursor_lut14 0x0178 /* width RMuint32 */
+#define VO_cursor_lut15 0x017c /* width RMuint32 */
+#define VO_cursor_pix 0x8000 /* width RMuint32 */
+#define VO_cursor_pix0 0x8000 /* width RMuint32 */
+/* DispHardwareCursor registers done */
+
+/* DispMainVideoScaler registers */
+#define VO_main_reset_bit 0x04 /* width RMuint32 */
+#define VO_main_format_hds 0x0400 /* width RMuint32 */
+#define VO_main_output_size 0x0404 /* width RMuint32 */
+#define VO_main_scale_factor 0x0408 /* width RMuint32 */
+#define VO_main_scale_phase 0x040c /* width RMuint32 */
+#define VO_main_phase 0x040c /* width RMuint32 */
+#define VO_main_alpha_deint_routing 0x0410 /* width RMuint32 */
+#define VO_main_deint2 0x0414 /* width RMuint32 */
+#define VO_main_bcs 0x0418 /* width RMuint32 */
+#define VO_main_pulldown 0x041c /* width RMuint32 */
+#define VO_main_strip_filter 0x0420 /* width RMuint32 */
+#define VO_main_nonlinear_0 0x0424 /* width RMuint32 */
+#define VO_main_nonlinear_1 0x0428 /* width RMuint32 */
+#define VO_main_bcs2 0x042c /* width RMuint32 */
+/* DispMainVideoScaler registers done */
+
+/* DispSubPictureScaler registers */
+#define VO_subp_reset_bit 0x02 /* width RMuint32 */
+#define VO_subp_format_hds 0x0200 /* width RMuint32 */
+#define VO_subp_output_size 0x0204 /* width RMuint32 */
+#define VO_subp_scale_factor 0x0208 /* width RMuint32 */
+#define VO_subp_scale_phase_routing 0x020c /* width RMuint32 */
+#define VO_sp_lut 0x9400 /* width RMuint32 */
+#define VO_sp_lut0 0x9400 /* width RMuint32 */
+/* DispSubPictureScaler registers done */
+
+/* DispVCRMultiScaler registers */
+#define VO_VCR_reset_bit 0x05 /* width RMuint32 */
+#define VO_VCR_format_hds 0x0500 /* width RMuint32 */
+#define VO_VCR_output_size 0x0504 /* width RMuint32 */
+#define VO_VCR_scale_factor 0x0508 /* width RMuint32 */
+#define VO_VCR_scale_phase 0x050c /* width RMuint32 */
+#define VO_VCR_phase 0x050c /* width RMuint32 */
+#define VO_VCR_alpha_routing 0x0510 /* width RMuint32 */
+#define VO_VCR_key_color 0x0514 /* width RMuint32 */
+#define VO_VCR_bcs 0x0518 /* width RMuint32 */
+#define VO_VCR_strip_edge 0x051C /* width RMuint32 */
+#define VO_VCR_nonlinear_0 0x0520 /* width RMuint32 */
+#define VO_VCR_nonlinear_1 0x0524 /* width RMuint32 */
+#define VO_VCR_tiling 0x0528 /* width RMuint32 */
+#define VO_VCR_bcs2 0x052c /* width RMuint32 */
+#define VO_VCR_lut 0xa000 /* width RMuint32 */
+#define VO_VCR_lut0 0xa000 /* width RMuint32 */
+/* DispVCRMultiScaler registers done */
+
+/* DispCRTMultiScaler registers */
+#define VO_CRT_reset_bit 0x06 /* width RMuint32 */
+#define VO_CRT_format_hds 0x0600 /* width RMuint32 */
+#define VO_CRT_output_size 0x0604 /* width RMuint32 */
+#define VO_CRT_scale_factor 0x0608 /* width RMuint32 */
+#define VO_CRT_scale_phase 0x060c /* width RMuint32 */
+#define VO_CRT_phase 0x060c /* width RMuint32 */
+#define VO_CRT_alpha_routing 0x0610 /* width RMuint32 */
+#define VO_CRT_key_color 0x0614 /* width RMuint32 */
+#define VO_CRT_bcs 0x0618 /* width RMuint32 */
+#define VO_CRT_strip_edge 0x061C /* width RMuint32 */
+#define VO_CRT_nonlinear_0 0x0620 /* width RMuint32 */
+#define VO_CRT_nonlinear_1 0x0624 /* width RMuint32 */
+#define VO_CRT_tiling 0x0628 /* width RMuint32 */
+#define VO_CRT_bcs2 0x062c /* width RMuint32 */
+#define VO_CRT_lut 0xb000 /* width RMuint32 */
+#define VO_CRT_lut0 0xb000 /* width RMuint32 */
+/* DispCRTMultiScaler registers done */
+
+/* DispGFXMultiScaler registers */
+#define VO_GFX_reset_bit 0x07 /* width RMuint32 */
+#define VO_GFX_format_hds 0x0700 /* width RMuint32 */
+#define VO_GFX_output_size 0x0704 /* width RMuint32 */
+#define VO_GFX_scale_factor 0x0708 /* width RMuint32 */
+#define VO_GFX_scale_phase 0x070c /* width RMuint32 */
+#define VO_GFX_phase 0x070c /* width RMuint32 */
+#define VO_GFX_alpha_routing 0x0710 /* width RMuint32 */
+#define VO_GFX_key_color 0x0714 /* width RMuint32 */
+#define VO_GFX_bcs 0x0718 /* width RMuint32 */
+#define VO_GFX_strip_edge 0x071C /* width RMuint32 */
+#define VO_GFX_nonlinear_0 0x0720 /* width RMuint32 */
+#define VO_GFX_nonlinear_1 0x0724 /* width RMuint32 */
+#define VO_GFX_tiling 0x0728 /* width RMuint32 */
+#define VO_GFX_bcs2 0x072c /* width RMuint32 */
+#define VO_GFX_lut 0xc000 /* width RMuint32 */
+#define VO_GFX_lut0 0xc000 /* width RMuint32 */
+/* DispGFXMultiScaler registers done */
+
+/* DispMainMixer registers */
+#define VO_mix_reset_bit 0x08 /* width RMuint32 */
+#define VO_mix_gfx_pos 0x0800 /* width RMuint32 */
+#define VO_mix_crt_pos 0x0804 /* width RMuint32 */
+#define VO_mix_vcr_pos 0x0808 /* width RMuint32 */
+#define VO_mix_sp_pos 0x080C /* width RMuint32 */
+#define VO_mix_mv_pos 0x0810 /* width RMuint32 */
+#define VO_mix_osd_pos 0x0814 /* width RMuint32 */
+#define VO_mix_gin_pos 0x0818 /* width RMuint32 */
+#define VO_mix_cur_pos 0x081C /* width RMuint32 */
+#define VO_mix_index 0x0820 /* width RMuint32 */
+#define VO_mix_frame_size 0x0824 /* width RMuint32 */
+#define VO_mix_background 0x0828 /* width RMuint32 */
+/* DispMainMixer registers done */
+
+/* DispVCRMixer registers */
+#define VO_vcrmix_reset_bit 0x09 /* width RMuint32 */
+#define VO_vcrmix_gfx_pos 0x0900 /* width RMuint32 */
+#define VO_vcrmix_crt_pos 0x0904 /* width RMuint32 */
+#define VO_vcrmix_sp_pos 0x0908 /* width RMuint32 */
+#define VO_vcrmix_vcr_pos 0x090C /* width RMuint32 */
+#define VO_vcrmix_index 0x0910 /* width RMuint32 */
+#define VO_vcrmix_frame_size 0x0914 /* width RMuint32 */
+#define VO_vcrmix_background 0x0918 /* width RMuint32 */
+/* DispVCRMixer registers done */
+
+/* DispColorBars registers */
+#define VO_color_bars_reset_bit 0x0b /* width RMuint32 */
+#define VO_color_bars_ctrl 0x0d00 /* width RMuint32 */
+#define VO_color_bars_size 0x0d04 /* width RMuint32 */
+/* DispColorBars registers done */
+
+/* DispRouting registers */
+#define VO_routing_reset_bit 0x16 /* width RMuint32 */
+#define VO_routing_ctrl 0x1208 /* width RMuint32 */
+/* DispRouting registers done */
+
+/* DispVideoInput registers */
+#define VO_vid_in_reset_bit 0x10 /* width RMuint32 */
+#define VO_vid_in_format 0x0b00 /* width RMuint32 */
+#define VO_vid_in_data_size 0x0b04 /* width RMuint32 */
+#define VO_vid_in_data_Xoffset 0x0b08 /* width RMuint32 */
+#define VO_vid_in_data_Yoffset 0x0b0c /* width RMuint32 */
+#define VO_vid_in_hz_sync 0x0b10 /* width RMuint32 */
+#define VO_vid_in_vt_sync 0x0b14 /* width RMuint32 */
+#define VO_vid_in_sync_coord 0x0b18 /* width RMuint32 */
+#define VO_vid_in_top_vbi 0x0b1c /* width RMuint32 */
+#define VO_vid_in_bot_vbi 0x0b20 /* width RMuint32 */
+#define VO_vid_in_counters 0x0b24 /* width RMuint32 */
+#define VO_vid_in_vbi_size 0x0b28 /* width RMuint32 */
+#define VO_vid_in_vbi_vsm 0x0b2c /* width RMuint32 */
+#define VO_vid_in_vbi_Voffset 0x0b30 /* width RMuint32 */
+#define VO_vid_in_format2 0x0b34 /* width RMuint32 */
+#define VO_vid_in_counters2 0x0b38 /* width RMuint32 */
+/* DispVideoInput registers done */
+
+/* DispGraphicInput registers */
+#define VO_graph_in_reset_bit 0x11 /* width RMuint32 */
+#define VO_graph_in_format 0x0c00 /* width RMuint32 */
+#define VO_graph_in_alpha_routing 0x0c04 /* width RMuint32 */
+#define VO_graph_in_key_color 0x0c08 /* width RMuint32 */
+#define VO_graph_in_data_size 0x0c0c /* width RMuint32 */
+#define VO_graph_in_data_Xoffset 0x0c10 /* width RMuint32 */
+#define VO_graph_in_data_Yoffset 0x0c14 /* width RMuint32 */
+#define VO_graph_in_hz_sync 0x0c18 /* width RMuint32 */
+#define VO_graph_in_vt_sync 0x0c1c /* width RMuint32 */
+#define VO_graph_in_sync_coord 0x0c20 /* width RMuint32 */
+#define VO_graph_in_sync_offset 0x0c24 /* width RMuint32 */
+#define VO_graph_in_top_vbi 0x0c28 /* width RMuint32 */
+#define VO_graph_in_bot_vbi 0x0c2c /* width RMuint32 */
+#define VO_graph_in_counters 0x0c30 /* width RMuint32 */
+#define VO_graph_in_format2 0x0c34 /* width RMuint32 */
+#define VO_graph_in_counters2 0x0c38 /* width RMuint32 */
+#define VO_graph_in_vbi_size 0x0c3c /* width RMuint32 */
+#define VO_graph_in_vbi_vsm 0x0c40 /* width RMuint32 */
+#define VO_graph_in_vbi_Voffset 0x0c44 /* width RMuint32 */
+/* DispGraphicInput registers done */
+
+/* DispDigitalOut registers */
+#define VO_digit_out_reset_bit 0x12 /* width RMuint32 */
+#define VO_digit_out_conv0 0x0e00 /* width RMuint32 */
+#define VO_digit_out_conv1 0x0e04 /* width RMuint32 */
+#define VO_digit_out_conv2 0x0e08 /* width RMuint32 */
+#define VO_digit_out_conv3 0x0e0c /* width RMuint32 */
+#define VO_digit_out_conv4 0x0e10 /* width RMuint32 */
+#define VO_digit_out_conv5 0x0e14 /* width RMuint32 */
+#define VO_digit_out_format 0x0e20 /* width RMuint32 */
+#define VO_digit_out_Xoffset 0x0e24 /* width RMuint32 */
+#define VO_digit_out_Yoffset 0x0e28 /* width RMuint32 */
+#define VO_digit_out_hz_sync 0x0e2c /* width RMuint32 */
+#define VO_digit_out_vt_sync 0x0e30 /* width RMuint32 */
+#define VO_digit_out_vsync_coord 0x0e34 /* width RMuint32 */
+#define VO_digit_out_pads_config 0x0020 /* width RMuint32 */
+#define VO_digit_out_gamma_lut0 0xf000 /* width RMuint32 */
+#define VO_digit_out_temp_lut0 0xf400 /* width RMuint32 */
+#define VO_digit_out_sync_ext_sync 0x0e38 /* width RMuint32 */
+/* DispDigitalOut registers done */
+
+/* DispMainAnalogOut registers */
+#define VO_main_analog_reset_bit 0x13 /* width RMuint32 */
+#define VO_main_analog_conv0 0x0f00 /* width RMuint32 */
+#define VO_main_analog_conv1 0x0f04 /* width RMuint32 */
+#define VO_main_analog_conv2 0x0f08 /* width RMuint32 */
+#define VO_main_analog_conv3 0x0f0c /* width RMuint32 */
+#define VO_main_analog_conv4 0x0f10 /* width RMuint32 */
+#define VO_main_analog_conv5 0x0f14 /* width RMuint32 */
+#define VO_main_analog_xoffset_field 0x0f18 /* width RMuint32 */
+#define VO_main_analog_yoffset 0x0f1c /* width RMuint32 */
+#define VO_main_analog_cvbs_conv0 0x0f20 /* width RMuint32 */
+#define VO_main_analog_cvbs_conv1 0x0f24 /* width RMuint32 */
+#define VO_main_analog_cvbs_conv2 0x0f28 /* width RMuint32 */
+#define VO_main_analog_cvbs_conv3 0x0f2c /* width RMuint32 */
+#define VO_main_analog_cvbs_conv4 0x0f30 /* width RMuint32 */
+#define VO_main_analog_cvbs_conv5 0x0f34 /* width RMuint32 */
+#define VO_main_analog_TV_config 0x0f40 /* width RMuint32 */
+#define VO_main_analog_TV_size 0x0f44 /* width RMuint32 */
+#define VO_main_analog_TV_hsync 0x0f48 /* width RMuint32 */
+#define VO_main_analog_TV_vsync_O_0 0x0f4c /* width RMuint32 */
+#define VO_main_analog_TV_vsync_O_1 0x0f50 /* width RMuint32 */
+#define VO_main_analog_TV_vsync_E_0 0x0f54 /* width RMuint32 */
+#define VO_main_analog_TV_vsync_E_1 0x0f58 /* width RMuint32 */
+#define VO_main_analog_TV_HD_hsync_info 0x0f5c /* width RMuint32 */
+#define VO_main_analog_TV_HD_vsync 0x0f60 /* width RMuint32 */
+#define VO_main_analog_TV_CGMS 0x0f64 /* width RMuint32 */
+#define VO_main_analog_TV_CC_AGC 0x0f68 /* width RMuint32 */
+#define VO_main_analog_TV_test_config 0x0f6c /* width RMuint32 */
+#define VO_main_analog_TV_teletext_config 0x0f70 /* width RMuint32 */
+#define VO_main_analog_TV_MV_N_0_22 0x0f80 /* width RMuint32 */
+#define VO_main_analog_TV_MV_N_1_2_3_4 0x0f84 /* width RMuint32 */
+#define VO_main_analog_TV_MV_N_5_6_7_8 0x0f88 /* width RMuint32 */
+#define VO_main_analog_TV_MV_N_9_10_11 0x0f8c /* width RMuint32 */
+#define VO_main_analog_TV_MV_N_12_13_14 0x0f90 /* width RMuint32 */
+#define VO_main_analog_TV_MV_N_15_16_17_18 0x0f94 /* width RMuint32 */
+#define VO_main_analog_TV_MV_N_19_20_21 0x0f98 /* width RMuint32 */
+#define VO_main_analog_TV_timing_sync 0x0f7c /* width RMuint32 */
+/* DispMainAnalogOut registers done */
+
+/* DispComponentOut registers */
+#define VO_component_out_reset_bit 0x14 /* width RMuint32 */
+#define VO_component_out_conv0 0x1000 /* width RMuint32 */
+#define VO_component_out_conv1 0x1004 /* width RMuint32 */
+#define VO_component_out_conv2 0x1008 /* width RMuint32 */
+#define VO_component_out_conv3 0x100c /* width RMuint32 */
+#define VO_component_out_conv4 0x1010 /* width RMuint32 */
+#define VO_component_out_conv5 0x1014 /* width RMuint32 */
+#define VO_component_out_xoffset_field 0x1018 /* width RMuint32 */
+#define VO_component_out_yoffset 0x101c /* width RMuint32 */
+#define VO_component_out_TV_config 0x1040 /* width RMuint32 */
+#define VO_component_out_TV_size 0x1044 /* width RMuint32 */
+#define VO_component_out_TV_hsync 0x1048 /* width RMuint32 */
+#define VO_component_out_TV_vsync_O_0 0x104c /* width RMuint32 */
+#define VO_component_out_TV_vsync_O_1 0x1050 /* width RMuint32 */
+#define VO_component_out_TV_vsync_E_0 0x1054 /* width RMuint32 */
+#define VO_component_out_TV_vsync_E_1 0x1058 /* width RMuint32 */
+#define VO_component_out_TV_HD_hsync_info 0x105c /* width RMuint32 */
+#define VO_component_out_TV_HD_vsync 0x1060 /* width RMuint32 */
+#define VO_component_out_TV_CGMS 0x1064 /* width RMuint32 */
+#define VO_component_out_TV_CC_AGC 0x1068 /* width RMuint32 */
+#define VO_component_out_TV_test_config 0x106c /* width RMuint32 */
+#define VO_component_out_TV_MV_N_0_22 0x1080 /* width RMuint32 */
+#define VO_component_out_TV_MV_N_1_2_3_4 0x1084 /* width RMuint32 */
+#define VO_component_out_TV_MV_N_5_6_7_8 0x1088 /* width RMuint32 */
+#define VO_component_out_TV_MV_N_9_10_11 0x108c /* width RMuint32 */
+#define VO_component_out_TV_MV_N_12_13_14 0x1090 /* width RMuint32 */
+#define VO_component_out_TV_MV_N_15_16_17_18 0x1094 /* width RMuint32 */
+#define VO_component_out_TV_MV_N_19_20_21 0x1098 /* width RMuint32 */
+#define VO_component_out_TV_timing_sync 0x1078 /* width RMuint32 */
+/* DispComponentOut registers done */
+
+/* DispCompositeOut registers */
+#define VO_composite_out_reset_bit 0x15 /* width RMuint32 */
+#define VO_composite_out_bcs 0x1100 /* width RMuint32 */
+#define VO_composite_out_Xoffset 0x1104 /* width RMuint32 */
+#define VO_composite_out_Yoffset 0x1108 /* width RMuint32 */
+#define VO_composite_out_TV_config 0x1140 /* width RMuint32 */
+#define VO_composite_out_TV_size 0x1144 /* width RMuint32 */
+#define VO_composite_out_TV_hsync 0x1148 /* width RMuint32 */
+#define VO_composite_out_TV_vsync_O_0 0x114c /* width RMuint32 */
+#define VO_composite_out_TV_vsync_O_1 0x1150 /* width RMuint32 */
+#define VO_composite_out_TV_vsync_E_0 0x1154 /* width RMuint32 */
+#define VO_composite_out_TV_vsync_E_1 0x1158 /* width RMuint32 */
+#define VO_composite_out_TV_CGMS 0x1164 /* width RMuint32 */
+#define VO_composite_out_TV_CC_AGC 0x1168 /* width RMuint32 */
+#define VO_composite_out_TV_test_config 0x116c /* width RMuint32 */
+#define VO_composite_out_TV_MV_N_0_22 0x1180 /* width RMuint32 */
+#define VO_composite_out_TV_MV_N_1_2_3_4 0x1184 /* width RMuint32 */
+#define VO_composite_out_TV_MV_N_5_6_7_8 0x1188 /* width RMuint32 */
+#define VO_composite_out_TV_MV_N_9_10_11 0x118c /* width RMuint32 */
+#define VO_composite_out_TV_MV_N_12_13_14 0x1190 /* width RMuint32 */
+#define VO_composite_out_TV_MV_N_15_16_17_18 0x1194 /* width RMuint32 */
+#define VO_composite_out_TV_MV_N_19_20_21 0x1198 /* width RMuint32 */
+/* DispCompositeOut registers done */
+
+/* DemuxEngine registers */
+#define REG_BASE_demux_engine 0x000A0000 /* width RMuint32 */
+#define MEM_BASE_demux_engine 0x00140000 /* width RMuint32 */
+#define PMEM_BASE_demux_engine 0x00140000 /* width RMuint32 */
+#define DMEM_BASE_demux_engine 0x00150000 /* width RMuint32 */
+#define demux_MISC_dr_mode 0x2f00 /* width RMuint32 */
+#define demux_MISC_dr_length 0x2f01 /* width RMuint32 */
+#define demux_MISC_dr_address 0x2f02 /* width RMuint32 */
+#define demux_MISC_dw_mode 0x2f04 /* width RMuint32 */
+#define demux_MISC_dw_length 0x2f05 /* width RMuint32 */
+#define demux_MISC_dw_address 0x2f06 /* width RMuint32 */
+#define demux_MISC_reset0 0x2f08 /* width RMuint32 */
+#define demux_MISC_reset1 0x2f09 /* width RMuint32 */
+#define demux_MISC_interrupt 0x2f0a /* width RMuint32 */
+#define demux_MISC_timer_div 0x2f0b /* width RMuint32 */
+#define demux_MISC_timer_count 0x2f0c /* width RMuint32 */
+#define demux_mutex0 0x2f10 /* width RMuint32 */
+#define demux_mutex1 0x2f11 /* width RMuint32 */
+#define demux_mutex2 0x2f12 /* width RMuint32 */
+#define demux_mutex3 0x2f13 /* width RMuint32 */
+#define demux_mutex4 0x2f14 /* width RMuint32 */
+#define demux_mutex5 0x2f15 /* width RMuint32 */
+#define demux_mutex6 0x2f16 /* width RMuint32 */
+#define demux_mutex7 0x2f17 /* width RMuint32 */
+#define demux_GBUSIF_MAIN_WADD 0x2ea0 /* width RMuint32 */
+#define demux_GBUSIF_MAIN_RADD 0x2ea1 /* width RMuint32 */
+#define demux_GBUSIF_MAIN_BYTE 0x2ea2 /* width RMuint32 */
+#define demux_GBUSIF_MAIN_WORD 0x2ea3 /* width RMuint32 */
+#define demux_GBUSIF_MAIN_DWORD 0x2ea4 /* width RMuint32 */
+#define demux_GBUSIF_MAIN_STATUS 0x2ea5 /* width RMuint32 */
+#define demux_GBUSIF_ISR_WADD 0x2ea8 /* width RMuint32 */
+#define demux_GBUSIF_ISR_RADD 0x2ea9 /* width RMuint32 */
+#define demux_GBUSIF_ISR_BYTE 0x2eaa /* width RMuint32 */
+#define demux_GBUSIF_ISR_WORD 0x2eab /* width RMuint32 */
+#define demux_GBUSIF_ISR_DWORD 0x2eac /* width RMuint32 */
+#define demux_GBUSIF_ISR_STATUS 0x2ead /* width RMuint32 */
+#define demux_MBUSIF_w0_add 0x2ec0 /* width RMuint32 */
+#define demux_MBUSIF_w0_cnt 0x2ec1 /* width RMuint32 */
+#define demux_MBUSIF_w0_skip 0x2ec2 /* width RMuint32 */
+#define demux_MBUSIF_w0_cmd 0x2ec3 /* width RMuint32 */
+#define demux_MBUSIF_r0_add 0x2ed0 /* width RMuint32 */
+#define demux_MBUSIF_r0_cnt 0x2ed1 /* width RMuint32 */
+#define demux_MBUSIF_r0_skip 0x2ed2 /* width RMuint32 */
+#define demux_MBUSIF_r0_cmd 0x2ed3 /* width RMuint32 */
+#define demux_cipher_c2_secret_key 0x2c00 /* width RMuint32 */
+#define demux_cipher_c2_key_lsb 0x2c70 /* width RMuint32 */
+#define demux_cipher_c2_key_msb 0x2c71 /* width RMuint32 */
+#define demux_cipher_c2g_ecb_data_lsb 0x2c72 /* width RMuint32 */
+#define demux_cipher_c2g_ecb_data_msb 0x2c73 /* width RMuint32 */
+#define demux_cipher_c2_flags 0x2c74 /* width RMuint32 */
+#define demux_cipher_multi2_syst_key 0x2c80 /* width RMuint32 */
+#define demux_cipher_multi2_data_key 0x2c88 /* width RMuint32 */
+#define demux_cipher_multi2_iv       0x2c8a /* width RMuint32 */
+#define demux_cipher_multi2_flags 0x2c8c /* width RMuint32 */
+#define demux_cipher_config 0x2c8f /* width RMuint32 */
+#define demux_cipher_rc4_key_0 0x2e40 /* width RMuint32 */
+#define demux_cipher_rc4_key_1 0x2e41 /* width RMuint32 */
+#define demux_cipher_rc4_key_2 0x2e42 /* width RMuint32 */
+#define demux_cipher_rc4_key_3 0x2e43 /* width RMuint32 */
+#define demux_cipher_rc4_key_4 0x2e44 /* width RMuint32 */
+#define demux_cipher_rc4_key_5 0x2e45 /* width RMuint32 */
+#define demux_cipher_rc4_key_6 0x2e46 /* width RMuint32 */
+#define demux_cipher_rc4_key_7 0x2e47 /* width RMuint32 */
+#define demux_cipher_rc4_flags 0x2e48 /* width RMuint32 */
+#define demux_cipher_des_key1_1 0x2e50 /* width RMuint32 */
+#define demux_cipher_des_key1_2 0x2e51 /* width RMuint32 */
+#define demux_cipher_des_key2_1 0x2e52 /* width RMuint32 */
+#define demux_cipher_des_key2_2 0x2e53 /* width RMuint32 */
+#define demux_cipher_des_key3_1 0x2e54 /* width RMuint32 */
+#define demux_cipher_des_key3_2 0x2e55 /* width RMuint32 */
+#define demux_cipher_des_IV_1 0x2e56 /* width RMuint32 */
+#define demux_cipher_des_IV_2 0x2e57 /* width RMuint32 */
+#define demux_cipher_des_flags 0x2e58 /* width RMuint32 */
+#define demux_cipher_dvbcsa_key_lsb 0x2e5c /* width RMuint32 */
+#define demux_cipher_dvbcsa_key_msb 0x2e5d /* width RMuint32 */
+#define demux_cipher_dvbcsa_flags 0x2e5e /* width RMuint32 */
+#define demux_cipher_aes_key_1 0x2e60 /* width RMuint32 */
+#define demux_cipher_aes_key_2 0x2e61 /* width RMuint32 */
+#define demux_cipher_aes_key_3 0x2e62 /* width RMuint32 */
+#define demux_cipher_aes_key_4 0x2e63 /* width RMuint32 */
+#define demux_cipher_aes_key_5 0x2e64 /* width RMuint32 */
+#define demux_cipher_aes_key_6 0x2e65 /* width RMuint32 */
+#define demux_cipher_aes_key_7 0x2e66 /* width RMuint32 */
+#define demux_cipher_aes_key_8 0x2e67 /* width RMuint32 */
+#define demux_cipher_aes_flags 0x2e68 /* width RMuint32 */
+#define demux_cipher_aes_IV_1 0x2e69 /* width RMuint32 */
+#define demux_cipher_aes_IV_2 0x2e6a /* width RMuint32 */
+#define demux_cipher_aes_IV_3 0x2e6b /* width RMuint32 */
+#define demux_cipher_aes_IV_4 0x2e6c /* width RMuint32 */
+#define demux_cipher_aes_IV_5 0x2e6d /* width RMuint32 */
+#define demux_cipher_aes_IV_6 0x2e6e /* width RMuint32 */
+#define demux_cipher_aes_IV_7 0x2e6f /* width RMuint32 */
+#define demux_cipher_aes_IV_8 0x2e70 /* width RMuint32 */
+#define demux_cipher_dvd_cnt 0x2e78 /* width RMuint32 */
+#define demux_cipher_dvd_tklo 0x2e7a /* width RMuint32 */
+#define demux_cipher_dvd_tkhi 0x2e7b /* width RMuint32 */
+#define demux_cipher_dvd_state0 0x2e7c /* width RMuint32 */
+#define demux_cipher_dvd_state1 0x2e7d /* width RMuint32 */
+#define demux_cw_ram_multi2_syst_key 0x2a00 /* width RMuint32 */
+#define demux_cw_ram_multi2_data_key 0x2a80 /* width RMuint32 */
+#define demux_cw_ram_multi2_iv 0x2aa0 /* width RMuint32 */
+#define demux_cw_ram_rc4_key 0x2ac0 /* width RMuint32 */
+#define demux_cw_ram_aes_key 0x2b00 /* width RMuint32 */
+#define demux_cw_ram_aes_iv 0x2b08 /* width RMuint32 */
+#define demux_cw_ram_dvbcsa_key 0x2b60 /* width RMuint32 */
+#define demux_cw_ram_des_key1 0x2b80 /* width RMuint32 */
+#define demux_cw_ram_des_key2 0x2ba0 /* width RMuint32 */
+#define demux_cw_ram_des_key3 0x2bc0 /* width RMuint32 */
+#define demux_cw_ram_des_iv 0x2be0 /* width RMuint32 */
+#define demux_section_filter_start 0x3800 /* width RMuint32 */
+#define demux_channel_status 0x3e08 /* width RMuint32 */
+#define demux_channel_config_routing 0x3e09 /* width RMuint32 */
+#define demux_ts_frame_size 0x3e0a /* width RMuint32 */
+#define demux_pat0_pidentry 0x3cc0 /* width RMuint32 */
+#define demux_pat0_outputmask 0x3cc1 /* width RMuint32 */
+#define demux_cat0_pidentry 0x3cc2 /* width RMuint32 */
+#define demux_cat0_outputmask 0x3cc3 /* width RMuint32 */
+#define demux_mgt0_pidentry 0x3cc4 /* width RMuint32 */
+#define demux_mgt0_outputmask 0x3cc5 /* width RMuint32 */
+#define demux_pcr0_outputmask 0x3cc6 /* width RMuint32 */
+#define demux_pat1_pidentry 0x3cc8 /* width RMuint32 */
+#define demux_pat1_outputmask 0x3cc9 /* width RMuint32 */
+#define demux_cat1_pidentry 0x3cca /* width RMuint32 */
+#define demux_cat1_outputmask 0x3ccb /* width RMuint32 */
+#define demux_mgt1_pidentry 0x3ccc /* width RMuint32 */
+#define demux_mgt1_outputmask 0x3ccd /* width RMuint32 */
+#define demux_pcr1_outputmask 0x3cce /* width RMuint32 */
+#define demux_pat2_pidentry 0x3cd0 /* width RMuint32 */
+#define demux_pat2_outputmask 0x3cd1 /* width RMuint32 */
+#define demux_cat2_pidentry 0x3cd2 /* width RMuint32 */
+#define demux_cat2_outputmask 0x3cd3 /* width RMuint32 */
+#define demux_mgt2_pidentry 0x3cd4 /* width RMuint32 */
+#define demux_mgt2_outputmask 0x3cd5 /* width RMuint32 */
+#define demux_pcr2_outputmask 0x3cd6 /* width RMuint32 */
+#define demux_splice0_status 0x3ce0 /* width RMuint32 */
+#define demux_splice1_status 0x3ce1 /* width RMuint32 */
+#define demux_splice2_status 0x3ce2 /* width RMuint32 */
+#define demux_pid_bank 0x3d00 /* width RMuint32 */
+#define demux_spi_write_ptr0 0x1e08 /* width RMuint32 */
+#define demux_spi_write_ptr1 0x1e09 /* width RMuint32 */
+#define demux_spi_write_ptr2 0x1e0a /* width RMuint32 */
+#define demux_spi_write_ptr3 0x1e0b /* width RMuint32 */
+#define demux_spi_routing 0x1e0c /* width RMuint32 */
+#define demux_spi_clk_phase 0x1e0d /* width RMuint32 */
+#define demux_spi_sync_bytes 0x1e0e /* width RMuint32 */
+#define demux_idma_write_ptr 0x1e18 /* width RMuint32 */
+#define demux_idma_cnt 0x1e19 /* width RMuint32 */
+#define demux_odma_read_ptr 0x1e20 /* width RMuint32 */
+#define demux_odma_cnt 0x1e21 /* width RMuint32 */
+#define demux_odma_sc_stat 0x1e22 /* width RMuint32 */
+#define demux_odma_sc_match 0x1e23 /* width RMuint32 */
+#define demux_sbox_mode 0x1e28 /* width RMuint32 */
+#define demux_MISC_UNRESET_MASK 0xd800 /* width RMuint32 */
+#define demux_MISC_RESET_MASK 0xd8d8 /* width RMuint32 */
+#define demux_SP_init 0x7fe /* width RMuint32 */
+/* DemuxEngine registers done */
+
+/* Demux registers */
+/* Demux registers done */
+
+/* DemuxProgram registers */
+/* DemuxProgram registers done */
+
+/* MpegEngine registers */
+#define REG_BASE_mpeg_engine_0 0x00080000 /* width RMuint32 */
+#define MEM_BASE_mpeg_engine_0 0x00100000 /* width RMuint32 */
+#define PMEM_BASE_mpeg_engine_0 0x00100000 /* width RMuint32 */
+#define DMEM_BASE_mpeg_engine_0 0x00110000 /* width RMuint32 */
+#define REG_BASE_mpeg_engine_1 0x00090000 /* width RMuint32 */
+#define MEM_BASE_mpeg_engine_1 0x00120000 /* width RMuint32 */
+#define PMEM_BASE_mpeg_engine_1 0x00120000 /* width RMuint32 */
+#define DMEM_BASE_mpeg_engine_1 0x00130000 /* width RMuint32 */
+#define mpeg_mutex0 0x0fe0 /* width RMuint32 */
+#define mpeg_mutex1 0x0fe1 /* width RMuint32 */
+#define mpeg_mutex2 0x0fe2 /* width RMuint32 */
+#define mpeg_mutex3 0x0fe3 /* width RMuint32 */
+#define mpeg_mutex4 0x0fe4 /* width RMuint32 */
+#define mpeg_mutex5 0x0fe5 /* width RMuint32 */
+#define mpeg_mutex6 0x0fe6 /* width RMuint32 */
+#define mpeg_mutex7 0x0fe7 /* width RMuint32 */
+#define RBUS_offset 0x4000 /* width RMuint32 */
+#define mpeg_MBUSIF_w0_addlo 0xE80 /* width RMuint32 */
+#define mpeg_MBUSIF_w0_addhi 0xE81 /* width RMuint32 */
+#define mpeg_MBUSIF_w0_xcnt 0xE82 /* width RMuint32 */
+#define mpeg_MBUSIF_w0_ycnt 0xE83 /* width RMuint32 */
+#define mpeg_MBUSIF_w0_skiplo 0xE84 /* width RMuint32 */
+#define mpeg_MBUSIF_w0_skiphi 0xE85 /* width RMuint32 */
+#define mpeg_MBUSIF_w0_cmd 0xE86 /* width RMuint32 */
+#define mpeg_MBUSIF_w0_vbuf_width 0xE87 /* width RMuint32 */
+#define mpeg_MBUSIF_r0_addlo 0xE90 /* width RMuint32 */
+#define mpeg_MBUSIF_r0_addhi 0xE91 /* width RMuint32 */
+#define mpeg_MBUSIF_r0_xcnt 0xE92 /* width RMuint32 */
+#define mpeg_MBUSIF_r0_ycnt 0xE93 /* width RMuint32 */
+#define mpeg_MBUSIF_r0_skiplo 0xE94 /* width RMuint32 */
+#define mpeg_MBUSIF_r0_skiphi 0xE95 /* width RMuint32 */
+#define mpeg_MBUSIF_r0_cmd 0xE96 /* width RMuint32 */
+#define mpeg_MBUSIF_r0_vbuf_width 0xE97 /* width RMuint32 */
+#define mpeg_MBUSIF_r1_addlo 0xEA0 /* width RMuint32 */
+#define mpeg_MBUSIF_r1_addhi 0xEA1 /* width RMuint32 */
+#define mpeg_MBUSIF_r1_xcnt 0xEA2 /* width RMuint32 */
+#define mpeg_MBUSIF_r1_ycnt 0xEA3 /* width RMuint32 */
+#define mpeg_MBUSIF_r1_skiplo 0xEA4 /* width RMuint32 */
+#define mpeg_MBUSIF_r1_skiphi 0xEA5 /* width RMuint32 */
+#define mpeg_MBUSIF_r1_cmd 0xEA6 /* width RMuint32 */
+#define mpeg_MBUSIF_r1_vbuf_width 0xEA7 /* width RMuint32 */
+#define mpeg_MBUSIF_w1_addlo 0xEB0 /* width RMuint32 */
+#define mpeg_MBUSIF_w1_addhi 0xEB1 /* width RMuint32 */
+#define mpeg_MBUSIF_w1_xcnt 0xEB2 /* width RMuint32 */
+#define mpeg_MBUSIF_w1_ycnt 0xEB3 /* width RMuint32 */
+#define mpeg_MBUSIF_w1_skiplo 0xEB4 /* width RMuint32 */
+#define mpeg_MBUSIF_w1_skiphi 0xEB5 /* width RMuint32 */
+#define mpeg_MBUSIF_w1_cmd 0xEB6 /* width RMuint32 */
+#define mpeg_MBUSIF_w1_vbuf_width 0xEB7 /* width RMuint32 */
+#define mpeg_MBUSIF_r2_addlo 0xEC0 /* width RMuint32 */
+#define mpeg_MBUSIF_r2_addhi 0xEC1 /* width RMuint32 */
+#define mpeg_MBUSIF_r2_xcnt 0xEC2 /* width RMuint32 */
+#define mpeg_MBUSIF_r2_ycnt 0xEC3 /* width RMuint32 */
+#define mpeg_MBUSIF_r2_skiplo 0xEC4 /* width RMuint32 */
+#define mpeg_MBUSIF_r2_skiphi 0xEC5 /* width RMuint32 */
+#define mpeg_MBUSIF_r2_cmd 0xEC6 /* width RMuint32 */
+#define mpeg_MBUSIF_r2_vbuf_width 0xEC7 /* width RMuint32 */
+#define mpeg_GBUSIF_MAIN_WADD_LOW 0xFA0 /* width RMuint32 */
+#define mpeg_GBUSIF_MAIN_WADD_HIGH 0xFA1 /* width RMuint32 */
+#define mpeg_GBUSIF_MAIN_RADD_LOW 0xFA2 /* width RMuint32 */
+#define mpeg_GBUSIF_MAIN_RADD_HIGH 0xFA3 /* width RMuint32 */
+#define mpeg_GBUSIF_MAIN_BYTE 0xFA4 /* width RMuint32 */
+#define mpeg_GBUSIF_MAIN_WORD 0xFA5 /* width RMuint32 */
+#define mpeg_GBUSIF_MAIN_DWORD_LOW 0xFA6 /* width RMuint32 */
+#define mpeg_GBUSIF_MAIN_DWORD_HIGH 0xFA7 /* width RMuint32 */
+#define mpeg_GBUSIF_MAIN_STATUS 0xFA8 /* width RMuint32 */
+#define mpeg_GBUSIF_ISR_WADD_LOW 0xFB0 /* width RMuint32 */
+#define mpeg_GBUSIF_ISR_WADD_HIGH 0xFB1 /* width RMuint32 */
+#define mpeg_GBUSIF_ISR_RADD_LOW 0xFB2 /* width RMuint32 */
+#define mpeg_GBUSIF_ISR_RADD_HIGH 0xFB3 /* width RMuint32 */
+#define mpeg_GBUSIF_ISR_BYTE 0xFB4 /* width RMuint32 */
+#define mpeg_GBUSIF_ISR_WORD 0xFB5 /* width RMuint32 */
+#define mpeg_GBUSIF_ISR_DWORD_LOW 0xFB6 /* width RMuint32 */
+#define mpeg_GBUSIF_ISR_DWORD_HIGH 0xFB7 /* width RMuint32 */
+#define mpeg_GBUSIF_ISR_STATUS 0xFB8 /* width RMuint32 */
+#define mpeg_MISC_dr_mode 0xFF0 /* width RMuint32 */
+#define mpeg_MISC_dr_length 0xFF1 /* width RMuint32 */
+#define mpeg_MISC_dr_address 0xFF2 /* width RMuint32 */
+#define mpeg_MISC_sbox_mode 0xFF3 /* width RMuint32 */
+#define mpeg_MISC_dw_mode 0xFF4 /* width RMuint32 */
+#define mpeg_MISC_dw_length 0xFF5 /* width RMuint32 */
+#define mpeg_MISC_dw_address 0xFF6 /* width RMuint32 */
+#define mpeg_MISC_codec_type 0xFF7 /* width RMuint32 */
+#define mpeg_MISC_reset0 0xFF8 /* width RMuint32 */
+#define mpeg_MISC_reset1 0xFF9 /* width RMuint32 */
+#define mpeg_MISC_interrupt 0xFFA /* width RMuint32 */
+#define mpeg_MISC_timer_div 0xFFB /* width RMuint32 */
+#define mpeg_MISC_timer_count 0xFFC /* width RMuint32 */
+#define mpeg_MISC_sbox_read_ctrl 0xFFD /* width RMuint32 */
+#define mpeg_MISC_sbox_write_ctrl 0xFFE /* width RMuint32 */
+#define mpeg_MISC_reserved2 0xFFF /* width RMuint32 */
+#define mpeg_MISC_UNRESET_MASK 0x3500 /* width RMuint32 */
+#define mpeg_MISC_RESET_MASK 0x3535 /* width RMuint32 */
+#define mpeg_SP_init 0x7fe /* width RMuint32 */
+/* MpegEngine registers done */
+
+/* VideoDecoder registers */
+/* VideoDecoder registers done */
+
+/* AudioEngine registers */
+#define REG_BASE_audio_engine_0 0x000c0000 /* width RMuint32 */
+#define MEM_BASE_audio_engine_0 0x00180000 /* width RMuint32 */
+#define PMEM_BASE_audio_engine_0 0x00180000 /* width RMuint32 */
+#define DMEM_BASE_audio_engine_0 0x00190000 /* width RMuint32 */
+#define REG_BASE_audio_engine_1 0x000d0000 /* width RMuint32 */
+#define MEM_BASE_audio_engine_1 0x001a0000 /* width RMuint32 */
+#define PMEM_BASE_audio_engine_1 0x001a0000 /* width RMuint32 */
+#define DMEM_BASE_audio_engine_1 0x001b0000 /* width RMuint32 */
+#define audio_SO_L0_DATA 0x3e00 /* width RMuint32 */
+#define audio_SO_R0_DATA 0x3e01 /* width RMuint32 */
+#define audio_SO_L1_DATA 0x3e02 /* width RMuint32 */
+#define audio_SO_R1_DATA 0x3e03 /* width RMuint32 */
+#define audio_SO_L2_DATA 0x3e04 /* width RMuint32 */
+#define audio_SO_R2_DATA 0x3e05 /* width RMuint32 */
+#define audio_SO_LS_DATA 0x3e06 /* width RMuint32 */
+#define audio_SO_RS_DATA 0x3e07 /* width RMuint32 */
+#define audio_SO_CH_INTR 0x3e08 /* width RMuint32 */
+#define audio_SO_CH_CTRL 0x3e09 /* width RMuint32 */
+#define audio_SO_SPDIF_CH_STAT 0x3e0a /* width RMuint32 */
+#define audio_SO_AUDIO_CLK_DIV 0x3e0e /* width RMuint32 */
+#define audio_SI_L0_DATA 0x3e40 /* width RMuint32 */
+#define audio_SI_R0_DATA 0x3e41 /* width RMuint32 */
+#define audio_SI_STATUS 0x3e42 /* width RMuint32 */
+#define audio_SI_CONF 0x3e43 /* width RMuint32 */
+#define audio_SI_SPDIF_STATUS 0x3e44 /* width RMuint32 */
+#define audio_mutex0 0x3e90 /* width RMuint32 */
+#define audio_mutex1 0x3e91 /* width RMuint32 */
+#define audio_mutex2 0x3e92 /* width RMuint32 */
+#define audio_mutex3 0x3e93 /* width RMuint32 */
+#define audio_mutex4 0x3e94 /* width RMuint32 */
+#define audio_mutex5 0x3e95 /* width RMuint32 */
+#define audio_mutex6 0x3e96 /* width RMuint32 */
+#define audio_mutex7 0x3e97 /* width RMuint32 */
+#define audio_MBUSIF_w0_add 0x3ec0 /* width RMuint32 */
+#define audio_MBUSIF_w0_cnt 0x3ec1 /* width RMuint32 */
+#define audio_MBUSIF_w0_skip 0x3ec2 /* width RMuint32 */
+#define audio_MBUSIF_w0_cmd 0x3ec3 /* width RMuint32 */
+#define audio_MBUSIF_r0_add 0x3ed0 /* width RMuint32 */
+#define audio_MBUSIF_r0_cnt 0x3ed1 /* width RMuint32 */
+#define audio_MBUSIF_r0_skip 0x3ed2 /* width RMuint32 */
+#define audio_MBUSIF_r0_cmd 0x3ed3 /* width RMuint32 */
+#define audio_GBUSIF_MAIN_WADD 0x3ea0 /* width RMuint32 */
+#define audio_GBUSIF_MAIN_RADD 0x3ea1 /* width RMuint32 */
+#define audio_GBUSIF_MAIN_BYTE 0x3ea2 /* width RMuint32 */
+#define audio_GBUSIF_MAIN_WORD 0x3ea3 /* width RMuint32 */
+#define audio_GBUSIF_MAIN_DWORD 0x3ea4 /* width RMuint32 */
+#define audio_GBUSIF_MAIN_STATUS 0x3ea5 /* width RMuint32 */
+#define audio_GBUSIF_ISR_WADD 0x3ea8 /* width RMuint32 */
+#define audio_GBUSIF_ISR_RADD 0x3ea9 /* width RMuint32 */
+#define audio_GBUSIF_ISR_BYTE 0x3eaa /* width RMuint32 */
+#define audio_GBUSIF_ISR_WORD 0x3eab /* width RMuint32 */
+#define audio_GBUSIF_ISR_DWORD 0x3eac /* width RMuint32 */
+#define audio_GBUSIF_ISR_STATUS 0x3ead /* width RMuint32 */
+#define audio_MISC_dr_mode 0x3e80 /* width RMuint32 */
+#define audio_MISC_dr_length 0x3e81 /* width RMuint32 */
+#define audio_MISC_dr_address 0x3e82 /* width RMuint32 */
+#define audio_MISC_dw_mode 0x3e84 /* width RMuint32 */
+#define audio_MISC_dw_length 0x3e85 /* width RMuint32 */
+#define audio_MISC_dw_address 0x3e86 /* width RMuint32 */
+#define audio_MISC_reset0 0x3e88 /* width RMuint32 */
+#define audio_MISC_reset1 0x3e89 /* width RMuint32 */
+#define audio_MISC_interrupt 0x3e8A /* width RMuint32 */
+#define audio_MISC_timer_div 0x3e8B /* width RMuint32 */
+#define audio_MISC_timer_count 0x3e8C /* width RMuint32 */
+#define audio_MISC_UNRESET_MASK 0xc300 /* width RMuint32 */
+#define audio_MISC_RESET_MASK 0xc3c3 /* width RMuint32 */
+#define audio_SP_init 0x1ffe /* width RMuint32 */
+/* AudioEngine registers done */
+
+/* AudioDecoder registers */
+/* AudioDecoder registers done */
+
+/* AudioCapture registers */
+/* AudioCapture registers done */
+
+/* CRCDecoder registers */
+/* CRCDecoder registers done */
+
+/* XCRCDecoder registers */
+/* XCRCDecoder registers done */
+
+/* StreamCapture registers */
+/* StreamCapture registers done */
+
+/* RawDataTransfer registers */
+/* RawDataTransfer registers done */
+
+/* I2C registers */
+#define I2C_MASTER_CONFIG 0x80 /* width RMuint32 */
+#define I2C_MASTER_CLK_DIV 0x84 /* width RMuint32 */
+#define I2C_MASTER_DEV_ADDR 0x88 /* width RMuint32 */
+#define I2C_MASTER_ADDR 0x8c /* width RMuint32 */
+#define I2C_MASTER_DATA_OUT 0x90 /* width RMuint32 */
+#define I2C_MASTER_DATA_IN 0x94 /* width RMuint32 */
+#define I2C_MASTER_STATUS 0x98 /* width RMuint32 */
+#define I2C_MASTER_STARTXFER 0x9c /* width RMuint32 */
+#define I2C_MASTER_BYTE_CNT 0xa0 /* width RMuint32 */
+#define I2C_MASTER_INTEN 0xa4 /* width RMuint32 */
+#define I2C_MASTER_INT 0xa8 /* width RMuint32 */
+#define I2C_SLAVE_ADDR_REG 0xC0 /* width RMuint32 */
+#define I2C_SLAVE_DATAOUT 0xC4 /* width RMuint32 */
+#define I2C_SLAVE_DATAIN 0xC8 /* width RMuint32 */
+#define I2C_SLAVE_STATUS 0xCC /* width RMuint32 */
+#define I2C_SLAVE_INTEN 0xD0 /* width RMuint32 */
+#define I2C_SLAVE_INT 0xD4 /* width RMuint32 */
+#define I2C_SLAVE_BUS_HOLD 0xD8 /* width RMuint32 */
+/* I2C registers done */
+
+/* GFXEngine registers */
+#define VO_graph_acc_reset_bit 0x0a /* width RMuint32 */
+#define VO_graph_acc_reset_mask 0x00300000 /* width RMuint32 */
+#define VO_graph_acc_reset_run 0x00000000 /* width RMuint32 */
+#define VO_graph_acc_reset_path 0x00100000 /* width RMuint32 */
+#define VO_graph_acc_reset_time 0x00200000 /* width RMuint32 */
+#define VO_graph_acc_reset_conf 0x00300000 /* width RMuint32 */
+#define VO_graph_acc_X_format 0x0a00 /* width RMuint32 */
+#define VO_graph_acc_X_alpha 0x0a04 /* width RMuint32 */
+#define VO_graph_acc_X_keycolor 0x0a08 /* width RMuint32 */
+#define VO_graph_acc_Y_format 0x0a0c /* width RMuint32 */
+#define VO_graph_acc_Y_keycolor 0x0a10 /* width RMuint32 */
+#define VO_graph_acc_control 0x0a14 /* width RMuint32 */
+#define VO_graph_acc_font 0x0a18 /* width RMuint32 */
+#define VO_graph_acc_fill 0x0a18 /* width RMuint32 */
+#define VO_graph_acc_control2 0x0a1c /* width RMuint32 */
+#define VO_graph_acc_Z_format 0x0a20 /* width RMuint32 */
+#define VO_graph_acc_lut0 0xd000 /* width RMuint32 */
+#define VO_graph_acc_FILL 0 /* width RMuint32 */
+#define VO_graph_acc_BLEND 1 /* width RMuint32 */
+#define VO_graph_acc_MOVE 2 /* width RMuint32 */
+#define VO_graph_acc_REPLACE 3 /* width RMuint32 */
+#define VO_graph_acc_RASTER 4 /* width RMuint32 */
+#define VO_graph_acc_mode_control 0x0a80 /* width RMuint32 */
+#define VO_graph_acc_DRAM_read_address 0x0a84 /* width RMuint32 */
+#define VO_graph_acc_DRAM_write_address 0x0a88 /* width RMuint32 */
+#define VO_graph_acc_X_bounding_box 0x0a8c /* width RMuint32 */
+#define VO_graph_acc_Y_bounding_box 0x0a90 /* width RMuint32 */
+#define VO_graph_acc_scaling_and_contours 0x0a94 /* width RMuint32 */
+#define VO_graph_acc_matrix_coeffs_scale 0x0a98 /* width RMuint32 */
+#define VO_graph_acc_matrix_coeffs_cross_scale 0x0a9c /* width RMuint32 */
+#define VO_graph_acc_matrix_coeffs_offset 0x0aa0 /* width RMuint32 */
+#define VO_graph_acc_grd_color0 0x0a40 /* width RMuint32 */
+#define VO_graph_acc_grd_color1 0x0a44 /* width RMuint32 */
+#define VO_graph_acc_grd_scale_factor 0x0a48 /* width RMuint32 */
+#define VO_graph_acc_grd_vt_scale_init 0x0a4c /* width RMuint32 */
+#define VO_graph_acc_grd_init_square_dist 0x0a50 /* width RMuint32 */
+#define VO_graph_acc_grd_ext_radius 0x0a54 /* width RMuint32 */
+#define VO_graph_acc_grd_int_radius 0x0a58 /* width RMuint32 */
+#define VO_graph_acc_grd_center 0x0a5c /* width RMuint32 */
+#define VO_graph_acc_grd_control 0x0a60 /* width RMuint32 */
+/* GFXEngine registers done */
+
+/* MM registers */
+/* MM registers done */
+
+/* SpuDecoder registers */
+/* SpuDecoder registers done */
+
+/* ClosedCaptionDecoder registers */
+/* ClosedCaptionDecoder registers done */
+
+/* RTC registers */
+/* RTC registers done */
+
+/* Cipher registers */
+/* Cipher registers done */
+
+/* STC registers */
+/* STC registers done */
+
+/* PLL registers */
+/* PLL registers done */
+
+/* DemuxTask registers */
+/* DemuxTask registers done */
+
+/* DemuxOutput registers */
+/* DemuxOutput registers done */
+
+/* CCFifo registers */
+/* CCFifo registers done */
+
+/* DispVideoPlane registers */
+#define VO_VP_conf 0x0600 /* width RMuint32 */
+#define VO_VP_size 0x0604 /* width RMuint32 */
+/* DispVideoPlane registers done */
+
+/* DispHDSDConverter registers */
+#define VO_HDSD_reset_bit 0x0c /* width RMuint32 */
+#define VO_HDSD_read_reset_bit 0x0d /* width RMuint32 */
+#define VO_HDSD_config 0x1300 /* width RMuint32 */
+#define VO_HDSD_xscale 0x1304 /* width RMuint32 */
+#define VO_HDSD_yscale 0x1308 /* width RMuint32 */
+#define VO_HDSD_dump 0x130c /* width RMuint32 */
+/* DispHDSDConverter registers done */
+
+/* Sha1Sum registers */
+/* Sha1Sum registers done */
+
+/* XTask registers */
+/* XTask registers done */
+
+#endif /* __EMHWLIB_REGISTERS_TANGO2_H__ */
+
+/* End of generated file ../emhwlib_hal/include/tango2/emhwlib_registers_tango2.h */
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./hardware.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/hardware.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/hardware.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,8 @@
+#ifndef HARDWARE_H
+#define HARDWARE_H
+
+#include <linux/version.h>
+#include "tango2_regs.h"
+#include "tango2_irqs.h"
+
+#endif /* HARDWARE_H */
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./rmem86xxid.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/rmem86xxid.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./rmem86xxid.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/rmem86xxid.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,151 @@
+/*****************************************
+ Copyright © 2004-2005
+ Sigma Designs, Inc. All Rights Reserved
+ Proprietary and Confidential
+ *****************************************/
+/**
+  @file   rmem86xxid.h
+  @brief  
+
+  long description
+
+  @author Emmanuel Michon
+  @date   2004-09-22
+*/
+
+#ifndef __RMEM86XXID_H__
+#define __RMEM86XXID_H__
+
+#define EM86XX_CHIP	EM86XX_CHIPID_TANGO2
+#define EM86XX_REVISION	6
+
+/*
+  the main chip ids 
+  
+  tango3 is for asic development (should be tango\infty)
+
+  Usually, users do not set by hand, but thru `rmcflags' helper
+*/
+#define EM86XX_CHIPID_MAMBO      1000
+#define EM86XX_CHIPID_MAMBOLIGHT 2000
+#define EM86XX_CHIPID_TANGO      3000
+#define EM86XX_CHIPID_TANGOLIGHT 4000
+#define EM86XX_CHIPID_TANGO15    4500
+#define EM86XX_CHIPID_TANGO2     5000
+#define EM86XX_CHIPID_TANGO3    10000
+
+#if (EM86XX_CHIP==EM86XX_CHIPID_MAMBO)
+#define S_EM86XX_CHIPID "mambo"
+#elif (EM86XX_CHIP==EM86XX_CHIPID_MAMBOLIGHT)
+#define S_EM86XX_CHIPID "mambolight"
+#elif (EM86XX_CHIP==EM86XX_CHIPID_TANGOLIGHT)
+#define S_EM86XX_CHIPID "tangolight"
+#elif (EM86XX_CHIP==EM86XX_CHIPID_TANGO15)
+#define S_EM86XX_CHIPID "tango15"
+#elif (EM86XX_CHIP==EM86XX_CHIPID_TANGO2)
+#define S_EM86XX_CHIPID "tango2"
+#elif (EM86XX_CHIP==EM86XX_CHIPID_TANGO3)
+#define S_EM86XX_CHIPID "tango3"
+#else
+#error EM86XX_CHIP is not set
+#endif
+
+/* 
+  revisions...
+  
+  Referring to whatever is written at the surface of the BGA,
+  not the PCI revid / subid / etc. This detail is important for some chips
+  are ambiguous software wise.
+  
+  1: ES1
+  2: ES2
+  3: ES3
+  4: ES4 
+  65: revA
+  66: revB
+  67: revC
+  
+  No ID, but numbers. For a 8630ES2 for instance: build with
+  RMCFLAGS="... -DEM86XX_CHIP=EM86XX_CHIPID_TANGO2 -DEM86XX_REVISION=2 ..."
+
+  --------------------------------------------------------------------------
+  package writing          ES1  ES2  ES3  ES4      ES5 revA revB revC
+
+  EM86XX_REVISION            1    2    3    4        5  'A'  'B'  'C'
+
+  8600 `mambo' series                                     1    2    3
+  8620 `tangolight' series                              (a)  (b) 0x82
+  8630 `tango2' series (c)0x81 0x81 0x81 0x82  (e)0x82                     
+  8622 `tango15' series   0x81                      (d)0x81 0x82
+                             ^this is the PCI revID
+
+  (a) don't remember
+  (b) did this chip exist?
+  (c) 8630: FibbedES1 ES1 ES2 ES3 are the same chip
+  (d) 8622: ES1 and revA cannot be distinguished from revID. Software test impossible in practice
+  (e) 8630: ES4 and ES5 cannot be distinguished from revID. Software test with 0x6c900 bit12
+  --------------------------------------------------------------------------
+
+  Usually, users do not set by hand, but thru `rmcflags' helper
+*/
+#ifndef EM86XX_REVISION
+#error EM86XX_REVISION is not set
+#endif
+
+#if (EM86XX_REVISION==1)
+#define S_EM86XX_REVISION "ES1"
+#elif (EM86XX_REVISION==2)
+#define S_EM86XX_REVISION "ES2"
+#elif (EM86XX_REVISION==3)
+#define S_EM86XX_REVISION "ES3"
+#elif (EM86XX_REVISION==4)
+#define S_EM86XX_REVISION "ES4"
+#elif (EM86XX_REVISION==5)
+#define S_EM86XX_REVISION "ES5"
+#elif (EM86XX_REVISION==6)
+#define S_EM86XX_REVISION "ES6"
+#elif (EM86XX_REVISION==7)
+#define S_EM86XX_REVISION "ES7"
+#elif (EM86XX_REVISION=='A')
+#define S_EM86XX_REVISION "revA"
+#elif (EM86XX_REVISION=='B')
+#define S_EM86XX_REVISION "revB"
+#elif (EM86XX_REVISION=='C')
+#define S_EM86XX_REVISION "revC"
+#else
+#error complete revision strings
+#endif
+
+/* the compilation modes */
+#define EM86XX_MODEID_WITHHOST   1000
+#define EM86XX_MODEID_STANDALONE 2000
+
+/* the dsps */
+#define EM86XX_ENGINEID_MPEG0 10
+#define EM86XX_ENGINEID_MPEG1 11
+#define EM86XX_ENGINEID_AUDIO0 20
+#define EM86XX_ENGINEID_AUDIO1 21
+#define EM86XX_ENGINEID_DEMUX 30
+
+/* user does not have to set an engine id. This makes sense for mu only */
+#ifdef EM86XX_ENGINE
+#if (EM86XX_ENGINE==EM86XX_ENGINEID_MPEG0)
+#define SENG "mpeg0"
+#elif (EM86XX_ENGINE==EM86XX_ENGINEID_MPEG1)
+#define SENG "mpeg1"
+#elif (EM86XX_ENGINE==EM86XX_ENGINEID_AUDIO0)
+#define SENG "audio0"
+#elif (EM86XX_ENGINE==EM86XX_ENGINEID_AUDIO1)
+#define SENG "audio1"
+#elif (EM86XX_ENGINE==EM86XX_ENGINEID_DEMUX)
+#define SENG "demux"
+#else
+#endif // end of engine dependent stuff
+#endif
+
+/* the microcode debug mode */
+
+#define EM86XX_DEBUG_CHIP	1000
+#define EM86XX_DEBUG_SIMU	2000
+
+#endif // __RMEM86XXID_H__
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./spaces.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/spaces.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./spaces.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/spaces.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,33 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
+ * Copyright (C) 2000, 2002  Maciej W. Rozycki
+ * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_MACH_TANGO2_SPACES_H
+#define _ASM_MACH_TANGO2_SPACES_H
+
+#define PHYS_OFFSET		0x10000000UL
+
+#define CAC_BASE		0x80000000
+#define IO_BASE			0xa0000000
+#define UNCAC_BASE		0xb0000000
+#define MAP_BASE		0xc0000000
+
+/*
+ * This handles the memory map.
+ * We handle pages at KSEG0 for kernels with 32 bit address space.
+ */
+#define PAGE_OFFSET		0x90000000UL
+
+/*
+ * Memory above this physical address will be considered highmem.
+ */
+#ifndef HIGHMEM_START
+#define HIGHMEM_START		0x20000000UL
+#endif
+
+#endif /* __ASM_MACH_TANGO2_SPACES_H */
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_board.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_board.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_board.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_board.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,32 @@
+#ifndef TANGO2_BOARD_H_
+#define TANGO2_BOARD_H_
+
+/*
+ * board callbacks
+ */
+const char *board_get_name(void);
+
+void board_prom_init(void);
+
+void board_setup(void);
+
+int board_register_devices(void);
+
+void board_machine_restart(void);
+
+unsigned int board_get_dram_size(void);
+
+void board_reset_pci(void);
+
+/*
+ * exported API for board
+ */
+void tango2_cpu_reset(void);
+
+void tango2_reset_periphs(void);
+
+int tango2_ethernet_enabled(void);
+
+int tango2_bmide_enabled(void);
+
+#endif /* TANGO2_BOARD_H_ */
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_gbus.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_gbus.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_gbus.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_gbus.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,105 @@
+/*
+  Refer to bug #3644.
+
+  TLB-based implementation works on the ranges:
+  [0x00000000..0x20000000[ access thru kseg1
+  [0x20000000..0x2xxxxxxx (size  of dram1, a  parameter of ioremap())[
+  access thru tlb. Outside: unpredictable/oops.
+
+  Remap-based implementation does:
+  00xy b27b26..b0 to 101y(b27|x)b26..b0.
+  and works  everywhere excepted ranges:  [0x18000000..0x20000000[ and
+  [0x28000000..0xffffffff]
+
+  Test with
+  {
+	volatile int q=gbus_read_uint32(pGBus,0x1020212c); // correct
+	q=gbus_read_uint32(pGBus,0x1f20212c);              // incorrect
+	q=gbus_read_uint32(pGBus,0x2020212c);              // correct
+	q=gbus_read_uint32(pGBus,0x2720212c);              // correct
+	q=gbus_read_uint32(pGBus,0x2820212c);              // incorrect
+	q=gbus_read_uint32(pGBus,0x2f20212c);              // incorrect
+  }
+*/
+
+#ifndef __TANGO2_GBUS_H
+#define __TANGO2_GBUS_H
+
+#include "tango2_types.h"
+#include <asm/addrspace.h>
+
+struct gbus;
+#define pGBus ((struct gbus *)1)
+
+__asm__ (
+	"	.macro gbus_swizzle_addr res tmp addr			\n"
+	"	rotr	\\res, \\addr, 29				\n"
+	"	ins	\\res, \\res, 30, 1				\n"
+	"	or	\\res, 5					\n"
+	"	rotr	\\res, 3					\n"
+	"	.endm");
+
+
+/*
+ * we just want to set kseg1 bit, most of the time address is known at
+ * compile time, so this will usually be reduced to 2 instructions
+ */
+
+#define BUILD_GBUS_READ(size)						\
+static inline RMuint32 gbus_read_uint##size(struct gbus *pgbus,		\
+					    RMuint32 byte_address)	\
+{									\
+	if (__builtin_constant_p(byte_address)) {			\
+		if ((byte_address & 0x70000000) == 0x20000000) {	\
+			byte_address &= ~0x20000000;			\
+			byte_address |= 0x08000000;			\
+		}							\
+		return *((volatile RMuint##size *)KSEG1ADDR(byte_address)); \
+	} else {							\
+		RMuint32 res, tmp;					\
+									\
+		__asm__ __volatile(					\
+			"gbus_swizzle_addr\t%0 %1 %2\n"			\
+			: "=&r" (res), "=&r" (tmp) : "r" (byte_address)); \
+		return *((volatile RMuint##size *)res);			\
+	}								\
+}
+
+BUILD_GBUS_READ(8);
+BUILD_GBUS_READ(16);
+BUILD_GBUS_READ(32);
+
+#define BUILD_GBUS_WRITE(size)						\
+static inline void gbus_write_uint##size(struct gbus *pgbus,		\
+				     RMuint32 byte_address,		\
+				     RMuint##size data)			\
+{									\
+	if (__builtin_constant_p(byte_address)) {			\
+		if ((byte_address & 0x70000000) == 0x20000000) {	\
+			byte_address &= ~0x20000000;			\
+			byte_address |= 0x08000000;			\
+		}							\
+		*((volatile RMuint##size *)KSEG1ADDR(byte_address)) = data; \
+	} else {							\
+		RMuint32 res, tmp;					\
+									\
+		__asm__ __volatile(					\
+			"gbus_swizzle_addr\t%0 %1 %2\n"			\
+			: "=&r" (res), "=&r" (tmp) : "r" (byte_address)); \
+		*((volatile RMuint##size *)res) = data;			\
+	}								\
+}
+
+BUILD_GBUS_WRITE(8);
+BUILD_GBUS_WRITE(16);
+BUILD_GBUS_WRITE(32);
+
+
+#define gbus_readl(r)		gbus_read_uint32(pGBus, (r))
+#define gbus_writel(r, v)	gbus_write_uint32(pGBus, (r), (v))
+#define gbus_readw(r)		gbus_read_uint16(pGBus, (r))
+#define gbus_writew(r, v)	gbus_write_uint16(pGBus, (r), (v))
+#define gbus_readb(r)		gbus_read_uint8(pGBus, (r))
+#define gbus_writeb(r, v)	gbus_write_uint8(pGBus, (r), (v))
+
+#endif /* __TANGO2_GBUS_H */
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_gpio.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_gpio.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_gpio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_gpio.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,14 @@
+
+#ifndef TANGO2_GPIO_H_
+#define TANGO2_GPIO_H_
+
+#define GPIO_INPUT		0
+#define GPIO_OUTPUT		1
+
+int em86xx_gpio_read(int gpio);
+void em86xx_gpio_write(int gpio, int data);
+void em86xx_gpio_setdirection(int gpio, int dir);
+void em86xx_gpio_uart_mode(int uart, int mode);
+void em86xx_gpio_uart_dir(int uart, int dir);
+
+#endif /* TANGO2_GPIO_H_ */
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_hardware.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_hardware.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_hardware.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_hardware.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,16 @@
+
+#ifndef TANGO2_HARDWARE_H_
+#define TANGO2_HARDWARE_H_
+
+#define TANGO2_BASE_FREQUENCY		27000000
+
+#define TANGO2_FLASH_BASE		0x48000000
+#define TANGO2_FLASH_CS			2
+
+#define MEMORY_BASE_PCI_CONFIG		0x50000000UL  /* PCI configuration */
+#define MEMORY_BASE_PCI_IO		0x58000000UL  /* PCI I/O space */
+#define MEMORY_BASE_PCI_MEMORY		0x60000000UL  /* PCI Memory Base */
+
+#define PCIBIOS_MIN_MEM_EM86XX		(MEMORY_BASE_PCI_MEMORY + 0x10000000UL)
+
+#endif /* TANGO2_HARDWARE_H_ */
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_irqs.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_irqs.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_irqs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_irqs.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,26 @@
+
+#ifndef TANGO2_IRQS_H_
+#define TANGO2_IRQS_H_
+
+#include "emhwlib_registers_tango2.h"
+
+#define MIPS_CPU_IRQ_BASE	0
+
+#define IRQ_CONTROLLER_IRQ_BASE 8
+#define FIQ_CONTROLLER_IRQ_BASE 72
+#define IIQ_CONTROLLER_IRQ_BASE 136 // bit31 of iiq is linux irq 199
+
+#define IRQ_ENET	(LOG2_CPU_ETH_MAC_INT + IRQ_CONTROLLER_IRQ_BASE)
+#define IRQ_IDECTRL_IDE	(LOG2_CPU_IDE_INT + IRQ_CONTROLLER_IRQ_BASE)
+#define IRQ_IDECTRL_IDEDMA	(LOG2_CPU_DMAIDE_INT + IRQ_CONTROLLER_IRQ_BASE)
+#define IRQ_PCIFAULT	(LOG2_CPU_PCI_FAULT_INT + IRQ_CONTROLLER_IRQ_BASE)
+#define IRQ_PCIINTA	(LOG2_CPU_PCI_INTA + IRQ_CONTROLLER_IRQ_BASE)
+#define IRQ_PCIINTB	(LOG2_CPU_PCI_INTB + IRQ_CONTROLLER_IRQ_BASE)
+#define IRQ_IR		(LOG2_CPU_INFRARED_INT + IRQ_CONTROLLER_IRQ_BASE)
+#define IRQ_FIP		(LOG2_CPU_FRONTPANEL_INT + IRQ_CONTROLLER_IRQ_BASE)
+
+#define TANGO2_EHCI_IRQ	(IRQ_CONTROLLER_IRQ_BASE + LOG2_CPU_USB_EHCI_INT)
+#define TANGO2_OHCI_IRQ	(IRQ_CONTROLLER_IRQ_BASE + LOG2_CPU_USB_OHCI_INT)
+
+
+#endif /* TANGO2_IRQS_H_ */
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_mbus.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_mbus.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_mbus.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_mbus.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,28 @@
+
+#ifndef TANGO2_MBUS_H_
+#define TANGO2_MBUS_H_
+
+enum {
+	SBOX_MBUS_W0 = 0,
+	SBOX_MBUS_W1,
+	SBOX_PCIMASTER,
+	SBOX_PCISLAVE,
+	SBOX_UNUSED1,
+	SBOX_IDEFLASH,
+	SBOX_IDEDVD,
+	SBOX_UNUSED2,
+	SBOX_MAX = SBOX_UNUSED2,
+};
+
+typedef void (*mbus_irq_handler_t)(int irq, void *arg);
+
+int em86xx_mbus_init(void);
+int em86xx_mbus_alloc_dma(int sbox, int fromdev, unsigned long *pregbase,
+			  int *pirq);
+void em86xx_mbus_free_dma(unsigned long regbase, int sbox);
+int em86xx_mbus_setup_dma(unsigned int regbase, unsigned int addr,
+			  unsigned int count, mbus_irq_handler_t handler,
+			  void *arg);
+int em86xx_mbus_wait(unsigned int regbase, int sbox);
+
+#endif /* TANGO2_MBUS_H_ */
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_memcfg.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_memcfg.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_memcfg.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_memcfg.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,31 @@
+
+#ifndef TANGO2_MEMCFG_H_
+#define TANGO2_MEMCFG_H_
+
+#include <asm/mach-tango2/emhwlib_dram.h>
+
+static inline int is_valid_memcfg(memcfg_t *memcfg_ptr)
+{
+	unsigned int sum, i, *ptr;
+
+	if ((memcfg_ptr->signature) != MEMCFG_SIGNATURE)
+		return(0);
+	for (sum = i = 0, ptr = (unsigned int *)memcfg_ptr;
+		i < (sizeof(memcfg_t) / sizeof(unsigned int)); i++, ptr++)
+		sum += (*ptr);
+	return((sum == 0) ? 1 : 0);
+}
+
+static inline void gen_memcfg_checksum(memcfg_t *memcfg_ptr)
+{
+	unsigned int sum, i, *ptr;
+
+	memcfg_ptr->checksum = 0;
+	for (sum = i = 0, ptr = (unsigned int *)memcfg_ptr;
+		i < (sizeof(memcfg_t) / sizeof(unsigned int)); i++, ptr++)
+		sum += (*ptr);
+	memcfg_ptr->checksum = ~sum + 1;
+}
+
+#endif /* TANGO2_MEMCFG_H_ */
+
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_pci.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_pci.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_pci.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,68 @@
+
+#ifndef __TANGO2_PCI_H
+#define __TANGO2_PCI_H
+
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+#include <asm/mach-tango2/tango2_hardware.h>
+
+#define PCIEM86XX_ARBITER_LEVEL		0x00
+#define PCIEM86XX_ARBITER_GRANTTIMEOUT	0x10101010
+
+#define PCIEM86XX_IDSEL_MAX		0x05
+#define PCIEM86XX_IDSEL_BITS		0x03
+
+#define PCIEM86XX_OHCI_SLOT		9
+#define PCIEM86XX_EHCI_SLOT		10
+
+/*
+ * helpers to access host interface registers
+ */
+#define RD_HOST_REG32(r)	\
+		gbus_readl(REG_BASE_host_interface + (r))
+
+#define WR_HOST_REG32(r, v)	\
+		gbus_writel(REG_BASE_host_interface + (r), (v))
+
+#define RD_HOST_REG8(r)	\
+		gbus_readb(REG_BASE_host_interface + (r))
+
+#define WR_HOST_REG8(r, v)	\
+		gbus_writeb(REG_BASE_host_interface + (r), (v))
+
+
+/*
+ * read/write data  from/to the configuration space.  The  only way to
+ * know if there is a device is by checking that we did not generate a
+ * bus fault interrupt, so we need to mask them during the access.
+ */
+#define BUILD_TANGO2_CFG_ACCESS(pfx, __x)				\
+static inline int tango2_cfg_##pfx(void __iomem *addr, u32 *data)	\
+{									\
+	unsigned long flags, status;					\
+									\
+	local_irq_save(flags);						\
+									\
+	__x;								\
+	status = (RD_HOST_REG8(PCI_host_reg2 + 3) >> 1) & 0x3;		\
+	if (status) {							\
+		WR_HOST_REG8(PCI_host_reg2 + 3, 1);			\
+		WR_HOST_REG8(PCI_host_reg2 + 3, 0);			\
+		local_irq_restore(flags);				\
+		return 1;						\
+	}								\
+									\
+	local_irq_restore(flags);					\
+	return 0;							\
+}
+
+BUILD_TANGO2_CFG_ACCESS(read8, *data = readb(addr) & 0xff)
+BUILD_TANGO2_CFG_ACCESS(read16, *data = readw(addr) & 0xffff)
+BUILD_TANGO2_CFG_ACCESS(read32, *data = readl(addr))
+BUILD_TANGO2_CFG_ACCESS(write8, writeb(*data & 0xff, addr))
+BUILD_TANGO2_CFG_ACCESS(write16, writew(*data & 0xffff, addr))
+BUILD_TANGO2_CFG_ACCESS(write32, writel(*data, addr))
+
+#endif
+
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_regs.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_regs.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_regs.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,31 @@
+
+#ifndef TANGO2_REGS_H_
+#define TANGO2_REGS_H_
+
+#include "emhwlib_registers_tango2.h"
+
+#define CPU_uart0_gpio_dir		(CPU_UART0_base + CPU_UART_GPIODIR)
+#define CPU_uart0_gpio_data		(CPU_UART0_base + CPU_UART_GPIODATA)
+#define CPU_uart0_gpio_mode		(CPU_UART0_base + CPU_UART_GPIOMODE)
+
+#define CPU_uart1_gpio_dir		(CPU_UART1_base + CPU_UART_GPIODIR)
+#define CPU_uart1_gpio_data		(CPU_UART1_base + CPU_UART_GPIODATA)
+#define CPU_uart1_gpio_mode		(CPU_UART1_base + CPU_UART_GPIOMODE)
+
+#define MIF_add_offset			0x0
+#define MIF_cnt_offset			(MIF_W0_CNT - MIF_W0_ADD)
+#define MIF_add2_skip_offset		(MIF_W0_SKIP - MIF_W0_ADD)
+#define MIF_cmd_offset			(MIF_W0_CMD - MIF_W0_ADD)
+
+
+#define HOST_pb0_base			0x0000
+#define HOST_pb_base_cs(n)		(HOST_pb0_base + (0x0200 * (n)))
+
+#define PB_timing_slot(n)		(PB_timing0 + (0x04 * (n)))
+
+#define REG_BASE_host_interface_BMIDE	(REG_BASE_host_interface + \
+						IDECTRL_pri_cmdblock)
+
+
+#endif /* TANGO2_REGS_H_ */
+
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_types.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_types.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_types.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_types.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,11 @@
+
+#ifndef __TANGO2_TYPES_H
+#define __TANGO2_TYPES_H
+
+typedef unsigned long RMuint32;
+typedef unsigned short RMuint16;
+typedef unsigned char RMuint8;
+typedef char RMascii;
+typedef int RMstatus;
+
+#endif
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_usb.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_usb.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_usb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_usb.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,36 @@
+
+#ifndef __TANGO2_USB_H
+#define __TANGO2_USB_H
+
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+#include <asm/mach-tango2/tango2_regs.h>
+
+#define TANGO2_EHCI_BASE_ADDR		(REG_BASE_host_interface + 0x1400)
+#define TANGO2_OHCI_BASE_ADDR		(REG_BASE_host_interface + 0x1500)
+#define TANGO2_USB_CTL_STATUS_REG_BASE	(REG_BASE_host_interface + 0x1700)
+
+/*
+ * helpers to access USB registers
+ */
+#define RD_OHCI_REG32(r)	\
+		gbus_readl(TANGO2_OHCI_BASE_ADDR + (r))
+
+#define WR_OHCI_REG32(r, v)	\
+		gbus_writel(TANGO2_OHCI_BASE_ADDR + (r), (v))
+
+#define RD_USB_REG32(r)	\
+		gbus_readl(TANGO2_USB_CTL_STATUS_REG_BASE + (r))
+
+#define WR_USB_REG32(r, v)	\
+		gbus_writel(TANGO2_USB_CTL_STATUS_REG_BASE + (r), (v))
+
+#define RD_EHCI_REG32(r)	\
+		gbus_readl(TANGO2_EHCI_BASE_ADDR + (r))
+
+#define WR_EHCI_REG32(r, v)	\
+		gbus_writel(TANGO2_EHCI_BASE_ADDR + (r), (v))
+
+void tango2_reset_usb(void);
+
+#endif
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_xenv.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_xenv.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./tango2_xenv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/tango2_xenv.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,13 @@
+#ifndef TANGO2_XENV_H_
+#define TANGO2_XENV_H_
+
+extern int tango2_flash_get_info(int cs, uint32_t *size, uint32_t *part_count);
+extern int tango2_flash_get_parts(int cs, uint32_t *offsets, uint32_t *sizes);
+extern int tango2_ethernet_getmac(uint8_t *mac);
+extern unsigned int tango2_get_dramstuffing(void);
+extern int tango2_uart_enabled(int uart);
+extern int tango2_uart_baudrate(int uart);
+extern int tango2_fip_enabled(void);
+extern int tango2_ir_enabled(void);
+
+#endif
diff -Nruw linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./war.h linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/war.h
--- linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2./war.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/include/asm/mach-tango2/war.h	2010-03-18 18:28:48.522753830 +0100
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_TANGO2_WAR_H
+#define __ASM_MIPS_MACH_TANGO2_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR	0
+#define R4600_V1_HIT_CACHEOP_WAR	0
+#define R4600_V2_HIT_CACHEOP_WAR	0
+#define R5432_CP0_INTERRUPT_WAR		0
+#define BCM1250_M3_WAR			0
+#define SIBYTE_1956_WAR			0
+#define MIPS4K_ICACHE_REFILL_WAR	0
+#define MIPS_CACHE_SYNC_WAR		0
+#define TX49XX_ICACHE_INDEX_INV_WAR	0
+#define RM9000_CDEX_SMP_WAR		0
+#define ICACHE_REFILLS_WORKAROUND_WAR	0
+#define R10000_LLSC_WAR			0
+#define MIPS34K_MISSED_ITLB_WAR		0
+
+#endif /* __ASM_MIPS_MACH_BCM63XX_WAR_H */
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/arch/mips/pci/fixup-tango2.c	2010-03-18 18:28:48.572754811 +0100
@@ -0,0 +1,37 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/mach-tango2/tango2_pci.h>
+
+extern int tango2_pcidev_irq_map(int pci_idsel, int int_num);
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/* return xenv config */
+	return tango2_pcidev_irq_map(slot, pin);
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/arch/mips/pci/ops-tango2.c	2010-03-18 18:28:48.572754811 +0100
@@ -0,0 +1,130 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/mach-tango2/tango2_pci.h>
+
+/*
+ * remapped address to access config space from kernel
+ */
+void __iomem *tango2_pci_config_base;
+
+/*
+ * list of devices for which we allow configuration access
+ */
+int enabled_devices[PCIEM86XX_IDSEL_MAX];
+extern int tango2_pci_host_enabled(void);
+
+/*
+ * find cfg address to use for given bus/device/Address
+ */
+#define CFG_ADDR(bus,devfn,where)	\
+	(tango2_pci_config_base + (((bus) << 16) + ((devfn) << 8) + (where)))
+
+
+
+/*
+ * read/write callbacks for pci configuration memory access
+ */
+int tango2_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+			int where, int size, u32 *val)
+{
+	void __iomem *addr = CFG_ADDR(bus->number, devfn, where);
+	int ret, slot;
+
+	slot = PCI_SLOT(devfn);
+
+	/*
+	 * check that it is ok to use this slot
+	 */
+	if (!tango2_pci_host_enabled() ||
+	    !enabled_devices[slot] || slot >= PCIEM86XX_IDSEL_MAX)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * reject silly sizes
+	 */
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	switch (size) {
+	case 1:
+		ret = tango2_cfg_read8(addr, val);
+		break;
+
+	case 2:
+		ret = tango2_cfg_read16(addr, val);
+		break;
+
+	default:
+		ret = tango2_cfg_read32(addr, val);
+		break;
+	}
+
+	return ret;
+}
+
+int tango2_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+			 int where, int size, u32 val)
+{
+	void __iomem *addr = CFG_ADDR(bus->number, devfn, where);
+	int ret, slot;
+
+	slot = PCI_SLOT(devfn);
+
+	/*
+	 * check that it is ok to use this slot
+	 */
+	if (!tango2_pci_host_enabled() ||
+	    !enabled_devices[slot] || slot >= PCIEM86XX_IDSEL_MAX)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * reject silly sizes
+	 */
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	switch (size) {
+	case 1:
+		ret = tango2_cfg_write8(addr, &val);
+		break;
+
+	case 2:
+		ret = tango2_cfg_write16(addr, &val);
+		break;
+
+	default:
+		ret = tango2_cfg_write32(addr, &val);
+		break;
+	}
+
+	return ret;
+}
+
+struct pci_ops tango2_pci_ops = {
+	.read = tango2_pcibios_read,
+	.write = tango2_pcibios_write,
+};
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/arch/mips/pci/pci-tango2.c	2010-03-18 18:28:48.572754811 +0100
@@ -0,0 +1,321 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <asm/pci.h>
+
+#include <asm/mach-tango2/tango2_board.h>
+#include <asm/mach-tango2/tango2_pci.h>
+
+#define PFX	"tango2_pci: "
+
+/*
+ * computed in prom.c
+ */
+extern unsigned long __initdata em8xxx_kmem_start;
+extern unsigned long __initdata em8xxx_kmem_size;
+
+/*
+ * pci addresses used by dma subsystem
+ */
+unsigned long g_pcimem_busaddr[2];
+unsigned long g_pcimem_busaddr_end[2];
+unsigned long g_pcimem_physaddr[2];
+unsigned long g_pcimem_physaddr_end[2];
+
+
+/*
+ * We can't  touch iospace directly from  kseg1, we need  to remap it.
+ * No  need to  remap too  much space,  only 256  bytes per  device is
+ * allowed, so 64k should be more than enough.
+ */
+#define MEMORY_SIZE_PCI_IO			(64 * 1024)
+
+static struct resource tango2_pci_io_resource = {
+	.name   = "tango2 pci IO space",
+	.start  = MEMORY_BASE_PCI_IO,
+	.end    = MEMORY_BASE_PCI_IO + MEMORY_SIZE_PCI_IO - 1,
+	.flags  = IORESOURCE_IO
+};
+
+/*
+ * give 256MB for PCI memory space
+ */
+static struct resource tango2_pci_mem_resource = {
+	.name   = "tango2 pci memory space",
+	.start  = MEMORY_BASE_PCI_MEMORY,
+	.end    = MEMORY_BASE_PCI_MEMORY + 0xfffffff,
+	.flags  = IORESOURCE_MEM
+};
+
+
+/*
+ * Need to  remap config  space to access  it from kernel.   Note that
+ * remap size is just enough for PCIEM86XX_IDSEL_MAX devices on 1 bus.
+ */
+#define MEMORY_SIZE_PCI_CONFIG	(PCIEM86XX_IDSEL_MAX * (1 << 11))
+
+/*
+ * in ops-tango2.c
+ */
+extern void __iomem *tango2_pci_config_base;
+extern struct pci_ops tango2_pci_ops;
+extern int enabled_devices[PCIEM86XX_IDSEL_MAX];
+
+struct pci_controller tango2_controller = {
+	.pci_ops	= &tango2_pci_ops,
+	.io_resource    = &tango2_pci_io_resource,
+	.mem_resource   = &tango2_pci_mem_resource,
+
+	/*
+	 * gbus  addresses are  not the  same as  pci  addresses, tell
+	 * Linux about this so it can adjust resource addresses.
+	 */
+	.mem_offset	= MEMORY_BASE_PCI_MEMORY,
+	.io_offset	= MEMORY_BASE_PCI_CONFIG,
+};
+
+/*
+ * helpers to access host interface registers
+ */
+#define RD_HOST_REG32(r)	\
+		gbus_readl(REG_BASE_host_interface + (r))
+
+#define WR_HOST_REG32(r, v)	\
+		gbus_writel(REG_BASE_host_interface + (r), (v))
+
+#define RD_HOST_REG8(r)	\
+		gbus_readb(REG_BASE_host_interface + (r))
+
+#define WR_HOST_REG8(r, v)	\
+		gbus_writeb(REG_BASE_host_interface + (r), (v))
+
+
+/*
+ * This is the  interrupt handler for bus fault  interrupt. Just clear
+ * it and warn user
+ */
+static irqreturn_t pci_busfault_intr(int irq, void *devinfo)
+{
+	static const char *reasons[] = {
+		"OK", "Master Abort", "Retry timer expired", "Unknown" };
+	static int faultcount = 0;
+	unsigned int data;
+
+	data = (RD_HOST_REG8(PCI_host_reg2 + 3) >> 1) & 3;
+	WR_HOST_REG8(PCI_host_reg2 + 3, 1);
+	WR_HOST_REG8(PCI_host_reg2 + 3, 0);
+
+	/* don't flood */
+	if (printk_ratelimit())
+		printk(KERN_ERR PFX "PCI bus fault (count %d): %s\n",
+		       ++faultcount, reasons[data]);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * platform initialization code
+ */
+extern int tango2_pci_host_enabled(void);
+extern int tango2_pcidev_enabled(int idsel);
+
+static int __init tango2_pci_init(void)
+{
+	void __iomem *pci_io_base;
+	unsigned long memsize, regsize, membase;
+	u32 data;
+	int i;
+
+	/* don't do anything if pci support is not enabled in xenv */
+	if (!tango2_pci_host_enabled()) {
+		printk(KERN_NOTICE PFX "pci host support disabled\n");
+		goto register_controller;
+	}
+
+	board_reset_pci();
+
+	printk(KERN_INFO PFX "Initializing SMP863x PCI host controller\n");
+
+	/*
+	 * Enable pci host support
+	 */
+	WR_HOST_REG32(PCI_chip_is_host, 1);
+
+	/*
+	 * HOST_REG1 :
+	 * [31:16] : # of PCI retry cycle = 0xffff (default = 0xff)
+	 * [8] : host Super Request = 0
+	 * [3:0] arbitration level = 0x00 (Level 1)
+	 */
+	WR_HOST_REG32(PCI_host_reg1, 0xffff0000 | PCIEM86XX_ARBITER_LEVEL);
+
+	/*
+	 * PCI_CTRL1 :
+	 * [17] : enable "Memory Read Multiple" and "Memory Read Line"
+	 * [16] [7:0] : enable "prefetch" for PCI slave regions 2..7
+	 * [17] : Always enabled
+	 * [18] : additional bit for Tango. Long PCI memory read burst
+	 */
+	WR_HOST_REG32(PCI_pcictrl_reg1, 0x00030000);
+
+	/*
+	 * PCI_CTRL2 :
+	 * [18] : fast back-to-back capable = 0 (default)
+	 * [17] : read FIFO level = 1 (8 level deep, default)
+	 * [16] : discard timer enable = 1 (default)
+	 * [15:8] : subs latency = 0x06 (default = 0x08)
+	 * [7:0] : initial latency = 0x0d (default = 0x0b)
+	 */
+	WR_HOST_REG32(PCI_pcictrl_reg2, 0x0003060d);
+
+	/*
+	 * PCI_CTRL3 :
+	 * [16] : slave abort clear = 0
+	 * [10:8] : abort interrupt enable = 0 (default)
+	 * [2:0] : abort status = 0
+	 */
+	WR_HOST_REG32(PCI_pcictrl_reg3, 0);
+
+	/* clear any pending PCI bus fault */
+	if ((RD_HOST_REG8(PCI_host_reg2 + 3) >> 1) & 0x3) {
+		WR_HOST_REG8(PCI_host_reg2 + 3, 1);
+		WR_HOST_REG8(PCI_host_reg2 + 3, 0);
+	}
+
+	/* Setting pci_configuration_vld */
+	WR_HOST_REG8(PCI_host_reg2 + 2, 1);
+
+	/* grant timeout */
+	WR_HOST_REG32(PCI_host_reg3, PCIEM86XX_ARBITER_GRANTTIMEOUT);
+	WR_HOST_REG32(PCI_host_reg5,
+		      PCIEM86XX_ARBITER_GRANTTIMEOUT & 0x000000ff);
+
+	/* initialize arbiter */
+	WR_HOST_REG32(PCI_host_reg4, 0);
+
+
+	/*
+	 * remap iorange and give port base to linux.
+	 */
+	pci_io_base = ioremap(MEMORY_BASE_PCI_IO, MEMORY_SIZE_PCI_IO);
+	set_io_port_base((unsigned long)pci_io_base - MEMORY_BASE_PCI_IO);
+
+	printk(KERN_INFO PFX
+	       "Remapped PCI I/O space 0x%08lx to 0x%p, size %u kB\n",
+	       MEMORY_BASE_PCI_IO, pci_io_base, MEMORY_SIZE_PCI_IO / 1024);
+
+	/*
+	 * remap configuration space also
+	 */
+	tango2_pci_config_base = ioremap(MEMORY_BASE_PCI_CONFIG,
+					 MEMORY_SIZE_PCI_CONFIG);
+
+	printk(KERN_INFO PFX
+	       "Remapped PCI config space 0x%08lx to 0x%p, size %u kB\n",
+	       MEMORY_BASE_PCI_CONFIG, tango2_pci_config_base,
+	       MEMORY_SIZE_PCI_CONFIG / 1024);
+
+	memset(&enabled_devices, 0, sizeof (enabled_devices));
+	for (i = 1; i < PCIEM86XX_IDSEL_MAX; i++) {
+		if (tango2_pcidev_enabled(i)) {
+			enabled_devices[i] = 1;
+		} else {
+			printk(KERN_INFO PFX "device %d disabled\n", i);
+		}
+	}
+
+	/*
+	 * check that we can probe the EM8XXX at id 0
+	 */
+	if (tango2_cfg_read32(tango2_pci_config_base, &data)) {
+		printk(KERN_ERR PFX
+		       "Can't initialize EM86XX as a PCI slave\n");
+		return 1;
+	}
+
+	/*
+	 * configure it as a PCI slave
+	 *
+	 * set PCI memory size to maximum, so the PCI memory will cover the
+	 * whole memory if the total DRAM size is smaller than 96MB.
+	 * maximum = 128MB => 16MB per region => DMA memory = 16 * 6 = 96MB
+	 * But the current code doesn't care 2nd DRAM controller.
+	 */
+	WR_HOST_REG8(PCI_REG3, 0x7);
+
+	memsize = RD_HOST_REG32(PCI_REG3) & 0x07;
+	memsize = 1 << memsize;
+
+	/* get memory size in bytes / 8 */
+	regsize = (memsize << 20) >> 3;
+
+	/* pci command */
+	__raw_writew(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER,
+		     (void *)(tango2_pci_config_base + PCI_COMMAND));
+
+	/* base address 0 */
+	g_pcimem_busaddr[0] = PCIBIOS_MIN_MEM_EM86XX - MEMORY_BASE_PCI_MEMORY;
+	__raw_writel(g_pcimem_busaddr[0],
+		     (void *)(tango2_pci_config_base + PCI_BASE_ADDRESS_0));
+
+	printk(KERN_INFO PFX "Configured SMP863x as PCI slave with %ldMB "
+	       "PCI memory\n", memsize);
+
+	printk(KERN_INFO PFX "Region size is %ldKB\n", regsize >> 10);
+
+	g_pcimem_physaddr[0] = MEM_BASE_dram_controller_0;
+	g_pcimem_busaddr[0] += regsize;
+	membase = g_pcimem_physaddr[0];
+
+	/*
+	 * PCI slave access
+	 * region 0 (R) : Configuration area
+	 * region 1 - 7: mapped 96MB in DRAM0
+	 */
+	g_pcimem_physaddr_end[0] = g_pcimem_physaddr[0] + 7 * regsize;
+	g_pcimem_busaddr_end[0] = g_pcimem_busaddr[0] + 7 * regsize;
+	for (i = 1; i < 8; ++i) {
+		WR_HOST_REG32(PCI_REGION_0_BASE + (i * 4), membase);
+		membase += regsize;
+	}
+
+	printk(KERN_INFO PFX "bus 0x%08lx-0x%08lx <=> DRAM 0x%08lx-0x%08lx\n",
+	       g_pcimem_busaddr[0], g_pcimem_busaddr_end[0],
+	       g_pcimem_physaddr[0], g_pcimem_physaddr_end[0]);
+
+	/*
+	 * register the PCI bus fault interrupt
+	 */
+	if (request_irq(IRQ_PCIFAULT, pci_busfault_intr,
+			IRQF_DISABLED, "tango2_pci_fault", NULL)) {
+		printk(KERN_ERR PFX "unable to register bus fault irq\n");
+		return 1;
+	}
+
+register_controller:
+	/* finally register pci controller */
+	register_pci_controller(&tango2_controller);
+
+	return 0;
+}
+
+arch_initcall(tango2_pci_init);
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./boards/board-fbx5b.c linux-2.6.31.7-fbx/arch/mips/tango2/boards/board-fbx5b.c
--- linux-2.6.31.7-fbx/arch/mips/tango2./boards/board-fbx5b.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/boards/board-fbx5b.c	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,482 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/fbxmtd.h>
+
+#include <asm/mach-tango2/emhwlib_lram.h>
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_hardware.h>
+#include <asm/mach-tango2/tango2_xenv.h>
+#include <asm/mach-tango2/tango2_board.h>
+#include <asm/mach-tango2/tango2_gpio.h>
+#include <asm/mach-tango2/board-fbx5b.h>
+#include <asm/mach-tango2/devices.h>
+
+#define PFX	"board-fbx5b: "
+
+/*
+ * board id
+ */
+unsigned int fbx_board_id = 0;
+EXPORT_SYMBOL(fbx_board_id);
+
+char zboot_version_str[128] = { 0 };
+EXPORT_SYMBOL(zboot_version_str);
+
+
+/*
+ * fbxserialinfo stuff.
+ */
+#include <linux/fbxserial.h>
+
+static struct fbx_serial fbxserial;
+static unsigned int fbxserial_ok = 0;
+
+const struct fbx_serial *arch_get_fbxserial(void)
+{
+	/* make sure we don't return  junk in case initcall are messed
+	 * up */
+	if (!fbxserial_ok)
+		return NULL;
+	return &fbxserial;
+}
+
+EXPORT_SYMBOL(arch_get_fbxserial);
+
+const char *board_get_name(void)
+{
+	switch (fbx_board_id) {
+	case E_FBXBOARDID_FBX5B1:
+		return "fbx5b";
+	case E_FBXBOARDID_FBX5B2_QIMONDA:
+		return "fbx5b2_quimonda";
+	case E_FBXBOARDID_FBX5B2_NANYA:
+		return "fbx5b2_nanya";
+	case E_FBXBOARDID_FBX5B2_SAMSUNG:
+		return "fbx5b2_samsung";
+	case E_FBXBOARDID_FBX5B2_ELPIDA:
+		return "fbx5b2_elpida";
+	case E_FBXBOARDID_FBXO1B:
+		return "fbxo1b";
+	default:
+		return "unknown";
+	}
+}
+
+unsigned int board_get_dram_size(void)
+{
+	return 40 * 1024 * 1024;
+}
+
+void board_machine_restart(void)
+{
+	tango2_reset_periphs();
+
+	/* try to reboot using gpio */
+	printk(KERN_NOTICE PFX "Rebooting via board reset gpio ");
+	if (fbx_board_id == E_FBXBOARDID_FBX5B1) {
+		/* fbx5b1 */
+		printk("(fbx5b1)...\n");
+		em86xx_gpio_write(GPIO_BOARD_RESET, 1);
+		mdelay(10);
+		em86xx_gpio_setdirection(GPIO_BOARD_RESET, GPIO_OUTPUT);
+		mdelay(10);
+		em86xx_gpio_write(GPIO_BOARD_RESET, 0);
+
+	} else if (fbx_board_id >= E_FBXBOARDID_FBX5B2_FIRST &&
+		   fbx_board_id <= E_FBXBOARDID_FBX5B2_LAST) {
+		/* fbx5b2 */
+		printk("(fbx5b2)...\n");
+		em86xx_gpio_write(GPIO_BOARD_RESET_2, 1);
+		mdelay(10);
+		em86xx_gpio_setdirection(GPIO_BOARD_RESET_2, GPIO_OUTPUT);
+		mdelay(10);
+		em86xx_gpio_write(GPIO_BOARD_RESET_2, 1);
+	} else if (fbx_board_id == E_FBXBOARDID_FBXO1B) {
+		/* fbxo1_b */
+		printk("(fbxo1_b)...\n");
+		em86xx_gpio_write(GPIO_BOARD_RESET_2, 1);
+		em86xx_gpio_write(GPIO_BOARD_RESET_3, 1);
+		mdelay(10);
+		em86xx_gpio_setdirection(GPIO_BOARD_RESET_3, GPIO_OUTPUT);
+		em86xx_gpio_setdirection(GPIO_BOARD_RESET_3, GPIO_OUTPUT);
+		mdelay(10);
+		em86xx_gpio_write(GPIO_BOARD_RESET_2, 1);
+		em86xx_gpio_write(GPIO_BOARD_RESET_3, 1);
+	}
+	mdelay(3000);
+
+	/* fallthrough in case it did not work */
+	printk(KERN_WARNING PFX "failed! revert to xrpc\n");
+	tango2_cpu_reset();
+}
+
+void __init board_prom_init(void)
+{
+	/* read board id */
+	fbx_board_id = em86xx_gpio_read(GPIO_IDCARD0) |
+		em86xx_gpio_read(GPIO_IDCARD1) << 1 |
+		em86xx_gpio_read(GPIO_IDCARD2) << 2 |
+		em86xx_gpio_read(GPIO_IDCARD3) << 3;
+	printk(KERN_INFO PFX "board id: 0x%x\n", fbx_board_id);
+
+}
+
+void __init board_setup(void)
+{
+	/* fetch zboot version in lram */
+	memcpy(zboot_version_str,
+	       (void *)KSEG1ADDR(REG_BASE_cpu_block + LR_STACKTOP - 132), 128);
+	zboot_version_str[127] = 0;
+
+	/* small sanity check */
+	if (strncmp(zboot_version_str, "ZBOOT", 5))
+		strcpy(zboot_version_str, "UNKNOWN");
+
+	printk(KERN_INFO PFX "zboot version: %s\n", zboot_version_str);
+
+	em86xx_gpio_write(GPIO_USB_ENABLE, 1);
+
+}
+
+static int __init fetch_fbxserial(void)
+{
+	void __iomem *data;
+
+	data = ioremap(TANGO2_FLASH_BASE + TANGO2_FBXSERIAL_OFFSET, 2 * 1024);
+	if (data == NULL) {
+		printk(KERN_ERR PFX "unable to ioremap serial data\n");
+		return 1;
+	}
+
+	if (fbxserialinfo_read(data, &fbxserial)) {
+		/* use another default mac on fbxo1_b */
+		if (fbx_board_id == E_FBXBOARDID_FBXO1B) {
+			memcpy(fbxserial.mac_addr_base,
+			       "\x00\x07\xCB\x00\x00\xFC", 6);
+		}
+	}
+
+	fbxserial_ok = 1;
+	iounmap(data);
+	return 0;
+}
+
+arch_initcall(fetch_fbxserial);
+
+/*
+ * partition table for fbx5b1 & fbx5b2
+ */
+static struct fbxmtd_platform_part fbx5bx_parts[] = {
+	{
+		.name	= "all",
+		.flags	= FBXMTD_PART_MAP_ALL,
+	},
+	{
+		.name	= "xenv",
+	},
+	{
+		.name	= "zboot",
+	},
+	{
+		.name	= "cfe",
+	},
+	{
+		.name	= "serial",
+	},
+	{
+		.name	= "bank0",
+		.flags	= FBXMTD_PART_HAS_FS,
+	},
+	{
+		.name	= "nvram",
+		.flags	= FBXMTD_PART_RW,
+	},
+	{
+		.name	= "bank1",
+		.flags	= FBXMTD_PART_HAS_FS | FBXMTD_PART_RW,
+	},
+};
+
+/*
+ * partition table for fbxo1b
+ */
+static struct fbxmtd_platform_part fbxo1b_parts[] = {
+	{
+		.name	= "all",
+		.flags	= FBXMTD_PART_MAP_ALL,
+	},
+	{
+		.name	= "xenv",
+	},
+	{
+		.name	= "zboot",
+	},
+	{
+		.name	= "cfe",
+	},
+	{
+		.name	= "serial",
+	},
+	{
+		.name	= "bank0",
+		.flags	= FBXMTD_PART_HAS_FS,
+	},
+	{
+		.name	= "nvram",
+		.flags	= FBXMTD_PART_RW,
+	},
+	{
+		.name	= "bank1",
+		.flags	= FBXMTD_PART_HAS_FS | FBXMTD_PART_RW,
+	},
+	{
+		.name	= "uboot",
+	},
+};
+
+/*
+ * known partition infos for freebox boards
+ */
+static struct fbxboard_part_info {
+	unsigned int part_count;
+	int bank1_offset;
+	struct fbxmtd_platform_part *parts;
+} fbxboard_part_infos[] __initdata = {
+	[E_FBXBOARDID_FBX5B1]		= { 7, 6, fbx5bx_parts },
+	[E_FBXBOARDID_FBX5B2_QIMONDA]	= { 7, 6, fbx5bx_parts },
+	[E_FBXBOARDID_FBX5B2_NANYA]	= { 7, 6, fbx5bx_parts },
+	[E_FBXBOARDID_FBX5B2_SAMSUNG]	= { 7, 6, fbx5bx_parts },
+	[E_FBXBOARDID_FBX5B2_ELPIDA]	= { 7, 6, fbx5bx_parts },
+	[E_FBXBOARDID_FBXO1B]		= { 8, 6, fbxo1b_parts },
+};
+
+/*
+ * flash mapping device
+ */
+static struct fbxmtd_platform_data tango2_mtd_data = {
+	.name		= "flash0",
+	.base		= TANGO2_FLASH_BASE,
+	.width		= 2,
+	.parts		= NULL, /* computed at runtime */
+	.num_parts	= 0, /* computed at runtime */
+};
+
+static struct platform_device tango2_mtd_device = {
+	.name	= "fbxmtd_map_drv_fbx",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &tango2_mtd_data,
+	},
+};
+
+/*
+ * failsafe partition table in case we have no information about
+ * current layout
+ */
+static struct fbxmtd_platform_part tango2_default_parts[FBXMTD_MAX_PART] = {
+	{
+		.name	= "all",
+		.flags	= FBXMTD_PART_MAP_ALL,
+	},
+	/* let remaining names to NULL, fbxmtd will assign name
+	 * itself */
+};
+
+/*
+ * read xenv partition layout and create fbxmtd mapping with the right
+ * partition offset/size.
+ *
+ * on  freebox boards,  try  to identify  partition  layout to  assign
+ * correct names to them.
+ */
+static int __init fbx5b_fbxmtd_layout_init(void)
+{
+	struct fbxmtd_platform_part *parts;
+	uint32_t offsets[FBXMTD_MAX_PART];
+	uint32_t sizes[FBXMTD_MAX_PART];
+	uint32_t flash_size;
+	uint32_t part_count;
+	int i;
+
+	printk(KERN_INFO PFX "loading partition table from xenv.\n");
+
+	if (tango2_flash_get_info(TANGO2_FLASH_CS, &flash_size,
+				  &part_count) != 0) {
+		printk(KERN_ERR PFX "unable to get flash "
+		       "size/partitioncount from xenv.\n");
+		return -ENODEV;
+	}
+	printk(KERN_INFO PFX "xenv flash size: %uM; partition count: %u\n",
+	       flash_size >> 20, part_count);
+
+	if (part_count > FBXMTD_MAX_PART) {
+		printk("two many partitions: %d\n", part_count);
+		return -ENODEV;
+	}
+
+	if (tango2_flash_get_parts(TANGO2_FLASH_CS, offsets, sizes)) {
+		printk("unable to get partition table from xenv.\n");
+		return -ENODEV;
+	}
+
+	parts = tango2_default_parts;
+
+	/* see  if  we  match  expected partition  table  for  current
+	 * freebox board */
+	if (fbxboard_part_infos[fbx_board_id].part_count == part_count) {
+		struct fbxboard_part_info *pinfo;
+
+		pinfo = &fbxboard_part_infos[fbx_board_id];
+
+		/* use correct partition names */
+		parts = pinfo->parts;
+
+#ifndef CONFIG_FBX5B_FBXMTD_LAYOUT_READ_BANK1_TAG
+		printk(KERN_INFO PFX "not reading BANK1 imagetag.\n");
+		parts[pinfo->bank1_offset].flags |= FBXMTD_PART_IGNORE_TAG;
+#endif
+
+#ifdef CONFIG_FBX5B_FBXMTD_LAYOUT_NOCRC
+		printk(KERN_INFO PFX "disabling crc check on partitions: ");
+		for (i = 0; i < part_count; ++i) {
+			if (parts[i].flags & FBXMTD_PART_HAS_FS) {
+				parts[i].flags |= FBXMTD_PART_NOCRC;
+				printk("%s ", parts[i].name);
+			}
+		}
+		printk("\n");
+#endif
+	} else {
+		struct fbxboard_part_info *pinfo;
+
+		pinfo = &fbxboard_part_infos[fbx_board_id];
+		printk(KERN_WARNING PFX "partition count mismatch for "
+		       "board id %d, expected %d but got %d, using default\n",
+		       fbx_board_id, pinfo->part_count, part_count);
+	}
+
+	/*
+	 * fill partition size/offset from xenv data
+	 */
+	for (i = 1; i < part_count + 1; i++) {
+		parts[i].offset = offsets[i - 1];
+		parts[i].size = sizes[i - 1];
+	}
+
+#ifdef CONFIG_FBX5B_FBXMTD_LAYOUT_ALL_RW
+	printk(KERN_INFO PFX "making all partitions read/write.\n");
+	for (i = 0; i < part_count + 1; ++i)
+		parts[i].flags |= FBXMTD_PART_RW;
+#endif
+
+	tango2_mtd_data.parts = parts;
+	tango2_mtd_data.num_parts = part_count + 1;
+	platform_device_register(&tango2_mtd_device);
+
+	return 0;
+}
+
+/*
+ * tango2_ide platform data
+ */
+static struct tango2_ide_platform_data tango2_ide_pd;
+
+static struct platform_device tango2_ide_device = {
+	.name	= "tango2_ide",
+	.dev	= {
+		.platform_data = &tango2_ide_pd,
+	},
+};
+
+static void fbx_reset_ide(void)
+{
+	printk(KERN_NOTICE PFX "Resetting freebox IDE...\n");
+	em86xx_gpio_write(GPIO_IDE_RESET, 0);
+	mdelay(1);
+	em86xx_gpio_write(GPIO_IDE_RESET, 1);
+}
+
+static void __init register_ide(void)
+{
+	if (!tango2_bmide_enabled()) {
+		printk(KERN_NOTICE PFX "bmide support is disabled\n");
+		return;
+	}
+
+	memset(&tango2_ide_pd, 0, sizeof (tango2_ide_pd));
+	tango2_ide_pd.reset_ide = fbx_reset_ide;
+	platform_device_register(&tango2_ide_device);
+}
+
+/*
+ * tango2_enet platform structures.
+ */
+static struct tango2_enet_platform_data tango2_enet_pd;
+
+static struct platform_device tango2_enet_device = {
+	.name	= "tango2_enet",
+	.dev	= {
+		.platform_data	= &tango2_enet_pd,
+	},
+};
+
+static void __init register_enet(void)
+{
+	if (!tango2_ethernet_enabled()) {
+		printk(KERN_NOTICE PFX "ethernet support is disabled\n");
+		return;
+	}
+
+	memset(&tango2_enet_pd, 0, sizeof (tango2_enet_pd));
+	fbxserialinfo_get_mac_addr(tango2_enet_pd.mac_addr);
+	if (fbx_board_id == E_FBXBOARDID_FBX5B1)
+		tango2_enet_pd.phy_need_reset = 1;
+	tango2_enet_pd.phy_is_ics1893 = 1;
+	platform_device_register(&tango2_enet_device);
+}
+
+/*
+ * usb platform device
+ */
+static u64 ohci_dmamask = ~(u32)0;
+static struct platform_device tango2_ohci_device = {
+	.name	= "tango2_ohci",
+	.dev	= {
+		.dma_mask		= &ohci_dmamask,
+		.coherent_dma_mask      = 0xffffffff,
+	},
+};
+
+static u64 ehci_dmamask = ~(u32)0;
+static struct platform_device tango2_ehci_device = {
+	.name	= "tango2_ehci",
+	.dev	= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask      = 0xffffffff,
+	},
+};
+
+static void __init register_usb(void)
+{
+	platform_device_register(&tango2_ohci_device);
+	platform_device_register(&tango2_ehci_device);
+}
+
+int __init board_register_devices(void)
+{
+	fbx5b_fbxmtd_layout_init();
+	register_enet();
+	register_ide();
+	register_usb();
+	return 0;
+}
+
+void __init board_reset_pci(void)
+{
+	printk(KERN_NOTICE "Resetting freebox PCI...\n");
+	em86xx_gpio_write(GPIO_PCI_RESET, 0);
+	mdelay(100);
+	em86xx_gpio_write(GPIO_PCI_RESET, 1);
+}
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./boards/Kconfig linux-2.6.31.7-fbx/arch/mips/tango2/boards/Kconfig
--- linux-2.6.31.7-fbx/arch/mips/tango2./boards/Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/boards/Kconfig	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,30 @@
+
+choice
+	prompt "SMP8634 target Board"
+	depends on TANGO2
+
+config ARCH_FBX5_B
+	bool "Freebox v5b"
+	depends on TANGO2_XENV_READ
+	select FBXSERIAL
+
+endchoice
+
+#
+# FBX5B options
+#
+config FBX5B_FBXMTD_LAYOUT_READ_BANK1_TAG
+	bool "Read BANK1 tag"
+	default y
+	depends on ARCH_FBX5_B
+
+config FBX5B_FBXMTD_LAYOUT_ALL_RW
+	bool "Make all partition RW"
+	default n
+	depends on ARCH_FBX5_B
+
+config FBX5B_FBXMTD_LAYOUT_NOCRC
+	bool "disable CRC check"
+	default n
+	depends on ARCH_FBX5_B
+
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./boards/Makefile linux-2.6.31.7-fbx/arch/mips/tango2/boards/Makefile
--- linux-2.6.31.7-fbx/arch/mips/tango2./boards/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/boards/Makefile	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_FBX5_B) += board-fbx5b.o
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./gbus.c linux-2.6.31.7-fbx/arch/mips/tango2/gbus.c
--- linux-2.6.31.7-fbx/arch/mips/tango2./gbus.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/gbus.c	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,14 @@
+/*
+ * export gbus symbol to modules
+ */
+
+#include <linux/module.h>
+
+#include <asm/mach-tango2/tango2_gbus.h>
+
+EXPORT_SYMBOL(gbus_read_uint32);
+EXPORT_SYMBOL(gbus_write_uint32);
+EXPORT_SYMBOL(gbus_read_uint16);
+EXPORT_SYMBOL(gbus_write_uint16);
+EXPORT_SYMBOL(gbus_read_uint8);
+EXPORT_SYMBOL(gbus_write_uint8);
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./gpio.c linux-2.6.31.7-fbx/arch/mips/tango2/gpio.c
--- linux-2.6.31.7-fbx/arch/mips/tango2./gpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/gpio.c	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,113 @@
+
+#include <linux/module.h>
+
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_gpio.h>
+
+#include "setup.h"
+
+#define GPIO_DIR_INPUT(gpio)		((1 << (16 + (gpio))))
+#define GPIO_DIR_OUTPUT(gpio)		((1 << (16 + (gpio))) | (1 << (gpio)))
+#define GPIO_DATA_SET(gpio)		((1 << (16 + (gpio))) | (1 << (gpio)))
+#define GPIO_DATA_CLEAR(gpio)		((1 << (16 + (gpio))))
+
+#define UART_GPIO_DIR_INPUT(gpio)	((1 << (8 + (gpio))))
+#define UART_GPIO_DIR_OUTPUT(gpio)	((1 << (8 + (gpio))) | (1 << (gpio)))
+#define UART_GPIO_DATA_SET(gpio)	((1 << (8 + (gpio))) | (1 << (gpio)))
+#define UART_GPIO_DATA_CLEAR(gpio)	((1 << (8 + (gpio))))
+
+static int em86xx_uart0_gpio_read(int gpio)
+{
+	return (gbus_readw(REG_BASE_cpu_block +
+			   CPU_uart0_gpio_data) >> gpio) & 1;
+}
+
+static int em86xx_uart1_gpio_read(int gpio)
+{
+	return (gbus_readw(REG_BASE_cpu_block +
+			   CPU_uart1_gpio_data) >> gpio) & 1;
+}
+
+static void em86xx_uart0_gpio_write(int gpio, int data)
+{
+	gbus_writew(REG_BASE_cpu_block + CPU_uart0_gpio_data,
+		    data ? UART_GPIO_DATA_SET(gpio) :
+		    UART_GPIO_DATA_CLEAR(gpio));
+}
+
+static void em86xx_uart1_gpio_write(int gpio, int data)
+{
+	gbus_writew(REG_BASE_cpu_block + CPU_uart1_gpio_data,
+		    data ? UART_GPIO_DATA_SET(gpio) :
+		    UART_GPIO_DATA_CLEAR(gpio));
+}
+
+void em86xx_gpio_uart_mode(int uart, int mode)
+{
+	gbus_writel(REG_BASE_cpu_block +
+			(uart == 0 ? CPU_UART0_base : CPU_UART1_base) +
+			CPU_UART_GPIOMODE, 0x7f00 | (mode & 0x7f));
+}
+
+void em86xx_gpio_uart_dir(int uart, int dir)
+{
+	gbus_writel(REG_BASE_cpu_block +
+			(uart == 0 ? CPU_UART0_base : CPU_UART1_base) +
+			CPU_UART_GPIODIR, 0x7f00 | (dir & 0x7f));
+}
+
+int em86xx_gpio_read(int gpio)
+{
+	if (gpio >= 64)
+		return em86xx_uart1_gpio_read(gpio - 64);
+
+	if (gpio >= 32)
+		return em86xx_uart0_gpio_read(gpio - 32);
+
+	if (gpio >= 16)
+		return (gbus_readl(REG_BASE_host_interface +
+				   ETH_gpio_data) >> (gpio - 16)) & 1;
+
+	else if (gpio >= 0)
+		return (gbus_readl(REG_BASE_system_block +
+				   SYS_gpio_data) >> gpio) & 1;
+
+	return 0;
+}
+
+void em86xx_gpio_write(int gpio, int data)
+{
+	if (gpio >= 64)
+		return em86xx_uart1_gpio_write(gpio - 64, data);
+
+	if (gpio >= 32)
+		return em86xx_uart0_gpio_write(gpio - 32, data);
+
+	if (gpio >= 16)
+		gbus_writel(REG_BASE_host_interface + ETH_gpio_data, data ?
+			    GPIO_DATA_SET(gpio - 16) :
+			    GPIO_DATA_CLEAR(gpio - 16));
+
+	else if (gpio >= 0)
+		gbus_writel(REG_BASE_system_block + SYS_gpio_data, data ?
+			    GPIO_DATA_SET(gpio) : GPIO_DATA_CLEAR(gpio));
+}
+
+void em86xx_gpio_setdirection(int gpio, int dir)
+{
+	if (gpio >= 16 && gpio < 32)
+		gbus_writel(REG_BASE_host_interface + ETH_gpio_dir, dir ?
+			    GPIO_DIR_OUTPUT(gpio - 16) :
+			    GPIO_DIR_INPUT(gpio - 16));
+
+	else if (gpio >= 0)
+		gbus_writel(REG_BASE_system_block + SYS_gpio_dir, dir ?
+			    GPIO_DIR_OUTPUT(gpio) : GPIO_DIR_INPUT(gpio));
+}
+
+EXPORT_SYMBOL(em86xx_gpio_read);
+EXPORT_SYMBOL(em86xx_gpio_write);
+EXPORT_SYMBOL(em86xx_gpio_setdirection);
+EXPORT_SYMBOL(em86xx_gpio_uart_mode);
+EXPORT_SYMBOL(em86xx_gpio_uart_dir);
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./irq.c linux-2.6.31.7-fbx/arch/mips/tango2/irq.c
--- linux-2.6.31.7-fbx/arch/mips/tango2./irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/irq.c	2010-10-25 13:43:56.001440874 +0200
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch_init_irq for tango2.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/irq_cpu.h>
+
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+
+#include "setup.h"
+
+/*
+ * helpers to access cpu block registers
+ */
+#define RD_CPU_REG32(r)	\
+		gbus_readl(REG_BASE_cpu_block + (r))
+
+#define WR_CPU_REG32(r, v)	\
+		gbus_writel(REG_BASE_cpu_block + (r), (v))
+
+
+/*
+ * dispatch routine called from tango2IRQ.S
+ */
+void tango2_dispatch(void)
+{
+	u32 status, status_hi;
+	int x;
+
+	do {
+		status = RD_CPU_REG32(CPU_irq_status);
+		status_hi = RD_CPU_REG32(CPU_irq_status_hi);
+
+		if (!status && !status_hi)
+			break;
+
+		x = ffs(status);
+		if (x)
+			do_IRQ(IRQ_CONTROLLER_IRQ_BASE + x - 1);
+
+		x = ffs(status_hi);
+		if (x)
+			do_IRQ(IRQ_CONTROLLER_IRQ_BASE + 32 + x - 1);
+
+	} while (1);
+}
+
+/*
+ * arch callback for irq dispatching
+ */
+asmlinkage void plat_irq_dispatch(void)
+{
+	unsigned int pending;
+
+	do {
+		pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+		if (!pending)
+			break;
+
+		if (pending & CAUSEF_IP7)
+			do_IRQ(7);
+		else if (pending & CAUSEF_IP2)
+			tango2_dispatch();
+		else {
+			if (pending)
+				printk("spurious irq\n");
+			spurious_interrupt();
+		}
+	} while (1);
+}
+
+static void tango2_irq_mask(unsigned int x)
+{
+	int bit = x - IRQ_CONTROLLER_IRQ_BASE;
+
+	if (bit >= 32)
+		WR_CPU_REG32(CPU_irq_enableclr_hi, 1 << (bit - 32));
+	else
+		WR_CPU_REG32(CPU_irq_enableclr, 1 << bit);
+}
+
+static void tango2_irq_unmask(unsigned int x)
+{
+	int bit = x - IRQ_CONTROLLER_IRQ_BASE;
+
+	if (bit >= 32)
+		WR_CPU_REG32(CPU_irq_enableset_hi, 1 << (bit - 32));
+	else
+		WR_CPU_REG32(CPU_irq_enableset, 1 << bit);
+}
+
+static void tango2_irq_ack(unsigned int x)
+{
+	int bit = x - IRQ_CONTROLLER_IRQ_BASE;
+
+	if (bit >= 32)
+		WR_CPU_REG32(CPU_edge_rawstat_hi, 1 << (bit - 32));
+	else
+		WR_CPU_REG32(CPU_edge_rawstat, 1 << bit);
+}
+
+/*
+ * our hw_irq_controller
+ */
+static struct irq_chip tango2_level_irq_controller = {
+	.name = "tango2-level",
+
+	.mask = tango2_irq_mask,
+	.unmask = tango2_irq_unmask,
+	.ack = tango2_irq_ack,
+};
+
+static struct irq_chip tango2_edge_irq_controller = {
+	.name = "tango2-edge",
+
+	.mask = tango2_irq_mask,
+	.unmask = tango2_irq_unmask,
+	.ack = tango2_irq_ack,
+};
+
+static struct irqaction irq_cascade = {
+	no_action, 0, { { 0, } }, "cascade", NULL, NULL
+};
+
+void __init arch_init_irq(void)
+{
+	unsigned long x, irq_base, irq_count;
+	unsigned long rise = 0;
+	unsigned long fall = 0;
+	unsigned long edge_trig = 0;
+	unsigned long rise_hi = 0;
+	unsigned long fall_hi = 0;
+	unsigned long edge_trig_hi = 0;
+
+	/* irq_desc entries 0..7 */
+	mips_cpu_irq_init();
+
+	/*
+	 * irq_desc entries 8..39 (for 8630ES), 8..71 (for 863X)
+	 */
+	irq_base = IRQ_CONTROLLER_IRQ_BASE;
+
+	/* SMP863xES4 or above has 64 interrupt sources */
+	irq_count = 64;
+
+	WR_CPU_REG32(CPU_irq_enableclr, 0xffffffff);
+	WR_CPU_REG32(CPU_fiq_enableclr, 0xffffffff);
+	WR_CPU_REG32(CPU_iiq_enableclr, 0xffffffff);
+	WR_CPU_REG32(CPU_irq_enableclr_hi, 0xffffffff);
+	WR_CPU_REG32(CPU_fiq_enableclr_hi, 0xffffffff);
+	WR_CPU_REG32(CPU_iiq_enableclr_hi, 0xffffffff);
+
+	rise = RD_CPU_REG32(CPU_edge_config_rise);
+	fall = RD_CPU_REG32(CPU_edge_config_fall);
+	edge_trig = rise ^ fall;
+	WR_CPU_REG32(CPU_edge_rawstat, edge_trig);
+	rise_hi = RD_CPU_REG32(CPU_edge_config_rise_hi);
+	fall_hi = RD_CPU_REG32(CPU_edge_config_fall_hi);
+	edge_trig_hi = rise_hi ^ fall_hi;
+	WR_CPU_REG32(CPU_edge_rawstat_hi, edge_trig_hi);
+
+	for (x = irq_base; x < irq_base + irq_count; x++) {
+		irq_flow_handler_t hdl;
+		struct irq_chip *chip;
+		unsigned long val;
+		int bit = x - IRQ_CONTROLLER_IRQ_BASE;
+
+		if (bit >= 32) {
+			val = edge_trig_hi;
+			bit -= 32;
+		} else
+			val = edge_trig;
+
+		if (val & bit) {
+			hdl = handle_edge_irq;
+			chip = &tango2_edge_irq_controller;
+		} else {
+			hdl = handle_level_irq;
+			chip = &tango2_level_irq_controller;
+		}
+
+		set_irq_chip_and_handler(x, chip, hdl);
+	}
+
+	setup_irq(MIPS_CPU_IRQ_BASE + 2, &irq_cascade);
+}
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./Kconfig linux-2.6.31.7-fbx/arch/mips/tango2/Kconfig
--- linux-2.6.31.7-fbx/arch/mips/tango2./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/Kconfig	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,121 @@
+
+#
+# XENV stuffs
+#
+config TANGO2_XENV_READ
+	bool "Read config from XENV"
+	depends on TANGO2
+	default y
+	help
+	 If you  say yes  here, board configuration  (enabled devices,
+	 pci irq routing,  ...) will be read from  xenv space.
+
+
+menu "XENV config"
+	depends on TANGO2_XENV_READ
+
+config TANGO2_XENV_DUMP
+	bool "Dump XENV content at boot"
+	default n
+
+config TANGO2_XENV_READ_SAFE
+	bool "Don't boot if XENV invalid"
+	default n
+	help
+	 If you say yes here and XENV content is invalid, linux wont boot.
+
+config TANGO2_XENV_DEF_CS0_SIZE
+	hex "CS0 size (flash0)"
+	default 0
+
+config TANGO2_XENV_DEF_CS1_SIZE
+	hex "CS1 size (flash1)"
+	default 0
+
+config TANGO2_XENV_DEF_CS2_SIZE
+	hex "CS2 size (flash2)"
+	default 0x0
+
+config TANGO2_XENV_DEF_CS3_SIZE
+	hex "CS3 size (flash3)"
+	default 0
+
+config TANGO2_XENV_DEF_UART0
+	int "UART0 enabled"
+	default 0
+
+config TANGO2_XENV_DEF_UART1
+	int "UART1 enabled"
+	default 0
+
+config TANGO2_XENV_DEF_BAUDRATE
+	int "Default baudrate"
+	default 115200
+
+config TANGO2_XENV_DEF_ENET
+	int "Ethernet enabled"
+	default 0
+
+config TANGO2_XENV_DEF_FIP
+	int "FIP enabled"
+	default 0
+
+config TANGO2_XENV_DEF_I2CM
+	int "I2CM enabled"
+	default 0
+
+config TANGO2_XENV_DEF_I2CS
+	int "I2CS enabled"
+	default 0
+
+config TANGO2_XENV_DEF_BMIDE
+	int "IDE BM controller enabled"
+	default 0
+
+config TANGO2_XENV_DEF_IR
+	int "IR enabled"
+	default 0
+
+config TANGO2_XENV_DEF_PCIHOST
+	int "PCI Host enabled"
+	default 0
+
+config TANGO2_XENV_DEF_PCI_ID1
+	int "PCI device 1 enabled"
+	default 0
+
+config TANGO2_XENV_DEF_PCI_ID1_IRQ
+	hex "PCI device 1 IRQ route"
+	default 0x0
+
+config TANGO2_XENV_DEF_PCI_ID2
+	int "PCI device 2 enabled"
+	default 0
+
+config TANGO2_XENV_DEF_PCI_ID2_IRQ
+	hex "PCI device 2 IRQ route"
+	default 0x0
+
+config TANGO2_XENV_DEF_PCI_ID3
+	int "PCI device 3 enabled"
+	default 0
+
+config TANGO2_XENV_DEF_PCI_ID3_IRQ
+	hex "PCI device 3 IRQ route"
+	default 0x0
+
+config TANGO2_XENV_DEF_PCI_ID4
+	int "PCI device 4 enabled"
+	default 0
+
+config TANGO2_XENV_DEF_PCI_ID4_IRQ
+	hex "PCI device 4 IRQ route"
+	default 0x0
+
+config TANGO2_XENV_DEF_USB
+	int "USB enabled"
+	default 0
+
+endmenu
+
+source "arch/mips/tango2/boards/Kconfig"
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./Makefile linux-2.6.31.7-fbx/arch/mips/tango2/Makefile
--- linux-2.6.31.7-fbx/arch/mips/tango2./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/Makefile	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,6 @@
+obj-y += irq.o setup.o prom.o gbus.o gpio.o xenv_config.o mbus.o
+
+obj-$(CONFIG_EARLY_PRINTK) += console.o
+obj-$(CONFIG_TANGO2_XENV_READ) += sha1.o xenv.o
+
+obj-y += boards/
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./mbus.c linux-2.6.31.7-fbx/arch/mips/tango2/mbus.c
--- linux-2.6.31.7-fbx/arch/mips/tango2./mbus.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/mbus.c	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,461 @@
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-tango2/tango2_mbus.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+#include <asm/mach-tango2/tango2_regs.h>
+
+#include "setup.h"
+
+/*
+ * switchbox stuffs
+ *
+ * We keep  track of  current mapping using  this globals  rather than
+ * reading hardware registers each time.
+ */
+static unsigned int g_sbox_map[SBOX_MAX + 1];
+
+static inline void sbox_update_route(void)
+{
+	int i;
+	unsigned int data;
+
+	for (i = SBOX_MAX, data = 0; i >= 0; --i)
+		data = (data << 4) | g_sbox_map[i];
+
+	gbus_writel(REG_BASE_host_interface + SBOX_ROUTE, data);
+}
+
+static void sbox_reset(void)
+{
+	/* Leave W1/R1 alone. */
+	gbus_writel(REG_BASE_host_interface + SBOX_FIFO_RESET, 0x7d7dfdfd);
+	gbus_writel(REG_BASE_host_interface + SBOX_FIFO_RESET, 0x7d00fd00);
+}
+
+
+static void sbox_setup(void)
+{
+	/* W0 initially disconnected */
+	g_sbox_map[SBOX_MBUS_W0] = 0xf;
+
+	/* Leave W1 alone */
+	g_sbox_map[SBOX_MBUS_W1] = 0;
+
+	g_sbox_map[SBOX_PCIMASTER] = 0xf;
+	g_sbox_map[SBOX_PCISLAVE] = 0x4;
+	g_sbox_map[SBOX_UNUSED1] = 0xf;
+	g_sbox_map[SBOX_IDEDVD] = 0xf;
+	g_sbox_map[SBOX_IDEFLASH] = 0xf;
+	g_sbox_map[SBOX_UNUSED2] = 0xf;
+
+	sbox_update_route();
+}
+
+/*
+ * Connect given interface to R0/W0 channel
+ */
+static int sbox_connect(int iface)
+{
+	unsigned long flags;
+
+	/* Already connected? */
+	if (g_sbox_map[SBOX_MBUS_W0] == (iface + 1) && g_sbox_map[iface] == 1)
+		return 0;
+
+	/* In use ? */
+	if (g_sbox_map[SBOX_MBUS_W0] != 0xf || g_sbox_map[iface] != 0xf)
+		return 1;
+
+	local_irq_save(flags);
+
+	g_sbox_map[SBOX_MBUS_W0] = iface + 1;
+	g_sbox_map[iface] = 1;
+	sbox_update_route();
+	wmb();
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static void sbox_disconnect(int iface)
+{
+	unsigned long flags;
+
+	if (iface >= 0) {
+		local_irq_save(flags);
+
+		g_sbox_map[SBOX_MBUS_W0] = 0xf;
+		g_sbox_map[iface] = 0xf;
+		sbox_update_route();
+		wmb();
+
+		local_irq_restore(flags);
+	}
+}
+
+static void sbox_init(void)
+{
+	sbox_setup();
+	sbox_reset();
+}
+
+
+/*
+ * mbus stuffs
+ *
+ * to  avoid   requesting/freeing  irq   each  time,  we   keep  given
+ * handler/args  for each  dma  request and  call  it in  our own  irq
+ * handler.
+ */
+#define MBUS_LINEAR_MAX		(0x2000 - 0x200)
+
+static mbus_irq_handler_t g_mbus_intr_handler[4];
+static void *g_mbus_intr_handler_arg[4];
+
+/*
+ * alloc_dma, need to be called before setup, will try to connect
+ * needed sbox.
+ */
+int em86xx_mbus_alloc_dma(int sbox, int fromdev, unsigned long *pregbase,
+			  int *pirq)
+{
+	int x;
+
+	if (sbox_connect(sbox) < 0)
+		return -1;
+
+	x = (fromdev ? 0 : 2);
+
+	if (pirq)
+		*pirq = LOG2_CPU_HOST_MBUS_W0_INT +
+			IRQ_CONTROLLER_IRQ_BASE + x;
+
+	if (pregbase)
+		*pregbase = REG_BASE_host_interface + MIF_W0_ADD + x * 0x40;
+
+	return 0;
+}
+
+/*
+ * free_dma,  need to  be called  after  transfer is  done to  release
+ * switchbox.
+ */
+void em86xx_mbus_free_dma(unsigned long regbase, int sbox)
+{
+	unsigned long flags;
+	int idx;
+
+	idx = (regbase - REG_BASE_host_interface - MIF_W0_ADD) / 0x40;
+
+	local_irq_save(flags);
+	g_mbus_intr_handler[idx] = NULL;
+	wmb();
+	local_irq_restore(flags);
+
+	sbox_disconnect(sbox);
+}
+
+/*
+ * irq handler for mbus interrupt
+ */
+static irqreturn_t mbus_intr(int irq, void *devinfo)
+{
+	int idx;
+
+	idx = irq - (LOG2_CPU_HOST_MBUS_W0_INT + IRQ_CONTROLLER_IRQ_BASE);
+
+	if (g_mbus_intr_handler[idx]) {
+		mbus_irq_handler_t f;
+
+		f = g_mbus_intr_handler[idx];
+		g_mbus_intr_handler[idx] = NULL;
+		wmb();
+		f(irq, g_mbus_intr_handler_arg[idx]);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * check if mbus is in use for given regbase
+ */
+static inline int mbus_inuse(unsigned int regbase)
+{
+	return (gbus_readl(regbase + MIF_cmd_offset) & 0x7) != 0;
+}
+
+/*
+ * setup mbus  register to start  a linear transfer (count  bytes from
+ * addr, where count < MBUS_LINEAR_MAX)
+ */
+static inline void mbus_setup_dma_linear(unsigned int regbase,
+					 unsigned int addr,
+					 unsigned int count)
+{
+	gbus_writel(regbase + MIF_add_offset, addr);
+	gbus_writel(regbase + MIF_cnt_offset, count);
+	iob();
+	gbus_writel(regbase + MIF_cmd_offset, 0x5);
+}
+
+/*
+ * setup mbus  register to start  a double transfer (count  bytes from
+ * addr and count2 bytes from addr2, where count < MBUS_LINEAR_MAX and
+ * count2 < MBUS_LINEAR_MAX)
+ */
+static inline void mbus_setup_dma_double(unsigned int regbase,
+					 unsigned int addr,
+					 unsigned int count,
+					 unsigned int addr2,
+					 unsigned int count2)
+{
+	gbus_writel(regbase + MIF_add_offset, addr);
+	gbus_writel(regbase + MIF_cnt_offset, (count2 << 16) | count);
+	gbus_writel(regbase + MIF_add2_skip_offset, addr2);
+	iob();
+	gbus_writel(regbase + MIF_cmd_offset, 0x6);
+}
+
+/*
+ * setup mbus  register to start  a rectangle transfer (horiz  * lines
+ * bytes  from  addr,  where  horiz  <  MBUS_LINEAR_MAX  and  lines  <
+ * MBUS_LINEAR_MAX)
+ */
+static inline void mbus_setup_dma_rectangle(unsigned int regbase,
+					    unsigned int addr,
+					    unsigned int horiz,
+					    unsigned int lines)
+{
+	gbus_writel(regbase + MIF_add_offset, addr);
+	gbus_writel(regbase + MIF_cnt_offset, (lines << 16) | horiz);
+	gbus_writel(regbase + MIF_add2_skip_offset, horiz);
+	iob();
+	gbus_writel(regbase + MIF_cmd_offset, 0x7);
+}
+
+/*
+ * register mbus interrupt if not done
+ */
+static int mbus_register_intr(void)
+{
+	static int done = 0;
+	int ret;
+
+	if (done)
+		return 0;
+	done = 1;
+	/*
+	 * register irq handler for R0/W0 only (R1/W1 are not used for
+	 * the moment)
+	 */
+	ret = request_irq(LOG2_CPU_HOST_MBUS_R0_INT + IRQ_CONTROLLER_IRQ_BASE,
+			  mbus_intr, 0, "tango2_mbus_r0", NULL);
+	if (ret)
+		return ret;
+
+	ret = request_irq(LOG2_CPU_HOST_MBUS_W0_INT + IRQ_CONTROLLER_IRQ_BASE,
+			  mbus_intr, 0, "tango2_mbus_w0", NULL);
+	return ret;
+}
+
+/*
+ * start  a   mbus  dma,   use  this  after   a  sucessfull   call  to
+ * em86xx_mbus_alloc_dma
+ */
+int em86xx_mbus_setup_dma(unsigned int regbase, unsigned int addr,
+			  unsigned int count, mbus_irq_handler_t handler,
+			  void *arg)
+{
+	int idx, horiz, lines;
+	unsigned long flags;
+
+	idx = (regbase - REG_BASE_host_interface - MIF_W0_ADD) / 0x40;
+
+	/*
+	 * make sure no one uses the mbus before
+	 */
+	if (unlikely(mbus_inuse(regbase))) {
+		printk(KERN_ERR "MBUS: error previous command is pending\n");
+		return 1;
+	}
+
+	/*
+	 * "register" given handler if any
+	 */
+	if (handler) {
+		mbus_register_intr();
+		local_irq_save(flags);
+		g_mbus_intr_handler[idx] = handler;
+		g_mbus_intr_handler_arg[idx] = arg;
+		wmb();
+		local_irq_restore(flags);
+	}
+
+	/*
+	 * decide which dma function to use depending on count
+	 */
+	if (count <= MBUS_LINEAR_MAX) {
+		mbus_setup_dma_linear(regbase, addr, count);
+		return 0;
+	}
+
+	if (count <= (MBUS_LINEAR_MAX * 2)) {
+		mbus_setup_dma_double(regbase, addr, MBUS_LINEAR_MAX,
+				      addr + MBUS_LINEAR_MAX,
+				      count - MBUS_LINEAR_MAX);
+		return 0;
+	}
+
+	/*
+	 * bad luck maybe, we  need to use rectangle, compute  horiz & lines
+	 * values to use
+	 *
+	 * Some  count values  are impossible  to use  using rectangle
+	 * (prime number > MBUS_LINEAR_MAX for instance), so we assume
+	 * count is a multiple of 512 (2^9).
+	 *
+	 * Maximum count value is (2^9) * MBUS_LINEAR_MAX
+	 */
+	if ((count & 0x1ff) != 0 || count > (512 * MBUS_LINEAR_MAX)) {
+		printk(KERN_ERR "MBUS: can't handle rectangle transfer "
+		       "of %d bytes\n", count);
+		BUG();
+	}
+
+	horiz = 512;
+	lines = count >> 9;
+	mbus_setup_dma_rectangle(regbase, addr, horiz, lines);
+
+	return 0;
+}
+
+/*
+ * Note: 06/24/2004 there're errors  in the spec.  The bit assignments
+ * should be (* indicates error)
+ *
+ * Bit 0/8: MBUS_R0_SBOX
+ * Bit 1/9: MBUS_R1_SBOX
+ * Bit 2/10: PCI_MASTER_SBOX
+ * Bit 3/11: PCI_SLAVE_SBOX
+ * Bit 4/12: CIPHER_SBOX
+ * Bit 5/13: IDE_ISA_SBOX*
+ * Bit 6/14: IDE_DVD_SBOX*
+ * Bit 7/15: SFLA_SBOX
+ * Bit 16/24: SBOX_MBUS_W0*
+ * Bit 17/25: SBOX_MBUS_W1*
+ * Bit 18/26: SBOX_PCI_MASTER*
+ * Bit 19/27: SBOX_PCI_SLAVE*
+ * Bit 20/28: SBOX_CIPHER*
+ * Bit 21/29: SBOX_ISA*
+ * Bit 22/30: SBOX_DVD*
+ */
+static const unsigned int sbox_reset_vals[2][4] = {
+	{ 0x01012020, 0x02022020, 0x20200101, 0x20200202 },
+	{ 0x01014040, 0x02024040, 0x40400101, 0x40400202 }
+};
+
+static const unsigned int sbox_unreset_vals[2][4] = {
+	{ 0x01002000, 0x02002000, 0x20000100, 0x20000200 },
+	{ 0x01004000, 0x02004000, 0x40000100, 0x40000200 }
+};
+
+/*
+ * clear MBUS transaction for given regbase/sbox
+ */
+static void mbus_reset(unsigned int regbase, int sbox)
+{
+	int midx;
+	int sidx;
+
+	midx = (regbase - REG_BASE_host_interface - MIF_W0_ADD) / 0x40;
+	sidx = sbox - SBOX_IDEFLASH;
+
+	if (((midx < 0) || (midx > 3)) || ((sidx < 0) || (sidx > 2))) {
+		printk(KERN_ERR "MBUS reset: out of range, midx %d, sidx %d\n",
+		       midx, sidx);
+		return;
+	}
+
+	gbus_writel(REG_BASE_host_interface + SBOX_FIFO_RESET,
+		    sbox_reset_vals[sidx][midx]);
+	iob();
+	gbus_writel(REG_BASE_host_interface + SBOX_FIFO_RESET,
+		    sbox_unreset_vals[sidx][midx]);
+	iob();
+}
+
+/*
+ * busy wait  for current mbus transfer  to finish, will  not wait for
+ * more than 200 ms. 0 is ok, 1 timeout, 2 for timeout + reset error.
+ */
+#define MBUS_TIMEOUT	200000
+
+int em86xx_mbus_wait(unsigned int regbase, int sbox)
+{
+
+	int timeout;
+
+	/* wait for mbus to be released */
+	timeout = 0;
+	do {
+		if (!mbus_inuse(regbase))
+			break;
+		udelay(1);
+		timeout++;
+	} while (timeout < MBUS_TIMEOUT);
+
+	if (timeout < MBUS_TIMEOUT) {
+		/* ok */
+		return 0;
+	}
+
+	/* timeout, let's dump some registers ! */
+	printk(KERN_ERR "MBUS timeout : MBUS CMD = %08lx\n",
+	       gbus_readl(regbase + MIF_cmd_offset) & 0x7);
+
+	printk(KERN_ERR "MBUS registers : %08lx %08lx %08lx %08lx\n",
+	       gbus_readl(regbase + MIF_add_offset),
+	       gbus_readl(regbase + MIF_cnt_offset),
+	       gbus_readl(regbase + MIF_add2_skip_offset),
+	       gbus_readl(regbase + MIF_cmd_offset));
+
+	printk(KERN_ERR "MBUS fails, resetting %d ..\n", sbox);
+	mbus_reset(regbase, sbox);
+
+	/* If not able to reset, return  1, so the DMA can be disabled
+	   accordingly  */
+	return mbus_inuse(regbase) ? 0 : 1;
+}
+
+
+int em86xx_mbus_init(void)
+{
+	static int done = 0;
+
+	if (done)
+		return 0;
+	done = 1;
+
+	/* reset sbox to default values */
+	sbox_init();
+
+#ifdef CONFIG_BLK_DEV_IDE_TANGO2
+	/* give maximum MBUS bandwidth for IDE */
+	gbus_writel(REG_BASE_system_block + MARB_mid02_cfg, 0x11f1f);
+	gbus_writel(REG_BASE_system_block + MARB_mid22_cfg, 0x11f1f);
+#endif
+
+	return 0;
+}
+
+EXPORT_SYMBOL(em86xx_mbus_alloc_dma);
+EXPORT_SYMBOL(em86xx_mbus_free_dma);
+EXPORT_SYMBOL(em86xx_mbus_setup_dma);
+EXPORT_SYMBOL(em86xx_mbus_wait);
+EXPORT_SYMBOL(em86xx_mbus_init);
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./prom.c linux-2.6.31.7-fbx/arch/mips/tango2/prom.c
--- linux-2.6.31.7-fbx/arch/mips/tango2./prom.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/prom.c	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,295 @@
+
+#include <linux/init.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+#include <asm/io.h>
+
+#include <asm/mach-tango2/tango2_board.h>
+#include <asm/mach-tango2/tango2_memcfg.h>
+#include <asm/mach-tango2/tango2_hardware.h>
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_xenv.h>
+
+#include "setup.h"
+#include "xenv.h"
+
+/*
+ * em8xxx_sys_frequency is  used later in the serial  code, DON'T mark
+ * it as initdata
+ */
+unsigned long em8xxx_sys_frequency;
+unsigned long __initdata em8xxx_cpu_frequency;
+unsigned long __initdata em8xxx_kmem_start;
+unsigned long __initdata em8xxx_kmem_size;
+
+/*
+ * we will restore remap registers before rebooting
+ */
+unsigned long em8xxx_remap_registers[4];
+
+/*
+ * helper to access base registers
+ */
+#define RD_BASE_REG32(r)	\
+		gbus_readl(REG_BASE_system_block + (r))
+
+/*
+ * return system type (/proc/cpuinfo)
+ */
+const char *get_system_type(void)
+{
+	static char buf[128];
+	sprintf(buf, "Sigma Designs Tango2 (%s)", board_get_name());
+	return buf;
+}
+
+/*
+ * return system frequency
+ */
+static unsigned long __init tango2_get_sysclock(void)
+{
+	unsigned long sys_clkgen_pll, sysclk_mux, sysclk_premux;
+	unsigned long n, m, freq, div, k, mux;
+
+	k = m = sys_clkgen_pll = 0;
+	sysclk_mux = RD_BASE_REG32(SYS_sysclk_mux);
+	sysclk_premux = RD_BASE_REG32(SYS_sysclk_premux);
+
+	switch (sysclk_premux & 0x3) {
+		case 0:
+			sys_clkgen_pll = RD_BASE_REG32(SYS_clkgen0_pll);
+			m = (sys_clkgen_pll >> 16) & 0x1f;
+			k = (sys_clkgen_pll >> 14) & 0x3;
+			break;
+		case 1:
+			sys_clkgen_pll = RD_BASE_REG32(SYS_clkgen1_pll);
+			m = (sys_clkgen_pll >> 16) & 0x7f;
+			break;
+		case 2:
+			sys_clkgen_pll = RD_BASE_REG32(SYS_clkgen2_pll);
+			m = (sys_clkgen_pll >> 16) & 0x7f;
+			break;
+		case 3:
+			sys_clkgen_pll = RD_BASE_REG32(SYS_clkgen3_pll);
+			m = (sys_clkgen_pll >> 16) & 0x7f;
+			break;
+	}
+	n = sys_clkgen_pll & 0x000003ff;
+
+	/* Not using XTAL_IN, cannot calculate */
+	if ((sys_clkgen_pll & 0x07000000) != 0x01000000)
+		return(0);
+
+	/* Calculate the divider */
+	mux = (sysclk_mux >> 8) & 0xf;
+	if (mux == 0) /* Get system clock frequency */
+		div = 2;
+	else if ((mux == 1) || ((mux >= 8) && (mux < 0xc)))
+		div = 4;
+	else if ((mux >= 2) && (mux < 8))
+		div = 3;
+	else
+		return(0); /* Wrong divider setting */
+
+	if (sysclk_mux & 0x1) 	/* PLL is used */
+		freq = ((TANGO2_BASE_FREQUENCY / (m + 2)) * (n + 2)) /
+			(div * (1 << k));
+	else
+		freq = TANGO2_BASE_FREQUENCY / div;
+	return(freq);
+}
+
+/*
+ * return cpu frequency
+ */
+static unsigned long __init tango2_get_cpuclock(void)
+{
+	unsigned long sys_clkgen_pll, sysclk_mux, sysclk_premux;
+	unsigned long n, m, freq, div, k, mux;
+
+	k = m = sys_clkgen_pll = 0;
+	sysclk_mux = RD_BASE_REG32(SYS_sysclk_mux);
+	sysclk_premux = RD_BASE_REG32(SYS_sysclk_premux);
+
+	switch(sysclk_premux & 0x3) {
+		case 0:
+			sys_clkgen_pll = RD_BASE_REG32(SYS_clkgen0_pll);
+			m = (sys_clkgen_pll >> 16) & 0x1f;
+			k = (sys_clkgen_pll >> 14) & 0x3;
+			break;
+		case 1:
+			sys_clkgen_pll = RD_BASE_REG32(SYS_clkgen1_pll);
+			m = (sys_clkgen_pll >> 16) & 0x7f;
+			break;
+		case 2:
+			sys_clkgen_pll = RD_BASE_REG32(SYS_clkgen2_pll);
+			m = (sys_clkgen_pll >> 16) & 0x7f;
+			break;
+		case 3:
+			sys_clkgen_pll = RD_BASE_REG32(SYS_clkgen3_pll);
+			m = (sys_clkgen_pll >> 16) & 0x7f;
+			break;
+	}
+	n = sys_clkgen_pll & 0x000003ff;
+
+	/* Not using XTAL_IN, cannot calculate */
+	if ((sys_clkgen_pll & 0x07000000) != 0x01000000)
+		return(0);
+
+	/* Calculate the divider */
+	mux = (sysclk_mux >> 8) & 0xf;
+	if ((mux == 3) || (mux == 4) || (mux == 6)) /* Get CPU frequency */
+		div = 3;
+	else if ((mux == 8) || (mux == 0xa))
+		div = 4;
+	else if ((mux == 0) || (mux == 1) || (mux == 2) ||
+		 (mux == 5) || (mux == 7) ||
+		 (mux == 9) || (mux == 0xb))
+		div = 2;
+	else
+		return(0); /* Wrong divider setting */
+
+	if (sysclk_mux & 0x1) 	/* PLL is used */
+		freq = ((TANGO2_BASE_FREQUENCY / (m + 2)) * (n + 2)) /
+			(div * (1 << k));
+	else
+		freq = TANGO2_BASE_FREQUENCY / div;
+	return(freq);
+}
+
+
+/*
+ * setup  remap registers  in case  we use  remap registers  to access
+ * dram1
+ */
+static int __init tango2_remap_setup(void)
+{
+	/*
+	 * Use remap strategy (CPU_remap3/4 for 128MB resolution)
+	 */
+	printk("tango2: creating CPU mapping for 0x%08x at 0x%08x, "
+	       "size 0x%08x.\n", MEM_BASE_dram_controller_1,
+	       CPU_remap3_address, 0x08000000);
+
+	/*
+	 * remap dram controller 1 at 0x08000000 -> 0x0fffffff (128MB)
+	 * so Linux can see it in KSEG[01]
+	 */
+	gbus_writel(REG_BASE_cpu_block + CPU_remap3,
+		    MEM_BASE_dram_controller_1);
+	gbus_writel(REG_BASE_cpu_block + CPU_remap4,
+		    MEM_BASE_dram_controller_1 + 0x04000000);
+	iob();
+
+	return 0;
+}
+
+extern int do_syslog(int type, char * buf, int len);
+extern int __init xenv_config(void);
+extern void __init tango2_device_info(void);
+extern const char *tango2_xenv_cmdline(void);
+
+void __init prom_init(void)
+{
+	unsigned long offset, em8xxx_kmem_end;
+	memcfg_t *m;
+	int xenv_res, i;
+
+	/*
+	 * save remap registers for reboot time
+	 */
+	for (i = 0; i < 4; i++) {
+		em8xxx_remap_registers[i] =
+			gbus_readl(REG_BASE_cpu_block + CPU_remap + i * 4);
+	}
+
+	/*
+	 * Set remap  so that 0x1fc00000  and 0x0 back to  they should
+	 * be...
+	 */
+	gbus_writel(REG_BASE_cpu_block + CPU_remap, 0x1fc00000);
+	gbus_writel(REG_BASE_cpu_block + CPU_remap1, 0x0);
+
+	/*
+	 * make exception vector point to the right area
+	 */
+	write_c0_ebase(PAGE_OFFSET);
+
+	/*
+	 * read xenv  configuration, we  need it quickly  to configure
+	 * console accordingly.
+	 *
+	 * NOTE: We  may stay STUCK in  this if safe  mode is required
+	 * and XENV is not valid !
+	 */
+	xenv_res = xenv_config();
+
+	/*
+	 * calculate cpu & sys frequency (needed for uart init)
+	 */
+	em8xxx_cpu_frequency = tango2_get_cpuclock();
+	em8xxx_sys_frequency = tango2_get_sysclock();
+
+	/*
+	 * program the SYSCLK clock divider in both uart
+	 */
+	gbus_writel(REG_BASE_cpu_block + CPU_UART0_base + CPU_UART_CLKSEL, 0);
+	gbus_writel(REG_BASE_cpu_block + CPU_UART1_base + CPU_UART_CLKSEL, 0);
+
+	/*
+	 * show KERN_DEBUG message on console
+	 */
+	do_syslog(8, NULL, 8);
+
+	/* warn user if we use failsafe values for xenv */
+	if (xenv_res)
+		printk("Invalid XENV content, using failsafe values\n");
+	tango2_device_info();
+
+
+	/*
+	 * compute kernel memory start address/size
+	 * _text section gives kernel address start
+	 */
+	em8xxx_kmem_start = ((unsigned long)(&_text)) & PAGE_MASK;
+	em8xxx_kmem_size = ((board_get_dram_size() +
+		    em8xxx_kmem_start) & 0xfff00000) - em8xxx_kmem_start;
+
+	tango2_remap_setup();
+
+	board_prom_init();
+
+	/*
+	 * tell kernel about available memory size/offset
+	 */
+	offset = KSEG1ADDR(em8xxx_kmem_start) -
+		KSEG1ADDR(MEM_BASE_dram_controller_0);
+
+	add_memory_region(MEM_BASE_dram_controller_0 + offset,
+			  em8xxx_kmem_size, BOOT_MEM_RAM);
+
+	/*
+	 * check/fill the memcfg
+	 */
+	m = (memcfg_t *)KSEG1ADDR(MEM_BASE_dram_controller_0 + FM_MEMCFG);
+	em8xxx_kmem_end = KSEG1ADDR(em8xxx_kmem_start + em8xxx_kmem_size) -
+		KSEG1ADDR(MEM_BASE_dram_controller_0);
+
+	if (is_valid_memcfg(m) == 0) {
+		memset(m, 0, sizeof (memcfg_t));
+		m->signature = MEMCFG_SIGNATURE;
+		/* fetch dram0 size from xenv */
+		m->dram0_size = (tango2_get_dramstuffing() & 0x3ff) << 20;
+		m->kernel_end = em8xxx_kmem_end;
+	} else {
+		m->kernel_end = em8xxx_kmem_end;
+	}
+
+	gen_memcfg_checksum(m);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./setup.c linux-2.6.31.7-fbx/arch/mips/tango2/setup.c
--- linux-2.6.31.7-fbx/arch/mips/tango2./setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/setup.c	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/tango2/setup.c
+ *     The setup file for tango2.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include <asm/reboot.h>
+#include <asm/io.h>
+#include <asm/cacheflush.h>
+#include <asm/time.h>
+#include <asm/serial.h>
+
+#include <asm/mach-tango2/devices.h>
+#include <asm/mach-tango2/emhwlib_lram.h>
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_mbus.h>
+#include <asm/mach-tango2/tango2_xenv.h>
+#include <asm/mach-tango2/tango2_board.h>
+#include <asm/mach-tango2/tango2_usb.h>
+
+#include "setup.h"
+#include "xenv.h"
+
+
+/*
+ * helpers to access cpu block registers
+ */
+#define RD_CPU_REG32(r)	\
+		gbus_readl(REG_BASE_cpu_block + (r))
+
+#define WR_CPU_REG32(r, v)	\
+		gbus_writel(REG_BASE_cpu_block + (r), (v))
+
+
+/*
+ * we use xrpc to reboot
+*/
+struct xrpc_block_header {
+	u32 callerid;
+	u32 xrpcid;
+
+	u32 param0;
+	u32 param1;
+	u32 param2;
+	u32 param3;
+	u32 param4;
+
+	u32 headerandblocksize;
+};
+
+#define XRPC_ID_REBOOT		19
+#define SOFT_IRQ_XRPC		(1 << 4)
+
+void tango2_reset_periphs(void)
+{
+	int i;
+
+	local_irq_disable();
+
+	/* Resetting Video block */
+	gbus_writel(REG_BASE_display_block + G2L_RESET_CONTROL, 3);
+	udelay(1);
+	gbus_writel(REG_BASE_display_block + G2L_RESET_CONTROL, 2);
+
+	/* Resetting MPEG0 block */
+	gbus_writel(REG_BASE_mpeg_engine_0 + G2L_RESET_CONTROL, 3);
+	udelay(1);
+	gbus_writel(REG_BASE_mpeg_engine_0 + G2L_RESET_CONTROL, 2);
+
+	/* Resetting MPEG1 block */
+	gbus_writel(REG_BASE_mpeg_engine_1 + G2L_RESET_CONTROL, 3);
+	udelay(1);
+	gbus_writel(REG_BASE_mpeg_engine_1 + G2L_RESET_CONTROL, 2);
+
+	/* Resetting Transport demux block */
+	gbus_writel(REG_BASE_demux_engine + G2L_RESET_CONTROL, 3);
+	udelay(1);
+	gbus_writel(REG_BASE_demux_engine + G2L_RESET_CONTROL, 2);
+
+	/* Resetting Audio0 block */
+	gbus_writel(REG_BASE_audio_engine_0 + G2L_RESET_CONTROL, 3);
+	udelay(1);
+	gbus_writel(REG_BASE_audio_engine_0 + G2L_RESET_CONTROL, 2);
+
+	/* Resetting Audio1 block */
+	gbus_writel(REG_BASE_audio_engine_1 + G2L_RESET_CONTROL, 3);
+	udelay(1);
+	gbus_writel(REG_BASE_audio_engine_1 + G2L_RESET_CONTROL, 2);
+
+	/* restore remap registers to boot state */
+	for (i = 0; i < 4; i++) {
+		gbus_writel(REG_BASE_cpu_block + CPU_remap + i * 4,
+			    em8xxx_remap_registers[i]);
+	}
+	iob();
+
+}
+
+void tango2_cpu_reset(void)
+{
+	struct xrpc_block_header *pB;
+	unsigned long base_addr;
+	int loop;
+
+	/* nowhere to  jump, everything is  in xload format,  lets ask
+	 * xpu to reboot */
+	base_addr = DMEM_BASE_audio_engine_0;
+
+	pB = (struct xrpc_block_header *)base_addr;
+	gbus_writel((unsigned long)&pB->callerid, 0);
+	gbus_writel((unsigned long)&pB->headerandblocksize,
+		    (sizeof(struct xrpc_block_header) + 63) & ~63);
+	gbus_writel((unsigned long)&pB->xrpcid, XRPC_ID_REBOOT);
+
+	/* try to lock xrpc mutex for at most 1 sec */
+	for (loop = 0; loop < 1000; loop++) {
+		if (!gbus_readl(REG_BASE_host_interface + host_mutex10))
+			break;
+		mdelay(1);
+	}
+	gbus_writel(REG_BASE_cpu_block + LR_XPU_STAGE, (unsigned long)pB);
+
+	/* cross our fingers now */
+	gbus_writel(REG_BASE_irq_handler_block + CPU_irq_softset,
+		    SOFT_IRQ_XRPC);
+	while (1);
+}
+
+static void tango2_machine_restart(char *str)
+{
+	board_machine_restart();
+}
+
+void tango2_machine_halt(void)
+{
+	while (1);
+}
+
+void tango2_machine_power_off(void)
+{
+	while (1);
+}
+
+void __init plat_time_init(void)
+{
+	mips_hpt_frequency = em8xxx_cpu_frequency / 2;
+}
+
+void __init plat_mem_setup(void)
+{
+#ifdef CONFIG_SERIAL_8250
+	int i;
+#endif
+
+	_machine_restart = tango2_machine_restart;
+	_machine_halt = tango2_machine_halt;
+	pm_power_off = tango2_machine_power_off;
+
+#ifdef CONFIG_SERIAL_8250
+	/*
+	 * register enable uart(s)
+	 */
+	for (i = 0; i < 2; i++) {
+		struct uart_port uart;
+
+		if (!tango2_uart_enabled(i))
+			continue;
+
+		memset(&uart, 0, sizeof (uart));
+		uart.line = i;
+		uart.uartclk = tango2_uart_baudrate(i) << 4;
+		uart.irq = IRQ_CONTROLLER_IRQ_BASE + LOG2_CPU_UART0_INT + i;
+		uart.flags = UPF_BOOT_AUTOCONF;
+		uart.membase = (unsigned char *)(REG_BASE_cpu_block +
+						 CPU_UART0_base + i * 0x100);
+		uart.iotype = UPIO_MEM;
+		uart.regshift = 2;
+
+		if (early_serial_setup(&uart))
+			printk(KERN_ERR "early_serial_setup failed\n");
+	}
+#endif
+
+	/*
+	 * set I/O /mem regions limit
+	 */
+	ioport_resource.start = 0;
+	ioport_resource.end = 0x80000000UL - 1;
+	iomem_resource.start = 0;
+	iomem_resource.end = 0x80000000UL - 1;
+
+	/* reboot 10s after panic */
+	panic_timeout = 10;
+
+	board_setup();
+	em86xx_mbus_init();
+}
+
+static int __init tango2_register_devices(void)
+{
+	return board_register_devices();
+}
+
+device_initcall(tango2_register_devices);
+
+void tango2_reset_usb(void)
+{
+	static int done = 0;
+	u32 val;
+
+	if (done)
+		return;
+	done = 1;
+
+	WR_USB_REG32(0x0, 0x1);
+	udelay(100);
+	WR_USB_REG32(0x0, 0x0);
+	mdelay(5);
+
+	val = RD_OHCI_REG32(0x08);
+	WR_OHCI_REG32(0x08, val | 0x01);
+	mdelay(5);
+
+	val = RD_USB_REG32(0);
+	WR_USB_REG32(0x0, val | (1 << 19));
+	mdelay(10);
+
+	val = RD_EHCI_REG32(0x10);
+	WR_EHCI_REG32(0x10, val | 0x02);
+	mdelay(10);
+}
+
+EXPORT_SYMBOL(tango2_reset_usb);
+
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./setup.h linux-2.6.31.7-fbx/arch/mips/tango2/setup.h
--- linux-2.6.31.7-fbx/arch/mips/tango2./setup.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/setup.h	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,15 @@
+/*
+ * misc vars/func shared by platform setup code
+ */
+
+#ifndef __SETUP_H
+#define __SETUP_H
+
+/*
+ * in prom.c
+ */
+extern unsigned long em8xxx_cpu_frequency;
+extern unsigned long em8xxx_sys_frequency;
+extern unsigned long em8xxx_remap_registers[4];
+
+#endif
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./sha1.c linux-2.6.31.7-fbx/arch/mips/tango2/sha1.c
--- linux-2.6.31.7-fbx/arch/mips/tango2./sha1.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/sha1.c	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,110 @@
+/*
+ * SHA1 Secure Hash Algorithm.
+ *
+ * dup of  crypto/sha1.c, because we  can't use crypto api  cleanly at
+ * init time...
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/crypto.h>
+#include <linux/cryptohash.h>
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+
+#define SHA1_DIGEST_SIZE	20
+#define SHA1_HMAC_BLOCK_SIZE	64
+
+struct sha1_ctx {
+	u64 count;
+	u32 state[5];
+	u8 buffer[64];
+};
+
+static void __init sha1_init(void *ctx)
+{
+	struct sha1_ctx *sctx = ctx;
+	static const struct sha1_ctx initstate = {
+	  0,
+	  { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 },
+	  { 0, }
+	};
+
+	*sctx = initstate;
+}
+
+static void __init sha1_update(void *ctx, const u8 *data, unsigned int len)
+{
+	struct sha1_ctx *sctx = ctx;
+	unsigned int i, j;
+	u32 temp[SHA_WORKSPACE_WORDS];
+
+	j = (sctx->count >> 3) & 0x3f;
+	sctx->count += len << 3;
+
+	if ((j + len) > 63) {
+		memcpy(&sctx->buffer[j], data, (i = 64-j));
+		sha_transform(sctx->state, sctx->buffer, temp);
+		for ( ; i + 63 < len; i += 64) {
+			sha_transform(sctx->state, &data[i], temp);
+		}
+		j = 0;
+	}
+	else i = 0;
+	memset(temp, 0, sizeof(temp));
+	memcpy(&sctx->buffer[j], &data[i], len - i);
+}
+
+/* Add padding and return the message digest. */
+static void __init sha1_final(void* ctx, u8 *out)
+{
+	struct sha1_ctx *sctx = ctx;
+	u32 i, j, index, padlen;
+	u64 t;
+	u8 bits[8] = { 0, };
+	static const u8 padding[64] = { 0x80, };
+
+	t = sctx->count;
+	bits[7] = 0xff & t; t>>=8;
+	bits[6] = 0xff & t; t>>=8;
+	bits[5] = 0xff & t; t>>=8;
+	bits[4] = 0xff & t; t>>=8;
+	bits[3] = 0xff & t; t>>=8;
+	bits[2] = 0xff & t; t>>=8;
+	bits[1] = 0xff & t; t>>=8;
+	bits[0] = 0xff & t;
+
+	/* Pad out to 56 mod 64 */
+	index = (sctx->count >> 3) & 0x3f;
+	padlen = (index < 56) ? (56 - index) : ((64+56) - index);
+	sha1_update(sctx, padding, padlen);
+
+	/* Append length */
+	sha1_update(sctx, bits, sizeof bits);
+
+	/* Store state in digest */
+	for (i = j = 0; i < 5; i++, j += 4) {
+		u32 t2 = sctx->state[i];
+		out[j+3] = t2 & 0xff; t2>>=8;
+		out[j+2] = t2 & 0xff; t2>>=8;
+		out[j+1] = t2 & 0xff; t2>>=8;
+		out[j  ] = t2 & 0xff;
+	}
+
+	/* Wipe context */
+	memset(sctx, 0, sizeof *sctx);
+}
+
+void __init sha1_full(u8 *digest, const u8 *src, u32 len)
+{
+	struct sha1_ctx ctx;
+	int i;
+
+	sha1_init(&ctx);
+	sha1_update(&ctx, src, len);
+	sha1_final(&ctx, digest);
+
+	for (i = 0; i < SHA1_DIGEST_SIZE / 2; i++)
+		digest[i] = digest[SHA1_DIGEST_SIZE - i - 1];
+}
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./xenv.c linux-2.6.31.7-fbx/arch/mips/tango2/xenv.c
--- linux-2.6.31.7-fbx/arch/mips/tango2./xenv.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/xenv.c	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,113 @@
+/*****************************************
+ Copyright © 2004-2005
+ Sigma Designs, Inc. All Rights Reserved
+ Proprietary and Confidential
+ *****************************************/
+
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include "xenv.h"
+
+#if 0
+# define DPRINTK(fmt, args...)	printk(KERN_DEBUG "xenv: " fmt, ## args)
+#else
+# define DPRINTK(fmt, args...)
+#endif
+
+void sha1_full(u8 *digest, const u8 *src, u32 len);
+
+#define REC_SIZE(x)	((((u16)x[0] & 0xff) << 8) | ((u16)x[1] & 0xff))
+#define REC_ATTR(x)	((x[0] & 0xff) >> 4)
+
+/*
+ * check for valid XENV at given address
+ */
+int __init xenv_isvalid(u32 *base, u32 maxsize)
+{
+	u32 env_size = base[0];
+
+	if ((24 <= env_size) && (env_size <= maxsize)) {
+		u8 hash[20];
+
+		memset(hash, 0, sizeof (hash));
+		sha1_full(hash, (const u8 *)(base + 6), env_size - 24);
+		if (memcmp(base + 1, hash, 5) != 0) {
+			DPRINTK("corrupted\n");
+			return -1;
+		}
+
+		/* valid xenv ! */
+		return env_size;
+	}
+
+	DPRINTK("runaway %d\n", env_size);
+	return -1;
+}
+
+int __init xenv_foreach(u32 *base, u32 size,
+			void (*cb)(char *recordname, void *data, u32 datasize))
+{
+	int i;
+
+	/* jump over first header */
+	i = 24;
+
+	/* loop on each record name */
+	while (i < size) {
+		u16 rec_size;
+		char *p, *recordname;
+		void *data;
+		u32 key_len, data_len;
+
+		p = (char *)base + i;
+		rec_size = REC_SIZE(p);
+		recordname = p + 2;
+		key_len = strlen(recordname);
+		data = recordname + key_len + 1;
+		data_len = rec_size - 2 - key_len - 1;
+
+		cb(recordname, data, data_len);
+		i += rec_size;
+	}
+
+	return -1;
+}
+
+
+#ifdef CONFIG_TANGO2_XENV_DUMP
+void __init xenv_dump(u32 *base, u32 size)
+{
+	int i;
+	u32 records = 0;
+
+	printk("@%p\n", base);
+
+	/* jump over first header */
+	i = 24;
+
+	while (i < size){
+		u8 rec_attr;
+		u16 rec_size;
+		char *p, *recordname, *x;
+		u32 key_len;
+
+		p = (char *)base + i;
+		rec_attr = REC_ATTR(p);
+		rec_size = REC_SIZE(p);
+		recordname = p + 2;
+		key_len = strlen(recordname);
+
+		printk("(0x%02x) [%s] =", rec_attr, recordname);
+		for (x = recordname + key_len + 1;
+		     x < recordname + rec_size - 2; x++)
+			printk(" %02x", (u8)*x);
+		printk(" .\n");
+
+		records++;
+		i += rec_size;
+	}
+
+	printk("%d records, %d bytes\n\n", records, size);
+}
+#endif
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./xenv_config.c linux-2.6.31.7-fbx/arch/mips/tango2/xenv_config.c
--- linux-2.6.31.7-fbx/arch/mips/tango2./xenv_config.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/xenv_config.c	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,449 @@
+/*
+ * Check and  read full xenv config  at boot if valid,  else will stop
+ * boot process or use failsafe values.
+ */
+
+#include <linux/module.h>
+#include <asm/bootinfo.h>
+
+#include <asm/mach-tango2/emhwlib_lram.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_regs.h>
+
+#include "xenv.h"
+#include "xenvkeys.h"
+
+/*
+ * use CPU_remap4 to access XENV content
+ */
+#define REMAPPED_REG	CPU_remap4
+#define REMAPPED_BASE	KSEG1ADDR(CPU_remap4_address)
+
+/*
+ * cached values of xenv content
+ */
+#define XENV_MAX_FLASH_PARTITIONS   16
+
+
+/*
+ * default is  to have one  partition on each  flash at offset  0 that
+ * span all the flash. If CONFIG_TANGO2_XENV_DEF_CSx_SIZE is set to 0,
+ * cs will be ignored.
+ */
+static u32 cs_flash_size[4] = {
+	CONFIG_TANGO2_XENV_DEF_CS0_SIZE,
+	CONFIG_TANGO2_XENV_DEF_CS1_SIZE,
+	CONFIG_TANGO2_XENV_DEF_CS2_SIZE,
+	CONFIG_TANGO2_XENV_DEF_CS3_SIZE
+};
+
+static u32 cs_flash_parts[4] = { 1, 1, 1, 1 };
+
+static u32 flash_parts_size[4][XENV_MAX_FLASH_PARTITIONS] = {
+	{ CONFIG_TANGO2_XENV_DEF_CS0_SIZE },
+	{ CONFIG_TANGO2_XENV_DEF_CS1_SIZE },
+	{ CONFIG_TANGO2_XENV_DEF_CS2_SIZE },
+	{ CONFIG_TANGO2_XENV_DEF_CS3_SIZE },
+};
+
+static u32 flash_parts_offset[4][XENV_MAX_FLASH_PARTITIONS] = {
+	{ 0 },
+	{ 0 },
+	{ 0 },
+	{ 0 },
+};
+
+static u32 scard_5v_pin = 0;
+static u32 scard_off_pin = 0;
+static u32 scard_cmd_pin = 0;
+
+/* enabled_devices bits */
+#define ISAIDE_SHIFT		0
+#define BMIDE_SHIFT		1
+#define PCIHOST_SHIFT		2
+#define ETHERNET_SHIFT		3
+#define IR_SHIFT		4
+#define FIP_SHIFT		5
+#define I2CM_SHIFT		6
+#define I2CS_SHIFT		7
+#define SDIO_SHIFT		8
+#define USB_SHIFT		9
+#define PCI1_SHIFT		10
+#define PCI2_SHIFT		11
+#define PCI3_SHIFT		12
+#define PCI4_SHIFT		13
+#define PCI5_SHIFT		14
+#define PCI6_SHIFT		15
+#define SATA_SHIFT		16
+#define SCARD_SHIFT		17
+
+static u32 enabled_devices =
+	(CONFIG_TANGO2_XENV_DEF_PCI_ID1 << PCI1_SHIFT) |
+	(CONFIG_TANGO2_XENV_DEF_PCI_ID2 << PCI2_SHIFT) |
+	(CONFIG_TANGO2_XENV_DEF_PCI_ID3 << PCI3_SHIFT) |
+	(CONFIG_TANGO2_XENV_DEF_PCI_ID4 << PCI4_SHIFT) |
+	(CONFIG_TANGO2_XENV_DEF_ENET << ETHERNET_SHIFT) |
+	(CONFIG_TANGO2_XENV_DEF_FIP << FIP_SHIFT) |
+	(CONFIG_TANGO2_XENV_DEF_I2CM << I2CM_SHIFT) |
+	(CONFIG_TANGO2_XENV_DEF_I2CS << I2CS_SHIFT) |
+	(CONFIG_TANGO2_XENV_DEF_BMIDE << BMIDE_SHIFT) |
+	(CONFIG_TANGO2_XENV_DEF_IR << IR_SHIFT) |
+	(CONFIG_TANGO2_XENV_DEF_PCIHOST << PCIHOST_SHIFT) |
+	(CONFIG_TANGO2_XENV_DEF_USB << USB_SHIFT);
+
+static u32 uart_baudrate = CONFIG_TANGO2_XENV_DEF_BAUDRATE;
+static u32 uart_baudrate0 = 0;
+static u32 uart_baudrate1 = 0;
+
+static u32 uart_used_ports = (CONFIG_TANGO2_XENV_DEF_UART0 |
+			       (CONFIG_TANGO2_XENV_DEF_UART1 << 1));
+
+/* mac address to use if xenv is not readable  */
+static const u8 def_mac_address[6] = { 0x48, 0x4a, 0xe5, 0x00, 0x00, 0x01 };
+static u8 mac_address[6];
+static u32 pcidev_irq_route[4] = { CONFIG_TANGO2_XENV_DEF_PCI_ID1_IRQ,
+				   CONFIG_TANGO2_XENV_DEF_PCI_ID2_IRQ,
+				   CONFIG_TANGO2_XENV_DEF_PCI_ID3_IRQ,
+				   CONFIG_TANGO2_XENV_DEF_PCI_ID4_IRQ };
+
+static char xenv_cmdline[CL_SIZE] = { 0 };
+static char xenv_version[128] = { };
+
+static u32 dram_stuffing = 0;
+
+#ifdef CONFIG_TANGO2_XENV_READ
+/*
+ * called for each entry found in xenv
+ */
+void __init xenv_val_cb(char *recordname, void *data, u32 datasize)
+{
+	char buf[64];
+	int i;
+
+#define CHECK_AND_STORE(_key, _reqlen, _var)				\
+	if (!strcmp(_key, recordname) && datasize <= _reqlen)	{	\
+		memcpy(&_var, data, _reqlen);				\
+		return;							\
+	}
+
+	CHECK_AND_STORE(XENV_KEY_ENABLED_DEVICES, 4, enabled_devices);
+	CHECK_AND_STORE(XENV_KEY_DEF_BAUDRATE, 4, uart_baudrate);
+	CHECK_AND_STORE(XENV_KEY_UART0_BAUDRATE, 4, uart_baudrate0);
+	CHECK_AND_STORE(XENV_KEY_UART1_BAUDRATE, 4, uart_baudrate1);
+	CHECK_AND_STORE(XENV_KEY_UART_USED_PORTS, 4, uart_used_ports);
+	for (i = 1; i < 5; i++) {
+		sprintf(buf, XENV_KEYS_PCI_IRQ_ROUTE, i);
+		CHECK_AND_STORE(buf, 4, pcidev_irq_route[i - 1]);
+	}
+
+	CHECK_AND_STORE(XENV_KEY_SCARD_OFF, 4, scard_off_pin);
+	CHECK_AND_STORE(XENV_KEY_SCARD_5V, 4, scard_5v_pin);
+	CHECK_AND_STORE(XENV_KEY_SCARD_CMD, 4, scard_cmd_pin);
+
+	CHECK_AND_STORE(XENV_KEY_X_DRAM_STUFFING, 4, dram_stuffing);
+
+	for (i = 0; i < 4; i++) {
+		int j;
+
+		sprintf(buf, XENV_KEYS_CS_SIZE, i);
+		CHECK_AND_STORE(buf, 4, cs_flash_size[i]);
+
+		sprintf(buf, XENV_KEYS_CS_PARTS, i);
+		CHECK_AND_STORE(buf, 4, cs_flash_parts[i]);
+
+		for (j = 1; j < XENV_MAX_FLASH_PARTITIONS; j++) {
+
+			sprintf(buf, XENV_KEYS_CS_PART_SIZE, i, j);
+			CHECK_AND_STORE(buf, 4, flash_parts_size[i][j - 1]);
+
+			sprintf(buf, XENV_KEYS_CS_PART_OFFSET, i, j);
+			CHECK_AND_STORE(buf, 4, flash_parts_offset[i][j - 1]);
+		}
+	}
+
+	if (!strcmp(recordname, XENV_KEY_LINUX_CMD) &&
+	    datasize <= sizeof (xenv_cmdline) - 1) {
+		memcpy(xenv_cmdline, data, datasize);
+		xenv_cmdline[datasize] = 0;
+	}
+
+	if (!strcmp(recordname, XENV_KEY_VERSION) &&
+	    datasize <= sizeof (xenv_version) - 1) {
+		memcpy(xenv_version, data, datasize);
+		xenv_version[datasize] = 0;
+	}
+}
+
+/*
+ * try to read config from XENV
+ */
+static int __init xenv_read_content(void)
+{
+	unsigned long xenv_addr;
+	int xenv_size;
+	uint32_t mac_lo, mac_hi;
+
+	/*
+	 * fetch XENV address
+	 */
+	xenv_addr = gbus_readl(REG_BASE_cpu_block + LR_XENV_LOCATION);
+	if (!xenv_addr)
+		return 1;
+
+	/*
+	 * got the xenv address in  gbus form, now convert it in remap
+	 * form so we can access it
+	 */
+	gbus_writel(REG_BASE_cpu_block + REMAPPED_REG, xenv_addr & 0xfc000000);
+	iob();
+	xenv_addr = REMAPPED_BASE + (xenv_addr & 0x03ffffff);
+
+	/*
+	 * check xenv sanity
+	 */
+	xenv_size = xenv_isvalid((u32 *)xenv_addr, MAX_XENV_SIZE);
+	if (xenv_size < 0)
+		return 1;
+
+#ifdef CONFIG_TANGO2_XENV_DUMP
+	xenv_dump((u32 *)xenv_addr, xenv_size);
+#endif
+
+	/*
+	 * ok, we can start to load each wanted value
+	 */
+	xenv_foreach((u32 *)xenv_addr, xenv_size, xenv_val_cb);
+
+	/*
+	 * load remaining values
+	 */
+	mac_hi = gbus_readl(REG_BASE_cpu_block + LR_ETH_MAC_HI);
+	mac_lo = gbus_readl(REG_BASE_cpu_block + LR_ETH_MAC_LO);
+	mac_hi = cpu_to_be32(mac_hi);
+	mac_lo = cpu_to_be32(mac_lo);
+	memcpy(mac_address, (u8 *)&mac_hi + 2, 2);
+	memcpy(mac_address + 2, &mac_lo, 4);
+
+	return 0;
+}
+#endif
+
+/*
+ * load default values and try to fetch xenv content
+ */
+int __init xenv_config(void)
+{
+#ifndef CONFIG_TANGO2_XENV_READ
+	/* will use default values */
+	return 0;
+#else
+	/*
+	 * try to load XENV content
+	 */
+	if (xenv_read_content() == 0) {
+		/* ok */
+		return 0;
+	}
+
+#ifndef CONFIG_TANGO2_XENV_READ_SAFE
+	/* fallback to failsafe values */
+	return 1;
+#else
+	/* stop boot process */
+	while (1)
+		cpu_relax();
+	/* not reached */
+	return 1;
+#endif
+
+#endif /* !CONFIG_TANGO2_XENV_READ */
+}
+
+
+/*
+ * helpers to access xenv configuration cached data
+ */
+
+/*
+ * enabled device query function
+ */
+#define BUILD_ENABLED(name, shift)					\
+int tango2_##name##_enabled(void)					\
+{									\
+	return (((enabled_devices >> shift) & 1) != 0) ? 1 : 0;	\
+}
+
+BUILD_ENABLED(isaide, ISAIDE_SHIFT)
+BUILD_ENABLED(bmide, BMIDE_SHIFT)
+BUILD_ENABLED(ir, IR_SHIFT)
+BUILD_ENABLED(fip, FIP_SHIFT)
+BUILD_ENABLED(ethernet, ETHERNET_SHIFT)
+BUILD_ENABLED(usb, USB_SHIFT)
+BUILD_ENABLED(sdio, SDIO_SHIFT)
+BUILD_ENABLED(i2cm, I2CM_SHIFT)
+BUILD_ENABLED(i2cs, I2CS_SHIFT)
+BUILD_ENABLED(pci_host, PCIHOST_SHIFT)
+BUILD_ENABLED(sata, SATA_SHIFT)
+BUILD_ENABLED(scard, SCARD_SHIFT)
+
+int tango2_pcidev_enabled(int idsel)
+{
+	if (!tango2_pci_host_enabled())
+		return 0;
+
+	idsel--;
+	return (((enabled_devices >> (idsel + PCI1_SHIFT)) & 1) != 0) ? 1 : 0;
+}
+
+int tango2_pcidev_irq_map(int pci_idsel, int int_num)
+{
+	int route;
+	int irq;
+
+	route = pcidev_irq_route[pci_idsel - 1];
+
+	/* int_num: 0-3 = INTA-D */
+	irq = (int)((route >> (int_num * 8)) & 0x3);
+	if (irq >= 0)
+		irq += (IRQ_CONTROLLER_IRQ_BASE + LOG2_CPU_PCI_INTA);
+	return irq;
+}
+
+int tango2_ethernet_getmac(unsigned char *mac)
+{
+	/* filter broadcast & multicast addresses */
+	if (mac_address[0] == 0x01 || mac_address[0] == 0xff)
+		memcpy(mac, def_mac_address, 6);
+	else
+		memcpy(mac, mac_address, 6);
+	return 0;
+}
+
+int tango2_uart_enabled(int uart)
+{
+	return (((uart_used_ports >> uart) & 1) != 0) ? 1 : 0;
+}
+
+int tango2_uart_baudrate(int uart)
+{
+	if (uart) {
+		if (uart_baudrate1)
+			return uart_baudrate1;
+	} else {
+		if (uart_baudrate0)
+			return uart_baudrate0;
+	}
+	return uart_baudrate;
+}
+
+int tango2_flash_get_info(int cs, unsigned int *size, unsigned int *part_count)
+{
+	if (cs > 3)
+		return 1;
+
+	*size = cs_flash_size[cs];
+	*part_count = 0;
+	if (cs_flash_size[cs] > 0)
+		*part_count = cs_flash_parts[cs];
+
+	return 0;
+}
+
+int tango2_flash_get_parts(int cs, unsigned int *offset, unsigned int *size)
+{
+	int i;
+
+	if (!cs_flash_size[cs])
+		return 1;
+
+	for (i = 0; i < cs_flash_parts[cs]; i++) {
+		offset[i] = flash_parts_offset[cs][i];
+		size[i] = flash_parts_size[cs][i];
+	}
+
+	return 0;
+}
+
+const char *tango2_xenv_cmdline(void)
+{
+	/* remove "" from command line */
+	if (xenv_cmdline[0] == '"') {
+		int len;
+
+		len = strlen(xenv_cmdline);
+		if (xenv_cmdline[len - 1] == '"')
+			xenv_cmdline[len - 1] = 0;
+		return xenv_cmdline + 1;
+	}
+	return xenv_cmdline;
+}
+
+const char *tango2_xenv_version(void)
+{
+	/* remove "" from version */
+	if (xenv_version[0] == '"') {
+		int len;
+
+		len = strlen(xenv_version);
+		if (xenv_version[len - 1] == '"')
+			xenv_version[len - 1] = 0;
+		return xenv_version + 1;
+	}
+	return xenv_version;
+}
+
+unsigned int tango2_get_dramstuffing(void)
+{
+	return dram_stuffing;
+}
+
+/*
+ * show enabled devices according to xenv content
+ */
+void __init tango2_device_info(void)
+{
+	int i;
+
+	printk(KERN_INFO "SMP863x Enabled Devices under Linux "
+	       "(from XENV): 0x%08x\n", enabled_devices);
+
+	printk(KERN_INFO);
+	if (tango2_isaide_enabled())
+		printk(" ISA/IDE");
+	if (tango2_bmide_enabled())
+		printk(" BM/IDE");
+	if (tango2_pci_host_enabled())
+		printk(" PCIHost");
+	if (tango2_ethernet_enabled())
+		printk(" Ethernet");
+	if (tango2_ir_enabled())
+		printk(" IR");
+	if (tango2_fip_enabled())
+		printk(" FIP");
+	if (tango2_i2cm_enabled())
+		printk(" I2CM");
+	if (tango2_i2cs_enabled())
+		printk(" I2CS");
+	if (tango2_sdio_enabled())
+		printk(" SDIO");
+	if (tango2_usb_enabled())
+		printk(" USB");
+	for (i = 1; i <= 6; i++) {
+		if (tango2_pcidev_enabled(i))
+			printk(" PCIDev%d", i);
+	}
+	if (tango2_sata_enabled())
+		printk(" SATA");
+	if (tango2_scard_enabled())
+		printk(" SCARD");
+	printk("\n");
+}
+
+EXPORT_SYMBOL(tango2_ethernet_getmac);
+EXPORT_SYMBOL(tango2_ethernet_enabled);
+EXPORT_SYMBOL(tango2_flash_get_parts);
+EXPORT_SYMBOL(tango2_flash_get_info);
+EXPORT_SYMBOL(tango2_xenv_version);
+EXPORT_SYMBOL(tango2_bmide_enabled);
+EXPORT_SYMBOL(tango2_ir_enabled);
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./xenv.h linux-2.6.31.7-fbx/arch/mips/tango2/xenv.h
--- linux-2.6.31.7-fbx/arch/mips/tango2./xenv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/xenv.h	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,83 @@
+/*****************************************
+ Copyright © 2004-2005
+ Sigma Designs, Inc. All Rights Reserved
+ Proprietary and Confidential
+ *****************************************/
+/**
+  @file   xenv.h
+  @brief
+
+  The prototypes below act on a clear area respecting the xenv format.
+
+  (De)ciphering the  area, as well as committing  the changes (writing
+  the area to flash) are trivial add-ons on top of this API.
+
+  The underlying  implementation is not optimized for  speed (read and
+  write in  O(nrecords)). There  is no fragmentation  (data completely
+  rearranged at each write).
+
+  It is  not advised to repeatedly  act on flash stored  data, for the
+  device does  not support  unlimited read/write operations  (refer to
+  spec)
+
+  Power  loss when  committing the  changes cause  loss of  the stored
+  data.  This  can be avoided  by storing the  same data twice  to two
+  different sectors.
+
+  --------------------------------------------------------------------------
+  Specification   of   a   secure   storage   on   serial   flash   of
+  reboot-persistent data (xenv format)
+
+  We  describe a  way  to  concatenate (at  most  4KByte area  (12bits
+  limit)) variable  length records identified  by a string,  the `key'
+  (working much like Windows registry)
+
+  Page, seen as a byte array, is
+
+  0          4                   24                 env_size         4KB
+  | env_size | SHA-1 of following | rec0 | rec1 | .. | recn | xx xx .. |
+
+  The SHA-1 extent is env_size-24.
+
+  Description of a rec (bytes):
+
+  |4bits   12bits (2bytes)   | variable, NULL terminated | variable         |
+  attr     total record size   record name (string)        record value
+
+  attr =
+   XENV_ATTR_RW
+   XENV_ATTR_RO can be written once only but can be deleted
+   XENV_ATTR_OTP this record can be written once only and cannot be deleted
+  --------------------------------------------------------------------------
+
+  @author Emmanuel Michon
+  @date   2005-05-17
+*/
+
+#ifndef __XENV_H__
+#define __XENV_H__
+
+#include <linux/types.h>
+
+#define MAX_XENV_SIZE   16384
+
+/**
+   Check for compliance with xenv format
+
+   May be corrupted by:
+   - forgot to format
+   - power loss during sflash write
+   - intrusion
+
+   @param base
+   @param size
+   @return -ReturnValue-: env_size>=0 if valid, -1 if not.
+*/
+int xenv_isvalid(u32 *base, u32 maxsize);
+
+int xenv_foreach(u32 *base, u32 size,
+		 void (*cb)(char *recordname, void *data, u32 datasize));
+
+void xenv_dump(u32 *base, u32 size);
+
+#endif // __XENV_H__
diff -Nruw linux-2.6.31.7-fbx/arch/mips/tango2./xenvkeys.h linux-2.6.31.7-fbx/arch/mips/tango2/xenvkeys.h
--- linux-2.6.31.7-fbx/arch/mips/tango2./xenvkeys.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/arch/mips/tango2/xenvkeys.h	2010-03-18 18:28:48.582755223 +0100
@@ -0,0 +1,96 @@
+
+/* 
+ * The keys defined in XENV, more can be added.
+ */
+
+#ifndef __XENV_KEYS_H__
+#define __XENV_KEYS_H__
+
+#define XENV_KEY_X_BOOT_LOCATION    "x.boot"
+#define XENV_KEY_X_DRAM_STUFFING    "x.ds"
+#define XENV_KEY_X_D0_CFG           "x.d0.cfg"
+#define XENV_KEY_X_D1_CFG           "x.d1.cfg"
+#define XENV_KEY_X_D0_DELAY         "x.d0.dl0"
+#define XENV_KEY_X_D1_DELAY         "x.d1.cfg"
+#define XENV_KEY_X_DRAMTEST         "x.dt"
+#define XENV_KEY_X_PLL3             "x.pll3"
+#define XENV_KEY_X_MUX              "x.mux"
+#define XENV_KEY_X_CSF              "x.csf"
+
+#define XENV_KEY_BOARD_ID           "a.board_id"
+#define XENV_KEY_CHIP_REV           "a.chip_rev"
+
+#define XENV_KEY_PREMUX             "a.premux"
+#define XENV_KEY_AVCLK_MUX          "a.avclk_mux"
+#define XENV_KEY_HOSTCLK_MUX        "a.hostclk_mux"
+#define XENV_KEY_IRQ_RISE_EDGE_LO   "a.irq_rise_edge_lo"
+#define XENV_KEY_IRQ_FALL_EDGE_LO   "a.irq_fall_edge_lo"
+#define XENV_KEY_GPIO_IRQ_MAP       "a.gpio_irq_map"
+
+#define XENV_KEY_DEF_BAUDRATE       "a.baudrate"
+#define XENV_KEY_UART0_BAUDRATE     "a.uart0_baudrate"
+#define XENV_KEY_UART1_BAUDRATE     "a.uart1_baudrate"
+#define XENV_KEY_CONSOLE_UART_PORT  "a.uart_console_port"
+#define XENV_KEY_UART_USED_PORTS    "a.uart_used_ports"
+
+#define XENV_KEY_PB_CS_CONFIG       "a.pb_cs_config"
+#define XENV_KEY_DEF_TIMING         "a.pb_def_timing"
+#define XENV_KEY_PB_TIMING0         "a.pb_timing0"
+#define XENV_KEY_PB_USE_TIMING0     "a.pb_use_timing0"
+#define XENV_KEY_PB_TIMING1         "a.pb_timing1"
+#define XENV_KEY_PB_USE_TIMING1     "a.pb_use_timing1"
+#define XENV_KEY_PB_TIMING2         "a.pb_timing2"
+#define XENV_KEY_PB_USE_TIMING2     "a.pb_use_timing2"
+#define XENV_KEY_PB_TIMING3         "a.pb_timing3"
+#define XENV_KEY_PB_USE_TIMING3     "a.pb_use_timing3"
+#define XENV_KEY_PB_TIMING4         "a.pb_timing4"
+#define XENV_KEY_PB_USE_TIMING4     "a.pb_use_timing4"
+#define XENV_KEY_PB_TIMING5         "a.pb_timing5"
+#define XENV_KEY_PB_USE_TIMING5     "a.pb_use_timing5"
+
+#define XENV_KEY_IRQ_RISE_EDGE_HI   "a.irq_rise_edge_hi"
+#define XENV_KEY_IRQ_FALL_EDGE_HI   "a.irq_fall_edge_hi"
+
+#define XENV_KEY_ENABLED_DEVICES    "a.enable_devices"
+
+#define XENV_KEY_ETH_MAC            "a.eth_mac"
+
+#define XENV_KEY_SCARD_OFF          "a.scard_off_pin"
+#define XENV_KEY_SCARD_5V           "a.scard_5v_pin"
+#define XENV_KEY_SCARD_CMD          "a.scard_cmd_pin"
+
+#define XENV_KEY_ISAIDE_IRQ_ROUTE   "a.isaide_irq_route"
+#define XENV_KEY_ISAIDE_TIMING_SLOT "a.isaide_timing_slot"
+
+#define XENV_KEY_GPIO_DIR           "a.gpio_dir"
+#define XENV_KEY_GPIO_DATA          "a.gpio_data"
+
+#define XENV_KEY_LINUX_CMD          "a.linux_cmd"
+
+#define XENV_KEY_Z_BOOT_DEF         "z.default_boot"
+
+#define XENV_KEY_YAMON_ENV          "y.env"
+#define XENV_KEY_YAMON_IPADDR       "y.ipaddr"
+#define XENV_KEY_YAMON_SUBNET       "y.subnetmask"
+#define XENV_KEY_YAMON_GATEWAY      "y.gateway"
+#define XENV_KEY_YAMON_START        "y.start"
+#define XENV_KEY_YAMON_STARTDELAY   "y.startdelay"
+
+#define XENV_KEYS_PCI_IRQ_ROUTE     "a.pcidev%d_irq_route"
+#define XENV_KEYS_CD_FREQUENCY      "a.cd%d_freq"
+#define XENV_KEYS_UART_GPIO_MODE    "a.uart%d_gpio_mode"
+#define XENV_KEYS_UART_GPIO_DIR     "a.uart%d_gpio_dir"
+#define XENV_KEYS_UART_GPIO_DATA    "a.uart%d_gpio_data"
+
+#define XENV_KEYS_Z_BOOT_LOCATION   "z.boot%d"
+
+#define XENV_KEYS_CS_SIZE           "l.cs%d_size"
+#define XENV_KEYS_CS_PARTS          "l.cs%d_parts"
+
+#define XENV_KEYS_CS_PART_SIZE      "l.cs%d_part%d_size"
+#define XENV_KEYS_CS_PART_OFFSET    "l.cs%d_part%d_offset" 
+
+#define XENV_KEY_VERSION            "a.xenv_version"
+
+#endif
+
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/config	2011-09-09 16:18:14.300215659 +0200
@@ -0,0 +1,1879 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31.7
+# Fri Sep  9 16:17:15 2011
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+CONFIG_TANGO2=y
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+CONFIG_TANGO2_XENV_READ=y
+
+#
+# XENV config
+#
+# CONFIG_TANGO2_XENV_DUMP is not set
+# CONFIG_TANGO2_XENV_READ_SAFE is not set
+CONFIG_TANGO2_XENV_DEF_CS0_SIZE=0x0
+CONFIG_TANGO2_XENV_DEF_CS1_SIZE=0x0
+CONFIG_TANGO2_XENV_DEF_CS2_SIZE=0x0
+CONFIG_TANGO2_XENV_DEF_CS3_SIZE=0x0
+CONFIG_TANGO2_XENV_DEF_UART0=0
+CONFIG_TANGO2_XENV_DEF_UART1=0
+CONFIG_TANGO2_XENV_DEF_BAUDRATE=115200
+CONFIG_TANGO2_XENV_DEF_ENET=0
+CONFIG_TANGO2_XENV_DEF_FIP=0
+CONFIG_TANGO2_XENV_DEF_I2CM=0
+CONFIG_TANGO2_XENV_DEF_I2CS=0
+CONFIG_TANGO2_XENV_DEF_BMIDE=0
+CONFIG_TANGO2_XENV_DEF_IR=0
+CONFIG_TANGO2_XENV_DEF_PCIHOST=0
+CONFIG_TANGO2_XENV_DEF_PCI_ID1=0
+CONFIG_TANGO2_XENV_DEF_PCI_ID1_IRQ=0x0
+CONFIG_TANGO2_XENV_DEF_PCI_ID2=0
+CONFIG_TANGO2_XENV_DEF_PCI_ID2_IRQ=0x0
+CONFIG_TANGO2_XENV_DEF_PCI_ID3=0
+CONFIG_TANGO2_XENV_DEF_PCI_ID3_IRQ=0x0
+CONFIG_TANGO2_XENV_DEF_PCI_ID4=0
+CONFIG_TANGO2_XENV_DEF_PCI_ID4_IRQ=0x0
+CONFIG_TANGO2_XENV_DEF_USB=0
+CONFIG_ARCH_FBX5_B=y
+CONFIG_FBX5B_FBXMTD_LAYOUT_READ_BANK1_TAG=y
+# CONFIG_FBX5B_FBXMTD_LAYOUT_ALL_RW is not set
+# CONFIG_FBX5B_FBXMTD_LAYOUT_NOCRC is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CEVT_R4K=y
+CONFIG_CSRC_R4K_LIB=y
+CONFIG_CSRC_R4K=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_EARLY_PRINTK is not set
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DMCRYPTATBOOT is not set
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+# CONFIG_SHMEM is not set
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_FREEZER is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+CONFIG_MMU=y
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_NETSKBPAD=16
+# CONFIG_NETRXTHREAD is not set
+# CONFIG_SKB_RECYCLE is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_XFRM_GC_THRESH=1024
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=y
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_HL is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+CONFIG_NETFILTER_XT_MATCH_OWNER=y
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_FFN is not set
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+# CONFIG_IP_NF_TARGET_LOG is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=y
+# CONFIG_IP6_NF_MATCH_AH is not set
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
+# CONFIG_IP6_NF_MATCH_FRAG is not set
+# CONFIG_IP6_NF_MATCH_OPTS is not set
+# CONFIG_IP6_NF_MATCH_HL is not set
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
+# CONFIG_IP6_NF_MATCH_MH is not set
+# CONFIG_IP6_NF_MATCH_RT is not set
+# CONFIG_IP6_NF_TARGET_HL is not set
+# CONFIG_IP6_NF_TARGET_LOG 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_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_FBXATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=y
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_FREEBOX_PROCFS=y
+# CONFIG_MTD is not set
+CONFIG_FREEBOX_MTD=y
+CONFIG_FREEBOX_MTD_BACKEND_AMD=y
+# CONFIG_FREEBOX_MTD_BACKEND_INTEL is not set
+CONFIG_FREEBOX_MTD_BLK=y
+CONFIG_FREEBOX_MTD_CHAR=y
+
+#
+# Mapping drivers
+#
+CONFIG_FREEBOX_MTD_MAP_DRV_FBX=y
+# CONFIG_FREEBOX_MTD_MAP_DRV_BCM963XX is not set
+# CONFIG_FREEBOX_MTD_MAP_IOCTL is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+CONFIG_IDE_XFER_MODE=y
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+CONFIG_BLK_DEV_IDE_TANGO2=m
+CONFIG_BLK_DEV_IDEDMA=y
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=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 is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=y
+# CONFIG_DM_SNAPSHOT is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_ZERO is not set
+# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_HAPPYMEAL is not set
+CONFIG_TANGO2_ENET=y
+CONFIG_TANGO2_PCINET_H=m
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=8
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PXA is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_FREEBOX_GPIO=y
+# CONFIG_FREEBOX_JTAG is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_FREEBOX_WATCHDOG is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_DVB_CORE=y
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_TUNER=y
+CONFIG_MEDIA_TUNER_CUSTOMISE=y
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_DVB_DYNAMIC_MINORS is not set
+CONFIG_DVB_CAPTURE_DRIVERS=y
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+# CONFIG_TTPCI_EEPROM is not set
+# CONFIG_DVB_BUDGET_CORE is not set
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=y
+# CONFIG_DVB_USB_DEBUG is not set
+# CONFIG_DVB_USB_A800 is not set
+# CONFIG_DVB_USB_DIBUSB_MB is not set
+# CONFIG_DVB_USB_DIBUSB_MC is not set
+CONFIG_DVB_USB_DIB0700=m
+# CONFIG_DVB_USB_UMT_010 is not set
+# CONFIG_DVB_USB_CXUSB is not set
+# CONFIG_DVB_USB_M920X is not set
+# CONFIG_DVB_USB_GL861 is not set
+# CONFIG_DVB_USB_AU6610 is not set
+# CONFIG_DVB_USB_DIGITV is not set
+# CONFIG_DVB_USB_VP7045 is not set
+# CONFIG_DVB_USB_VP702X is not set
+# CONFIG_DVB_USB_GP8PSK is not set
+# CONFIG_DVB_USB_NOVA_T_USB2 is not set
+# CONFIG_DVB_USB_TTUSB2 is not set
+# CONFIG_DVB_USB_DTT200U is not set
+# CONFIG_DVB_USB_OPERA1 is not set
+# CONFIG_DVB_USB_AF9005 is not set
+# CONFIG_DVB_USB_DW2102 is not set
+# CONFIG_DVB_USB_CINERGY_T2 is not set
+# CONFIG_DVB_USB_ANYSEE is not set
+# CONFIG_DVB_USB_DTV5100 is not set
+# CONFIG_DVB_USB_AF9015 is not set
+# CONFIG_DVB_USB_CE6230 is not set
+# CONFIG_DVB_TTUSB_BUDGET is not set
+# CONFIG_DVB_TTUSB_DEC is not set
+# CONFIG_SMS_SIANO_MDTV is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported BT878 Adapters
+#
+
+#
+# Supported Pluto2 Adapters
+#
+# CONFIG_DVB_PLUTO2 is not set
+
+#
+# Supported SDMC DM1105 Adapters
+#
+# CONFIG_DVB_DM1105 is not set
+
+#
+# Supported Tango2 Adapters
+#
+CONFIG_DVB_TANGO2=m
+# CONFIG_DVB_TANGO2_TESTBED is not set
+
+#
+# Supported DVB Frontends
+#
+CONFIG_DVB_FE_CUSTOMISE=y
+
+#
+# Customise DVB Frontends
+#
+
+#
+# Multistandard (satellite) frontends
+#
+# CONFIG_DVB_STB0899 is not set
+# CONFIG_DVB_STB6100 is not set
+# CONFIG_DVB_STV090x is not set
+# CONFIG_DVB_STV6110x is not set
+
+#
+# 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_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
+
+#
+# DVB-T (terrestrial) frontends
+#
+# CONFIG_DVB_SP8870 is not set
+# CONFIG_DVB_SP887X is not set
+# CONFIG_DVB_CX22700 is not set
+# CONFIG_DVB_CX22702 is not set
+# CONFIG_DVB_DRX397XD is not set
+# CONFIG_DVB_L64781 is not set
+CONFIG_DVB_TDA1004X=y
+# CONFIG_DVB_NXT6000 is not set
+# CONFIG_DVB_MT352 is not set
+# CONFIG_DVB_ZL10353 is not set
+# CONFIG_DVB_DIB3000MB is not set
+# CONFIG_DVB_DIB3000MC is not set
+# CONFIG_DVB_DIB7000M is not set
+CONFIG_DVB_DIB7000P=y
+# CONFIG_DVB_TDA10048 is not set
+# CONFIG_DVB_AF9013 is not set
+
+#
+# DVB-C (cable) frontends
+#
+# CONFIG_DVB_VES1820 is not set
+# CONFIG_DVB_TDA10021 is not set
+# CONFIG_DVB_TDA10023 is not set
+# CONFIG_DVB_STV0297 is not set
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+# CONFIG_DVB_NXT200X is not set
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_OR51132 is not set
+# CONFIG_DVB_BCM3510 is not set
+# CONFIG_DVB_LGDT330X is not set
+# CONFIG_DVB_LGDT3304 is not set
+# CONFIG_DVB_LGDT3305 is not set
+# CONFIG_DVB_S5H1409 is not set
+# CONFIG_DVB_S5H1411 is not set
+
+#
+# ISDB-T (terrestrial) frontends
+#
+# CONFIG_DVB_S921 is not set
+
+#
+# Digital terrestrial only tuners/PLL
+#
+CONFIG_DVB_PLL=y
+CONFIG_DVB_TUNER_DIB0070=y
+
+#
+# SEC control devices for DVB-S
+#
+# CONFIG_DVB_LNBP21 is not set
+# CONFIG_DVB_ISL6405 is not set
+# CONFIG_DVB_ISL6421 is not set
+# CONFIG_DVB_ISL6423 is not set
+# CONFIG_DVB_LGS8GL5 is not set
+# CONFIG_DVB_LGS8GXX is not set
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_SSD1305 is not set
+# CONFIG_FB_SSD1327 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+CONFIG_USB_SERIAL_CP210X=m
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_FREEBOX_PANEL is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_FREEBOX_DMAMUX is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# Tango2 devices
+#
+CONFIG_TANGO2_FIP=y
+CONFIG_TANGO2_GPIO=y
+CONFIG_TANGO2_IR=m
+CONFIG_TANGO2_FB=y
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_XFS_FS=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_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_HFS_FS is not set
+CONFIG_HFSPLUS_FS=y
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_SUPPORT_ZLIB is not set
+CONFIG_SQUASHFS_SUPPORT_LZMA=y
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=y
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_KMEMCHECK is not set
+CONFIG_CMDLINE="console=ttyS0 root=/dev/nfs ip=dhcp"
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_RUNTIME_DEBUG=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+# CONFIG_CRYPTO_BUILTIN_TEST is not set
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_NULL=y
+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=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_SEQIV=y
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=y
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_LZMASDK=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_FBXSERIAL=y
+CONFIG_CROSS_PATH="/opt/toolchains/mipsel32-uclibc-std-0.9.30-gcc-4.3.2-binutils-2.19.50.0.1/bin/mipsel-linux-"
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxdmamux./Kconfig linux-2.6.31.7-fbx/drivers/fbxdmamux/Kconfig
--- linux-2.6.31.7-fbx/drivers/fbxdmamux./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxdmamux/Kconfig	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,17 @@
+
+menuconfig FREEBOX_DMAMUX
+	bool "Freebox DMA muxing support"
+
+if FREEBOX_DMAMUX
+
+config FREEBOX_DMAMUX_MAX_PRIO
+	int "Number of priority allowed"
+	default 1
+
+comment "DMA devices"
+
+config FREEBOX_DMAMUX_BCM63XX
+	tristate "Broadcom 63xx DMA support"
+	depends on BCM63XX
+
+endif
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxdmamux./Makefile linux-2.6.31.7-fbx/drivers/fbxdmamux/Makefile
--- linux-2.6.31.7-fbx/drivers/fbxdmamux./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxdmamux/Makefile	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,2 @@
+obj-$(CONFIG_FREEBOX_DMAMUX) += fbxdmamux.o
+obj-$(CONFIG_FREEBOX_DMAMUX_BCM63XX) += fbxdmamux_bcm63xx.o
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxgpio./fbxgpio_core.c linux-2.6.31.7-fbx/drivers/fbxgpio/fbxgpio_core.c
--- linux-2.6.31.7-fbx/drivers/fbxgpio./fbxgpio_core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxgpio/fbxgpio_core.c	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,312 @@
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/fbxgpio_core.h>
+
+#define PFX	"fbxgpio_core: "
+
+/* #define DEBUG */
+#ifdef DEBUG
+#define dprint(Fmt, Arg...)	printk(PFX Fmt, Arg)
+#else
+#define dprint(Fmt, Arg...)	do { } while (0)
+#endif
+
+static struct class *fbxgpio_class;
+
+/*
+ * show direction in for gpio associated with class_device dev.
+ */
+static ssize_t show_direction(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct fbxgpio_pin *p;
+	int dir, ret = 0;
+
+	p = dev_get_drvdata(dev);
+
+	if (p->ops->get_direction)
+		dir = p->ops->get_direction(p->pin_num);
+	else
+		dir = p->direction;
+
+	switch (dir) {
+	case GPIO_DIR_IN:
+		ret += sprintf(buf, "input\n");
+		break;
+	case GPIO_DIR_OUT:
+		ret += sprintf(buf, "output\n");
+		break;
+	default:
+		ret += sprintf(buf, "unknown\n");
+		break;
+	}
+	return ret;
+}
+
+/*
+ * store direction. return -EINVAL if direction string is bad. return
+ * -EPERM if flag FBXGPIO_PIN_DIR_RW is set in flags.
+ */
+static ssize_t store_direction(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	int dir;
+	struct fbxgpio_pin *p;
+	int match_len = 0;
+	int i;
+	static const char *word_match[] = {
+		[GPIO_DIR_IN] = "input",
+		[GPIO_DIR_OUT] = "output",
+	};
+
+	if (*buf == ' ' || *buf == '\t' || *buf == '\r' || *buf == '\n')
+		/* silently eat any spaces/tab/linefeed/carriagereturn */
+		return 1;
+
+	p = dev_get_drvdata(dev);
+	if (!(p->flags & FBXGPIO_PIN_DIR_RW)) {
+		dprint("pin %s direction is read only.\n", p->pin_name);
+		return -EPERM;
+	}
+	dir = 0;
+	for (i = 0; i < 2; ++i) {
+		if (size >= strlen(word_match[i]) &&
+		    !strncmp(buf, word_match[i], strlen(word_match[i]))) {
+			dir = i;
+			match_len = strlen(word_match[i]);
+			break ;
+		}
+	}
+	if (i == 2)
+		return -EINVAL;
+
+	p->ops->set_direction(p->pin_num, dir);
+	return match_len;
+}
+
+/*
+ * show input data for input gpio pins.
+ */
+static ssize_t show_datain(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	int val;
+	struct fbxgpio_pin *p;
+
+	p = dev_get_drvdata(dev);
+	if (p->direction == GPIO_DIR_OUT)
+		return -EINVAL;
+	val = p->ops->get_datain(p->pin_num);
+
+	if (p->flags & FBXGPIO_PIN_REVERSE_POL)
+		val = 1 - val;
+	return sprintf(buf, "%i\n", val);
+}
+
+/*
+ * show output data for output gpio pins.
+ */
+static ssize_t show_dataout(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	int val;
+	struct fbxgpio_pin *p;
+
+	p = dev_get_drvdata(dev);
+	if (p->direction == GPIO_DIR_IN)
+		return -EINVAL;
+	if (p->ops->get_dataout)
+		val = p->ops->get_dataout(p->pin_num);
+	else
+		val = p->cur_dataout;
+
+	if (p->flags & FBXGPIO_PIN_REVERSE_POL)
+		val = 1 - val;
+	return sprintf(buf, "%i\n", val);
+}
+
+/*
+ * store new dataout value for output gpio pins.
+ */
+static ssize_t store_dataout(struct device *dev,
+	    struct device_attribute *attr, const char *buf, size_t size)
+{
+	int val;
+	struct fbxgpio_pin *p;
+
+	if (*buf == ' ' || *buf == '\t' || *buf == '\r' || *buf == '\n')
+		/* silently eat any spaces/tab/linefeed/carriagereturn */
+		return 1;
+
+	p = dev_get_drvdata(dev);
+
+	if (p->direction != GPIO_DIR_OUT)
+		return -EINVAL;
+
+	switch (*buf) {
+	case '0':
+		val = 0;
+		break ;
+	case '1':
+		val = 1;
+		break ;
+	default:
+		return -EINVAL;
+	}
+
+	p->cur_dataout = val;
+
+	if (p->flags & FBXGPIO_PIN_REVERSE_POL)
+		val = 1 - val;
+	p->ops->set_dataout(p->pin_num, val);
+	return 1;
+}
+
+/*
+ * show pin number associated with gpio pin.
+ */
+static ssize_t show_pinnum(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	struct fbxgpio_pin *p;
+
+	p = dev_get_drvdata(dev);
+	return sprintf(buf, "%i\n", p->pin_num);
+}
+
+/*
+ * attribute list associated with each class device.
+ */
+static struct device_attribute gpio_attributes[] = {
+	__ATTR(direction, 0600, show_direction, store_direction),
+	__ATTR(data_in,   0400, show_datain, NULL),
+	__ATTR(data_out,  0600, show_dataout, store_dataout),
+	__ATTR(pin_num,   0400, show_pinnum, NULL),
+};
+
+static int fbxgpio_register_pin(struct platform_device *ppdev,
+				struct fbxgpio_pin *pin)
+{
+	struct device *dev;
+	int i, ret;
+
+	dprint("registering pin %s\n", pin->pin_name);
+
+	/* ensure ops is valid */
+	if (!pin->ops) {
+		printk(KERN_ERR PFX "no operation set for pin %s\n",
+		       pin->pin_name);
+		return -EINVAL;
+	}
+
+	dev = device_create(fbxgpio_class, &ppdev->dev, 0, pin,
+			    "%s", pin->pin_name);
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
+	for (i = 0; i < ARRAY_SIZE(gpio_attributes); i++) {
+		ret = device_create_file(dev, &gpio_attributes[i]);
+		if (ret)
+			goto err_out;
+	}
+
+	/* ensure pin direction matches hardware state */
+	if (pin->ops->get_direction &&
+	    pin->direction != pin->ops->get_direction(pin->pin_num)) {
+		printk(KERN_WARNING PFX "pin %s default direction does not "
+		       "match current hardware state, fixing.\n",
+		       pin->pin_name);
+		pin->ops->set_direction(pin->pin_num, pin->direction);
+	}
+	pin->dev = dev;
+	return 0;
+
+err_out:
+	for (; i >= 0; i--)
+		device_remove_file(dev, &gpio_attributes[i]);
+	device_unregister(dev);
+	return ret;
+}
+
+static void fbxgpio_unregister_pin(struct fbxgpio_pin *pin)
+{
+	struct device *dev;
+	int i;
+
+	dprint("unregistering pin %s\n", pin->pin_name);
+	dev = pin->dev;
+	pin->dev = NULL;
+
+	for (i = 0; i < ARRAY_SIZE(gpio_attributes); i++)
+		device_remove_file(dev, &gpio_attributes[i]);
+	device_unregister(dev);
+}
+
+static int fbxgpio_platform_probe(struct platform_device *pdev)
+{
+	struct fbxgpio_pin *p;
+	int err = 0;
+
+	p = pdev->dev.platform_data;
+	while (p->pin_name) {
+		err = fbxgpio_register_pin(pdev, p);
+		if (err)
+			return err;
+		++p;
+	}
+	return 0;
+}
+
+static int fbxgpio_platform_remove(struct platform_device *pdev)
+{
+	struct fbxgpio_pin *p;
+
+	p = pdev->dev.platform_data;
+	while (p->pin_name) {
+		fbxgpio_unregister_pin(p);
+		++p;
+	}
+	return 0;
+}
+
+static struct platform_driver fbxgpio_platform_driver =
+{
+	.probe	= fbxgpio_platform_probe,
+	.remove	= fbxgpio_platform_remove,
+	.driver	= {
+		.name	= "fbxgpio",
+	}
+};
+
+static int __init fbxgpio_init(void)
+{
+	int ret;
+
+	fbxgpio_class = class_create(THIS_MODULE, "fbxgpio");
+	if (IS_ERR(fbxgpio_class))
+		return PTR_ERR(fbxgpio_class);
+
+	ret = platform_driver_register(&fbxgpio_platform_driver);
+	if (ret) {
+		printk(KERN_ERR PFX "unable to register fbxgpio driver.\n");
+		class_destroy(fbxgpio_class);
+		return ret;
+	}
+	return 0;
+}
+
+static void __exit fbxgpio_exit(void)
+{
+	platform_driver_unregister(&fbxgpio_platform_driver);
+	class_destroy(fbxgpio_class);
+}
+
+subsys_initcall(fbxgpio_init);
+module_exit(fbxgpio_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nicolas Schichan <nicolas.schichan@freebox.fr>");
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxgpio./Kconfig linux-2.6.31.7-fbx/drivers/fbxgpio/Kconfig
--- linux-2.6.31.7-fbx/drivers/fbxgpio./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxgpio/Kconfig	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,3 @@
+config FREEBOX_GPIO
+	tristate "Freebox GPIO control interface"
+	default n
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxgpio./Makefile linux-2.6.31.7-fbx/drivers/fbxgpio/Makefile
--- linux-2.6.31.7-fbx/drivers/fbxgpio./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxgpio/Makefile	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1 @@
+obj-$(CONFIG_FREEBOX_GPIO)	+= fbxgpio_core.o
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxjtag./Kconfig linux-2.6.31.7-fbx/drivers/fbxjtag/Kconfig
--- linux-2.6.31.7-fbx/drivers/fbxjtag./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxjtag/Kconfig	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,3 @@
+config FREEBOX_JTAG
+	tristate "Freebox JTAG control interface"
+	default n
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxjtag./Makefile linux-2.6.31.7-fbx/drivers/fbxjtag/Makefile
--- linux-2.6.31.7-fbx/drivers/fbxjtag./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxjtag/Makefile	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1 @@
+obj-$(CONFIG_FREEBOX_JTAG)	+= fbxjtag.o
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_blk_dev.c linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_blk_dev.c
--- linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_blk_dev.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_blk_dev.c	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,367 @@
+/*
+ * Freebox Memory Technology Device r/o block device interface.
+ *
+ * Interface to the flash via a  block device. A mapping is done using
+ * minor  number  and partitions  so  a  maximum  of 8  partitions  is
+ * possible per device.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/blkdev.h>
+#include <linux/kthread.h>
+
+#include <asm/atomic.h>
+#include <asm/io.h>
+
+#include <linux/fbxmtd.h>
+
+#include "fbxmtd_priv.h"
+#include "fbxmtd_blk_dev.h"
+
+#define PFX			"fbxmtd_blk: "
+#define FBXMTD_BLK_MAJOR	252
+#define PART_PER_DEVICE		FBXMTD_MAX_PART
+
+
+static struct mutex disks_mutex;
+static struct list_head disks;
+
+/*
+ * list helpers
+ */
+static int fbxmtd_add_disk(struct fbxmtd_blk_disk *d)
+{
+	mutex_lock(&disks_mutex);
+	list_add_tail(&d->list, &disks);
+	mutex_unlock(&disks_mutex);
+
+	return 0;
+}
+
+static void _fbxmtd_put_disk(struct fbxmtd_blk_disk *d)
+{
+	if (!atomic_dec_and_test(&d->refcount))
+		return;
+
+	fbxmtd_put_part(d->part);
+	if (d->worker)
+		kthread_stop(d->worker);
+	if (d->gd) {
+		del_gendisk(d->gd);
+		put_disk(d->gd);
+	}
+	if (d->queue)
+		blk_cleanup_queue(d->queue);
+	list_del(&d->list);
+	kfree(d);
+}
+
+static void fbxmtd_put_disk(struct fbxmtd_blk_disk *d)
+{
+	mutex_lock(&disks_mutex);
+	_fbxmtd_put_disk(d);
+	mutex_unlock(&disks_mutex);
+}
+
+static void fbxmtd_put_disk_by_part(struct fbxmtd_part *part)
+{
+	struct fbxmtd_blk_disk *d;
+
+	mutex_lock(&disks_mutex);
+	list_for_each_entry(d, &disks, list) {
+		if (d->part == part) {
+			_fbxmtd_put_disk(d);
+			break;
+		}
+	}
+	mutex_unlock(&disks_mutex);
+}
+
+
+/*
+ * blk funcs
+ */
+static int transfer(struct fbxmtd_part *part, unsigned long sector,
+		    unsigned long nbytes, char *buffer, int write,
+		    int can_sleep)
+{
+	unsigned long offset = sector * 512;
+
+	/* delay write request, as they will sleep, but try to
+	 * process read request now if it's possible */
+	if (!can_sleep) {
+		if (write)
+			return -EWOULDBLOCK;
+		return fbxmtd_read_part(part, offset, buffer, nbytes, 0);
+	}
+
+	/* we can sleep */
+	if (write)
+		return fbxmtd_write_part(part, offset, buffer, nbytes);
+	return fbxmtd_read_part(part, offset, buffer, nbytes, 1);
+}
+
+/*
+ * worker thread main func
+ */
+static int kworkerthread(void *data)
+{
+	struct fbxmtd_blk_disk *disk;
+	struct request_queue *q;
+	struct request *req = NULL;
+
+	disk = (struct fbxmtd_blk_disk *)data;
+	q = disk->queue;
+
+	/* we  grab queue  lock until  there  are no  more request  to
+	 * process */
+	spin_lock_irq(&disk->lock);
+	while (!kthread_should_stop()) {
+		int ret;
+
+		/* process next request */
+		if (!req && !(req = blk_fetch_request(q))) {
+			/* nothing to do, sleep */
+			spin_unlock_irq(&disk->lock);
+			wait_event_interruptible(disk->worker_wq,
+						 disk->work_to_do == 1 ||
+						 kthread_should_stop());
+			disk->work_to_do = 0;
+			spin_lock_irq(&disk->lock);
+			continue;
+		}
+
+		/* process the  request, release queue lock  as we may
+		 * sleep */
+		spin_unlock_irq(&disk->lock);
+		ret = transfer(disk->part, blk_rq_pos(req),
+			       blk_rq_cur_bytes(req), req->buffer,
+			       rq_data_dir(req), 1);
+		spin_lock_irq(&disk->lock);
+
+		ret = ret >= 0 ? 0 : -EIO;
+		if (!__blk_end_request_cur(req, ret))
+			req = NULL;
+	}
+
+	if (req)
+		__blk_end_request_all(req, -EIO);
+
+	spin_unlock_irq(&disk->lock);
+
+	return 0;
+}
+
+
+static void blk_request(struct request_queue *q)
+{
+	struct fbxmtd_blk_disk *disk = q->queuedata;
+
+	/* wakeup the worker thread to request */
+	disk->work_to_do = 1;
+	wake_up(&disk->worker_wq);
+}
+
+static int blk_open(struct block_device *bdev, fmode_t mode)
+{
+	struct fbxmtd_blk_disk *disk = bdev->bd_disk->private_data;
+
+	atomic_inc(&disk->refcount);
+	return 0;
+}
+
+static int blk_release(struct gendisk *gen_disk, fmode_t mode)
+{
+	struct fbxmtd_blk_disk *disk = gen_disk->private_data;
+	fbxmtd_put_disk(disk);
+	return 0;
+}
+
+static struct block_device_operations fbxmtd_blk_ops = {
+	.open = blk_open,
+	.release = blk_release,
+	.owner = THIS_MODULE,
+};
+
+
+/*
+ * setup a fbxmtd blk disk for the given partition
+ */
+static int setup_disk(struct fbxmtd_part *part)
+{
+	struct fbxmtd_blk_disk *disk;
+
+	if (!(disk = kmalloc(sizeof (struct fbxmtd_blk_disk), GFP_KERNEL)))
+		return 1;
+
+	memset(disk, 0, sizeof (struct fbxmtd_blk_disk));
+	disk->part = part;
+	snprintf(disk->name, sizeof (disk->name), "%s/%s", part->dev->name,
+		 part->name);
+	INIT_LIST_HEAD(&disk->list);
+	spin_lock_init(&disk->lock);
+	init_waitqueue_head(&disk->worker_wq);
+	atomic_set(&disk->refcount, 1);
+
+
+	/* alloc queue */
+	disk->queue = blk_init_queue(blk_request, &disk->lock);
+	if (disk->queue == NULL) {
+		printk(KERN_ERR PFX "blk_init_queue failed !\n");
+		goto free;
+	}
+	blk_queue_logical_block_size(disk->queue, 512);
+	blk_queue_max_phys_segments(disk->queue, 1);
+	disk->queue->queuedata = disk;
+
+	/* alloc gendisk */
+	if (!(disk->gd = alloc_disk(1))) {
+		printk(KERN_ERR PFX "alloc_disk failed !\n");
+		goto free;
+	}
+	snprintf(disk->gd->disk_name, sizeof (disk->gd->disk_name),
+		 "fbxmtdblk%c%d", disk->part->dev->idx + 'a', part->idx);
+
+	disk->gd->major = FBXMTD_BLK_MAJOR;
+	disk->gd->first_minor = disk->part->dev->idx * PART_PER_DEVICE +
+		part->idx;
+
+	disk->gd->queue = disk->queue;
+	disk->gd->fops = &fbxmtd_blk_ops;
+	disk->gd->private_data = disk;
+	set_capacity(disk->gd, (part->size / 512) == 0 ? 1 : part->size / 512);
+
+	/* create worker kthread */
+	disk->worker = kthread_create(kworkerthread, disk,
+				      "kfbxmtdblk/%s", part->name);
+	if (IS_ERR(disk->worker)) {
+		disk->worker = NULL;
+		printk(KERN_ERR PFX "Error creating worker kthread\n");
+		goto free;
+	}
+
+	/* add gen disk */
+	add_disk(disk->gd);
+
+	/* add disk to the list */
+	if (fbxmtd_add_disk(disk))
+		goto free;
+
+	wake_up_process(disk->worker);
+	return 0;
+free:
+	if (disk->worker)
+		kthread_stop(disk->worker);
+	if (disk->gd) {
+		del_gendisk(disk->gd);
+		put_disk(disk->gd);
+	}
+	if (disk->queue)
+		blk_cleanup_queue(disk->queue);
+	kfree(disk);
+	return 1;
+}
+
+
+static void fbxmtd_notifier_cb(void *cb_data, struct fbxmtd_part *part,
+			       uint32_t event)
+{
+	if (event == FBXMTD_EVENT_DEAD) {
+		fbxmtd_put_disk_by_part(part);
+	} else {
+		/* event == FBXMTD_EVENT_ADD */
+		if (part->size < 512 || part->size % 512) {
+			printk(KERN_INFO PFX "skipped too small or non "
+			       "512 bytes aligned partition %s\n", part->name);
+			return;
+		}
+		if (!setup_disk(part))
+			atomic_inc(&part->dev->refcount);
+	}
+}
+
+static int foreach_part_cb(void *cb_data, struct fbxmtd_part *part)
+{
+	if (part->size < 512 || part->size % 512) {
+		printk(KERN_INFO PFX "skipped too small partition %s\n",
+		       part->name);
+		return 0;
+	}
+
+	if (!setup_disk(part)) {
+		/* keep a reference on part */
+		atomic_inc(&part->dev->refcount);
+		return 0;
+	}
+	return 1;
+}
+
+
+static int __init fbxmtd_blk_init(void)
+{
+	struct fbxmtd_blk_disk *d, *d2;
+
+	printk(KERN_INFO PFX "Freebox MTD block device access support\n");
+
+	INIT_LIST_HEAD(&disks);
+	mutex_init(&disks_mutex);
+
+	/* register blk device */
+	if (register_blkdev(FBXMTD_BLK_MAJOR, "fbxmtd") < 0) {
+		printk(KERN_ERR PFX "Unable to get blkdev major %d\n",
+		       FBXMTD_BLK_MAJOR);
+		return -ENODEV;
+	}
+
+	/* register notifier for future addition of mtddevice */
+	if (fbxmtd_register_notifier(fbxmtd_notifier_cb, NULL,
+				     FBXMTD_EVENT_DEAD | FBXMTD_EVENT_PART)) {
+		printk(KERN_ERR PFX "Unable to register fbxmtd notifier\n");
+		goto err;
+	}
+
+	/* create disk for existing partitions */
+	if (fbxmtd_foreach_part(foreach_part_cb, NULL))
+		goto err;
+
+	return 0;
+
+err:
+	unregister_blkdev(FBXMTD_BLK_MAJOR, "fbxmtd");
+	fbxmtd_unregister_notifier(fbxmtd_notifier_cb);
+	/* put all devices */
+	mutex_lock(&disks_mutex);
+	list_for_each_entry_safe(d, d2, &disks, list) {
+		_fbxmtd_put_disk(d);
+	}
+	mutex_unlock(&disks_mutex);
+	return -ENODEV;
+}
+
+static void __exit fbxmtd_blk_exit(void)
+{
+	struct fbxmtd_blk_disk *d, *d2;
+
+	fbxmtd_unregister_notifier(fbxmtd_notifier_cb);
+
+	/* put all devices */
+	mutex_lock(&disks_mutex);
+	list_for_each_entry_safe(d, d2, &disks, list) {
+		_fbxmtd_put_disk(d);
+	}
+	mutex_unlock(&disks_mutex);
+
+	unregister_blkdev(FBXMTD_BLK_MAJOR, "fbxmtd");
+}
+
+
+module_init(fbxmtd_blk_init);
+module_exit(fbxmtd_blk_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_blk_dev.h linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_blk_dev.h
--- linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_blk_dev.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_blk_dev.h	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,22 @@
+
+#ifndef FBXMTD_BLK_DEV_H_
+# define FBXMTD_BLK_DEV_H_
+
+#include <linux/list.h>
+#include <asm/atomic.h>
+
+struct fbxmtd_blk_disk
+{
+	char name[32];
+	struct fbxmtd_part *part;
+	struct list_head list;
+	atomic_t refcount;
+        spinlock_t lock;
+        struct request_queue *queue;
+        struct gendisk *gd;
+        struct task_struct *worker;
+	wait_queue_head_t worker_wq;
+	int work_to_do;
+};
+
+#endif /* !FBXMTD_BLK_DEV_H_ */
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_char_dev.c linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_char_dev.c
--- linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_char_dev.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_char_dev.c	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,221 @@
+/*
+ * Freebox Memory Technology Device character device interface.
+ *
+ * Interface to  the flash via a  character device. A  mapping is done
+ * using minor  number and  partitions so a maximum  of 8  partitions is
+ * possible per device.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/fs.h>
+#include <linux/vmalloc.h>
+#include <asm/uaccess.h>
+
+#include <linux/fbxmtd.h>
+
+#include "fbxmtd_priv.h"
+
+#define PFX			"fbxmtd_chr: "
+#define FBXMTD_CHAR_MAJOR	251
+#define PART_PER_DEVICE		FBXMTD_MAX_PART
+#define MAX_VMALLOC_SIZE	(256 * 1024)
+
+/*
+ * open callback
+ * map the minor to the associated device / partition and keep track of it
+ */
+static int fbxmtd_open(struct inode *inode, struct file *file)
+{
+	struct fbxmtd_part *part;
+	int minor, dev_idx, part_idx;
+
+	/* find partition associated if any */
+	minor = MINOR(inode->i_rdev);
+	dev_idx = minor / PART_PER_DEVICE;
+	part_idx = minor % PART_PER_DEVICE;
+
+	/* get associated partition */
+	part = fbxmtd_get_part(dev_idx, part_idx);
+	if (!part)
+		return -ENODEV;
+	file->private_data = part;
+
+	return 0;
+}
+
+/*
+ * release callback
+ * put reference to the partition we have
+ */
+static int fbxmtd_release(struct inode *inode, struct file *file)
+{
+	struct fbxmtd_part *part;
+
+	part = (struct fbxmtd_part *)file->private_data;
+	fbxmtd_put_part(part);
+
+	return 0;
+}
+
+/*
+ * read callback
+ * adjust offset and count and forward request to the core
+ */
+
+static ssize_t fbxmtd_read(struct file *file, char *buffer, size_t count,
+			   loff_t *ppos)
+{
+	struct fbxmtd_part *part;
+	size_t total_len;
+	int len;
+	char *kbuf;
+
+	part = (struct fbxmtd_part *)file->private_data;
+
+	/* adjust size if count is too big */
+	if (*ppos >= part->size)
+		return 0;
+	if (count > part->size - *ppos)
+		count = part->size - *ppos;
+
+	if (count > MAX_VMALLOC_SIZE)
+		len = MAX_VMALLOC_SIZE;
+	else
+		len = count;
+
+	if (!(kbuf = vmalloc(len)))
+		return -ENOMEM;
+
+	total_len = 0;
+	while (count) {
+
+		if (need_resched())
+			yield();
+
+		if (count > MAX_VMALLOC_SIZE)
+			len = MAX_VMALLOC_SIZE;
+		else
+			len = count;
+
+		len = fbxmtd_read_part(part, *ppos, kbuf, len, 1);
+		if (len <= 0) {
+			vfree(kbuf);
+			return len;
+		}
+
+		if (len) {
+			if (copy_to_user(buffer, kbuf, len)) {
+				vfree(kbuf);
+				return -EFAULT;
+			}
+		}
+
+		count -= len;
+		buffer += len;
+		*ppos += len;
+		total_len += len;
+	}
+
+	vfree(kbuf);
+	return total_len;
+}
+
+
+/*
+ * write callback
+ * adjust offset and count and forward request to the core
+ */
+static ssize_t fbxmtd_write(struct file *file, const char *buffer,
+			    size_t count, loff_t *ppos)
+{
+	struct fbxmtd_part *part;
+	size_t total_len;
+	char *kbuf;
+	int len;
+
+	part = (struct fbxmtd_part *)file->private_data;
+
+	/* write access outside the partition region is an error */
+	if (*ppos >= part->size)
+		return -EINVAL;
+	if (count > part->size - *ppos)
+		return -EFBIG;
+
+	if (count > MAX_VMALLOC_SIZE)
+		len = MAX_VMALLOC_SIZE;
+	else
+		len = count;
+
+	if (!(kbuf = vmalloc(len)))
+		return -ENOMEM;
+
+	total_len = 0;
+	while (count) {
+
+		if (need_resched())
+			yield();
+
+		if (count > MAX_VMALLOC_SIZE)
+			len = MAX_VMALLOC_SIZE;
+		else
+			len = count;
+
+		if (copy_from_user(kbuf, buffer, len)) {
+			vfree(kbuf);
+			return -EFAULT;
+		}
+
+		len = fbxmtd_write_part(part, *ppos, kbuf, len);
+		if (len <= 0) {
+			vfree(kbuf);
+			return len;
+		}
+
+		count -= len;
+		buffer += len;
+		*ppos += len;
+		total_len += len;
+	}
+
+	vfree(kbuf);
+	return total_len;
+
+}
+
+
+static struct file_operations fbxmtd_fops = {
+	.open = fbxmtd_open,
+	.release = fbxmtd_release,
+	.read = fbxmtd_read,
+	.write = fbxmtd_write,
+	.owner = THIS_MODULE,
+};
+
+static int __init fbxmtd_chr_init(void)
+{
+	printk(KERN_INFO PFX "Freebox MTD character device access support\n");
+
+	/* register char device */
+	if (register_chrdev(FBXMTD_CHAR_MAJOR, "fbxmtd", &fbxmtd_fops) < 0) {
+		printk(KERN_ERR PFX "Unable to get chrdev major %d\n",
+		       FBXMTD_CHAR_MAJOR);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void __exit fbxmtd_chr_exit(void)
+{
+	unregister_chrdev(FBXMTD_CHAR_MAJOR, "fbxmtd");
+}
+
+
+module_init(fbxmtd_chr_init);
+module_exit(fbxmtd_chr_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_core_amd.c linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_core_amd.c
--- linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_core_amd.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_core_amd.c	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,622 @@
+/*
+ *
+ * Support for AMD compatible flash for Freebox MTD
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#include <linux/fbxmtd.h>
+
+#include "fbxmtd_priv.h"
+#include "fbxmtd_core_amd.h"
+
+#define PFX		"fbxmtd_amd: "
+#define POLL_TIMEOUT	(10 * HZ)
+
+#define SZ_1K				0x00000400
+#define SZ_2K				0x00000800
+#define SZ_4K				0x00001000
+#define SZ_8K				0x00002000
+#define SZ_16K				0x00004000
+#define SZ_32K				0x00008000
+#define SZ_64K				0x00010000
+#define SZ_128K				0x00020000
+#define SZ_256K				0x00040000
+#define SZ_512K				0x00080000
+#define SZ_1M				0x00100000
+#define SZ_2M				0x00200000
+#define SZ_4M				0x00400000
+#define SZ_8M				0x00800000
+#define SZ_16M				0x01000000
+#define SZ_32M				0x02000000
+#define SZ_64M				0x04000000
+#define SZ_128M				0x08000000
+#define SZ_256M				0x10000000
+#define SZ_512M				0x20000000
+
+/*
+ * List of known flash we support
+ */
+static const struct amd_flash_info amd_flash_infos[] = {
+
+	{
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29LV040B,
+		.name = "AMD AM29LV040B",
+		.size = SZ_512K,
+		.use_dq5 = 1,
+		.use_ext_dev_id = 0,
+		.need_tpoll_delay = 1,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_64K, .count = 8 },
+			{ .count = 0 },
+		},
+	 },
+
+	{
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = SPANSION_GENERIC,
+		.ext_dev_id = { 0x221A, 0x2200 },
+		.name = "AMD AM29LV320MB / S29GL032[AN]R4 (bottom)",
+		.size = SZ_4M,
+		.use_dq5 = 1,
+		.use_ext_dev_id = 1,
+		.need_tpoll_delay = 1,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_8K, .count = 8 },
+			{ .offset = 0x10000, .size = SZ_64K, .count = 63 },
+			{ .count = 0 },
+		},
+	 },
+
+	{
+		.mfr_id = MANUFACTURER_SPANSION,
+		.dev_id = SPANSION_GENERIC,
+		.ext_dev_id = { 0x2210, 0x2200 },
+		.name = "SPANSION S29GL064[AMN]R4 (bottom)",
+		.size = SZ_8M,
+		.use_dq5 = 1,
+		.need_tpoll_delay = 1,
+		.use_ext_dev_id = 1,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_8K, .count = 8 },
+			{ .offset = 0x10000, .size = SZ_64K, .count = 126 },
+			{ .count = 0 },
+		},
+	 },
+
+	{
+		.mfr_id = MANUFACTURER_SPANSION,
+		.dev_id = SPANSION_GENERIC,
+		.ext_dev_id = { 0x2222, 0x2201 },
+		.name = "SPANSION S29GL256[PN]",
+		.size = SZ_32M,
+		.use_dq5 = 1,
+		.use_ext_dev_id = 1,
+		.use_write_buffer = 1,
+		.write_buffer_size = 32,
+		.need_tpoll_delay = 1,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_128K, .count = 256 },
+			{ .count = 0 },
+		},
+	 },
+
+	{
+		.mfr_id = MANUFACTURER_SPANSION,
+		.dev_id = SPANSION_GENERIC,
+		.ext_dev_id = { 0x2221, 0x2201 },
+		.name = "SPANSION S29GL128P",
+		.size = SZ_16M,
+		.use_dq5 = 1,
+		.use_ext_dev_id = 1,
+		.use_write_buffer = 1,
+		.write_buffer_size = 32,
+		.need_tpoll_delay = 1,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_128K, .count = 128 },
+		},
+	},
+
+	{
+		.mfr_id = MANUFACTURER_ATMEL,
+		.dev_id = AT49BV322A,
+		.name = "ATMEL AT49BV322A (bottom)",
+		.size = SZ_4M,
+		.use_dq5 = 1,
+		.need_tpoll_delay = 0,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_8K, .count = 8 },
+			{ .offset = 0x10000, .size = SZ_64K, .count = 63 },
+			{ .count = 0 },
+		},
+	},
+
+
+	{
+		.mfr_id = MANUFACTURER_SST,
+		.dev_id = SST39VF3201,
+		.name = "SST 39VF3201",
+		.size = SZ_4M,
+		.use_dq5 = 0,
+		.need_tpoll_delay = 0,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_4K, .count = 1024 },
+			{ .count = 0 },
+		},
+	},
+
+	{
+		.mfr_id = MANUFACTURER_SST,
+		.dev_id = SST39VF3202_REVB,
+		.name = "SST 39VF3202 (rev B)",
+		.size = SZ_4M,
+		.use_dq5 = 0,
+		.need_tpoll_delay = 0,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_64K, .count = 64 },
+			{ .count = 0 },
+		},
+	},
+
+	{
+		.mfr_id = MANUFACTURER_SST,
+		.dev_id = SST39VF6401,
+		.name = "SST 39VF6401",
+		.size = SZ_8M,
+		.use_dq5 = 0,
+		.need_tpoll_delay = 0,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_4K, .count = 2048 },
+			{ .count = 0 },
+		},
+	},
+
+	{
+		.mfr_id = MANUFACTURER_SST,
+		.dev_id = SST39VF6401_REVB,
+		.name = "SST 39VF6401 (rev B)",
+		.size = SZ_8M,
+		.use_dq5 = 0,
+		.need_tpoll_delay = 0,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_64K, .count = 128 },
+			{ .count = 0 },
+		},
+	},
+
+
+	{
+		.mfr_id = MANUFACTURER_MACRONIX,
+		.dev_id = MX29LV320DT,
+		.name = "MX 29LV320DT (top)",
+		.size = SZ_4M,
+		.use_dq5 = 1,
+		.need_tpoll_delay = 0,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_64K, .count = 63 },
+			{ .offset = 0x3f0000, .size = SZ_8K, .count = 8 },
+			{ .count = 0 },
+		},
+	},
+
+	{
+		.mfr_id = MANUFACTURER_SPANSION,
+		.dev_id = S29AL032D_M3,
+		.name = "SPANSION S29AL032D_M3",
+		.size = SZ_4M,
+		.use_dq5 = 1,
+		.need_tpoll_delay = 1,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_64K, .count = 63 },
+			{ .offset = 0x3f0000, .size = SZ_8K, .count = 8 },
+			{ .count = 0 },
+		},
+	 },
+
+	{
+		.mfr_id = MANUFACTURER_NUMONIX,
+		.dev_id = SPANSION_GENERIC,
+		.ext_dev_id = { 0x2222, 0x2201 },
+		.name = "NUMONIX M29EW256",
+		.size = SZ_32M,
+		.use_dq5 = 1,
+		.use_ext_dev_id = 1,
+		.use_write_buffer = 1,
+		.write_buffer_size = 256,
+		.need_tpoll_delay = 0,
+
+		.regions = {
+			{ .offset = 0x0, .size = SZ_128K, .count = 256 },
+			{ .count = 0 },
+		},
+	 },
+
+	/* end of list */
+	{
+		.mfr_id = 0,
+	},
+};
+
+
+/*
+ * send given command to flash wrt its width
+ */
+static uint32_t __amd_swizzle_addr(struct fbxmtd_dev_map *map, uint32_t addr)
+{
+	return addr << (map->flash_width - 1);
+}
+
+static void __amd_unlock(struct fbxmtd_dev_map *map)
+{
+	fbxmtd_bus_width_write(map, __amd_swizzle_addr(map, ADDR_UNLOCK1),
+			       CMD_UNLOCK_DATA_1);
+	fbxmtd_bus_width_write(map, __amd_swizzle_addr(map, ADDR_UNLOCK2),
+			       CMD_UNLOCK_DATA_2);
+}
+
+static void amd_reset(struct fbxmtd_dev_map *map)
+{
+	fbxmtd_bus_width_write(map, 0, CMD_RESET_DATA);
+}
+
+static void amd_cmd(struct fbxmtd_dev_map *map, uint32_t cmd)
+{
+	__amd_unlock(map);
+	fbxmtd_bus_width_write(map, __amd_swizzle_addr(map, ADDR_UNLOCK1),
+			       cmd);
+}
+
+static void amd_cmd_addr(struct fbxmtd_dev_map *map, uint32_t addr,
+			 uint32_t cmd)
+{
+	__amd_unlock(map);
+	fbxmtd_bus_width_write(map, addr, cmd);
+}
+
+/*
+ * poll status bit waiting for operation to finish
+ */
+static int amd_status_poll(struct fbxmtd_dev *dev, uint32_t offset,
+			   uint16_t data)
+{
+	struct amd_flash_info *info;
+	unsigned long timeout;
+
+	info = (struct amd_flash_info *)dev->priv_data;
+	if (info->need_tpoll_delay)
+		udelay(5);
+
+	timeout = jiffies + POLL_TIMEOUT;
+	do {
+		uint16_t flag;
+
+		flag = fbxmtd_bus_width_read(&dev->map, offset);
+		if ((flag & 0x80) == (data & 0x80)) {
+			return 0;
+		}
+
+		if (info->use_dq5 && (flag & 0x20)) {
+			flag = fbxmtd_bus_width_read(&dev->map, offset);
+			return ((flag & 0x80) == (data & 0x80)) ? 0 : 1;
+		}
+
+		if (need_resched())
+			yield();
+
+	} while (time_before(jiffies, timeout));
+
+	printk(KERN_ERR PFX "poll: timeout !\n");
+	return -ETIMEDOUT;
+}
+
+/*
+ * erase chip
+ */
+static int amd_erase_chip(struct fbxmtd_dev *dev)
+{
+	printk(KERN_INFO PFX "Erasing chip...\n");
+
+	amd_cmd(&dev->map, CMD_UNLOCK_ERASE);
+	amd_cmd(&dev->map, CMD_CHIP_ERASE);
+
+	if (amd_status_poll(dev, 0, 0xffff) < 0) {
+		printk(KERN_ERR PFX "Chip erase failed at 0x%.8x\n",
+		       (uint32_t)dev->map.base);
+		amd_reset(&dev->map);
+		return -EIO;
+	}
+	amd_reset(&dev->map);
+
+	return 0;
+}
+
+/*
+ * erase sector at given offset
+ */
+static int amd_erase_sector(struct fbxmtd_dev *dev, uint32_t offset)
+{
+	struct amd_flash_info *info;
+
+	info = (struct amd_flash_info *)dev->priv_data;
+
+	amd_cmd(&dev->map, CMD_UNLOCK_ERASE);
+	amd_cmd_addr(&dev->map, offset, CMD_SECTOR_ERASE);
+
+	if (amd_status_poll(dev, offset, 0xffff) < 0) {
+		printk(KERN_ERR PFX "Sector erase failed at 0x%.8x\n",
+		       (uint32_t)(dev->map.base + offset));
+		amd_reset(&dev->map);
+		return -EIO;
+	}
+	amd_reset(&dev->map);
+
+	return 0;
+}
+
+/*
+ * program data in buf at requested offset using write buffer method
+ * count is assumed to be % write_buffer_size
+ */
+static int amd_program_buffer(struct fbxmtd_dev *dev, uint32_t offset,
+			      const uint8_t *buf, size_t count)
+{
+	struct amd_flash_info *info;
+	int status = 0;
+	uint32_t sec_offset;
+
+	info = (struct amd_flash_info *)dev->priv_data;
+
+	sec_offset = offset;
+	while (count > 0) {
+		unsigned int word_count;
+		uint32_t data, last_offset;
+		int i;
+
+		/* send write to buffer at sector address */
+		amd_cmd_addr(&dev->map, sec_offset, CMD_WRITE_TO_BUFFER);
+
+		/* send number of words to be programmed minus 1 */
+		word_count = info->write_buffer_size / dev->map.flash_width;
+		fbxmtd_bus_width_write(&dev->map, sec_offset, word_count - 1);
+
+		data = 0;
+		for (i = 0; i < word_count; i++) {
+			const uint8_t *p;
+
+			/* prevent unaligned access on buf */
+			p = buf + (i * dev->map.flash_width);
+			data = fbxmtd_get_bus_word(&dev->map, p);
+
+			/* try to program requested data */
+			fbxmtd_bus_width_write(&dev->map, offset + i * 2, data);
+		}
+
+		/* send program buffer at sector address */
+		fbxmtd_bus_width_write(&dev->map,
+				       sec_offset, CMD_PROGRAM_BUFFER);
+
+		/* poll on last offset / data */
+		last_offset = offset + info->write_buffer_size -
+			dev->map.flash_width;
+		status = amd_status_poll(dev, last_offset, data);
+
+		if (status < 0) {
+			printk(KERN_ERR PFX "write buffer failed at offset "
+			       "0x%08x\n", offset);
+			amd_cmd(&dev->map, CMD_WRITE_TO_BUFFER_RESET);
+			return status;
+		}
+
+		offset += info->write_buffer_size;
+		buf += info->write_buffer_size;
+		count -= info->write_buffer_size;
+	}
+
+	amd_reset(&dev->map);
+
+	return 0;
+}
+
+/*
+ * program data in buf at requested offset
+ */
+static int amd_program(struct fbxmtd_dev *dev, uint32_t offset,
+		       const uint8_t *buf, size_t count)
+{
+	struct amd_flash_info *info;
+	int status = 0;
+
+	/* sanity check */
+	if (offset % dev->map.flash_width) {
+		printk(KERN_ERR PFX "program offset must be bus aligned !\n");
+		return -EIO;
+	}
+
+	if (count % dev->map.flash_width) {
+		printk(KERN_ERR PFX "program count must be bus aligned !\n");
+		return -EIO;
+	}
+
+	info = (struct amd_flash_info *)dev->priv_data;
+
+	/* if  write buffer  is allowed  and  data to  program is  big
+	 * enough, then do it */
+	if (info->use_write_buffer && (count % info->write_buffer_size) == 0)
+		return amd_program_buffer(dev, offset, buf, count);
+
+	while (count > 0) {
+		uint32_t data;
+
+		/* prevent unaligned access on buf */
+		data = fbxmtd_get_bus_word(&dev->map, buf);
+
+		/* no need to program in case all bits are set */
+		if (fbxmtd_bus_word_equal(&dev->map, data, 0xffffffff))
+			goto next;
+
+		/* try to program requested data */
+		amd_cmd(&dev->map, CMD_PROGRAM_UNLOCK_DATA);
+		fbxmtd_bus_width_write(&dev->map, offset, data);
+		status = amd_status_poll(dev, offset, data);
+		if (status < 0) {
+			printk(KERN_ERR PFX "program failed at offset "
+			       "0x%08x\n", offset);
+			amd_reset(&dev->map);
+			return status;
+		}
+
+next:
+		offset += dev->map.flash_width;
+		buf += dev->map.flash_width;
+		count -= dev->map.flash_width;
+	}
+	amd_reset(&dev->map);
+
+	return 0;
+}
+
+/*
+ * Probe amd flash and return flash structure if found in table
+ */
+static const struct amd_flash_info *amd_probe(struct fbxmtd_dev_map *map)
+{
+	uint32_t mfr_id;
+	uint32_t dev_id;
+	uint32_t ext_id[2];
+	int i;
+
+	/* recover from bad state */
+	amd_cmd(map, CMD_WRITE_TO_BUFFER_RESET);
+	amd_reset(map);
+
+	/* read flash id */
+	amd_cmd(map, CMD_AUTOSELECT_DATA);
+	mfr_id = fbxmtd_bus_width_read(map, map->flash_width *
+				       ADDR_MANUFACTURER);
+	dev_id = fbxmtd_bus_width_read(map, map->flash_width *
+				       ADDR_DEVICE_ID);
+	ext_id[0] = fbxmtd_bus_width_read(map, map->flash_width *
+					  ADDR_EXT_DEVICE_ID);
+	ext_id[1] = fbxmtd_bus_width_read(map, map->flash_width *
+					  (ADDR_EXT_DEVICE_ID + 1));
+
+	/* return to read mode */
+	amd_reset(map);
+
+	for (i = 0; amd_flash_infos[i].mfr_id != 0; i++) {
+		const struct amd_flash_info *info = &amd_flash_infos[i];
+
+		if (mfr_id == info->mfr_id && dev_id == info->dev_id) {
+
+			if (info->use_ext_dev_id &&
+			    (ext_id[0] != info->ext_dev_id[0] ||
+			     ext_id[1] != info->ext_dev_id[1]))
+				continue;
+
+			printk(KERN_INFO PFX "Probed %s flash at 0x%08x, "
+			       "%d bit, size %ukB\n",
+			       info->name, (uint32_t)map->base,
+			       8 * (1 << (map->flash_width - 1)),
+			       info->size / 1024);
+			if (info->use_write_buffer)
+				printk(KERN_INFO PFX
+				       " -> using write buffer programming "
+				       "(%u bytes)\n",
+				       info->write_buffer_size);
+			return info;
+		}
+	}
+
+	if (mfr_id != 0xff && dev_id != 0xff) {
+		printk(KERN_NOTICE PFX "unknown flash at 0x%08x (man:%04x "
+		       "dev:%04x)\n", (uint32_t)map->base, mfr_id, dev_id);
+	}
+	return NULL;
+}
+
+/*
+ * return region information of device
+ */
+static struct fbxmtd_region *
+amd_get_region(struct fbxmtd_dev *dev)
+{
+	struct amd_flash_info *info;
+
+	info = (struct amd_flash_info *)dev->priv_data;
+	return info->regions;
+}
+
+/*
+ * return region information of device
+ */
+static uint32_t
+amd_get_size(struct fbxmtd_dev *dev)
+{
+	struct amd_flash_info *info;
+
+	info = (struct amd_flash_info *)dev->priv_data;
+	return info->size;
+}
+
+/*
+ * probe for an AMD flash and create mtd device if found
+ */
+struct fbxmtd_dev *fbxmtd_core_amd_probe(dma_addr_t base_phys,
+					 unsigned int flash_width)
+{
+	const struct amd_flash_info *info;
+	struct fbxmtd_dev_map map;
+	struct fbxmtd_dev *dev;
+	uint8_t *base_remap;
+
+	/* temporary remap base until we know full size */
+	if (!(base_remap = ioremap((unsigned long)base_phys, 0x20000))) {
+		printk(KERN_ERR PFX "first ioremap failed\n");
+		return NULL;
+	}
+
+	/* create temporary mapping during probe */
+	map.base = base_remap;
+	map.base_phys = base_phys;
+	map.flash_width = flash_width;
+
+	if ((info = amd_probe(&map)) == NULL) {
+		iounmap(base_remap);
+		return NULL;
+	}
+	iounmap(base_remap);
+
+	if ((dev = kmalloc(sizeof (struct fbxmtd_dev), GFP_KERNEL)) == NULL)
+		return NULL;
+
+	memset(dev, 0, sizeof (struct fbxmtd_dev));
+
+	dev->erase = amd_erase_sector;
+	dev->program = amd_program;
+	dev->chip_erase = amd_erase_chip;
+	dev->get_region_info = amd_get_region;
+	dev->get_size = amd_get_size;
+	dev->priv_data = (void *)info;
+
+	return dev;
+}
+
+EXPORT_SYMBOL(fbxmtd_core_amd_probe);
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_core_amd.h linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_core_amd.h
--- linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_core_amd.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_core_amd.h	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,82 @@
+
+#ifndef FBXMTD_CORE_AMD_H_
+# define FBXMTD_CORE_AMD_H_
+
+#define ADDR_MANUFACTURER		0x0000
+#define ADDR_DEVICE_ID			0x0001
+#define ADDR_SECTOR_LOCK		0x0002
+#define ADDR_HANDSHAKE			0x0003
+#define ADDR_EXT_DEVICE_ID		0x000E
+#define ADDR_UNLOCK1			0x5555
+#define ADDR_UNLOCK2			0xAAAA
+
+#define CMD_CHIP_ERASE			0x0010
+#define CMD_UNLOCK_BYPASS_MODE		0x0020
+#define CMD_SECTOR_ERASE		0x0030
+#define CMD_UNLOCK_DATA_1		0x00AA
+#define CMD_UNLOCK_DATA_2		0x0055
+#define CMD_UNLOCK_SECTOR		0x0060
+#define CMD_UNLOCK_ERASE		0x0080
+#define CMD_AUTOSELECT_DATA		0x0090
+#define CMD_PROGRAM_UNLOCK_DATA		0x00A0
+#define CMD_WRITE_TO_BUFFER		0x0025
+#define CMD_PROGRAM_BUFFER		0x0029
+#define CMD_SET_CONFIG			0x00D0
+#define CMD_RESET_DATA			0x00F0
+#define CMD_WRITE_TO_BUFFER_RESET	0x00F0
+
+#define D0_MASK				(0x0001 << 0)
+#define D1_MASK				(0x0001 << 1)
+#define D2_MASK				(0x0001 << 2)
+#define D3_MASK				(0x0001 << 3)
+#define D4_MASK				(0x0001 << 4)
+#define D5_MASK				(0x0001 << 5)
+#define D6_MASK				(0x0001 << 6)
+#define D7_MASK				(0x0001 << 7)
+
+
+#define MANUFACTURER_AMD		0x0001
+#define MANUFACTURER_FUJITSU		0x0004
+#define MANUFACTURER_ATMEL		0x001f
+#define MANUFACTURER_SPANSION		0x0001
+#define MANUFACTURER_ST			0x0020
+#define MANUFACTURER_NUMONIX		0x0089
+#define MANUFACTURER_MACRONIX		0x00C2
+#define MANUFACTURER_SST		0x00bf
+
+/* ATMEL */
+#define AT49BV322A			0x00c8
+
+/* Macronix */
+#define MX29LV320DT			0x22a7
+#define MX29LV320DB			0x22a8
+
+/* Spansion/AMD */
+#define AM29LV040B			0x004f
+#define SPANSION_GENERIC		0x227E
+#define S29AL032D_M3			0x22F6
+
+/* SST */
+#define SST39VF3201			0x235B
+#define SST39VF3202_REVB		0x235C
+#define SST39VF6401			0x236B
+#define SST39VF6401_REVB		0x236D
+
+#define MAX_REGION	4
+
+struct amd_flash_info
+{
+	uint16_t mfr_id;
+	uint16_t dev_id;
+	uint16_t ext_dev_id[2];
+	char *name;
+	uint32_t size;
+	int use_dq5;
+	int use_ext_dev_id;
+	int use_write_buffer;
+	unsigned int write_buffer_size;
+	int need_tpoll_delay;
+	struct fbxmtd_region regions[MAX_REGION + 1];
+};
+
+#endif /* !FBXMTD_CORE_AMD_H_ */
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_core.c linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_core.c
--- linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_core.c	2010-10-25 13:43:56.361441329 +0200
@@ -0,0 +1,806 @@
+/*
+ * Freebox Memory Technology Device driver
+ *
+ * Allow transparent access to flash (handle read modify erase write),
+ * and  partitionning of  device.  Read /  write  access are  mutually
+ * exclusive.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+
+#include <linux/fbxmtd.h>
+
+#include "fbxmtd_priv.h"
+
+#define PFX	"fbxmtd: "
+
+/*
+ * notifier stuffs
+ */
+static struct list_head notifiers;
+static struct mutex notifiers_mutex;
+
+static void fbxmtd_run_notifier(struct fbxmtd_part *part, uint32_t event)
+{
+	struct fbxmtd_notifier *n;
+
+	mutex_lock(&notifiers_mutex);
+	list_for_each_entry(n, &notifiers, list) {
+		if (n->event_mask & event) {
+			n->cb(n->cb_data, part, event);
+		}
+	}
+	mutex_unlock(&notifiers_mutex);
+}
+
+int fbxmtd_register_notifier(void (*cb)(void *, struct fbxmtd_part *,
+					uint32_t),
+			     void *cb_data, uint32_t mask)
+{
+	struct fbxmtd_notifier *n;
+
+	if (!(n = kmalloc(sizeof (struct fbxmtd_notifier), GFP_KERNEL)))
+		return 1;
+	n->cb = cb;
+	n->cb_data = cb_data;
+	n->event_mask = mask;
+	INIT_LIST_HEAD(&n->list);
+
+	mutex_lock(&notifiers_mutex);
+	list_add_tail(&n->list, &notifiers);
+	mutex_unlock(&notifiers_mutex);
+
+	return 0;
+}
+
+void fbxmtd_unregister_notifier(void (*cb)(void *, struct fbxmtd_part *,
+					   uint32_t))
+{
+	struct fbxmtd_notifier *n, *n2;
+
+	mutex_lock(&notifiers_mutex);
+	list_for_each_entry_safe(n, n2, &notifiers, list) {
+		if (cb == n->cb) {
+			list_del(&n->list);
+			kfree(n);
+		}
+	}
+	mutex_unlock(&notifiers_mutex);
+}
+
+
+/*
+ * mtd device list
+ */
+static struct fbxmtd_dev *mtddevs[FBXMTD_MAX_DEVICES];
+static int mtddevs_count = 0;
+static struct mutex mtddevs_mutex;
+
+/*
+ * helper for list access, they assume list lock is taken
+ */
+static int _add_device(struct fbxmtd_dev *dev)
+{
+	struct fbxmtd_dev *p;
+	int	i, first;
+
+	/* check for room */
+	if (mtddevs_count == FBXMTD_MAX_DEVICES) {
+		printk(KERN_ERR PFX "FBXMTD_MAX_DEVICES reached\n");
+		return 1;
+	}
+
+	/* check for name clash */
+	first = -1;
+	for (i = 0; i < FBXMTD_MAX_DEVICES; i++) {
+		p = mtddevs[i];
+		if (p == NULL) {
+			/* first empty slot */
+			if (first == -1)
+				first = i;
+			continue;
+		}
+		if (!strcmp(p->name, dev->name)) {
+			printk(KERN_ERR PFX "duplicate partition name "
+			       "\"%s\"\n", p->name);
+			return 1;
+		}
+	}
+
+	mtddevs[first] = dev;
+	dev->idx = first;
+	mtddevs_count++;
+	__module_get(THIS_MODULE);
+	mutex_init(&dev->sem);
+	atomic_set(&dev->refcount, 1);
+
+	return 0;
+}
+
+static struct fbxmtd_part *_get_part(unsigned int dev_idx,
+				     unsigned int part_idx)
+{
+	struct fbxmtd_dev *p;
+
+	/* find device */
+	p = mtddevs[dev_idx];
+
+	if (!p || p->dead)
+		return NULL;
+
+	/* find partition */
+	if (part_idx >= p->part_count) {
+		return NULL;
+	}
+
+	atomic_inc(&p->refcount);
+	return &p->parts[part_idx];
+}
+
+static struct fbxmtd_part *_get_part_by_name(unsigned int dev_idx,
+					     const char *part_name)
+{
+	struct fbxmtd_dev *p;
+	int i;
+
+	/* find device */
+	p = mtddevs[dev_idx];
+
+	if (!p || p->dead)
+		return NULL;
+
+	/* find partition */
+	for (i = 0; i < p->part_count; i++) {
+		if (!strcmp(p->parts[i].name, part_name)) {
+			atomic_inc(&p->refcount);
+			return &p->parts[i];
+		}
+	}
+	return NULL;
+}
+
+
+static void _put_device(struct fbxmtd_dev *dev)
+{
+	int i;
+
+	if (!atomic_dec_and_test(&dev->refcount))
+		return;
+
+	/* out of the list */
+	for (i = 0; i < FBXMTD_MAX_DEVICES; i++) {
+		if (mtddevs[i] == dev) {
+			mtddevs[i] = NULL;
+			break;
+		}
+	}
+	mtddevs_count--;
+
+	/* free it */
+	for (i = 0; i < dev->part_count; i++) {
+		if (dev->parts[i].name)
+			kfree(dev->parts[i].name);
+	}
+
+	if (dev->map.base) {
+		iounmap(dev->map.base);
+	}
+	kfree(dev->name);
+	kfree(dev);
+	module_put(THIS_MODULE);
+}
+
+/*
+ * list accessor
+ */
+static int fbxmtd_add_device(struct fbxmtd_dev *dev)
+{
+	int res;
+
+	mutex_lock(&mtddevs_mutex);
+	res = _add_device(dev);
+	mutex_unlock(&mtddevs_mutex);
+	return res;
+}
+
+struct fbxmtd_part *fbxmtd_get_part(unsigned int dev_idx,
+				    unsigned int part_idx)
+{
+	struct fbxmtd_part *part;
+
+	if (mutex_lock_interruptible(&mtddevs_mutex))
+		return NULL;
+	part = _get_part(dev_idx, part_idx);
+	mutex_unlock(&mtddevs_mutex);
+	return part;
+}
+
+struct fbxmtd_part *fbxmtd_get_part_by_name(unsigned int dev_idx,
+					    const char *part_name)
+{
+	struct fbxmtd_part *part;
+
+	if (mutex_lock_interruptible(&mtddevs_mutex))
+		return NULL;
+	part = _get_part_by_name(dev_idx, part_name);
+	mutex_unlock(&mtddevs_mutex);
+	return part;
+}
+
+void fbxmtd_put_device(struct fbxmtd_dev *dev)
+{
+	mutex_lock(&mtddevs_mutex);
+	_put_device(dev);
+	mutex_unlock(&mtddevs_mutex);
+}
+
+void fbxmtd_put_part(struct fbxmtd_part *part)
+{
+	mutex_lock(&mtddevs_mutex);
+	_put_device(part->dev);
+	mutex_unlock(&mtddevs_mutex);
+}
+
+/*
+ * call  given callback for  each existing  partitions, if  cb returns
+ * true, a reference on partition is taken for it
+ */
+int fbxmtd_foreach_part(int (cb)(void *, struct fbxmtd_part *),
+			void *cb_data)
+{
+	int i, j;
+
+	mutex_lock(&mtddevs_mutex);
+
+	for (i = 0; i < FBXMTD_MAX_DEVICES; i++) {
+		struct fbxmtd_dev *p;
+
+		p = mtddevs[i];
+
+		if (!p || p->dead)
+			continue;
+
+		for (j = 0; j < p->part_count; j++)
+			if (cb(cb_data, &p->parts[j])) {
+				mutex_unlock(&mtddevs_mutex);
+				return 1;
+			}
+	}
+	mutex_unlock(&mtddevs_mutex);
+	return 0;
+}
+
+
+/*
+ * read from fbxmtd device
+ */
+int fbxmtd_read_dev(struct fbxmtd_dev *dev, uint32_t offset, char *buffer,
+		    unsigned int count)
+{
+	uint32_t size;
+
+	/* eof if device is dead */
+	if (dev->dead)
+		return 0;
+
+	size = dev->get_size(dev);
+
+	/* access outside the device range is an error */
+	if (offset > size || count > size - offset)
+		return -EINVAL;
+
+	if (mutex_lock_interruptible(&dev->sem))
+		return -ERESTARTSYS;
+
+	memcpy_fromio(buffer, dev->map.base + offset, count);
+	mutex_unlock(&dev->sem);
+
+	return count;
+}
+
+/*
+ * find sector or next sector boundary for current offset
+ */
+static int find_sector_boundary(struct fbxmtd_dev *dev,
+				uint32_t offset, int want_next_sector,
+				uint32_t *boundary)
+{
+	struct fbxmtd_region *regs;
+	uint32_t r_offset, i;
+
+	regs = dev->get_region_info(dev);
+
+	r_offset = 0;
+	for (i = 0; regs[i].size != 0; i++) {
+		unsigned int sector;
+
+		if (offset < regs[i].offset ||
+		    (offset >= regs[i].offset + regs[i].count * regs[i].size))
+			continue;
+
+		/* this is the right region, get sector number */
+		sector = (offset - regs[i].offset) / regs[i].size;
+
+		if (want_next_sector) {
+			/* check if this was last sector of region */
+			if (sector < regs[i].count - 1)
+				sector++;
+			else {
+				/* yes, we want first sector of next
+				 * region if it exists */
+				i++;
+				if (!regs[i].size)
+					return -EINVAL;
+				sector = 0;
+			}
+		}
+
+		*boundary = regs[i].offset + sector * regs[i].size;
+		return 0;
+	}
+
+	/* offset is outside flash */
+	return -EINVAL;
+}
+
+int fbxmtd_find_sector_boundary(struct fbxmtd_dev *dev,
+				uint32_t offset, uint32_t *boundary)
+{
+	return find_sector_boundary(dev, offset, 0, boundary);
+}
+
+int fbxmtd_find_next_sector_boundary(struct fbxmtd_dev *dev,
+				     uint32_t offset, uint32_t *boundary)
+{
+	return find_sector_boundary(dev, offset, 1, boundary);
+}
+
+
+/*
+ * read from fbxmtd partition
+ */
+int fbxmtd_read_part(struct fbxmtd_part *part, uint32_t offset, char *buffer,
+		     unsigned int count, int can_sleep)
+{
+	/* eof if device is dead */
+	if (part->dev->dead)
+		return 0;
+
+	/* access outside the range partition is an error */
+	if (offset > part->size || count > part->size - offset)
+		return -EINVAL;
+
+	if (!can_sleep) {
+		if (mutex_trylock(&part->dev->sem))
+			return -EWOULDBLOCK;
+	} else {
+		if (mutex_lock_interruptible(&part->dev->sem))
+			return -ERESTARTSYS;
+	}
+	/* assume we can use it as memory mapped io */
+	offset += part->offset;
+
+	/* use memcpy */
+	memcpy_fromio(buffer, part->dev->map.base + offset, count);
+	mutex_unlock(&part->dev->sem);
+
+	return count;
+}
+
+
+/*
+ * write to fbxmtd partition
+ */
+int fbxmtd_write_part(struct fbxmtd_part *part, uint32_t offset, char *buffer,
+		      unsigned int count)
+{
+	struct fbxmtd_dev *dev;
+	struct fbxmtd_region *regs;
+	unsigned int total_len;
+
+	/* eof if device is dead */
+	if (part->dev->dead)
+		return 0;
+
+	/* check partition is rw */
+	if (part->rw == 0)
+		return -EBADF;
+
+	/* access outside the range of the partition is an error */
+	if (offset >= part->size)
+		return -EINVAL;
+	if (count > part->size - offset)
+		return -EFBIG;
+
+	/* fetch flash region information */
+	dev = part->dev;
+	regs = dev->get_region_info(dev);
+
+	/* calculate real offset in device */
+	offset = offset + part->offset;
+
+	/* start read/erase/modify/write loop */
+	total_len = 0;
+	while (count > 0) {
+		int		i, j, res, erase_needed, program_needed;
+		int		after_all_one;
+		uint32_t	r_offset, size;
+		uint8_t		*tbuf;
+
+		/* find flash region for this offset */
+		r_offset = 0;
+		for (i = 0; regs[i].size != 0; i++) {
+			if (offset < regs[i].offset ||
+			    (offset >= regs[i].offset +
+			     regs[i].count * regs[i].size))
+				continue;
+			/* this is the right region, get sector number */
+			res = (offset - regs[i].offset) / regs[i].size;
+			r_offset = regs[i].offset + res * regs[i].size;
+			break;
+		}
+
+		if (!regs[i].size) {
+			/* oops, no region found, region desc must be wrong*/
+			printk(KERN_ERR PFX "%s/%s: couldn't find associated "
+			       "region for offset %08x\n", dev->name,
+			       part->name, offset);
+			return -EIO;
+		}
+
+		/* read the current data */
+		if (!(tbuf = vmalloc(regs[i].size)))
+			return -ENOMEM;
+
+		/* size is the part of the data we will overwrite */
+		size = r_offset + regs[i].size - offset;
+		if (count < size)
+			size = count;
+
+		if (mutex_lock_interruptible(&dev->sem))
+			return -ERESTARTSYS;
+
+		/* read whole sector */
+		memcpy_fromio(tbuf, dev->map.base + r_offset, regs[i].size);
+
+		/*
+		 * check if we  need to erase the sector,  this is the
+		 * case if there is at  least one bit in the modified data
+		 * that has been set.
+		 *
+		 * we use a simple XOR/AND to test this, a XOR between
+		 * old  and new  data  gives us  bits  that have  been
+		 * toggled.
+		 *
+		 * If a logical AND between this and the original data
+		 * gives the same, then  all toggled bits where set in
+		 * the original data, and no erase is needed.
+		 *
+		 * orig ^ new = toggled
+		 * orig & toggled = common_modified_bits
+		 * (common_modified_bits == toggled) -> no erase needed
+		 */
+		erase_needed = 0;
+		program_needed = 0;
+		after_all_one = 1;
+
+		for (j = 0; j < size; j++) {
+			uint8_t before, after, toggled;
+
+			before = tbuf[(offset - r_offset) + j];
+			after = buffer[j];
+
+			/*
+			 * remember  if any  new byte  value is  to be
+			 * different than 0xff
+			 */
+			if (after != 0xff)
+				after_all_one = 0;
+
+			if (before != after) {
+				/*
+				 * we want to change the byte value
+				 */
+				if (after == 0xff) {
+					/*
+					 * we want to change it to
+					 * 0xff, the only way to do
+					 * this is to erase the sector
+					 */
+					erase_needed = 1;
+				} else {
+					/*
+					 * we want to  set the byte to
+					 * anything  else  than  0xff,
+					 * this  imply programming the
+					 * sector, this may also imply
+					 * erasing  if some  bits need
+					 * to be changed from 0 to 1
+					 */
+					program_needed = 1;
+					toggled = before ^ after;
+					if ((before & toggled) != toggled)
+						erase_needed = 1;
+				}
+			}
+
+			/*
+			 * if  we decide  that erasing  the  sector is
+			 * needed then all previous data will be lost,
+			 * thus  if  any new  byte  is  to  be set  to
+			 * anything else  than 0xff, then  we have to
+			 * program after erasing.
+			 */
+			if (erase_needed && !after_all_one)
+				program_needed = 1;
+
+			if (program_needed && erase_needed)
+				break;
+		}
+
+		/* modify data */
+		memcpy(tbuf + (offset - r_offset), buffer, size);
+
+		/* erase sector if needed */
+		if (erase_needed && dev->erase(dev, r_offset)) {
+			mutex_unlock(&dev->sem);
+			vfree(tbuf);
+			printk(KERN_ERR PFX "%s/%s: erase failed at "
+			       "[0x%08x/%d]\n", dev->name,
+			       part->name, r_offset, regs[i].size);
+			return -EIO;
+		}
+
+		/* program it with the new data */
+		if (program_needed &&
+		    dev->program(dev, r_offset, tbuf, regs[i].size)) {
+			mutex_unlock(&dev->sem);
+			vfree(tbuf);
+			printk(KERN_ERR PFX "%s/%s: program failed at "
+			       "[0x%08x/%d]\n", dev->name,
+			       part->name, r_offset, regs[i].size);
+			return -EIO;
+		}
+
+		mutex_unlock(&dev->sem);
+		vfree(tbuf);
+
+		if (printk_ratelimit())
+			printk(KERN_DEBUG PFX "%s/%s: %s%s%s%soffset=0x%08x "
+			       "segment=[0x%08x/%d]\n", dev->name,
+			       part->name,
+			       erase_needed ? "ERASE" : "",
+			       (erase_needed && program_needed) ? "/" : "",
+			       program_needed ? "PRGM" : "",
+			       (erase_needed || program_needed) ? " " : "",
+			       offset, r_offset, regs[i].size);
+
+		count -= size;
+		total_len += size;
+		offset += size;
+		buffer += size;
+
+		/* give readers a chance */
+		if (need_resched())
+			yield();
+	}
+
+	return total_len;
+}
+
+
+/*
+ * add partitions to fbxmtd device
+ */
+int fbxmtd_set_partitions(struct fbxmtd_dev *dev, struct fbxmtd_part *parts,
+			  unsigned int count)
+{
+	unsigned int	i, j, size;
+	int res;
+
+	/* grab the queue lock, so  nobody can get the device while we
+	 * are changing its partitions */
+	mutex_lock(&mtddevs_mutex);
+	res = 0;
+
+	if (dev->dead) {
+		res = -ENOENT;
+		goto out;
+	}
+
+	/* can't (re)partition while device is in use */
+	if (atomic_read(&dev->refcount) > 1) {
+		printk(KERN_ERR PFX "device \"%s\" is busy\n", dev->name);
+		res = -EBUSY;
+		goto out;
+	}
+
+	/* check partitions */
+	size = dev->get_size(dev);
+	for (i = 0; i < count; i++) {
+
+		if (!parts[i].name[0]) {
+			printk(KERN_ERR PFX "invalid partition %d name\n", i);
+			res = -EINVAL;
+			goto out;
+		}
+
+		/* (size == - 1) means greatest possible size */
+		if (parts[i].size == -1)
+			parts[i].size = size - parts[i].offset;
+
+		if (parts[i].offset % 2) {
+			printk(KERN_ERR PFX "odd partition %d offset\n", i);
+			res = -EINVAL;
+			goto out;
+		}
+
+		if (parts[i].size % 2) {
+			printk(KERN_ERR PFX "odd partition %d size\n", i);
+			res = -EINVAL;
+			goto out;
+		}
+
+		if (parts[i].offset + parts[i].size > size) {
+			printk(KERN_ERR PFX "partition %d size too big\n", i);
+			res = -EINVAL;
+			goto out;
+		}
+	}
+
+	/* check all partition have different name */
+	for (i = 0; i < count; i++) {
+		for (j = 0; j < count; j++) {
+			if (i == j)
+				continue;
+			if (!strcmp(parts[i].name, parts[j].name)) {
+				printk(KERN_ERR PFX "duplicate partition "
+				       "name: %s\n", parts[i].name);
+				res = -EINVAL;
+				goto out;
+			}
+		}
+	}
+
+	/* partitions seems ok, replace previous one with new  */
+	for (i = 0; i < dev->part_count; i++) {
+		if (dev->parts[i].name) {
+			kfree(parts[i].name);
+			parts[i].name = NULL;
+		}
+	}
+
+	for (i = 0; i < count; i++) {
+		dev->parts[i] = parts[i];
+		dev->parts[i].name = kstrdup(parts[i].name, GFP_KERNEL);
+		dev->parts[i].dev = dev;
+		dev->parts[i].idx = i;
+	}
+	dev->part_count = count;
+
+out:
+	mutex_unlock(&mtddevs_mutex);
+
+	/* notify partition  change, only caller  may change partition
+	 * again,  so it  is  safe  to read  partition  table in  this
+	 * event */
+	for (i = 0; i < dev->part_count; i++)
+		fbxmtd_run_notifier(&dev->parts[i], FBXMTD_EVENT_ADD);
+
+	return res;
+}
+
+/*
+ * ask for device removal
+ */
+void fbxmtd_mark_dead_dev(struct fbxmtd_dev *dev)
+{
+	int i;
+
+	dev->dead = 1;
+	/* notify dead device */
+	for (i = 0; i < dev->part_count; i++)
+		fbxmtd_run_notifier(&dev->parts[i], FBXMTD_EVENT_DEAD);
+}
+
+
+/*
+ * probe for an fbxmtd device at specified address
+ */
+struct fbxmtd_dev *fbxmtd_probe(const char *name, dma_addr_t base_phys,
+				unsigned int flash_width)
+{
+	struct fbxmtd_dev *dev;
+
+	/* probe using all method we know */
+#ifdef CONFIG_FREEBOX_MTD_BACKEND_AMD
+	if ((dev = fbxmtd_core_amd_probe(base_phys, flash_width)))
+		goto found;
+#endif
+#ifdef CONFIG_FREEBOX_MTD_BACKEND_INTEL
+	if ((dev = fbxmtd_core_intel_probe(base_phys, flash_width)))
+		goto found;
+#endif
+	/* nothing found */
+	return NULL;
+
+found:
+	/* add the device */
+	if (!(dev->name = kstrdup(name, GFP_KERNEL))) {
+		printk(KERN_ERR PFX "kstrdup failed\n");
+		goto free;
+	}
+
+	/* create final flash mapping */
+	dev->map.base_phys = base_phys;
+	dev->map.flash_width = flash_width;
+	if (!(dev->map.base = ioremap_nocache((unsigned long)base_phys,
+					      dev->get_size(dev)))) {
+		printk(KERN_ERR PFX "ioremap failed\n");
+		goto free;
+	}
+
+	if (fbxmtd_add_device(dev)) {
+		printk(KERN_ERR PFX "can't add device \"%s\"\n", name);
+		goto free;
+	}
+
+	return dev;
+free:
+	if (dev->name)
+		kfree(dev->name);
+	if (dev->map.base)
+		iounmap(dev->map.base);
+	kfree(dev);
+	return NULL;
+}
+
+
+static int __init fbxmtd_init(void)
+{
+	printk(KERN_INFO PFX "Freebox Memory Technology Device driver\n");
+
+	INIT_LIST_HEAD(&notifiers);
+	mutex_init(&mtddevs_mutex);
+	mutex_init(&notifiers_mutex);
+
+	return 0;
+}
+
+static void __exit fbxmtd_exit(void)
+{
+}
+
+
+module_init(fbxmtd_init);
+module_exit(fbxmtd_exit);
+
+EXPORT_SYMBOL(fbxmtd_probe);
+EXPORT_SYMBOL(fbxmtd_mark_dead_dev);
+EXPORT_SYMBOL(fbxmtd_set_partitions);
+EXPORT_SYMBOL(fbxmtd_foreach_part);
+
+EXPORT_SYMBOL(fbxmtd_register_notifier);
+EXPORT_SYMBOL(fbxmtd_unregister_notifier);
+
+EXPORT_SYMBOL(fbxmtd_read_dev);
+EXPORT_SYMBOL(fbxmtd_read_part);
+EXPORT_SYMBOL(fbxmtd_write_part);
+
+EXPORT_SYMBOL(fbxmtd_find_sector_boundary);
+EXPORT_SYMBOL(fbxmtd_find_next_sector_boundary);
+
+EXPORT_SYMBOL(fbxmtd_get_part_by_name);
+EXPORT_SYMBOL(fbxmtd_get_part);
+EXPORT_SYMBOL(fbxmtd_put_part);
+EXPORT_SYMBOL(fbxmtd_put_device);
+
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_core_io.c linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_core_io.c
--- linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_core_io.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_core_io.c	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,120 @@
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+#include <linux/fbxmtd.h>
+#include "fbxmtd_priv.h"
+
+
+#define FLASH_IO_READ_8(x)	__raw_readb((void *)x)
+#define FLASH_IO_READ_16(x)	__raw_readw((void *)x)
+#define FLASH_IO_READ_32(x)	__raw_readl((void *)x)
+
+#define FLASH_IO_WRITE_8(x,d)	__raw_writeb(d, (void *)x)
+#define FLASH_IO_WRITE_16(x,d)	__raw_writew(d, (void *)x)
+#define FLASH_IO_WRITE_32(x,d)	__raw_writel(d, (void *)x)
+
+/*
+ * read/write data by doing a flash bus width access
+ */
+uint32_t fbxmtd_bus_width_read(struct fbxmtd_dev_map *map,
+			       uint32_t offset)
+{
+	uint8_t *address;
+	uint32_t val;
+
+	address = map->base + offset;
+
+	switch (map->flash_width) {
+	case 1:
+		val = (uint32_t)FLASH_IO_READ_8(address);
+		break;
+
+	case 2:
+		val = (uint32_t)FLASH_IO_READ_16(address);
+		break;
+
+	case 4:
+		val = (uint32_t)FLASH_IO_READ_32(address);
+		break;
+
+	default:
+		printk(KERN_ERR "flash width not supported\n");
+		return 0;
+	}
+	return val;
+}
+
+void fbxmtd_bus_width_write(struct fbxmtd_dev_map *map, uint32_t offset,
+			    uint32_t data)
+{
+	uint8_t *address;
+
+	address = map->base + offset;
+
+	switch (map->flash_width) {
+	case 1:
+		FLASH_IO_WRITE_8(address, data);
+		break;
+
+	case 2:
+		FLASH_IO_WRITE_16(address, data);
+		break;
+
+	case 4:
+		FLASH_IO_WRITE_32(address, data);
+		break;
+
+	default:
+		printk(KERN_ERR "flash width not supported\n");
+		break;
+	}
+}
+
+uint32_t fbxmtd_get_bus_word(struct fbxmtd_dev_map *map, const uint8_t *buf)
+{
+	uint32_t val;
+
+	switch (map->flash_width) {
+	case 1:
+		val = buf[0];
+		break;
+
+	case 2:
+		val = (buf[0] << 8) | buf[1];
+		val = be16_to_cpu(val);
+		break;
+
+	case 4:
+		val = (buf[0] << 24) | (buf[1] << 16) |
+			(buf[2] << 8) | buf[3];
+		val = be32_to_cpu(val);
+		break;
+
+	default:
+		printk(KERN_ERR "flash width not supported\n");
+		return 0;
+	}
+
+	return val;
+}
+
+int fbxmtd_bus_word_equal(struct fbxmtd_dev_map *map, uint32_t d1,
+			  uint32_t d2)
+{
+	switch (map->flash_width) {
+	case 1:
+		return ((d1 & 0xff) == (d2 & 0xff));
+
+	case 2:
+		return ((d1 & 0xffff) == (d2 & 0xffff));
+
+	case 4:
+		return ((d1 & 0xffffffff) == (d2 & 0xffffffff));
+
+	default:
+		printk(KERN_ERR "flash width not supported\n");
+		return 0;
+	}
+}
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_map_drv_fbx.c linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_map_drv_fbx.c
--- linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_map_drv_fbx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_map_drv_fbx.c	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,456 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/crc32.h>
+#include <linux/fbxmtd.h>
+
+#define PFX	"fbxmtd_map_drv_fbx: "
+
+static struct fbxmtd_dev *dev = NULL;
+
+static struct fbxmtd_part partitions[FBXMTD_MAX_PART];
+uint32_t partition_count;
+
+struct cmplzma_header
+{
+	u32	dst;
+	u32	entry;
+	u32	len;
+};
+
+#define FBX_IMAGETAG_MAGIC		0x3658382b
+#define FBX_IMAGETAG_VERSION		1
+
+#define FBX_IMAGETAG_FLAGS_HAS_KERNEL   (1 << 0)
+#define FBX_IMAGETAG_FLAGS_HAS_FS       (1 << 1)
+#define FBX_IMAGETAG_FLAGS_SKRYPTED_KERNEL	(1 << 2)
+#define FBX_IMAGETAG_BANKNUM_SHIFT		0x3
+#define FBX_IMAGETAG_BANKNUM_MASK		0x1
+
+struct fbx_imagetag {
+	uint32_t	crc32;		/* for whole image minus this field */
+	uint32_t	magic;
+	uint32_t	version;
+	uint32_t	total_size;	/* in bytes */
+	char		name[128];	/* zero terminated */
+	uint32_t	build_date;	/* seconds since epoch */
+	char		builder[32];	/* builder name */
+	uint32_t	flags;
+	uint32_t	kernel_offset;	/* in bytes from origin */
+	uint32_t	kernel_size;	/* in bytes */
+	uint32_t	fs_offset;	/* in bytes from origin */
+	uint32_t	fs_size;	/* in bytes from origin */
+} __attribute__((packed));
+
+/*
+ * read imagetag at offset and set parts offset/size for romfs, this
+ * comes from the legacy fbxmtd map code.
+ */
+static void
+read_imagetag(struct fbxmtd_part *parent,
+	      struct fbxmtd_part *part,
+	      int check_crc, int skip_kernel)
+{
+	struct fbx_imagetag tag;
+	int ret;
+	int offset;
+
+	offset = parent->offset;
+
+	if (skip_kernel) {
+		/*
+		 * on fbx4, the CFE only know how to boot a cmplzma
+		 * compressed kernel image.
+		 *
+		 * the bank1 partition starts with a compressed kernel
+		 * image immediately followed by an image tag align on
+		 * a 4k page boundary. we skip the image here try to
+		 * look at an image tag right here.
+		 */
+		struct cmplzma_header hdr;
+
+		ret = fbxmtd_read_dev(dev, parent->offset, (u8*)&hdr,
+				      sizeof (hdr));
+		if (ret != sizeof (hdr))
+			printk(KERN_ERR PFX "%s: unable to read cmplzma "
+			       "header on at 0x%08x\n", parent->name,
+			       parent->offset);
+
+		offset += be32_to_cpu(hdr.len);
+
+		/* align offset on a 4k page boundary. */
+		offset &= ~0xfff;
+		offset += 0x1000;
+
+		printk(KERN_INFO PFX "image tag expected at 0x%08x\n", offset);
+	}
+
+	/* read the tag */
+	ret = fbxmtd_read_dev(dev, offset,
+			      (uint8_t *)&tag, sizeof (tag));
+	if (ret != sizeof(tag)) {
+		printk(KERN_ERR PFX "%s: unable to read image tag "
+		       "at 0x%08x\n", parent->name, offset);
+		return;
+	}
+
+	/* check the tag */
+	if (be32_to_cpu(tag.magic) != FBX_IMAGETAG_MAGIC) {
+		printk(KERN_NOTICE PFX "%s: invalid tag magic "
+		       "(0x%08x, expected 0x%08x)\n", parent->name,
+		       be32_to_cpu(tag.magic), FBX_IMAGETAG_MAGIC);
+		return;
+	}
+
+	if (check_crc) {
+		unsigned char buf[512];
+		int i, len;
+		unsigned int size, crc = 0;
+
+		/* calculate CRC32 of whole  image minus the crc field
+		 * itself */
+		size = be32_to_cpu(tag.total_size);
+		for (i = 0; i < size; i += 512) {
+			/* read some data */
+			len = (size - i) > 512 ? 512 : size - i;
+			ret = fbxmtd_read_dev(dev, offset + i,
+					      buf, len);
+			if (ret != len) {
+				printk(KERN_ERR PFX
+				       "%s: unable to check crc\n",
+				       parent->name);
+				return;
+			}
+
+			/* skip image tag CRC32 field */
+			if (i == 0)
+				crc = crc32(crc, buf + 4, len - 4);
+			else
+				crc = crc32(crc, buf, len);
+		}
+
+		if (crc != be32_to_cpu(tag.crc32)) {
+			printk(KERN_NOTICE PFX "%s: invalid image CRC "
+			       "(0x%08x, expected 0x%08x)\n", parent->name,
+			       crc, be32_to_cpu(tag.crc32));
+			return;
+		}
+		printk(KERN_NOTICE PFX "CRC on %s ok.\n", parent->name);
+	}
+
+	if (!(be32_to_cpu(tag.flags) & FBX_IMAGETAG_FLAGS_HAS_FS)) {
+		printk(KERN_NOTICE PFX "%s: image has no FS\n", parent->name);
+		goto end;
+	}
+
+	/* set right offset for fs */
+	part->offset = offset + be32_to_cpu(tag.fs_offset);
+	part->size = be32_to_cpu(tag.fs_size);
+	/* adjust off partition */
+	if (part->size % 2) {
+		part->size++;
+	}
+
+	/*
+	 * sanity check: check that fs partition ends before the
+	 * parent end.
+	 */
+	if (offset + part->size > offset + parent->size) {
+		printk(KERN_ERR PFX "skipping partition %s, partition ends "
+		       "after parent end, makes no sense.\n", parent->name);
+		part->size = 0;
+		part->offset = 0;
+	}
+
+end:
+	tag.name[127] = 0;
+	tag.builder[31] = 0;
+	printk(KERN_INFO PFX "%s: tag \"%s\" by \"%s\"\n", parent->name,
+	       tag.name, tag.builder);
+}
+
+struct fbxmtd_platform_part *
+get_partition_by_name(const char *name, struct fbxmtd_platform_part *parts,
+		      unsigned int num)
+{
+	int i;
+
+	if (name == NULL)
+		return NULL;
+
+	for (i = 0; i < num; ++i) {
+		if (!strcmp(name, parts[i].name))
+			return &parts[i];
+	}
+	return NULL;
+}
+
+static int
+fbxmtd_map_drv_fbx_probe(struct platform_device *pdev)
+{
+	int res;
+	uint32_t i;
+	struct fbxmtd_platform_data *pdat;
+	struct fbxmtd_platform_part *local_parts = NULL;
+	uint32_t size;
+
+	printk(KERN_DEBUG PFX "probe.\n");
+
+	pdat = pdev->dev.platform_data;
+
+	/* by default ... */
+	pdat->status = E_FBXMTD_FAULTY;
+
+	/* sanity check on platform data */
+	if (pdat == NULL) {
+		printk(KERN_ERR PFX "fbxmtd platform data is missing.\n");
+		return -ENODEV;
+	}
+	if (pdat->num_parts == 0 || pdat->parts == NULL) {
+		printk(KERN_ERR PFX "fbxmtd platform data is missing a "
+		       "partition table.\n");
+		return -ENODEV;
+	}
+
+	dev = fbxmtd_probe(pdat->name, pdat->base, pdat->width);
+	if (dev == NULL)
+		return -ENODEV;
+	size = dev->get_size(dev);
+	pdat->size = size;
+
+	printk(KERN_INFO PFX "flash has %iM size.\n", size >> 20);
+
+	/*
+	 * pdat->parts is const and it is good thing. however we need
+	 * to change fields, so kmalloc local_parts and memcpy it.
+	 */
+	local_parts = kmalloc(pdat->num_parts * sizeof (*local_parts),
+			      GFP_KERNEL);
+	if (local_parts == NULL) {
+		res = -ENOMEM;
+		goto out_cleanup;
+	}
+	memcpy(local_parts, pdat->parts,
+	       pdat->num_parts * sizeof (*local_parts));
+
+	/*
+	 * if FBXMTD_PART_MAP_ALL is set on partition 0 then it has
+	 * offset 0 and covers the whole flash.
+	 */
+	if (local_parts[0].flags & FBXMTD_PART_MAP_ALL) {
+		local_parts[0].offset = 0;
+		local_parts[0].size = size;
+		printk(KERN_INFO PFX "partition `%s' covers the whole "
+		       "flash.\n", pdat->parts[0].name);
+	}
+
+	/*
+	 * adjust offset values depending on roffset.
+	 */
+	for (i = 0; i < pdat->num_parts; ++i) {
+		if (local_parts[i].roffset) {
+			if (local_parts[i].roffset >= size) {
+				printk(KERN_ERR PFX "partition %s roffset "
+				       "too big!\n", local_parts[i].name);
+				local_parts[i].offset = 0;
+				local_parts[i].size = 0;
+				continue ;
+			}
+			local_parts[i].offset = size - local_parts[i].roffset;
+		}
+	}
+
+	/*
+	 * handle FBXMTD_PART_AUTOSIZE, end partition at the starting
+	 * offset of the next one, or the end of the flash.
+	 */
+	for (i = 0; i < pdat->num_parts; ++i) {
+		struct fbxmtd_platform_part *align_part;
+
+		if ((local_parts[i].flags & FBXMTD_PART_AUTOSIZE) == 0)
+			continue ;
+		align_part = get_partition_by_name(local_parts[i].align_part,
+						   local_parts,
+						   pdat->num_parts);
+		if (align_part == NULL) {
+			printk(KERN_ERR PFX "%s: no partition to align "
+			       "with, align with flash end.\n",
+			       local_parts[i].name);
+			local_parts[i].size = size - local_parts[i].offset;
+			continue ;
+		}
+
+		if (local_parts[i].offset >= align_part->offset) {
+			printk(KERN_ERR PFX "%s starts after %s: unable to "
+			       "align.\n", local_parts[i].name,
+			       align_part->name);
+			continue ;
+		}
+		local_parts[i].size = align_part->offset -
+		  local_parts[i].offset;
+	}
+
+	/*
+	 * build partition table from platform partition table. for
+	 * partitions that have the FBXMTD_PART_HAS_FS set, a
+	 * partition named $name_fs with the data found in the image
+	 * tag.
+	 */
+	for (partition_count = 0, i = 0; i < pdat->num_parts; ++i) {
+		const struct fbxmtd_platform_part *p;
+		char *name;
+
+		if (partition_count >= FBXMTD_MAX_PART) {
+			printk(KERN_ERR PFX "platform partition count too "
+			       "big.\n");
+			res = -EINVAL;
+			goto out_cleanup;
+		}
+		p = &local_parts[i];
+
+		/*
+		 * stop now if the partition is bigger than the
+		 * available flash size.
+		 */
+		if (p->offset + p->size > size)
+			break;
+
+		if (p->name) {
+			name = kstrdup(p->name, GFP_KERNEL);
+		} else {
+			/* set name to "part%d" */
+			name = kmalloc(8, GFP_KERNEL);
+		}
+		if (name == NULL) {
+			res = -ENOMEM;
+			goto out_cleanup;
+		}
+
+		if (!p->name)
+			sprintf(name, "part%d", partition_count);
+
+		partitions[partition_count].name = name;
+		partitions[partition_count].offset = p->offset;
+		partitions[partition_count].size = p->size;
+
+		if (p->flags & FBXMTD_PART_RW)
+			partitions[partition_count].rw = 1;
+		else
+			partitions[partition_count].rw = 0;
+
+
+		++partition_count;
+
+		if (p->flags & FBXMTD_PART_HAS_FS) {
+			if (partition_count >= FBXMTD_MAX_PART) {
+				printk(KERN_ERR PFX "platform partition "
+				       "count too big.\n");
+				res = -EINVAL;
+				goto out_cleanup;
+			}
+
+			name = kmalloc(strlen(p->name) + 4, GFP_KERNEL);
+			if (name == NULL) {
+				res = -ENOMEM;
+				goto out_cleanup;
+			}
+			snprintf(name, strlen(p->name) + 4, "%s_fs",
+				 p->name);
+
+			partitions[partition_count].name = name;
+			if (p->flags & FBXMTD_PART_IGNORE_TAG) {
+				partitions[partition_count].offset = 0;
+				partitions[partition_count].size = 0;
+			} else {
+				read_imagetag(&partitions[partition_count - 1],
+					      &partitions[partition_count],
+					      p->flags & FBXMTD_PART_CHECK_CRC,
+					      p->flags & FBXMTD_PART_SKIP_KERNEL);
+			}
+			++partition_count;
+		}
+	}
+
+	/*
+	 * print partition table.
+	 */
+	printk(PFX "partition table:\n");
+	for (i = 0; i < partition_count; ++i) {
+		struct fbxmtd_part *p;
+
+		p = &partitions[i];
+		printk("  %s(%i): %08x -> %08x (%iK), %s\n",
+		       p->name, i, p->offset,
+		       p->offset + p->size, p->size >> 10,
+		       p->rw ? "rw" : "ro");
+	}
+
+	res = fbxmtd_set_partitions(dev, partitions, partition_count);
+	if (res < 0) {
+		printk(KERN_ERR PFX "failed to set partition.\n");
+	} else {
+		pdat->core_dev = dev;
+		pdat->status = E_FBXMTD_PROBED;
+	}
+
+ out_cleanup:
+	if (local_parts)
+		kfree(local_parts);
+
+	for (i = 0; i < partition_count; ++i) {
+		if (partitions[i].name) {
+			kfree(partitions[i].name);
+			partitions[i].name = NULL;
+		}
+	}
+
+	if (dev && res < 0) {
+		fbxmtd_put_device(dev);
+		dev = NULL;
+	}
+	return res;
+}
+
+static int
+fbxmtd_map_drv_fbx_remove(struct platform_device *pdev)
+{
+	if (dev) {
+		fbxmtd_mark_dead_dev(dev);
+		fbxmtd_put_device(dev);
+	}
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+
+static struct platform_driver fbxmtd_map_drv_fbx =
+{
+	.probe	= fbxmtd_map_drv_fbx_probe,
+	.remove	= fbxmtd_map_drv_fbx_remove,
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "fbxmtd_map_drv_fbx",
+	},
+};
+
+int __init
+fbxmtd_map_drv_fbx_init(void)
+{
+	printk(KERN_INFO PFX "2007, Freebox SA.\n");
+
+	platform_driver_register(&fbxmtd_map_drv_fbx);
+	return 0;
+}
+
+void __exit
+fbxmtd_map_drv_fbx_exit(void)
+{
+	platform_driver_unregister(&fbxmtd_map_drv_fbx);
+}
+
+module_init(fbxmtd_map_drv_fbx_init);
+module_exit(fbxmtd_map_drv_fbx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_AUTHOR("Nicolas Schichan <nschichan@freebox.fr>");
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_priv.h linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_priv.h
--- linux-2.6.31.7-fbx/drivers/fbxmtd./fbxmtd_priv.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxmtd/fbxmtd_priv.h	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,44 @@
+
+#ifndef FBXMTD_PRIV_H_
+# define FBXMTD_PRIV_H_
+
+/*
+ * notifier
+ */
+#define FBXMTD_EVENT_PART	(1 << 0)
+#define FBXMTD_EVENT_DEAD	(1 << 1)
+
+struct fbxmtd_notifier
+{
+	uint32_t		event_mask;
+	void			(*cb)(void *cb_data,
+				      struct fbxmtd_part *, uint32_t);
+	void			*cb_data;
+	struct list_head	list;
+};
+
+
+/*
+ * io helper used by backend
+ */
+uint32_t fbxmtd_bus_width_read(struct fbxmtd_dev_map *map,
+			       uint32_t offset);
+
+void fbxmtd_bus_width_write(struct fbxmtd_dev_map *map, uint32_t offset,
+			    uint32_t data);
+
+uint32_t fbxmtd_get_bus_word(struct fbxmtd_dev_map *map, const uint8_t *buf);
+
+int fbxmtd_bus_word_equal(struct fbxmtd_dev_map *map, uint32_t d1,
+			  uint32_t d2);
+
+
+/*
+ * backend chip handler
+ */
+struct fbxmtd_dev *fbxmtd_core_amd_probe(dma_addr_t base_phys,
+					 unsigned int flash_width);
+struct fbxmtd_dev *fbxmtd_core_intel_probe(dma_addr_t base_phys,
+					   unsigned int flash_width);
+
+#endif /* ! FBXMTD_PRIV_H_ */
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxmtd./Kconfig linux-2.6.31.7-fbx/drivers/fbxmtd/Kconfig
--- linux-2.6.31.7-fbx/drivers/fbxmtd./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxmtd/Kconfig	2010-03-18 18:28:49.203436722 +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-2.6.31.7-fbx/drivers/fbxmtd./Makefile linux-2.6.31.7-fbx/drivers/fbxmtd/Makefile
--- linux-2.6.31.7-fbx/drivers/fbxmtd./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxmtd/Makefile	2010-03-18 18:28:49.203436722 +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-2.6.31.7-fbx/drivers/fbxpanel./Kconfig linux-2.6.31.7-fbx/drivers/fbxpanel/Kconfig
--- linux-2.6.31.7-fbx/drivers/fbxpanel./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxpanel/Kconfig	2010-03-18 18:28:49.203436722 +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-2.6.31.7-fbx/drivers/fbxpanel./Makefile linux-2.6.31.7-fbx/drivers/fbxpanel/Makefile
--- linux-2.6.31.7-fbx/drivers/fbxpanel./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxpanel/Makefile	2010-03-18 18:28:49.203436722 +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-2.6.31.7-fbx/drivers/fbxprocfs./fbxprocfs.c linux-2.6.31.7-fbx/drivers/fbxprocfs/fbxprocfs.c
--- linux-2.6.31.7-fbx/drivers/fbxprocfs./fbxprocfs.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxprocfs/fbxprocfs.c	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,205 @@
+/*
+ * Freebox ProcFs interface
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+
+#include <linux/fbxprocfs.h>
+
+#define PFX	"fbxprocfs: "
+
+
+static struct list_head clients;
+static struct semaphore 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;
+	down(&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:
+	up(&clients_mutex);
+	return ret;
+}
+
+/*
+ * unregister  a  fbxprocfs client, make sure usage count is zero
+ */
+int fbxprocfs_remove_client(struct fbxprocfs_client *client)
+{
+	int ret;
+
+	down(&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:
+	up(&clients_mutex);
+	return ret;
+}
+
+/*
+ * remove given entries from client directory
+ */
+static int
+__remove_entries(struct fbxprocfs_client *client,
+		 const struct fbxprocfs_ro_desc *ro_desc,
+		 const struct fbxprocfs_rw_desc *rw_desc)
+{
+	int i;
+
+	for (i = 0; ro_desc && ro_desc[i].name; i++) {
+		remove_proc_entry(ro_desc[i].name, client->dir);
+		atomic_dec(&client->refcount);
+	}
+
+	for (i = 0; rw_desc && rw_desc[i].name; i++) {
+		remove_proc_entry(rw_desc[i].name, client->dir);
+		atomic_dec(&client->refcount);
+	}
+
+	return 0;
+}
+
+/*
+ * create given entries in client directory
+ */
+static int
+__create_entries(struct fbxprocfs_client *client,
+		 const struct fbxprocfs_ro_desc *ro_desc,
+		 const struct fbxprocfs_rw_desc *rw_desc)
+{
+	struct proc_dir_entry	*proc;
+	int			i;
+
+	for (i = 0; ro_desc && ro_desc[i].name; i++) {
+		if (!(proc = create_proc_read_entry(ro_desc[i].name, 0,
+						    client->dir,
+						    ro_desc[i].rfunc,
+						    (void *) ro_desc[i].id))) {
+			printk(KERN_ERR PFX "can't create %s/%s entry\n",
+			       client->dirname, ro_desc[i].name);
+			goto err;
+		}
+		atomic_inc(&client->refcount);
+	}
+
+	for (i = 0; rw_desc && rw_desc[i].name; i++) {
+		if (!(proc = create_proc_entry(rw_desc[i].name, 0,
+					       client->dir))) {
+			printk(KERN_ERR PFX "can't create %s/%s entry\n",
+			       client->dirname, ro_desc[i].name);
+			goto err;
+		}
+
+		proc->read_proc  = rw_desc[i].rfunc;
+		proc->write_proc = rw_desc[i].wfunc;
+		proc->data = (void *)rw_desc[i].id;
+		atomic_inc(&client->refcount);
+	}
+
+	return 0;
+
+err:
+	__remove_entries(client, ro_desc, rw_desc);
+	return -1;
+}
+
+int
+fbxprocfs_create_entries(struct fbxprocfs_client *client,
+			 const struct fbxprocfs_ro_desc *ro_desc,
+			 const struct fbxprocfs_rw_desc *rw_desc)
+{
+	int	ret;
+
+	ret = __create_entries(client, ro_desc, rw_desc);
+	return ret;
+}
+
+int
+fbxprocfs_remove_entries(struct fbxprocfs_client *client,
+			 const struct fbxprocfs_ro_desc *ro_desc,
+			 const struct fbxprocfs_rw_desc *rw_desc)
+{
+	int	ret;
+
+	ret = __remove_entries(client, ro_desc, rw_desc);
+	return ret;
+}
+
+
+static int __init
+fbxprocfs_init(void)
+{
+	INIT_LIST_HEAD(&clients);
+	init_MUTEX(&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-2.6.31.7-fbx/drivers/fbxprocfs./Kconfig linux-2.6.31.7-fbx/drivers/fbxprocfs/Kconfig
--- linux-2.6.31.7-fbx/drivers/fbxprocfs./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxprocfs/Kconfig	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,2 @@
+config FREEBOX_PROCFS
+	tristate "Freebox procfs interface"
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxprocfs./Makefile linux-2.6.31.7-fbx/drivers/fbxprocfs/Makefile
--- linux-2.6.31.7-fbx/drivers/fbxprocfs./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxprocfs/Makefile	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1 @@
+obj-$(CONFIG_FREEBOX_PROCFS) += fbxprocfs.o
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxwatchdog./Kconfig linux-2.6.31.7-fbx/drivers/fbxwatchdog/Kconfig
--- linux-2.6.31.7-fbx/drivers/fbxwatchdog./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxwatchdog/Kconfig	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,16 @@
+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_BCM63XX
+	tristate "Broadcom 63xx Freebox Watchdog support"
+	depends on BCM63XX
+	default n
+
+endif
diff -Nruw linux-2.6.31.7-fbx/drivers/fbxwatchdog./Makefile linux-2.6.31.7-fbx/drivers/fbxwatchdog/Makefile
--- linux-2.6.31.7-fbx/drivers/fbxwatchdog./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/fbxwatchdog/Makefile	2010-03-18 18:28:49.203436722 +0100
@@ -0,0 +1,8 @@
+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_BCM63XX)	+= fbxwatchdog_bcm63xx.o
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/drivers/ide/tango2ide.c	2010-10-25 13:43:56.451445421 +0200
@@ -0,0 +1,485 @@
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ide.h>
+#include <linux/scatterlist.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <asm/mach-tango2/hardware.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+#include <asm/mach-tango2/tango2_mbus.h>
+#include <asm/mach-tango2/devices.h>
+
+#define PFX	"tango2_ide: "
+
+/*
+ * helper to access host interface
+ */
+#define RD_HOST_REG32(r)	\
+		gbus_readl(REG_BASE_host_interface + (r))
+
+#define WR_HOST_REG32(r, v)	\
+		gbus_writel(REG_BASE_host_interface + (r), (v))
+
+#define RD_HOST_REG8(r)	\
+		gbus_readb(REG_BASE_host_interface + (r))
+
+#define WR_HOST_REG8(r, v)	\
+		gbus_writeb(REG_BASE_host_interface + (r), (v))
+
+/*
+ * io helpers for PIO access
+ */
+static void tango2_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
+			      void *buf, unsigned int len)
+{
+	u16 *data;
+	int i;
+
+	data = (u16 *)buf;
+	for (i = 0; i < (len + 1) / 2; i++)
+		data[i] = gbus_readw(REG_BASE_host_interface_BMIDE);
+}
+
+static void tango2_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
+			       void *buf, unsigned int len)
+{
+	u16 *data;
+	int i;
+
+	data = (u16 *)buf;
+
+	for (i = 0; i < (len + 1) / 2; i++)
+		gbus_writew(REG_BASE_host_interface_BMIDE, data[i]);
+}
+
+/*
+ * dma operations
+ */
+static unsigned long g_mbus_reg = 0;
+static struct scatterlist *g_next_sg = NULL;
+
+static void tango2_ide_dma_host_set(ide_drive_t *drive, int on)
+{
+	u8 unit = drive->dn & 1;
+	u8 dma_stat = RD_HOST_REG32(IDECTRL_bmis);
+
+	if (on)
+		dma_stat |= (1 << (5 + unit));
+	else
+		dma_stat &= ~(1 << (5 + unit));
+
+	WR_HOST_REG32(IDECTRL_bmis, dma_stat);
+}
+
+static int tango2_ide_dma_test_irq(ide_drive_t *drive)
+{
+	u8 dma_stat = RD_HOST_REG32(IDECTRL_bmis);
+
+	return (dma_stat & ATA_DMA_INTR) ? 1 : 0;
+}
+
+static void tango2_mbus_intr(int irq, void *arg)
+{
+	ide_drive_t *drive = (ide_drive_t *)arg;
+	struct scatterlist *sg;
+	unsigned long flags;
+
+	em86xx_mbus_wait(g_mbus_reg, SBOX_IDEDVD);
+
+	/*
+	 * setup a new mbus transfer
+	 */
+	local_irq_save(flags);
+	sg = g_next_sg;
+	g_next_sg = sg_next(sg);
+	local_irq_restore(flags);
+
+	if (em86xx_mbus_setup_dma(g_mbus_reg, sg_dma_address(sg),
+				  sg_dma_len(sg),
+				  g_next_sg ? tango2_mbus_intr : NULL,
+				  drive)) {
+		printk(KERN_ERR PFX "fail to resetup dma, wait "
+		       "for timeout...\n");
+	}
+}
+
+static void tango2_dma_start(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct request *rq = hwif->rq;
+	unsigned long val;
+
+	/* setup IDE DMA transfer len */
+	WR_HOST_REG32(IDECTRL_ide_dmalen, blk_rq_bytes(rq));
+
+	/* enable bus mastering */
+	val = (1 << 2) | ATA_DMA_START;
+	if (hwif->cmd.sg_dma_direction == DMA_FROM_DEVICE)
+		val |= ATA_DMA_WR;
+
+	WR_HOST_REG32(IDECTRL_bmic, val);
+}
+
+static int tango2_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct scatterlist *sg = hwif->sg_table;
+	int iswrite;
+
+	iswrite = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
+
+	/* try to setup dma channel */
+	if (em86xx_mbus_alloc_dma(SBOX_IDEDVD, iswrite ? 0 : 1, &g_mbus_reg,
+				  NULL)) {
+		printk(KERN_ERR PFX "fail to alloc dma\n");
+		return 1;
+	}
+
+	/*
+	 * transfer first segment
+	 */
+	g_next_sg = sg_next(sg);
+
+	/*
+	 * setup mbus dma for this address.  we want an mbus interrupt
+	 * only if this  is not the last sg element,  so we can refeed
+	 * mbus.
+	 */
+	if (em86xx_mbus_setup_dma(g_mbus_reg, sg_dma_address(sg),
+				  sg_dma_len(sg),
+				  (cmd->sg_nents == 1) ? NULL :
+				  tango2_mbus_intr, drive)) {
+		printk(KERN_ERR PFX "fail to setup dma\n");
+		em86xx_mbus_free_dma(g_mbus_reg, SBOX_IDEDVD);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int tango2_ide_dma_end(ide_drive_t *drive)
+{
+	u8 dma_stat, mask;
+	int mbus_stat;
+
+	/* get DMA status */
+	dma_stat = RD_HOST_REG32(IDECTRL_bmis);
+
+	/*
+	 * make sure DMA is not in progress
+	 */
+	if ((dma_stat & 0x7) == 1) {
+		printk(KERN_ERR PFX "huh ? dma_end called while dma still "
+		       "in progress...\n");
+	}
+
+	/* clear INTR & ERROR bits */
+	WR_HOST_REG32(IDECTRL_bmis, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
+
+	/*
+	 * confirm  whether MBUS transfer  is done  due to  the memory
+	 * arbitration, IDE  device thinks  the DMA transfer  is done,
+	 * but the data might be held in MBUS FIFO
+	 */
+	mbus_stat = em86xx_mbus_wait(g_mbus_reg, SBOX_IDEDVD);
+
+	/* release mbus */
+	em86xx_mbus_free_dma(g_mbus_reg, SBOX_IDEDVD);
+
+	/* stop bus mastering */
+	WR_HOST_REG32(IDECTRL_bmic, 0x4);
+	wmb();
+
+	/* fake  dma  error  in  case  of mbus  timeout,  else  return
+	 * dma_status error bit */
+	if (mbus_stat)
+		return 0x1;
+	mask = ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR;
+	if ((dma_stat & mask) != ATA_DMA_INTR)
+		return 0x10 | dma_stat;
+	return 0;
+}
+
+static int tango2_dma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
+{
+	hwif->dma_base = 0x42424242;
+	return 0;
+}
+
+/*
+ * timing values for each ide mode
+ */
+static const unsigned int s_pio_tim[] = {
+	0xff230ee6, 0xd41b0fa4, 0xb4150f63, 0xa7110f62, 0x9a0f0552
+};
+
+static const unsigned int s_dma_tim[] = {
+	0xe92f2fa4, 0xa0110a63, 0x9a0f0552
+};
+static const unsigned int s_udma_tim1[] = {
+	0x35440b08, 0x35440a06, 0x35440804
+};
+static const unsigned int s_udma_tim2[] = {
+	0x00000208, 0x00000206, 0x00000204}
+;
+
+static const unsigned int s_udma_tim1_alt[] = {
+	0x44442418, 0x44441c10, 0x4444160b, 0x44441608,
+	0x44441605, 0x44441303, 0x44441302, 0x44441302
+};
+static const unsigned int s_udma_tim2_alt[] = {
+	0x0000010f, 0x0000010a, 0x00000106, 0x00000104,
+	0x00000101, 0x00000202, 0x00000202, 0x00000202
+};
+
+
+/*
+ * tango2_ide_set_pio_mode
+ */
+static void tango2_ide_set_pio_mode(ide_drive_t *drive, u8 pio)
+{
+	unsigned int ctrlreg;
+	int didx;
+
+	/*
+	 * setup timing for PIO mode
+	 */
+	printk("%s: set to PIO mode %u\n", drive->name, pio);
+
+	didx = drive->dn & 1;
+	WR_HOST_REG32(((didx == 0) ? IDECTRL_pri_drv0tim :
+		       IDECTRL_pri_drv1tim), s_pio_tim[pio]);
+
+	ctrlreg = RD_HOST_REG32(IDECTRL_pri_idectl);
+	ctrlreg &= ~(didx == 0 ? 0xf : 0xf0);
+	/* fast timing for PIO */
+	ctrlreg |= 0x1 << (didx * 4);
+	WR_HOST_REG32(IDECTRL_pri_idectl, ctrlreg);
+}
+
+/*
+ * tango2_ide_tune_chipset
+ */
+static void tango2_ide_set_dma_mode(ide_drive_t *drive, u8 xferspeed)
+{
+	unsigned int ctrlreg, newflag;
+	int didx;
+	u8 mode;
+
+	didx = drive->dn & 1;
+
+	newflag = 0;
+
+	if (xferspeed >= XFER_MW_DMA_0 && xferspeed <= XFER_MW_DMA_2) {
+		/*
+		 * setup timing for Multi-word DMA
+		 */
+		mode = xferspeed - XFER_MW_DMA_0;
+		printk("%s: set to Multi-word DMA mode %d\n", drive->name,
+		       mode);
+
+		/* fast timing for PIO, prefetch enable */
+		newflag = 0x05;
+
+		WR_HOST_REG32(((didx == 0) ? IDECTRL_pri_drv0tim :
+			     IDECTRL_pri_drv1tim), s_dma_tim[mode]);
+		WR_HOST_REG32(((didx == 0) ? IDECTRL_pri_drv0udmatim1 :
+			     IDECTRL_pri_drv1udmatim1), s_udma_tim1[mode]);
+		WR_HOST_REG32(((didx == 0) ? IDECTRL_pri_drv0udmatim2 :
+			     IDECTRL_pri_drv1udmatim2), s_udma_tim2[mode]);
+
+	} else if (xferspeed >= XFER_UDMA_0 && xferspeed <= XFER_UDMA_7) {
+		unsigned int val;
+
+		/*
+		 * setup timing for Ultra DMA
+		 */
+		mode = xferspeed - XFER_UDMA_0;
+		printk("%s: set to Ultra DMA mode %d\n", drive->name, mode);
+
+		newflag = 0x00;
+
+		/* enable Ultra DMA */
+		val = RD_HOST_REG32(IDECTRL_udmactl);
+		val |= (didx == 0) ? 0x01 : 0x02;
+		WR_HOST_REG32(IDECTRL_udmactl, val);
+
+		WR_HOST_REG32(((didx == 0) ? IDECTRL_pri_drv0udmatim1 :
+			     IDECTRL_pri_drv1udmatim1), s_udma_tim1_alt[mode]);
+		WR_HOST_REG32(((didx == 0) ? IDECTRL_pri_drv0udmatim2 :
+			     IDECTRL_pri_drv1udmatim2), s_udma_tim2_alt[mode]);
+	}
+
+	ctrlreg = RD_HOST_REG32(IDECTRL_pri_idectl);
+	ctrlreg &= ~(didx == 0 ? 0xf : 0xf0);
+	ctrlreg |= newflag << (didx * 4);
+	WR_HOST_REG32(IDECTRL_pri_idectl, ctrlreg);
+}
+
+static u8 tango2_ide_cable_detect(ide_hwif_t *hwif)
+{
+	if (RD_HOST_REG32(IDECTRL_idestatus) & (1 << 1))
+		return ATA_CBL_PATA40;
+	return ATA_CBL_PATA80;
+}
+
+static void tango2_hw_setup(struct ide_hw *hw)
+{
+	unsigned long reg;
+	int i;
+
+	memset(hw, 0, sizeof (*hw));
+
+	/* setup io_ports */
+	reg = KSEG1ADDR(REG_BASE_host_interface_BMIDE);
+	for (i = 0; i < IDE_NR_PORTS; i++) {
+		hw->io_ports_array[i] = reg;
+		reg += 4;
+	}
+
+	/* special case for ctl */
+	hw->io_ports.ctl_addr = KSEG1ADDR(REG_BASE_host_interface +
+					  IDECTRL_pri_ctrlblock);
+}
+
+static const struct ide_tp_ops tango2_ide_tp_ops = {
+	.exec_command		= ide_exec_command,
+	.read_status		= ide_read_status,
+	.read_altstatus		= ide_read_altstatus,
+
+	.write_devctl		= ide_write_devctl,
+
+	.dev_select		= ide_dev_select,
+	.tf_load		= ide_tf_load,
+	.tf_read		= ide_tf_read,
+
+	.input_data		= tango2_input_data,
+	.output_data		= tango2_output_data,
+};
+
+static const struct ide_dma_ops tango2_ide_dma_ops = {
+	.dma_host_set		= tango2_ide_dma_host_set,
+	.dma_setup		= tango2_dma_setup,
+	.dma_start		= tango2_dma_start,
+	.dma_end		= tango2_ide_dma_end,
+	.dma_test_irq		= tango2_ide_dma_test_irq,
+	.dma_lost_irq		= ide_dma_lost_irq,
+};
+
+static const struct ide_port_ops tango2_ide_port_ops = {
+	.set_pio_mode		= tango2_ide_set_pio_mode,
+	.set_dma_mode		= tango2_ide_set_dma_mode,
+	.cable_detect		= tango2_ide_cable_detect,
+};
+
+static const struct ide_port_info tango2_ide_port_info = {
+	.init_dma		= tango2_dma_init,
+
+	.tp_ops			= &tango2_ide_tp_ops,
+	.port_ops		= &tango2_ide_port_ops,
+	.dma_ops		= &tango2_ide_dma_ops,
+
+	.host_flags		= (IDE_HFLAG_NO_IO_32BIT |
+				   IDE_HFLAG_UNMASK_IRQS |
+				   IDE_HFLAG_POST_SET_MODE |
+				   IDE_HFLAG_MMIO),
+
+	.pio_mask		= ATA_PIO4,
+	.swdma_mask		= 0,
+	.mwdma_mask		= ATA_MWDMA2,
+	.udma_mask		= ATA_UDMA5,
+};
+
+int __init tango2_ide_probe(struct platform_device *pdev)
+{
+	struct tango2_ide_platform_data *pd;
+	struct ide_host *host;
+	struct ide_hw hw, *hws[] = { &hw, NULL, NULL, NULL };
+	int ret;
+
+	pd = pdev->dev.platform_data;
+	pd->reset_ide();
+
+	/* Enable bus master IDE interface */
+	WR_HOST_REG32(IDECTRL_pri_idectl, 0x8400);
+
+	/* no skew : normal IORDY, normal data */
+	WR_HOST_REG32(IDECTRL_idesrc, 0);
+
+	/* Enable non-PRD mode */
+	WR_HOST_REG32(IDECTRL_bmic, (1 << 2));
+
+	/*
+	 * set register offset for our controller
+	 */
+	tango2_hw_setup(&hw);
+
+	/*
+	 * Tango   has   two   interrupts   for   IDE   controller   :
+	 * IRQ_IDECTRL_IDE,  IRQ_IDECTRL_IDEDMA
+	 *
+
+	 * IRQ_IDECTRL_IDEDMA is to be used for DMA transfer but it is
+	 * almost same with IRQ_IDECTRL_IDE interrupt.  Tango triggers
+	 * IDEDMA interrupt  after DMA FIFO  is flushed, and  it stays
+	 * high   until  BMIS   register  bit   2  is   cleared.   Use
+	 * IRQ_IDECTRL_IDE interrupt for both of PIO and DMA.
+	 */
+	hw.irq = IRQ_IDECTRL_IDE;
+	hw.dev = &pdev->dev;
+
+	em86xx_mbus_init();
+
+	host = ide_host_alloc(&tango2_ide_port_info, hws, 1);
+	if (!host)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, host);
+
+	ret = ide_host_register(host, &tango2_ide_port_info, hws);
+	if (ret) {
+		printk(KERN_ERR PFX
+		       "failed to register SMP863x ide controller\n");
+		platform_set_drvdata(pdev, NULL);
+		ide_host_free(host);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __devexit tango2_ide_remove(struct platform_device *pdev)
+{
+	struct ide_host *host = platform_get_drvdata(pdev);
+	ide_host_remove(host);
+	return 0;
+}
+
+static struct platform_driver tango2_driver = {
+	.probe		= tango2_ide_probe,
+	.remove		= __devexit_p(tango2_ide_remove),
+	.driver = {
+		.name	= "tango2_ide",
+	},
+};
+
+static int __init tango2_ide_init(void)
+{
+	return platform_driver_register(&tango2_driver);
+}
+
+static void __exit tango2_ide_exit(void)
+{
+	platform_driver_unregister(&tango2_driver);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SMP86xx BM IDE driver");
+MODULE_ALIAS("platform:tango2ide");
+
+module_init(tango2_ide_init);
+module_exit(tango2_ide_exit);
diff -Nruw linux-2.6.31.7-fbx/drivers/media/dvb/tango2./Kconfig linux-2.6.31.7-fbx/drivers/media/dvb/tango2/Kconfig
--- linux-2.6.31.7-fbx/drivers/media/dvb/tango2./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/tango2/Kconfig	2010-03-18 18:28:49.863535392 +0100
@@ -0,0 +1,11 @@
+config DVB_TANGO2
+	tristate "Tango2 DVB adapter"
+	depends on DVB_CORE && ARCH_FBX5_B
+	select I2C
+	select I2C_ALGOBIT
+	select DVB_TDA1004X
+	select DVB_PLL
+
+config DVB_TANGO2_TESTBED
+	bool "extended testing and useful error codes"
+	depends on DVB_TANGO2
diff -Nruw linux-2.6.31.7-fbx/drivers/media/dvb/tango2./Makefile linux-2.6.31.7-fbx/drivers/media/dvb/tango2/Makefile
--- linux-2.6.31.7-fbx/drivers/media/dvb/tango2./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/tango2/Makefile	2010-03-18 18:28:49.863535392 +0100
@@ -0,0 +1,5 @@
+obj-$(CONFIG_DVB_TANGO2) = tango2_dvb.o
+
+tango2_dvb-objs := tango2.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff -Nruw linux-2.6.31.7-fbx/drivers/media/dvb/tango2./tango2.c linux-2.6.31.7-fbx/drivers/media/dvb/tango2/tango2.c
--- linux-2.6.31.7-fbx/drivers/media/dvb/tango2./tango2.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/media/dvb/tango2/tango2.c	2010-03-18 18:28:49.863535392 +0100
@@ -0,0 +1,411 @@
+/*
+ * tango2.c - DVB-T frontend driver for Beyonce
+ *
+ * Copyright (C) 2006 Christophe Massiot <cmassiot@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+#include <asm/mach-tango2/tango2_gpio.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/board-fbx5b.h>
+
+#include "dvb_frontend.h"
+#include "dvbdev.h"
+#include "tda1004x.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define DRIVER_NAME		"tango2_dvb"
+#define PFX			"tango2_dvb: "
+
+#define TANGO2_REGBASE	REG_BASE_system_block
+#define MASK_0 0x00010000
+#define MASK_1 0x00010001
+
+#define I2C_ADDR_TDA10046	0x10
+#define I2C_ADDR_TDQD5		0x61
+
+struct tango2 {
+	/* device */
+	struct platform_device *pdev;
+
+	/* dvb */
+	struct dvb_adapter dvb_adapter;
+	struct dvb_frontend *fe;
+	int pll_error;
+
+	/* i2c */
+	struct i2c_algo_bit_data i2c_bit;
+	struct i2c_adapter i2c_adap;
+};
+
+static struct tango2 *gtango2;
+
+static inline struct tango2 *frontend_to_tango2(struct dvb_frontend *fe)
+{
+	return container_of(fe->dvb, struct tango2, dvb_adapter);
+}
+
+/*
+ * i2c
+ */
+
+static void tango2_setsda(void *data, int state)
+{
+	if (state) {
+		gbus_write_uint32(NULL, TANGO2_REGBASE + SYS_gpio_dir, MASK_0 << GPIO_DEMOD_I2C_DATA);  /* input */
+	} else {
+		gbus_write_uint32(NULL, TANGO2_REGBASE + SYS_gpio_data, MASK_0 << GPIO_DEMOD_I2C_DATA);
+		gbus_write_uint32(NULL, TANGO2_REGBASE + SYS_gpio_dir, MASK_1 << GPIO_DEMOD_I2C_DATA); /* output */
+	}
+}
+
+static void tango2_setscl(void *data, int state)
+{
+	if (state) {
+		gbus_write_uint32(NULL, TANGO2_REGBASE + SYS_gpio_dir, MASK_0 << GPIO_DEMOD_I2C_CLK);  /* input */
+	} else {
+		gbus_write_uint32(NULL, TANGO2_REGBASE + SYS_gpio_data, MASK_0 << GPIO_DEMOD_I2C_CLK);
+		gbus_write_uint32(NULL, TANGO2_REGBASE + SYS_gpio_dir, MASK_1 << GPIO_DEMOD_I2C_CLK); /* output */
+	}
+}
+
+static int tango2_getsda(void *data)
+{
+	return !!(gbus_read_uint32(NULL, TANGO2_REGBASE + SYS_gpio_data) & (1 << GPIO_DEMOD_I2C_DATA));
+}
+
+static int tango2_getscl(void *data)
+{
+	return !!(gbus_read_uint32(NULL, TANGO2_REGBASE + SYS_gpio_data) & (1 << GPIO_DEMOD_I2C_CLK));
+}
+
+/*
+ * ALPS TDQD5
+ */
+struct dvb_pll_desc {
+	u32  min;
+	u32  max;
+	int  count;
+	struct {
+		u32 limit;
+		u32 offset;
+		u32 stepsize;
+		u8  config;
+		u8  cb;
+	} entries[3];
+};
+
+static int dvb_pll_configure(const struct dvb_pll_desc *desc, u8 *buf,
+			     u32 freq, int bandwidth)
+{
+	u32 div;
+	int i;
+
+	if (freq != 0 && (freq < desc->min || freq > desc->max))
+		return -EINVAL;
+
+	for (i = 0; i < desc->count; i++) {
+		if (freq > desc->entries[i].limit)
+			continue;
+		break;
+	}
+	if (i == desc->count)
+		return -EINVAL;
+
+	div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize;
+	buf[0] = div >> 8;
+	buf[1] = div & 0xff;
+	buf[2] = desc->entries[i].config;
+	buf[3] = desc->entries[i].cb;
+
+	if (bandwidth == BANDWIDTH_8_MHZ)
+		buf[3] |= 0x04;
+
+	// calculate the frequency we set it to
+	return (div * desc->entries[i].stepsize) - desc->entries[i].offset;
+}
+
+static const struct dvb_pll_desc dvb_pll_tdqd5 = {
+	.min = 174000000,
+	.max = 863000000,
+	.count = 3,
+	.entries = {
+		{ 230000000, 36166667, 166667, 0xa0, 0xa2 },
+		{ 782000000, 36166667, 166667, 0xa0, 0xec },
+		{ 999999999, 36166667, 166667, 0xa0, 0x2c },
+	}
+};
+
+#ifdef CONFIG_DVB_TANGO2_TESTBED
+/* Try to tune to a frequency and return an error if i2c communication fails */
+static int tango2_tuner_init(struct dvb_frontend* fe)
+{
+	struct tango2 *tango2 = frontend_to_tango2(fe);
+	u8 buf[5];
+	struct i2c_msg msg = { .addr = I2C_ADDR_TDQD5, .flags = 0, .buf = buf, .len = sizeof(buf) };
+	int i;
+
+	dvb_pll_configure(&dvb_pll_tdqd5, buf, 474166000 + 83333, BANDWIDTH_8_MHZ);
+
+	/* Set auxiliary config byte */
+	buf[4] = 0xc6;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	i = i2c_transfer(&tango2->i2c_adap, &msg, 1);
+	if (i != 1) {
+		printk(KERN_ERR PFX "i2c pll error\n");
+		tango2->pll_error = 1;
+		return -1;
+	}
+
+	return 0;
+}
+#endif
+
+static int tango2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+{
+	struct tango2 *tango2 = frontend_to_tango2(fe);
+	u8 buf[5];
+	struct i2c_msg msg = { .addr = I2C_ADDR_TDQD5, .flags = 0, .buf = buf, .len = sizeof(buf) };
+	int i;
+
+	dvb_pll_configure(&dvb_pll_tdqd5, buf, params->frequency + 83333, params->u.ofdm.bandwidth);
+
+	/* Set auxiliary config byte */
+	buf[4] = 0xc6;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	i = i2c_transfer(&tango2->i2c_adap, &msg, 1);
+	if (i != 1) {
+		printk(KERN_ERR PFX "i2c pll error\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * tda10046
+ */
+
+static int tango2_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name)
+{
+	struct tango2 *tango2 = frontend_to_tango2(fe);
+
+	return request_firmware(fw, name, &tango2->pdev->dev);
+}
+
+static struct tda1004x_config tango2_fe_config = {
+	.demod_address = I2C_ADDR_TDA10046 >> 1,
+	.invert = 0,
+	.invert_oclk = 1,
+	.no_eeprom = 1,
+	.xtal_freq = TDA10046_XTAL_16M,
+	.agc_config = TDA10046_AGC_IFO_AUTO_NEG,
+	.if_freq = TDA10046_FREQ_3617,
+	.request_firmware = tango2_request_firmware,
+};
+
+static struct platform_driver tango2_dvb_driver = {
+	.driver = {
+		.name = "tango2 dvb",
+	},
+};
+
+/*
+ * General init
+ */
+
+static void tango2_reset_frontend(struct tango2 *tango2)
+{
+	em86xx_gpio_setdirection(GPIO_DEMOD_RESET, 1);
+	em86xx_gpio_write(GPIO_DEMOD_RESET, 0);
+	mdelay(1);
+	em86xx_gpio_write(GPIO_DEMOD_RESET, 1);
+	mdelay(2);
+}
+
+static int __init tango2_init(void)
+{
+	struct tango2 *tango2;
+	int ret = -ENOMEM;
+
+	if (fbx_board_id == E_FBXBOARDID_FBXO1B)
+		return -ENODEV;
+
+	tango2 = kmalloc(sizeof(struct tango2), GFP_KERNEL);
+	if (!tango2)
+		goto out;
+
+	memset(tango2, 0, sizeof(struct tango2));
+
+	ret = platform_driver_register(&tango2_dvb_driver);
+	if (ret < 0) {
+		printk(KERN_ERR PFX "driver registration failed\n");
+		goto err_kfree;
+	}
+
+	tango2->pdev = platform_device_register_simple("tango2_dvb", -1, NULL, 0);
+	if (IS_ERR(tango2->pdev)) {
+		printk(KERN_ERR PFX "device registration failed\n");
+		ret = PTR_ERR(tango2->pdev);
+		goto err_driver_unregister;
+	}
+
+	/* i2c */
+	i2c_set_adapdata(&tango2->i2c_adap, tango2);
+#ifdef I2C_ADAP_CLASS_TV_DIGITAL
+	tango2->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
+#else
+	tango2->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
+#endif
+	strcpy(tango2->i2c_adap.name, DRIVER_NAME);
+	tango2->i2c_adap.owner = THIS_MODULE;
+	tango2->i2c_adap.dev.parent = &tango2->pdev->dev;
+	tango2->i2c_adap.algo_data = &tango2->i2c_bit;
+	tango2->i2c_bit.setsda = tango2_setsda;
+	tango2->i2c_bit.setscl = tango2_setscl;
+	tango2->i2c_bit.getsda = tango2_getsda;
+	tango2->i2c_bit.getscl = tango2_getscl;
+	tango2->i2c_bit.udelay = 5;
+	tango2->i2c_bit.timeout = 50;
+
+	/* raise SCL and SDA */
+	tango2_setsda(tango2, 1);
+	tango2_setscl(tango2, 1);
+
+	ret = i2c_bit_add_bus(&tango2->i2c_adap);
+	if (ret < 0) {
+		printk(KERN_ERR PFX "i2c registration failed\n");
+		goto err_platform_unregister;
+	}
+
+	/* dvb */
+	ret = dvb_register_adapter(&tango2->dvb_adapter, DRIVER_NAME,
+				   THIS_MODULE, &tango2->pdev->dev, adapter_nr);
+	if (ret < 0) {
+		printk(KERN_ERR PFX "dvb registration failed\n");
+		goto err_del_i2c;
+	}
+
+	/* frontend */
+	tango2_reset_frontend(tango2);
+
+	if (fbx_board_id != E_FBXBOARDID_FBX5B1)
+		tango2_fe_config.ts_mode = TDA10046_TS_SERIAL;
+
+	tango2->fe = dvb_attach(tda10046_attach, &tango2_fe_config,
+				&tango2->i2c_adap);
+	if (!(tango2->fe)) {
+		printk(KERN_ERR PFX "could not attach frontend\n");
+#ifdef CONFIG_DVB_TANGO2_TESTBED
+		ret = -1000;
+#else
+		ret = -ENODEV;
+#endif
+		goto err_dvb_unregister;
+	}
+#ifdef CONFIG_DVB_TANGO2_TESTBED
+	tango2->fe->ops.tuner_ops.init = tango2_tuner_init;
+#endif
+	tango2->fe->ops.tuner_ops.set_params = tango2_tuner_set_params;
+
+	ret = dvb_register_frontend(&tango2->dvb_adapter, tango2->fe);
+	if (ret < 0) {
+		printk(KERN_ERR PFX "frontend registration failed\n");
+		if (tango2->fe->ops.release)
+			tango2->fe->ops.release(tango2->fe);
+		goto err_dvb_unregister;
+	}
+
+#ifdef CONFIG_DVB_TANGO2_TESTBED
+	/* The following operation is normally done the first time
+	 * the frontend device is opened. For testing purposes it is more
+	 * convenient to get the error here. */
+	if (tango2->fe->ops.init) {
+		tango2->pll_error = 0;
+		ret = tango2->fe->ops.init(tango2->fe);
+		if (ret < 0) {
+			printk(KERN_ERR PFX "frontend init failed\n");
+			if (!tango2->pll_error)
+				ret = -1001;
+			else
+				ret = -1002;
+			goto err_dvb_frontend;
+		}
+	}
+#endif
+
+	gtango2 = tango2;
+out:
+	return ret;
+
+#ifdef CONFIG_DVB_TANGO2_TESTBED
+err_dvb_frontend:
+	dvb_unregister_frontend(tango2->fe);
+#endif
+err_dvb_unregister:
+	dvb_unregister_adapter(&tango2->dvb_adapter);
+err_del_i2c:
+	i2c_del_adapter(&tango2->i2c_adap);
+err_platform_unregister:
+	platform_device_unregister(tango2->pdev);
+err_driver_unregister:
+	platform_driver_unregister(&tango2_dvb_driver);
+err_kfree:
+	kfree(tango2);
+	return ret;
+}
+
+static void __exit tango2_exit(void)
+{
+	struct tango2 *tango2 = gtango2;
+
+	dvb_unregister_frontend(tango2->fe);
+	dvb_unregister_adapter(&tango2->dvb_adapter);
+
+	i2c_del_adapter(&tango2->i2c_adap);
+
+	platform_device_unregister(tango2->pdev);
+	platform_driver_unregister(&tango2_dvb_driver);
+
+	kfree(tango2);
+
+	/* Leave the tuner in power-saving mode */
+	em86xx_gpio_write(GPIO_DEMOD_RESET, 0);
+}
+
+module_init(tango2_init);
+module_exit(tango2_exit);
+
+MODULE_AUTHOR("Christophe Massiot <cmassiot@freebox.fr>");
+MODULE_DESCRIPTION("Tango2 DVB driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/drivers/net/tango2_enet.c	2010-10-25 13:43:56.851457787 +0200
@@ -0,0 +1,1187 @@
+/*
+ * New driver for SMP863x builtin Ethernet mac
+ *
+ * This driver uses NAPI and generic linux MII support.
+ *
+ * Tx path limits the number of interrupt by reclaiming sent buffer in
+ * a timer.  In case  the tx starts  to go  faster, it will  switch to
+ * interrupt mode.
+ *
+ * Note that OOM condition is not handled correctly, and can leave the
+ * rx path  in bad  shape. down/up the  interface should make  it work
+ * again though. But anyway, it's not likely to happen.
+ *
+ * Copyright (C) 2005 Maxime Bizon <mbizon@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/crc32.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-tango2/devices.h>
+
+#include "tango2_enet.h"
+
+#define PFX	"tango2_enet: "
+
+static int gphy_id = -1;
+
+/*
+ * mdio read/write callback, can run from userspace or timer
+ */
+static __inline int enet_mdio_read(struct net_device *dev, int phy_id,
+				   int location)
+{
+	int val;
+
+	while (enet_readl(ENET_MAC_MIIAR) & MIIAR_BUSY);
+	enet_writel(ENET_MAC_MIIAR, MIIAR_ADDR(phy_id) | MIIAR_REG(location));
+	udelay(1);
+	while (enet_readl(ENET_MAC_MIIAR) & MIIAR_BUSY);
+	val = enet_readl(ENET_MAC_MIIDR);
+
+	return val;
+}
+
+static void enet_mdio_write(struct net_device *dev, int phy_id,
+				     int location, int val)
+{
+	enet_writel(ENET_MAC_MIIDR, val);
+	enet_writel(ENET_MAC_MIIAR,
+		    MIIAR_ADDR(phy_id) | MIIAR_REG(location) | MIIAR_WRITE);
+	udelay(1);
+	while (enet_readl(ENET_MAC_MIIAR) & MIIAR_BUSY);
+}
+
+/*
+ * enable/disable interrupt helpers
+ * need proper locks since we will call them from any context
+ */
+static __inline void enet_disable_interrupts(struct tango2_enet_priv *priv,
+					     int rx_only)
+{
+	unsigned long flags, val;
+
+	spin_lock_irqsave(&priv->ier_lock, flags);
+	if (rx_only) {
+		val = enet_readl(ENET_DMA_IER);
+		val &= ~IER_R;
+		enet_writel(ENET_DMA_IER, val);
+	} else
+		enet_writel(ENET_DMA_IER, 0);
+	spin_unlock_irqrestore(&priv->ier_lock, flags);
+}
+
+static __inline void enet_enable_interrupts(struct tango2_enet_priv *priv,
+					    int rx_only)
+{
+	unsigned long flags, val;
+
+	spin_lock_irqsave(&priv->ier_lock, flags);
+	if (rx_only) {
+		val = enet_readl(ENET_DMA_IER);
+		val |= IER_R;
+		enet_writel(ENET_DMA_IER, val);
+	} else
+		enet_writel(ENET_DMA_IER, IER_NIS | IER_R | IER_T);
+	spin_unlock_irqrestore(&priv->ier_lock, flags);
+}
+
+
+/*
+ * rx poll func, called by network core
+ */
+static int enet_poll(struct napi_struct *napi, int budget)
+{
+	struct net_device *dev;
+	struct tango2_enet_priv *priv;
+	int received;
+
+	priv = container_of(napi, struct tango2_enet_priv, napi);
+	dev = priv->net_dev;
+
+	/* calculate how many rx packet we are allowed to fetch */
+	received = 0;
+
+	/* process no more than "budget" done rx */
+	do {
+		volatile struct enet_rx_desc *rx;
+		struct sk_buff *skb;
+		uint32_t rdes0_cache;
+		unsigned int len;
+
+		rx = &priv->rx_descs[priv->last_rx_desc];
+
+		/* we  need  multiple  read  on this  volatile,  avoid
+		 * memory access at each time */
+		rdes0_cache = rx->rdes0;
+		if (rdes0_cache & RDES0_OWN) {
+			break;
+		}
+
+		if (budget <= 0)
+			break;
+		--budget;
+
+		if (likely(skb = priv->rx_skbs[priv->last_rx_desc])) {
+
+			/* we don't handle multipacket frame */
+			if (!(rdes0_cache & RDES0_FIRST) ||
+			    !(rdes0_cache & RDES0_LAST)) {
+				/* we don't handle multipacket frame */
+				priv->stats.rx_errors++;
+				priv->stats.rx_length_errors++;
+				goto rearm;
+			}
+
+			/* check for CRC */
+			if (rdes0_cache & RDES0_CRC) {
+				priv->stats.rx_errors++;
+				priv->stats.rx_crc_errors++;
+				goto rearm;
+			}
+
+			/* sanity check on len field */
+			len = RDES0_FRAME_LEN(rdes0_cache);
+			if (rdes0_cache & (RDES0_TOO_LONG | RDES0_TRUNC) ||
+			    len > RX_BUF_SIZE) {
+				priv->stats.rx_errors++;
+				priv->stats.rx_length_errors++;
+				goto rearm;
+			}
+
+			/* check remaining error */
+			if (rdes0_cache & (RDES0_ERR_SUM | RDES0_COLLISION |
+					   RDES0_WATCHDOG_TMOUT |
+					   RDES0_MII_ERROR)) {
+				priv->stats.rx_errors++;
+				goto rearm;
+			}
+
+			/* ok, seems  valid, adjust skb  proto and len
+			 * and give it to kernel */
+			skb->dev = dev;
+			skb_put(skb, len);
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_receive_skb(skb);
+
+			priv->stats.rx_packets++;
+			priv->stats.rx_bytes += len;
+			dev->last_rx = jiffies;
+			priv->rx_skbs[priv->last_rx_desc] = NULL;
+			/* we will realloc an skb for this slot */
+		}
+
+		skb = dev_alloc_skb(RX_BUF_SIZE + SKB_RESERVE_SIZE);
+		if (unlikely(!skb))
+			break;
+
+		skb_reserve(skb, SKB_RESERVE_SIZE);
+		rx->rdes2 = dma_map_single(NULL, skb->data, RX_BUF_SIZE,
+					   DMA_FROM_DEVICE);
+		priv->rx_skbs[priv->last_rx_desc] = skb;
+
+rearm:
+		/* rearm descriptor */
+		wmb();
+		rx->rdes0 = RDES0_OWN;
+		priv->last_rx_desc++;
+		priv->last_rx_desc &= (ENET_RX_DESC_COUNT - 1);
+		received++;
+
+	} while (1);
+
+	if (budget <= 0) {
+		/* breaked, but there is still work to do */
+		return 1;
+	}
+
+	napi_complete(napi);
+	enet_enable_interrupts(priv, 1);
+
+	return 0;
+}
+
+/*
+ * tx reclaim func. Called by timer or tx done tasklet to reclaim sent
+ * buffers.
+ */
+static void enet_tx_reclaim(unsigned long data)
+{
+	struct net_device *dev;
+	struct tango2_enet_priv *priv;
+	volatile struct enet_tx_desc *tx;
+
+	dev = (struct net_device *)data;
+	priv = netdev_priv(dev);
+
+	spin_lock(&priv->tx_lock);
+
+	while (priv->free_tx_desc_count < ENET_TX_DESC_COUNT) {
+		uint32_t tdes0_cache;
+		struct sk_buff *skb;
+
+		tx = &priv->tx_descs[priv->dirty_tx_desc];
+
+		tdes0_cache = tx->tdes0;
+		if (tdes0_cache & TDES0_OWN)
+			break;
+
+		skb = priv->tx_skbs[priv->dirty_tx_desc];
+		priv->stats.tx_packets++;
+
+		/* check  for  transmission  errors and  update  stats
+		 * accordingly */
+		if (tdes0_cache & (TDES0_ERR_SUM | TDES0_CARRIER_LOST |
+				   TDES0_NO_CARRIER | TDES0_LATE_COLLISION |
+				   TDES0_EXC_COLLISION | TDES0_HEARTBEAT |
+				   TDES0_EXC_DEFERAL | TDES0_UNDERFLOW)) {
+			priv->stats.tx_errors++;
+		} else {
+			priv->stats.tx_bytes += skb->len;
+		}
+
+		dev_kfree_skb(skb);
+		priv->tx_skbs[priv->dirty_tx_desc] = NULL;
+		priv->dirty_tx_desc++;
+		priv->dirty_tx_desc %= ENET_TX_DESC_COUNT;
+		priv->free_tx_desc_count++;
+	}
+
+	if (priv->free_tx_desc_count != 0 && netif_queue_stopped(dev))
+		netif_wake_queue(dev);
+
+	spin_unlock(&priv->tx_lock);
+}
+
+/*
+ * tx done timer callback, just call tx_done and reschedule timer
+ */
+static void enet_tx_reclaim_timer(unsigned long data)
+{
+	struct net_device *dev;
+	struct tango2_enet_priv *priv;
+
+	dev = (struct net_device *)data;
+	priv = netdev_priv(dev);
+	enet_tx_reclaim(data);
+
+	priv->tx_reclaim_timer.expires = jiffies + TX_RECLAIM_TIMER_FREQ;
+	add_timer(&priv->tx_reclaim_timer);
+}
+
+
+/*
+ * tx request callback
+ */
+static int enet_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct tango2_enet_priv *priv;
+	volatile struct enet_tx_desc *tx;
+	unsigned long tdes1_cache;
+
+	spin_lock(&priv->tx_lock);
+
+	priv = netdev_priv(dev);
+	tx = &priv->tx_descs[priv->next_tx_desc];
+
+	/* make sure the next free tx desc is available */
+	if (unlikely(priv->free_tx_desc_count == 0)) {
+		/* no, this  should not happen since  queue is stopped
+		 * before we run out of tx desc */
+		printk(KERN_WARNING PFX "no free tx desc to handle pkt\n");
+		dev_kfree_skb(skb);
+		netif_stop_queue(dev);
+		spin_unlock(&priv->tx_lock);
+		return 0;
+	}
+
+	/* fill the tx desc with this skb address */
+	tdes1_cache = (TDES1_FIRST | TDES1_LAST);
+	if (priv->next_tx_desc == ENET_TX_DESC_COUNT - 1)
+		tdes1_cache |= TDES1_TER;
+
+	/* if we  start to  run low  on free tx  desc, then  enable tx
+	 * interrupt to reclaim them faster */
+	if (priv->free_tx_desc_count == ENET_TX_DESC_LOW) {
+		tdes1_cache |= (TDES1_ENABLE_ISR);
+	}
+	tdes1_cache |= TDES1_TBS1(skb->len);
+
+	tx->tdes1 = tdes1_cache;
+	tx->tdes2 = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE);
+
+	/* keep a pointer to it for later and give it to dma  */
+	priv->tx_skbs[priv->next_tx_desc] = skb;
+	wmb();
+	tx->tdes0 = TDES0_OWN;
+
+	/* kick tx dma in case it was suspended */
+	wmb();
+	enet_writel(ENET_DMA_TPDR, 0x1);
+
+	priv->next_tx_desc++;
+	priv->next_tx_desc %= ENET_TX_DESC_COUNT;
+
+	/* if next  tx descriptor is not  clean, then we  have to stop
+	 * queue */
+	if (unlikely(--priv->free_tx_desc_count == 0))
+		netif_stop_queue(dev);
+
+	spin_unlock(&priv->tx_lock);
+
+	return 0;
+}
+
+/*
+ * our  irq handler, just  ack it  and schedule  the right  tasklet to
+ * handle this
+ */
+static irqreturn_t enet_isr(int irq, void *dev_id)
+{
+	struct net_device *dev;
+	struct tango2_enet_priv *priv;
+	unsigned long val;
+
+	dev = (struct net_device *)dev_id;
+	priv = netdev_priv(dev);
+
+	/* fetch status & ack them */
+	val = enet_readl(ENET_DMA_SR);
+	enet_writel(ENET_DMA_SR, val);
+
+	/* handle interrupt */
+	if (val & SR_NIS) {
+		if (val & SR_T) {
+			tasklet_schedule(&priv->tx_reclaim_tasklet);
+		}
+
+		if (val & SR_R) {
+			if (napi_schedule_prep(&priv->napi)) {
+				/* disable rx interrupt */
+				enet_disable_interrupts(priv, 1);
+
+				/* ack  any  interrupt  that may  have
+				 * arrived  between last ack  to avoid
+				 * reentering */
+				enet_writel(ENET_DMA_SR, SR_NIS | SR_R);
+				__napi_schedule(&priv->napi);
+			}
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void enet_netpoll(struct net_device *dev)
+{
+	struct tango2_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+	enet_disable_interrupts(priv, 0);
+	enet_isr(0, dev, NULL);
+	enet_enable_interrupts(priv, 0);
+}
+#endif
+
+/*
+ * start/stop dma engine
+ */
+static __inline void enet_start_dma(struct tango2_enet_priv *priv)
+{
+	/* send start command to rx & tx dma */
+	enet_writel(ENET_DMA_CR, CR_SF | CR_SR | CR_ST);
+}
+
+static __inline void enet_stop_dma(struct tango2_enet_priv *priv)
+{
+	unsigned long val;
+
+	/* send stop command to rx & tx dma */
+	enet_writel(ENET_DMA_CR, 0);
+
+	/* wait for them to reach stopped state, should not be long */
+	do {
+		udelay(1);
+		val = enet_readl(ENET_DMA_SR);
+		if ((val & SR_TPS) && (val & SR_RPS))
+			break;
+	} while (1);
+}
+
+/*
+ * reconfigure mac for new link state
+ */
+static void enet_link_reconfigure(struct net_device *dev)
+{
+	struct tango2_enet_priv *priv;
+	unsigned long val;
+
+	priv = netdev_priv(dev);
+
+	if (dev->flags & IFF_UP)
+		enet_stop_dma(priv);
+
+	/* reflect duplex status in dma register */
+	spin_lock(&priv->maccr_lock);
+	val = enet_readl(ENET_MAC_MACCR);
+	if (priv->mii.full_duplex)
+		val |= MACCR_F;
+	else
+		val &= ~MACCR_F;
+	enet_writel(ENET_MAC_MACCR, val);
+	spin_unlock(&priv->maccr_lock);
+
+	if (dev->flags & IFF_UP)
+		enet_start_dma(priv);
+}
+
+/*
+ * link check timer callback
+ */
+static void enet_link_check(unsigned long data)
+{
+	struct net_device *dev;
+	struct tango2_enet_priv *priv;
+	int ret;
+	unsigned long val, pkts;
+
+	dev = (struct net_device *)data;
+	priv = netdev_priv(dev);
+
+	/* check for duplex change */
+	spin_lock(&priv->mii_lock);
+	ret = mii_check_media(&priv->mii, 1, 0);
+	spin_unlock(&priv->mii_lock);
+
+	if (ret)
+		enet_link_reconfigure(dev);
+
+	/* reschedule timer */
+	priv->link_check_timer.expires = jiffies + LINK_CHECK_TIMER_FREQ;
+	add_timer(&priv->link_check_timer);
+
+	/* check for internal fifo overflows */
+	val = enet_readl(ENET_DMA_MFBOC);
+
+	pkts = (val >> 17) & 0x7ff;
+	if (pkts) {
+		priv->stats.rx_errors += pkts;
+		priv->stats.rx_fifo_errors += pkts;
+		printk(KERN_WARNING PFX "TLI fifo overflow: %lu pkts\n", pkts);
+	}
+
+	pkts = (val & 0xffff);
+	if (pkts) {
+		priv->stats.rx_errors += pkts;
+		priv->stats.rx_missed_errors += pkts;
+		printk(KERN_WARNING PFX "DMA starvation loss: %lu pkts\n",
+		       pkts);
+	}
+}
+
+/*
+ * program given mac address in hw registers
+ */
+static int enet_set_mac_address(struct net_device *dev, void *p)
+{
+	unsigned long hi_mac, low_mac;
+	struct sockaddr *addr = p;
+
+	/* to make it safe, we won't do this while running */
+	if (netif_running(dev))
+		return -EBUSY;
+
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+	hi_mac = (dev->dev_addr[5] << 8) | dev->dev_addr[4];
+	low_mac = (dev->dev_addr[3] << 24)| (dev->dev_addr[2] << 16) |
+		(dev->dev_addr[1] << 8) | dev->dev_addr[0];
+
+	enet_writel(ENET_MAC_MACAHR, hi_mac);
+	enet_writel(ENET_MAC_MACALR, low_mac);
+
+	return 0;
+}
+
+/*
+ * update hash table to reflect new device multicast address list
+ */
+static void enet_set_multicast_list(struct net_device *dev)
+{
+	struct tango2_enet_priv *priv;
+	struct dev_mc_list *mclist;
+	unsigned long val;
+	uint32_t mc_filter[2];
+	int i;
+
+	priv = netdev_priv(dev);
+
+	/* the link check timer might change MACCR, we need to protect
+	 * against it */
+	spin_lock_bh(&priv->maccr_lock);
+	val = enet_readl(ENET_MAC_MACCR);
+
+	if (dev->flags & IFF_PROMISC) {
+		val |= MACCR_PR | MACCR_PM;
+	} else {
+		val &= ~MACCR_PR;
+		/* if we want all multicast or if address count is too
+		 * high, don't try to compute hash value */
+		if (dev->mc_count > 64 || dev->flags & IFF_ALLMULTI) {
+			val |= MACCR_PM;
+		}
+	}
+	enet_writel(ENET_MAC_MACCR, val);
+	spin_unlock_bh(&priv->maccr_lock);
+
+	/* we  don't  need  to  update  hash  table  if  we  pass  all
+	 * multicast */
+	if (val & MACCR_PM)
+		return;
+
+	mc_filter[0] = mc_filter[1] = 0;
+	mclist = dev->mc_list;
+
+	for (i = 0; i < dev->mc_count; i++) {
+		unsigned int n;
+		char *addr;
+
+		addr = mclist->dmi_addr;
+		mclist = mclist->next;
+		if (!(*addr & 1))
+			continue;
+
+		n = ether_crc(ETH_ALEN, addr) >> 26;
+		mc_filter[n >> 5] |= 1 << (n & 31);
+	}
+
+	enet_writel(ENET_MAC_MALR, mc_filter[0]);
+	enet_writel(ENET_MAC_MAHR, mc_filter[1]);
+}
+
+/*
+ * open callback
+ */
+static int enet_open(struct net_device *dev)
+{
+	struct tango2_enet_priv *priv;
+	unsigned long val;
+
+	priv = netdev_priv(dev);
+
+	/* check link */
+	if (mii_check_media(&priv->mii, 1, 1))
+		enet_link_reconfigure(dev);
+
+	/* start rx & tx dma engine */
+	enet_start_dma(priv);
+
+	/* enable mac rx & tx */
+	val = enet_readl(ENET_MAC_MACCR);
+	val |= MACCR_TE | MACCR_RE;
+	enet_writel(ENET_MAC_MACCR, val);
+
+	napi_enable(&priv->napi);
+
+	/*
+	 * clear & enable interrupts, we want:
+	 * - receive complete
+	 * - transmit complete
+	 */
+	enet_writel(ENET_DMA_SR, SR_NIS | SR_R | SR_T);
+	enet_enable_interrupts(priv, 0);
+
+	/* start link check & tx reclaim timer */
+	priv->link_check_timer.expires = jiffies + LINK_CHECK_TIMER_FREQ;
+	add_timer(&priv->link_check_timer);
+
+	priv->tx_reclaim_timer.expires = jiffies + TX_RECLAIM_TIMER_FREQ;
+	add_timer(&priv->tx_reclaim_timer);
+
+	/* and finally start tx queue */
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+/*
+ * stop callback
+ */
+static int enet_stop(struct net_device *dev)
+{
+	struct tango2_enet_priv *priv;
+	unsigned long val;
+	int i;
+
+	priv = netdev_priv(dev);
+
+	/* stop link timer */
+	del_timer_sync(&priv->link_check_timer);
+
+	/* stop tx queue */
+	netif_stop_queue(dev);
+
+	napi_disable(&priv->napi);
+
+	/* wait for all tx buffers to be reclaimed */
+	while (priv->free_tx_desc_count != ENET_TX_DESC_COUNT)
+		yield();
+
+	/* stop tx reclaim timer */
+	del_timer_sync(&priv->tx_reclaim_timer);
+
+	/* disable all interrupts */
+	enet_disable_interrupts(priv, 0);
+
+	/* stop dma */
+	enet_stop_dma(priv);
+
+	/* stop mac rx & tx */
+	val = enet_readl(ENET_MAC_MACCR);
+	val &= ~(MACCR_TE | MACCR_RE);
+	enet_writel(ENET_MAC_MACCR, val);
+
+	/* while we were stopping it,  the rx dma may have filled some
+	 * buffer, consider it junk and rearm all descriptor */
+	for (i = 0; i < ENET_RX_DESC_COUNT; i++) {
+		volatile struct enet_rx_desc *rx;
+
+		rx = &priv->rx_descs[i];
+		rx->rdes0 = RDES0_OWN;
+	}
+
+	/* make  the dma engine  restarts at  first descriptor  in the
+	 * list */
+	enet_writel(ENET_DMA_RBAR, PHYSADDR(priv->rx_descs));
+	enet_writel(ENET_DMA_TBAR, PHYSADDR(priv->tx_descs));
+	priv->dirty_tx_desc = priv->next_tx_desc = 0;
+	priv->last_rx_desc = 0;
+
+	return 0;
+}
+
+/*
+ * get_stats callback
+ */
+static struct net_device_stats *enet_get_stats(struct net_device *dev)
+{
+	struct tango2_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+
+	return &priv->stats;
+}
+
+/*
+ * ethtool callbacks
+ */
+static int enet_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct tango2_enet_priv *priv;
+	int ret;
+
+	priv = netdev_priv(dev);
+
+	spin_lock_bh(&priv->mii_lock);
+	ret = mii_ethtool_gset(&priv->mii, cmd);
+	spin_unlock_bh(&priv->mii_lock);
+
+	return ret;
+}
+
+static int enet_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct tango2_enet_priv *priv;
+	int ret;
+
+	priv = netdev_priv(dev);
+
+	spin_lock_bh(&priv->mii_lock);
+	ret = mii_ethtool_sset(&priv->mii, cmd);
+	spin_unlock_bh(&priv->mii_lock);
+
+	return ret;
+}
+
+static int enet_nway_reset(struct net_device *dev)
+{
+	struct tango2_enet_priv *priv;
+	int ret;
+
+	priv = netdev_priv(dev);
+
+	spin_lock_bh(&priv->mii_lock);
+	ret = mii_nway_restart(&priv->mii);
+	spin_unlock_bh(&priv->mii_lock);
+
+	return ret;
+}
+
+static u32 enet_get_link(struct net_device *dev)
+{
+	struct tango2_enet_priv *priv;
+	int ret;
+
+	priv = netdev_priv(dev);
+
+	spin_lock_bh(&priv->mii_lock);
+	ret = mii_link_ok(&priv->mii);
+	spin_unlock_bh(&priv->mii_lock);
+
+	return ret;
+}
+
+static struct ethtool_ops enet_ethtool_ops = {
+	.get_settings		= enet_get_settings,
+	.set_settings		= enet_set_settings,
+	.nway_reset		= enet_nway_reset,
+	.get_link		= enet_get_link,
+};
+
+static int enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct tango2_enet_priv *priv;
+	int ret;
+
+	priv = netdev_priv(dev);
+
+	spin_lock_bh(&priv->mii);
+	ret = generic_mii_ioctl(&priv->mii, if_mii(rq), cmd, NULL);
+	spin_unlock_bh(&priv->mii);
+
+	return ret;
+}
+
+/*
+ * dma ring allocation is done here
+ */
+static int enet_dma_init(struct tango2_enet_priv *priv)
+{
+	int i;
+
+	/*
+	 * allocate rx descriptor list & rx buffers
+	 *
+	 * We allocate  skb now and fill buffer  with their addresses,
+	 * note that we reserve 4 bytes at beginning of data buffer to
+	 * store skb address.
+	 *
+	 */
+	priv->rx_descs_size = ENET_RX_DESC_COUNT *
+		sizeof (struct enet_rx_desc);
+	priv->rx_descs = dma_alloc_coherent(NULL,
+					    priv->rx_descs_size,
+					    &priv->rx_descs_dma_addr,
+					    GFP_KERNEL);
+	if (!priv->rx_descs)
+		return -ENOMEM;
+
+	/*
+	 * initialize all rx descs
+	 */
+	for (i = 0; i < ENET_RX_DESC_COUNT; i++) {
+		volatile struct enet_rx_desc *rx;
+		struct sk_buff *skb;
+
+		rx = &priv->rx_descs[i];
+		rx->rdes0 = RDES0_OWN;
+
+		rx->rdes1 = RDES1_RBS2(0) | RDES1_RBS1(RX_BUF_SIZE);
+		if (i == ENET_RX_DESC_COUNT - 1)
+			rx->rdes1 |= RDES1_RER;
+
+		skb = dev_alloc_skb(RX_BUF_SIZE + SKB_RESERVE_SIZE);
+		if (!skb)
+			return -ENOMEM;
+
+		skb_reserve(skb, SKB_RESERVE_SIZE);
+		rx->rdes2 = dma_map_single(NULL, skb->data, RX_BUF_SIZE,
+					   DMA_FROM_DEVICE);
+		rx->rdes3 = 0;
+
+		priv->rx_skbs[i] = skb;
+	}
+	priv->last_rx_desc = 0;
+
+	/*
+	 * allocate tx descriptor list
+	 *
+	 * We allocate  only the descriptor list and  prepare them for
+	 * further use. When tx is needed, we will set the right flags
+	 * and kick the dma.
+	 */
+	priv->tx_descs_size =
+		ENET_TX_DESC_COUNT * sizeof (struct enet_tx_desc);
+	priv->tx_descs = dma_alloc_coherent(NULL,
+					    priv->tx_descs_size,
+					    &priv->tx_descs_dma_addr,
+					    GFP_KERNEL);
+	if (!priv->tx_descs)
+		return -ENOMEM;
+
+	/*
+	 * initialize tx descs
+	 */
+	for (i = 0; i < ENET_TX_DESC_COUNT; i++) {
+		volatile struct enet_tx_desc *tx;
+
+		tx = &priv->tx_descs[i];
+		tx->tdes0 = 0;
+		tx->tdes1 = 0;
+		if (i == ENET_TX_DESC_COUNT - 1)
+			tx->tdes1 |= TDES1_TER;
+		tx->tdes2 = 0;
+		tx->tdes3 = 0;
+	}
+	priv->dirty_tx_desc = priv->next_tx_desc = 0;
+	priv->free_tx_desc_count = ENET_TX_DESC_COUNT;
+
+	/*
+	 * write rx desc list & tx desc list addresses in registers
+	 */
+	enet_writel(ENET_DMA_RBAR, priv->rx_descs_dma_addr);
+	enet_writel(ENET_DMA_TBAR, priv->tx_descs_dma_addr);
+
+	return 0;
+}
+
+/*
+ * free  all dma rings  memory, called  at uninit  time or  when error
+ * occurs at init time
+ */
+static void enet_dma_free(struct tango2_enet_priv *priv)
+{
+	int i;
+
+	if (priv->rx_descs)
+		dma_free_coherent(NULL, priv->rx_descs_size,
+				  (void *)priv->rx_descs,
+				  priv->rx_descs_dma_addr);
+	if (priv->tx_descs)
+		dma_free_coherent(NULL, priv->tx_descs_size,
+				  (void *)priv->tx_descs,
+				  priv->tx_descs_dma_addr);
+
+	for (i = 0; i < ENET_RX_DESC_COUNT; i++) {
+		if (priv->rx_skbs[i])
+			kfree_skb(priv->rx_skbs[i]);
+	}
+
+	for (i = 0; i < ENET_TX_DESC_COUNT; i++) {
+		if (priv->tx_skbs[i])
+			kfree_skb(priv->tx_skbs[i]);
+	}
+}
+
+/*
+ * reset phy
+ */
+static int enet_reset_phy(struct net_device *dev)
+{
+	struct tango2_enet_priv *priv;
+	int loop;
+
+	priv = netdev_priv(dev);
+	enet_mdio_write(dev, priv->mii.phy_id, MII_BMCR, BMCR_RESET);
+
+	/* wait for the reset bit to clear */
+	udelay(100);
+	loop = 100;
+	while (loop) {
+		if (!(enet_mdio_read(dev, priv->mii.phy_id,
+				     MII_BMCR) & BMR_SWR))
+			break;
+		mdelay(1);
+		loop--;
+	}
+
+	if (!loop) {
+		printk(KERN_ERR PFX "PHY reset does not complete...\n");
+		return -EBUSY;
+	}
+	return 0;
+}
+
+/*
+ * mac hw init is done here
+ */
+static int enet_hw_init(struct net_device *dev, struct platform_device *pdev)
+{
+	struct tango2_enet_priv *priv;
+	struct tango2_enet_platform_data *pdat;
+	int loop;
+
+	priv = netdev_priv(dev);
+	pdat = pdev->dev.platform_data;
+
+	/* reset phy only if needed by platform */
+	if (pdat && pdat->phy_need_reset) {
+		int ret;
+
+		ret = enet_reset_phy(dev);
+		if (ret)
+			return ret;
+	}
+
+	if (pdat && pdat->phy_is_ics1893) {
+		/* disable fast transition detect */
+		enet_mdio_write(dev, priv->mii.phy_id, 0x18, 0xd200);
+	}
+
+	/* reset dma engine */
+	enet_writel(ENET_DMA_BMR, BMR_SWR);
+
+	/* wait for the reset bit to clear */
+	udelay(100);
+	loop = 100;
+	while (loop) {
+		if (!(enet_readl(ENET_DMA_BMR) & BMR_SWR))
+			break;
+		mdelay(1);
+		loop--;
+	}
+
+	if (!loop) {
+		printk(KERN_ERR PFX "dma engine does not exit reset...\n");
+		return -EBUSY;
+	}
+
+	/* set bus mode */
+	enet_writel(ENET_DMA_BMR, BMR_PBL(32));
+
+	/* enable MAC flow ctrl */
+	enet_writel(ENET_MAC_FCR, FCR_ENABLE);
+
+	/* configure MAC ctrller to do hash perfect filtering  */
+	enet_writel(ENET_MAC_MACCR, MACCR_ASTP | MACCR_HP);
+
+	/* clear hash table */
+	enet_writel(ENET_MAC_MAHR, 0xffffffff);
+	enet_writel(ENET_MAC_MALR, 0xffffffff);
+
+	return 0;
+}
+
+static const struct net_device_ops tango2_enet_ops = {
+	.ndo_open		= enet_open,
+	.ndo_stop		= enet_stop,
+	.ndo_start_xmit		= enet_xmit,
+	.ndo_get_stats		= enet_get_stats,
+	.ndo_set_mac_address	= enet_set_mac_address,
+	.ndo_set_multicast_list	= enet_set_multicast_list,
+	.ndo_do_ioctl		= enet_ioctl,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= enet_netpoll,
+#endif
+};
+
+/*
+ * allocate  netdevice structure,  do  all dma  rings allocations  and
+ * register the netdevice
+ */
+static int enet_probe(struct platform_device *pdev)
+{
+	struct tango2_enet_priv *priv;
+	struct net_device *dev;
+	int ret;
+	struct tango2_enet_platform_data *pdat;
+	struct sockaddr addr;
+
+	printk(KERN_INFO PFX "ethernet driver for SMP863x internal mac\n");
+
+	/* allocate  netdevice structure  with enough  length  for our
+	 * context data */
+	dev = alloc_etherdev(sizeof (*priv));
+	if (!dev)
+		return -ENOMEM;
+
+	/* initialize private data */
+	priv = netdev_priv(dev);
+	memset(priv, 0, sizeof (*priv));
+	spin_lock_init(&priv->tx_lock);
+	spin_lock_init(&priv->ier_lock);
+	spin_lock_init(&priv->maccr_lock);
+
+	/* init tx done tasklet */
+	tasklet_init(&priv->tx_reclaim_tasklet, enet_tx_reclaim,
+		     (unsigned long)dev);
+
+	/* init tx reclaim timer */
+	init_timer(&priv->tx_reclaim_timer);
+	priv->tx_reclaim_timer.data = (unsigned long )dev;
+	priv->tx_reclaim_timer.function = enet_tx_reclaim_timer;
+
+	/* init link check timer and mii lock */
+	init_timer(&priv->link_check_timer);
+	priv->link_check_timer.data = (unsigned long)dev;
+	priv->link_check_timer.function = enet_link_check;
+	spin_lock_init(&priv->mii_lock);
+
+	/* fill mii info */
+	priv->mii.dev = dev;
+	priv->mii.phy_id_mask = 0x1f;
+	priv->mii.reg_num_mask = 0x1f;
+	priv->mii.mdio_read = enet_mdio_read;
+	priv->mii.mdio_write = enet_mdio_write;
+
+	if (gphy_id != -1) {
+		/* phy id forced, just check for sanity */
+		if (gphy_id < 0 || gphy_id > 31) {
+			ret = -EINVAL;
+			goto err_free;
+		}
+		priv->mii.phy_id = gphy_id;
+
+	} else {
+		int i;
+
+		/* try to probe phy if not given */
+		for (i = 1; i < 32; i++) {
+			uint32_t id;
+			int val;
+
+			val = enet_mdio_read(dev, i, MII_PHYSID1);
+			id = (val << 16);
+			val = enet_mdio_read(dev, i, MII_PHYSID2);
+			id |= val;
+
+			if (id != 0xffffffff && id != 0x00000000)
+				break;
+		}
+
+		if (i == 32) {
+			printk(KERN_ERR PFX "unable to autodetect phy\n");
+			ret = -EIO;
+			goto err_free;
+		}
+
+		printk(KERN_INFO PFX "detected phy at address 0x%02x\n", i);
+		priv->mii.phy_id = i;
+	}
+
+	/* initialize hardware */
+	if ((ret = enet_hw_init(dev, pdev)))
+		goto err_free;
+
+	/* initialize dma rings */
+	if ((ret = enet_dma_init(priv)))
+		goto err_free;
+
+	/* register interrupt handler */
+	ret = request_irq(IRQ_ENET, enet_isr, IRQF_SAMPLE_RANDOM,
+			  "tango2_enet", dev);
+	if (ret)
+		goto err_free;
+	dev->irq = IRQ_ENET;
+
+	/* install driver callbacks and register netdevice */
+	dev->netdev_ops = &tango2_enet_ops;
+	dev->ethtool_ops = &enet_ethtool_ops;
+	netif_napi_add(dev, &priv->napi, enet_poll, 16);
+
+	/* read mac address from requested location */
+	pdat = pdev->dev.platform_data;
+	if (pdat)
+		memcpy(dev->dev_addr, pdat->mac_addr, ETH_ALEN);
+
+	memcpy(addr.sa_data, dev->dev_addr, ETH_ALEN);
+	enet_set_mac_address(dev, &addr);
+	priv->net_dev = dev;
+
+	if ((ret = register_netdev(dev))) {
+		printk(KERN_ERR PFX "unable to register netdevice\n");
+		goto err_free;
+	}
+
+	printk(KERN_INFO PFX "mac address %02x:%02x:%02x:%02x:%02x:%02x\n",
+	       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+	       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+
+	platform_set_drvdata(pdev, dev);
+
+	return 0;
+
+err_free:
+	if (dev->irq)
+		free_irq(dev->irq, dev);
+	enet_dma_free(priv);
+	free_netdev(dev);
+	return ret;
+}
+
+/*
+ * exit func, stops hardware and unregisters netdevice
+ */
+static int
+enet_remove(struct platform_device *pdev)
+{
+	struct tango2_enet_priv *priv;
+	struct net_device *dev;
+
+	dev = platform_get_drvdata(pdev);
+	free_irq(dev->irq, dev);
+	unregister_netdev(dev);
+
+	priv = netdev_priv(dev);
+	enet_dma_free(priv);
+
+	free_netdev(dev);
+	return 0;
+}
+
+struct platform_driver tango2_enet_driver =
+{
+	.probe	= enet_probe,
+	.remove	= enet_remove,
+	.driver	= {
+		.name	= "tango2_enet",
+	},
+};
+
+
+/*
+ * entry point, checks if ethernet is enabled on the board and if so,
+ * register platform driver.
+ */
+int __init tango2_enet_init(void)
+{
+	return platform_driver_register(&tango2_enet_driver);
+}
+
+void __exit tango2_enet_exit(void)
+{
+	platform_driver_unregister(&tango2_enet_driver);
+}
+
+
+module_init(tango2_enet_init);
+module_exit(tango2_enet_exit);
+
+MODULE_DESCRIPTION("SMP863x internal ethernet mac driver");
+MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
+MODULE_LICENSE("GPL");
+
+module_param(gphy_id, int, 0444);
+MODULE_PARM_DESC(gphy_id, "PHY id, else autodetect");
+
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/drivers/net/tango2_enet.h	2010-03-18 18:28:50.222791005 +0100
@@ -0,0 +1,294 @@
+#ifndef __TANGO2_ENET_H
+#define __TANGO2_ENET_H
+
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/mii.h>
+#include <linux/timer.h>
+
+#include <asm/addrspace.h>
+
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+
+/*
+ * number of rx/tx buffers available
+ * !!! MUST BE A POWER OF 2 !!!
+ */
+#define ENET_RX_DESC_COUNT	64
+#define ENET_TX_DESC_COUNT	64
+
+/*
+ * we enable tx  interrupt when there is equal to  this number of free
+ * tx desc. Keep it lower than ENET_TX_DESC_COUNT if you change it.
+ */
+#define ENET_TX_DESC_LOW	20
+
+/*
+ * sizeof rx buffers we give to the dma controller
+ */
+#define RX_BUF_SIZE		0x600
+
+/*
+ * ipv4 stack  assumes received  ip header is  32 bits aligned,  so we
+ * keep 2 bytes to align ip header
+ */
+#define SKB_RESERVE_SIZE	2
+
+/*
+ * we reclaim  transmited using a  timer, we switch to  interrupt mode
+ * under high load. this is the timer frequency
+ */
+#define TX_RECLAIM_TIMER_FREQ	(HZ / 100)
+
+/*
+ * link status  is polled on a regular  basis by a timer,  this is its
+ * frequency
+ */
+#define LINK_CHECK_TIMER_FREQ	(HZ)
+
+
+/*
+ * address space conversion
+ */
+#define CACHE_TO_NONCACHE(x)	KSEG1ADDR(x)
+#define PHYSADDR(x)		CPHYSADDR(x)
+
+
+/*
+ * Mac/DMA registers offset, refer to documentation
+ */
+#define ENET_HOST_BASE		REG_BASE_host_interface
+
+/* mac registers */
+#define ENET_MAC_BASE		(ENET_HOST_BASE + 0x6000)
+#define ENET_MAC_MACCR		(ENET_MAC_BASE + 0x0)
+#define MACCR_F			(1 << 20)
+#define MACCR_PM		(1 << 19)
+#define MACCR_PR		(1 << 18)
+#define MACCR_HP		(1 << 13)
+#define MACCR_ASTP		(1 << 8)
+#define MACCR_TE		(1 << 3)
+#define MACCR_RE		(1 << 2)
+#define ENET_MAC_MACAHR		(ENET_MAC_BASE + 0x4)
+#define ENET_MAC_MACALR		(ENET_MAC_BASE + 0x8)
+#define ENET_MAC_MAHR		(ENET_MAC_BASE + 0xc)
+#define ENET_MAC_MALR		(ENET_MAC_BASE + 0x10)
+#define ENET_MAC_MIIAR		(ENET_MAC_BASE + 0x14)
+#define MIIAR_ADDR(x)		((x) << 11)
+#define MIIAR_REG(x)		((x) << 6)
+#define MIIAR_WRITE		(1 << 1)
+#define MIIAR_BUSY		(1 << 0)
+#define ENET_MAC_MIIDR		(ENET_MAC_BASE + 0x18)
+#define ENET_MAC_FCR		(ENET_MAC_BASE + 0x1c)
+#define FCR_ENABLE		(1 << 1)
+
+/* dma registers */
+#define ENET_DMA_BASE		(ENET_HOST_BASE + 0x7000)
+#define ENET_DMA_BMR		(ENET_DMA_BASE + 0x00)
+#define BMR_PBL(x)		((x & 0x3f) << 8)
+#define BMR_SWR			(1 << 0)
+#define ENET_DMA_TPDR		(ENET_DMA_BASE + 0x04)
+#define ENET_DMA_RPDR		(ENET_DMA_BASE + 0x08)
+#define ENET_DMA_RBAR		(ENET_DMA_BASE + 0x0c)
+#define ENET_DMA_TBAR		(ENET_DMA_BASE + 0x10)
+#define ENET_DMA_SR		(ENET_DMA_BASE + 0x14)
+#define SR_EB(x)		(((x) >> 23) & 0x3)
+#define SR_TS(x)		(((x) >> 20) & 0x7)
+#define SR_RS(x)		(((x) >> 17) & 0x7)
+#define SR_NIS			(1 << 16)
+#define SR_AIS			(1 << 15)
+#define SR_ERI			(1 << 14)
+#define SR_FBE			(1 << 13)
+#define SR_ETI			(1 << 12)
+#define SR_RWT			(1 << 11)
+#define SR_RPS			(1 << 8)
+#define SR_RU			(1 << 7)
+#define SR_R			(1 << 6)
+#define SR_UNF			(1 << 5)
+#define SR_TU			(1 << 4)
+#define SR_TPS			(1 << 1)
+#define SR_T			(1 << 0)
+#define ENET_DMA_CR		(ENET_DMA_BASE + 0x18)
+#define CR_SF			(1 << 21)
+#define CR_ST			(1 << 13)
+#define CR_SR			(1 << 1)
+#define ENET_DMA_IER		(ENET_DMA_BASE + 0x1c)
+#define IER_NIS			(1 << 16)
+#define IER_AIS			(1 << 15)
+#define IER_ERE			(1 << 14)
+#define IER_FBE			(1 << 13)
+#define IER_ETE			(1 << 10)
+#define IER_RWT			(1 << 9)
+#define IER_RS			(1 << 8)
+#define IER_RU			(1 << 7)
+#define IER_R			(1 << 6)
+#define IER_UE			(1 << 5)
+#define IER_TBU			(1 << 2)
+#define IER_TS			(1 << 1)
+#define IER_T			(1 << 0)
+#define ENET_DMA_MFBOC		(ENET_DMA_BASE + 0x20)
+#define ENET_DMA_CHRBA		(ENET_DMA_BASE + 0x54)
+
+
+/*
+ * rx dma descriptor definition
+ */
+struct enet_rx_desc {
+	unsigned long rdes0;
+	unsigned long rdes1;
+	unsigned long rdes2;
+	unsigned long rdes3;
+};
+
+#define RDES0_OWN		(1 << 31)
+#define RDES0_FILTER_FAIL	(1 << 30)
+#define RDES0_FRAME_LEN(x)	(((x) & 0x1fff0000) >> 16)
+#define RDES0_ERR_SUM		(1 << 15)
+#define RDES0_TRUNC		(1 << 14)
+#define RDES0_LEN_ERROR		(1 << 12)
+#define RDES0_RUNT		(1 << 11)
+#define RDES0_FIRST		(1 << 9)
+#define RDES0_LAST		(1 << 8)
+#define RDES0_TOO_LONG		(1 << 7)
+#define RDES0_COLLISION		(1 << 6)
+#define RDES0_WATCHDOG_TMOUT	(1 << 4)
+#define RDES0_MII_ERROR		(1 << 3)
+#define RDES0_CRC		(1 << 1)
+
+#define RDES1_DISABLE_ISR	(1 << 31)
+#define RDES1_RER		(1 << 25)
+#define RDES1_RCH		(1 << 24)
+#define RDES1_RBS2(x)		((x) << 11)
+#define RDES1_RBS1(x)		(x)
+
+
+
+/*
+ * tx dma descriptor definition
+ */
+struct enet_tx_desc {
+	uint32_t tdes0;
+	uint32_t tdes1;
+	uint32_t tdes2;
+	uint32_t tdes3;
+};
+
+#define TDES0_OWN		(1 << 31)
+#define TDES0_ERR_SUM		(1 << 15)
+#define TDES0_CARRIER_LOST	(1 << 11)
+#define TDES0_NO_CARRIER	(1 << 10)
+#define TDES0_LATE_COLLISION	(1 << 9)
+#define TDES0_EXC_COLLISION	(1 << 8)
+#define TDES0_HEARTBEAT		(1 << 7)
+#define TDES0_EXC_DEFERAL	(1 << 2)
+#define TDES0_UNDERFLOW		(1 << 1)
+
+#define TDES1_ENABLE_ISR	(1 << 31)
+#define TDES1_LAST	 	(1 << 30)
+#define TDES1_FIRST		(1 << 29)
+#define TDES1_DISABLE_FCS	(1 << 26)
+#define TDES1_TER	 	(1 << 25)
+#define TDES1_TCH	 	(1 << 24)
+#define TDES1_DISABLE_PADDING	(1 << 23)
+#define TDES1_TBS2(x)		((x) << 11)
+#define TDES1_TBS1(x)		(x)
+
+
+/*
+ * our private context
+ */
+struct tango2_enet_priv {
+
+	/*
+	 * rx related
+	 */
+	struct napi_struct		napi;
+
+	/* pointer to rx descriptor array */
+	volatile struct enet_rx_desc	*rx_descs;
+	unsigned int			rx_descs_size;
+	dma_addr_t			rx_descs_dma_addr;
+
+	/* last rx descriptor processed */
+	unsigned int			last_rx_desc;
+
+	/* we keep a list of skb given */
+	struct sk_buff			*rx_skbs[ENET_RX_DESC_COUNT];
+
+	/* ethernet device stats */
+	struct net_device_stats		stats;
+
+
+
+
+	/*
+	 * tx related
+	 */
+
+	/* access  to  tx related  dma  stuffs  is  protected by  this
+	 * spinlock, this is because we  access them via a tasklet and
+	 * a timer */
+	spinlock_t			tx_lock;
+
+	/* pointer to tx descriptor array */
+	volatile struct enet_tx_desc	*tx_descs;
+	unsigned int			tx_descs_size;
+	dma_addr_t			tx_descs_dma_addr;
+
+	/* index of current dirty tx descriptor */
+	unsigned int			dirty_tx_desc;
+
+	/* index of next clean tx descriptor to use */
+	unsigned int			next_tx_desc;
+
+	/* count of free tx desc to avoid its computation */
+	unsigned int			free_tx_desc_count;
+
+	/* list of sent skb */
+	struct sk_buff			*tx_skbs[ENET_TX_DESC_COUNT];
+
+	/* tx  done operation is  done under  these tasklet  and timer
+	 * context */
+	struct tasklet_struct		tx_reclaim_tasklet;
+	struct timer_list		tx_reclaim_timer;
+
+
+	/*
+	 * misc
+	 */
+	/* spinlock used to protect interrupt enable register */
+	spinlock_t			ier_lock;
+
+	/* spinlock used to protect maccr register */
+	spinlock_t			maccr_lock;
+
+	/* our mii state */
+	struct mii_if_info		mii;
+
+	/* mii access is protected by following spinlock */
+	spinlock_t			mii_lock;
+
+	/* link status is checked periodically by this timer */
+	struct timer_list		link_check_timer;
+
+	struct net_device		*net_dev;
+};
+
+/*
+ * helpers to access registers
+ */
+#define enet_readl(x)		gbus_readl((x))
+
+static inline void enet_writel(unsigned long addr, unsigned long data)
+{
+	gbus_writel(addr, data);
+
+	/* some write  read sequence seems  to freeze completly  if no
+	 * barrier is done between each access. To be safe, we do this
+	 * after all write access */
+	iob();
+}
+
+#endif /* __TANGO2_ENET_H */
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/drivers/net/tango2_pcinet.h	2010-03-18 18:28:50.222791005 +0100
@@ -0,0 +1,117 @@
+
+#ifndef TANGO2_PCINET_H_
+#define TANGO2_PCINET_H_
+
+/*
+ * vendor id / device id
+ */
+#define TANGO2_PCINET_VENDOR		0x1105
+#define TANGO2_PCINET_DEVICE		PCI_ANY_ID
+#define TANGO2_PCINET_SUBVENDOR		0x4242
+#define TANGO2_PCINET_SUBDEVICE		0x02
+
+#define	PCINET_MAGIC			0x617D18B4
+
+/*
+ * buffer allocation size on rx side
+ */
+#define RX_BUF_SIZE			1500
+
+/*
+ * rx/tx ring point to these descriptors
+ */
+struct tango2_pci_desc
+{
+	/* relative bus address of data if any (address is relative to
+	 * BAR address) */
+	uint32_t	buf_addr;
+
+	/* data len */
+	uint32_t	data_len;
+
+	/* private data used by SMP863x only */
+	void		*priv;
+};
+
+/*
+ * list of message type that can be exchanged with mailbox
+ */
+#define MSG_STATE_CHANGE	1
+
+/*
+ * possible state for agent and smp863x
+ */
+#define SMP863X_STATE_DEAD		0
+#define SMP863X_STATE_RUNNING		1
+
+#define AGENT_STATE_DISCONNECTED	0
+#define AGENT_STATE_CONNECTING		1
+#define AGENT_STATE_CONNECTED		2
+
+/*
+ * this structure is shared between host and agent on PCI bus, all
+ * fields are little endian.
+ */
+struct tango2_pcinet_regs
+{
+	/* so that agent are sure they are reading valid register
+	 * data */
+	uint32_t	magic;
+
+	/* shared mutex over pci bus */
+	uint32_t	lock_smp863x;
+	uint32_t	lock_agent;
+	uint32_t	lock_turn;
+
+	/*
+	 * fields below are protected by shared mutex
+	 */
+	uint32_t	rx_ring_len;
+	uint32_t	tx_ring_len;
+
+	uint32_t	smp863x_state;
+	uint32_t	agent_state;
+
+	/*
+	 * fields below are  lockless, but they must not  be access by
+	 * agent when it's state is DISCONNECTED.
+	 */
+
+	/* rx (SMP863x side) ring, empty buffers allocated on SMP863x
+	 * side, remote agent fills the descriptor and move
+	 * rx_ring_head */
+
+	/* rx head is moved by agent */
+	uint32_t	rx_ring_head;
+
+	/* rx tail is moved by SMP863x */
+	uint32_t	rx_ring_tail;
+
+
+	/* tx (SMP863x side) ring, SMP863x fills descriptor and wait
+	 * for remote agent to clear them */
+
+	/* tx head is moved by SMP863x */
+	uint32_t	tx_ring_head;
+
+	/* tx tail is moved by agent */
+	uint32_t	tx_ring_tail;
+
+	/* smp/agent irq enabled */
+	uint32_t	h2d_rx_irq_enabled;
+	uint32_t	h2d_tx_done_irq_enabled;
+	uint32_t	d2h_rx_irq_enabled;
+	uint32_t	d2h_tx_done_irq_enabled;
+
+	/* mailbox SMP8634 -> remote agent */
+	uint32_t	tx_msg;
+	uint32_t	tx_msg_head;
+	uint32_t	tx_msg_tail;
+
+	/* mailbox remote -> SMP8634 */
+	uint32_t	rx_msg;
+	uint32_t	rx_msg_head;
+	uint32_t	rx_msg_tail;
+};
+
+#endif /* TANGO2_PCINET_H_ */
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/drivers/net/tango2_pcinet_h.c	2010-03-18 18:28:50.222791005 +0100
@@ -0,0 +1,770 @@
+/*
+ * Network  device over PCI  shared memory  driver for  SMP863x.  This
+ * driver runs on SMP863x side and  exports its memory on the PCI bus,
+ * making it possible for other agent to access it. Linux interface is
+ * a network device (pci%d).
+ *
+ * This is a point to point network device.
+ *
+ * Copyright (C) 2007 Maxime Bizon <mbizon@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <linux/pci_regs.h>
+
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+#include <asm/mach-tango2/tango2_gpio.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+
+#include "tango2_pcinet.h"
+#include "tango2_pcinet_h.h"
+#define GPIO_MARVELL_INT	5
+
+
+#define PFX	"tango2_pcinet_h: "
+
+static struct net_device *gdev = NULL;
+
+/*
+ * helpers to access SMP863x host interface registers
+ */
+#define RD_HOST_REG32(r)	\
+		gbus_readl(REG_BASE_host_interface + (r))
+
+#define WR_HOST_REG32(r, v)	\
+		gbus_writel(REG_BASE_host_interface + (r), (v))
+
+#define RD_HOST_REG8(r)	\
+		gbus_readb(REG_BASE_host_interface + (r))
+
+#define WR_HOST_REG8(r, v)	\
+		gbus_writeb(REG_BASE_host_interface + (r), (v))
+
+/*
+ * convert  local memory  bus address  to an  address relative  to the
+ * beginning of our exported memory.
+ */
+static inline uint32_t pcinet_bus_to_pci(dma_addr_t bus_addr)
+{
+	bus_addr -= MEM_BASE_dram_controller_0;
+	return (uint32_t)bus_addr;
+}
+
+/*
+ * convert  pci "bus" address  to a local bus address.
+ */
+static inline dma_addr_t pcinet_pci_to_bus(uint32_t pci_addr)
+{
+	pci_addr += MEM_BASE_dram_controller_0;
+	return (dma_addr_t)pci_addr;
+}
+
+/*
+ * apply link status change and log
+ */
+static inline void pcinet_link_change(struct net_device *dev, int status)
+{
+	if (status)
+		netif_carrier_on(dev);
+	else
+		netif_carrier_off(dev);
+	printk(KERN_INFO "%s: link is %s\n", dev->name,
+	       status ? "UP" : "DOWN");
+}
+
+/*
+ * init remote interrupt
+ */
+static inline void pcinet_init_interrupt(void)
+{
+	em86xx_gpio_write(GPIO_MARVELL_INT, 1);
+}
+
+/*
+ * generate a remote interrupt
+ */
+static inline void pcinet_gen_interrupt(void)
+{
+	em86xx_gpio_write(GPIO_MARVELL_INT, 0);
+	wmb();
+	em86xx_gpio_write(GPIO_MARVELL_INT, 1);
+}
+
+/*
+ * implement shared mutex over PCI using Peterson's algorithm
+ */
+static int pcinet_mutex_lock(struct tango2_pcinet_h_priv *priv,
+			     int sleep_ok, int timeout_us)
+{
+	struct tango2_pcinet_regs *regs;
+
+	/* try to acquire lock */
+	regs = priv->regs;
+	regs->lock_smp863x = 1;
+	wmb();
+	regs->lock_turn = 1;
+	mb();
+
+	while (regs->lock_agent) {
+		rmb();
+		if (regs->lock_turn == 0)
+			break;
+
+		if (sleep_ok)
+			msleep(1);
+		else {
+			/* not needed  for the lock  itself, it's just
+			 * to  avoid  using  gettimeofday  to  do  the
+			 * timeout */
+			udelay(1);
+		}
+
+		if (timeout_us <= 0) {
+			regs->lock_smp863x = 0;
+			printk(KERN_ERR PFX "mutex lock timeout, ignoring\n");
+			return 1;
+		}
+		timeout_us -= sleep_ok ? 1000 : 1;
+	}
+
+	return 0;
+}
+
+static void pcinet_mutex_unlock(struct tango2_pcinet_h_priv *priv)
+{
+	priv->regs->lock_smp863x = 0;
+	wmb();
+}
+
+/*
+ * reclaim sent buffers
+ */
+static void pcinet_tx_reclaim(struct net_device *dev, int force)
+{
+	struct tango2_pcinet_h_priv *priv;
+	struct tango2_pcinet_regs *regs;
+	int processed, i;
+
+	priv = netdev_priv(dev);
+	regs = priv->regs;
+
+	/*
+	 * reclaim all sent  buffer: bring tx dirty to  tx tail, or to
+	 * tx head if we force reclaim.
+	 */
+	processed = 0;
+	for (i = priv->tx_ring_dirty;
+	     force ? (i != le32_to_cpu(regs->tx_ring_head)) :
+		     (i != le32_to_cpu(regs->tx_ring_tail));
+	     i = (i + 1) % priv->tx_ring_len) {
+		struct sk_buff *skb;
+		struct tango2_pci_desc *tx_desc;
+		dma_addr_t bus_addr;
+
+		/* make sure we read tx_ring_tail again */
+		rmb();
+
+		tx_desc = &priv->tx_ring[i];
+		bus_addr = pcinet_pci_to_bus(le32_to_cpu(tx_desc->buf_addr));
+		dma_unmap_single(NULL, bus_addr, RX_BUF_SIZE, DMA_FROM_DEVICE);
+		skb = tx_desc->priv;
+		dev_kfree_skb(skb);
+		processed++;
+	}
+
+
+	if (force) {
+		priv->tx_ring_dirty = le32_to_cpu(regs->tx_ring_head);
+		regs->tx_ring_tail = regs->tx_ring_head;
+	} else
+		priv->tx_ring_dirty = i;
+
+	if (processed && netif_queue_stopped(dev))
+		netif_wake_queue(dev);
+}
+
+/*
+ * poll request called by network core, process rx ring, tx done, and
+ * incoming mailbox message.
+ */
+static int pcinet_poll(struct napi_struct *napi, int budget)
+{
+	struct net_device *dev;
+	struct tango2_pcinet_h_priv *priv;
+	struct tango2_pcinet_regs *regs;
+	int received, i;
+
+	priv = container_of(napi, struct tango2_pcinet_h_priv, napi);
+	dev = priv->net_dev;
+	regs = priv->regs;
+
+again:
+	/* check for incoming mailbox message */
+	if (unlikely(regs->rx_msg_tail != regs->rx_msg_head)) {
+		uint32_t msg;
+
+		msg = le32_to_cpu(regs->rx_msg);
+		regs->rx_msg_tail = regs->rx_msg_head;
+
+		if (msg == MSG_STATE_CHANGE) {
+			uint32_t state;
+
+			/* lock mutex to access state data */
+			pcinet_mutex_lock(priv, 0, MUTEX_LOCK_TIMEOUT);
+			state = le32_to_cpu(regs->agent_state);
+			if (state == AGENT_STATE_CONNECTED)
+				pcinet_link_change(dev, 1);
+			else {
+				pcinet_link_change(dev, 0);
+				/* flush the tx  queue, we can do this
+				 * since agent  is disconnected and we
+				 * hold the state change mutex */
+				pcinet_tx_reclaim(dev, 1);
+			}
+			wmb();
+			pcinet_mutex_unlock(priv);
+		}
+	}
+
+	/* reclaim sent tx buffers */
+	pcinet_tx_reclaim(dev, 0);
+
+	/* check how many packet we can receive */
+	received = 0;
+
+	/* try to bring rx tail to rx head */
+	for (i = le32_to_cpu(regs->rx_ring_tail);
+	     i != le32_to_cpu(regs->rx_ring_head);
+	     i = (i + 1) % priv->rx_ring_len) {
+		struct tango2_pci_desc *rx_desc;
+		struct sk_buff *skb, *nskb;
+		unsigned int len;
+		dma_addr_t bus_addr;
+
+		if (budget <= 0)
+			break;
+		--budget;
+		received++;
+
+		/* make sure we read rx_ring_head again */
+		rmb();
+
+		rx_desc = &priv->rx_ring[i];
+
+		nskb = dev_alloc_skb(RX_BUF_SIZE);
+		if (unlikely(!nskb)) {
+			/* low on memory ? resubmit current skb */
+			continue;
+		}
+
+		skb = (struct sk_buff *)rx_desc->priv;
+		skb->dev = dev;
+		skb->protocol = htons(ETH_P_IP);
+		len = le32_to_cpu(rx_desc->data_len);
+		skb_put(skb, len);
+		bus_addr = pcinet_pci_to_bus(le32_to_cpu(rx_desc->buf_addr));
+		dma_unmap_single(NULL, bus_addr, RX_BUF_SIZE, DMA_FROM_DEVICE);
+
+		netif_receive_skb(skb);
+
+		priv->stats.rx_packets++;
+		priv->stats.rx_bytes += len;
+		dev->last_rx = jiffies;
+
+		skb = nskb;
+		bus_addr = dma_map_single(NULL, skb->data, RX_BUF_SIZE,
+					  DMA_FROM_DEVICE);
+		rx_desc->buf_addr = cpu_to_le32(pcinet_bus_to_pci(bus_addr));
+		rx_desc->priv = skb;
+	}
+
+	regs->rx_ring_tail = cpu_to_le32(i);
+	/* beware of posted write*/
+	(void)(regs->rx_ring_tail);
+
+	if (budget <= 0) {
+		/* breaked, but there is still work to do */
+		return 1;
+	}
+
+	/* remove ourself from poll queue and reenable interrupt */
+	regs->d2h_rx_irq_enabled = 1;
+	regs->d2h_tx_done_irq_enabled = 1;
+	mb();
+
+	napi_complete(napi);
+
+	/* signal remote that we removed data from rx queue if
+	 * interrupt is enabled */
+	if (received && regs->h2d_tx_done_irq_enabled)
+		pcinet_gen_interrupt();
+
+	/* we have  a race  here, new packets  may have  been inserted
+	 * between the time we scanned the list and enabled interrupt,
+	 * so rescan */
+	if (regs->rx_ring_tail != regs->rx_ring_head ||
+	    priv->tx_ring_dirty != regs->tx_ring_tail ||
+	    regs->rx_msg_tail != regs->rx_msg_head) {
+		if (napi_reschedule(napi)) {
+			regs->d2h_rx_irq_enabled = 0;
+			regs->d2h_tx_done_irq_enabled = 0;
+			wmb();
+			goto again;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * interrupt request  from agent, can be a  new buffer in rx,  or a tx
+ * completion.
+ */
+static irqreturn_t pcinet_isr(int irq, void *dev_id)
+{
+	struct net_device *dev;
+	struct tango2_pcinet_h_priv *priv;
+
+	dev = (struct net_device *)dev_id;
+	priv = netdev_priv(dev);
+
+	/* add device to poll list to process all work */
+	if (napi_schedule_prep(&priv->napi)) {
+		/* disable remote interrupt */
+		priv->regs->d2h_rx_irq_enabled = 0;
+		priv->regs->d2h_tx_done_irq_enabled = 0;
+		__napi_schedule(&priv->napi);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * tx request callback
+ */
+static int pcinet_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct tango2_pcinet_h_priv *priv;
+	struct tango2_pcinet_regs *regs;
+	struct tango2_pci_desc *tx_desc;
+	unsigned int head, new_head;
+	dma_addr_t bus_addr;
+
+	priv = netdev_priv(dev);
+	regs = priv->regs;
+
+	/* don't send any data if link is down */
+	if (unlikely(!netif_carrier_ok(dev))) {
+		dev_kfree_skb(skb);
+		priv->stats.tx_dropped++;
+		priv->stats.tx_carrier_errors++;
+		return 0;
+	}
+
+	/* check for tx queue full */
+	head = le32_to_cpu(regs->tx_ring_head);
+	new_head = (head + 1) % priv->tx_ring_len;
+	if (new_head == priv->tx_ring_dirty) {
+		netif_stop_queue(dev);
+		dev_kfree_skb(skb);
+		priv->stats.tx_dropped++;
+		priv->stats.tx_fifo_errors++;
+		return 0;
+	}
+
+	/* fill descriptor and update tx head */
+	tx_desc = &priv->tx_ring[head];
+	tx_desc->data_len = cpu_to_le32(skb->len);
+	bus_addr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE);
+	tx_desc->buf_addr = pcinet_bus_to_pci(bus_addr);
+	tx_desc->priv = skb;
+	wmb();
+	regs->tx_ring_head = cpu_to_le32(new_head);
+	mb();
+	priv->stats.tx_packets++;
+	priv->stats.tx_bytes += skb->len;
+
+	/* signal remote if interrupt is enabled */
+	if (regs->h2d_rx_irq_enabled)
+		pcinet_gen_interrupt();
+
+	/* stop queue if it's now full */
+	new_head = (new_head + 1) % priv->tx_ring_len;
+	if (new_head == priv->tx_ring_dirty)
+		netif_stop_queue(dev);
+
+	return 0;
+}
+
+/*
+ * get_stats callback
+ */
+static struct net_device_stats *pcinet_get_stats(struct net_device *dev)
+{
+	struct tango2_pcinet_h_priv *priv;
+	priv = netdev_priv(dev);
+	return &priv->stats;
+}
+
+/*
+ * device open callback
+ */
+static int pcinet_open(struct net_device *dev)
+{
+	struct tango2_pcinet_h_priv *priv;
+	struct tango2_pcinet_regs *regs;
+	unsigned int rx_ring_size, tx_ring_size, total_size;
+	int ret, i;
+
+	priv = netdev_priv(dev);
+
+	/* allocate reg zone */
+	rx_ring_size = (DEF_RX_RING_LEN * sizeof (struct tango2_pci_desc));
+	tx_ring_size = (DEF_TX_RING_LEN * sizeof (struct tango2_pci_desc));
+	total_size = (sizeof (*regs) + rx_ring_size + tx_ring_size);
+
+	priv->regs = dma_alloc_coherent(NULL, total_size, &priv->regs_hw,
+					GFP_KERNEL);
+	if (!priv->regs)
+		return -ENOMEM;
+	regs = priv->regs;
+
+	/* register rx/tx done interrupt */
+	ret = request_irq(IRQ_PCIINTB, pcinet_isr, 0, "tango2_pcinet_h", dev);
+	if (ret)
+		goto out_free;
+
+	/* allocate both DMA queue */
+	priv->rx_ring_len = DEF_RX_RING_LEN;
+	priv->rx_ring = ((void *)regs + sizeof (*regs));
+	memset(priv->rx_ring, 0, rx_ring_size);
+
+	priv->tx_ring_len = DEF_TX_RING_LEN;
+	priv->tx_ring = ((void *)regs + sizeof (*regs) + rx_ring_size);
+	memset(priv->tx_ring, 0, tx_ring_size);
+
+	/* fill corresponding regs fields */
+	regs->magic = cpu_to_le32(PCINET_MAGIC);
+	regs->rx_ring_len = cpu_to_le32(priv->rx_ring_len);
+	regs->tx_ring_len = cpu_to_le32(priv->tx_ring_len);
+
+	/* init rx/tx queue pointers */
+	regs->rx_ring_head = regs->rx_ring_tail = 0;
+	regs->tx_ring_head = regs->tx_ring_tail = 0;
+	priv->tx_ring_dirty = 0;
+
+	/* init mailboxes */
+	regs->rx_msg = regs->rx_msg_head = regs->rx_msg_tail = 0;
+	regs->tx_msg = regs->tx_msg_head = regs->tx_msg_tail = 0;
+
+	/* init state */
+	regs->smp863x_state = cpu_to_le32(SMP863X_STATE_RUNNING);
+	regs->agent_state = cpu_to_le32(AGENT_STATE_DISCONNECTED);
+
+	/* fill rx queue with buffers and init descriptors */
+	for (i = 0; i < priv->rx_ring_len; i++) {
+		struct tango2_pci_desc *rx_desc;
+		struct sk_buff *skb;
+		dma_addr_t bus_addr;
+
+		skb = dev_alloc_skb(RX_BUF_SIZE);
+		if (!skb)
+			goto out_free;
+
+		bus_addr = dma_map_single(NULL, skb->data, RX_BUF_SIZE,
+					  DMA_FROM_DEVICE);
+		rx_desc = &priv->rx_ring[i];
+		rx_desc->buf_addr = cpu_to_le32(pcinet_bus_to_pci(bus_addr));
+		rx_desc->priv = skb;
+	}
+
+	/* point region 1 to registers */
+	WR_HOST_REG32(PCI_REGION_1_BASE, priv->regs_hw);
+
+	/* enable irq from remote and disable irq to remote */
+	regs->d2h_rx_irq_enabled = 1;
+	regs->d2h_tx_done_irq_enabled = 1;
+	regs->h2d_rx_irq_enabled = 0;
+	regs->h2d_tx_done_irq_enabled = 0;
+
+	/* init remote interrupt system generation */
+	pcinet_init_interrupt();
+
+	napi_enable(&priv->napi);
+
+	netif_start_queue(dev);
+
+	/* make sure everything is written and make us visible to
+	 * remote agent */
+	wmb();
+	WR_HOST_REG32(PCI_REG2, ((TANGO2_PCINET_SUBVENDOR << 16) |
+				 TANGO2_PCINET_SUBDEVICE));
+	return 0;
+
+out_free:
+	if (priv->rx_ring) {
+		int i;
+
+		for (i = 0; i < priv->rx_ring_len; i++) {
+			if (priv->rx_ring[i].priv) {
+				dma_addr_t bus_addr;
+				uint32_t addr;
+
+				kfree_skb(priv->rx_ring[i].priv);
+				addr = le32_to_cpu(priv->rx_ring[i].buf_addr);
+				bus_addr = pcinet_pci_to_bus(addr);
+				dma_unmap_single(NULL, bus_addr, RX_BUF_SIZE,
+						 DMA_FROM_DEVICE);
+			}
+		}
+	}
+	if (priv->regs)
+		dma_free_coherent(NULL, sizeof (struct tango2_pcinet_regs),
+				  priv->regs, priv->regs_hw);
+	return ret;
+}
+
+/*
+ * device stop callback
+ */
+static int pcinet_stop(struct net_device *dev)
+{
+	struct tango2_pcinet_h_priv *priv;
+	struct tango2_pcinet_regs *regs;
+	unsigned int total_size, rx_ring_size, tx_ring_size;
+	int i, loop;
+	uint32_t agent_state;
+
+	priv = netdev_priv(dev);
+	regs = priv->regs;
+
+	netif_stop_queue(dev);
+
+	/* from this point, neither pcinet_poll nor pcinet_xmit can be
+	 * called */
+
+	/* make sure we can not be probbed again */
+	WR_HOST_REG32(PCI_REG2, TANGO2_PCINET_SUBVENDOR << 16);
+	wmb();
+
+	/*
+	 * small race  condition here, the  agent may have  probbed us
+	 * and  could  be  waiting  for  mutex lock  to  mark  himself
+	 * connected.
+	 *
+	 * We avoid  this by  marking us dead  in all case,  the agent
+	 * will see it once it gets the lock
+	 */
+	pcinet_mutex_lock(priv, 1, MUTEX_LOCK_TIMEOUT);
+
+	regs->smp863x_state = cpu_to_le32(SMP863X_STATE_DEAD);
+	agent_state = le32_to_cpu(regs->agent_state);
+
+	if (agent_state == AGENT_STATE_CONNECTED) {
+		/* we must tell the agent to check for state change */
+		regs->tx_msg = cpu_to_le32(MSG_STATE_CHANGE);
+		wmb();
+		regs->tx_msg_head++;
+		wmb();
+		pcinet_gen_interrupt();
+	}
+	wmb();
+	pcinet_mutex_unlock(priv);
+
+	/* now wait for the agent to disconnect */
+	for (loop = 0; loop < 1000; loop++) {
+
+		pcinet_mutex_lock(priv, 1, MUTEX_LOCK_TIMEOUT);
+		agent_state = le32_to_cpu(regs->agent_state);
+		pcinet_mutex_unlock(priv);
+
+		if (agent_state == AGENT_STATE_DISCONNECTED)
+			break;
+		msleep(10);
+	}
+
+	if (loop == 1000)
+		printk(KERN_ERR PFX "agent still connected after timeout\n");
+
+	/* "unexport" register area */
+	WR_HOST_REG32(PCI_REGION_1_BASE, 0);
+	wmb();
+
+	/* free all allocated data */
+	pcinet_tx_reclaim(dev, 1);
+
+	for (i = 0; i < priv->rx_ring_len; i++) {
+		dma_addr_t bus_addr;
+		uint32_t addr;
+
+		addr = le32_to_cpu(priv->rx_ring[i].buf_addr);
+		bus_addr = pcinet_pci_to_bus(addr);
+		dma_unmap_single(NULL, bus_addr, RX_BUF_SIZE, DMA_FROM_DEVICE);
+		kfree_skb(priv->rx_ring[i].priv);
+	}
+
+	rx_ring_size = (priv->rx_ring_len * sizeof (struct tango2_pci_desc));
+	tx_ring_size = (priv->tx_ring_len * sizeof (struct tango2_pci_desc));
+	total_size = (sizeof (*regs) + rx_ring_size + tx_ring_size);
+	dma_free_coherent(NULL, total_size, priv->regs, priv->regs_hw);
+	free_irq(IRQ_PCIINTB, dev);
+
+	return 0;
+}
+
+/*
+ * init the PCI slave interface
+ */
+static void tango2_pcinet_pciinit(void)
+{
+	unsigned int membase, val;
+	int i;
+
+	/*
+	 * make sure memory decoder is disabled or cry
+	 */
+	WR_HOST_REG8(PCI_REG3 + 1, PCI_COMMAND >> 2);
+	val = RD_HOST_REG32(PCI_CONFIG);
+	if (val & PCI_COMMAND_MEMORY) {
+		printk(KERN_WARNING PFX "WARNING: PCI memory decoder is "
+		       "already enabled!\n");
+	}
+
+	/* we  have only  one BAR,  thus  registers and  data will  be
+	 * mixed, so we need to mark the BAR as non prefetchable
+	 *
+	 * [17] : enable "Memory Read Multiple" and "Memory Read Line"
+	 * [16] [7:0] : enable "prefetch" for PCI slave regions 2..7
+	 * [17] : Always enabled
+	 * [18] : additional bit for Tango. Long PCI memory read burst
+	 */
+	WR_HOST_REG32(PCI_pcictrl_reg1, 0xfc);
+
+	/*
+	 * PCI_CTRL2 :
+	 * [18] : fast back-to-back capable = 0 (default)
+	 * [17] : read FIFO level = 1 (8 level deep, default)
+	 * [16] : discard timer enable = 1 (default)
+	 * [15:8] : subs latency = 0x06 (default = 0x08)
+	 * [7:0] : initial latency = 0x0d (default = 0x0b)
+	 */
+	WR_HOST_REG32(PCI_pcictrl_reg2, 0x0003060d);
+
+	/*
+	 * We can map  7 of the 8 regions in our  memory.  Region 1 is
+	 * pointed to a  "register" area, the rest is  used to map our
+	 * DRAM.
+	 */
+
+	/* set region size to 8M (64M total size) */
+	WR_HOST_REG8(PCI_REG3, 0x6);
+
+	/* point region 2-7 to remaining memory, 48MB available, don't
+	 * attempt to map higher memory */
+	membase = MEM_BASE_dram_controller_0;
+        for (i = 2; i < 8; ++i) {
+		WR_HOST_REG32(PCI_REGION_0_BASE + (i * 4), membase);
+		membase += (8 << 20);
+	}
+
+	/* region 1 is set when device is opened */
+}
+
+/*
+ * netdev device setup callback
+ */
+static void pcinet_netdev_setup(struct net_device *dev)
+{
+	dev->hard_header_len = 0;
+	dev->mtu = RX_BUF_SIZE;
+	dev->addr_len = 0;
+	dev->tx_queue_len = 64;
+	dev->type = ARPHRD_PPP;
+	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+}
+
+static const struct net_device_ops tango2_pcinet_h_ops = {
+	.ndo_open		= pcinet_open,
+	.ndo_stop		= pcinet_stop,
+	.ndo_start_xmit		= pcinet_xmit,
+	.ndo_get_stats		= pcinet_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= pcinet_poll,
+#endif
+};
+
+/*
+ * module init, just register network device
+ */
+int __init tango2_pcinet_h_init(void)
+{
+	struct tango2_pcinet_h_priv *priv;
+	int ret;
+
+	/* allocate  netdevice structure  with enough  length  for our
+	 * context data */
+	gdev = alloc_netdev(sizeof (*priv), "pci%d", pcinet_netdev_setup);
+	if (!gdev)
+		return -ENOMEM;
+
+	priv = netdev_priv(gdev);
+	memset(priv, 0, sizeof (*priv));
+
+	/* install driver callbacks and register netdevice */
+	gdev->netdev_ops = &tango2_pcinet_h_ops;
+	netif_napi_add(gdev, &priv->napi, pcinet_poll, 16);
+
+	tango2_pcinet_pciinit();
+	priv->net_dev = gdev;
+
+	if ((ret = register_netdev(gdev))) {
+		printk(KERN_ERR PFX "unable to register netdevice\n");
+		free_netdev(gdev);
+		return ret;
+	}
+	netif_carrier_off(gdev);
+
+	return 0;
+}
+
+/*
+ * module exit
+ */
+void __exit tango2_pcinet_h_exit(void)
+{
+	struct net_device *dev;
+
+	dev = gdev;
+	unregister_netdev(dev);
+	free_netdev(dev);
+	gdev = NULL;
+}
+
+module_init(tango2_pcinet_h_init);
+module_exit(tango2_pcinet_h_exit);
+
+MODULE_DESCRIPTION("SMP863x PCI shared memory network device (slave)");
+MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
+MODULE_LICENSE("GPL");
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/drivers/net/tango2_pcinet_h.h	2010-03-18 18:28:50.222791005 +0100
@@ -0,0 +1,34 @@
+
+#ifndef TANGO2_PCINET_H_H_
+#define TANGO2_PCINET_H_H_
+
+#define DEF_RX_RING_LEN		32
+#define DEF_TX_RING_LEN		32
+
+#define MUTEX_LOCK_TIMEOUT	1000
+
+struct tango2_pcinet_h_priv
+{
+	/* cpu view of pci regs */
+	struct tango2_pcinet_regs *regs;
+
+	/* bus address of pci regs */
+	dma_addr_t regs_hw;
+
+	/* rx queue */
+	struct tango2_pci_desc *rx_ring;
+	unsigned int rx_ring_len;
+	unsigned int rx_ring_dirty;
+
+	/* tx queue */
+	struct tango2_pci_desc *tx_ring;
+	unsigned int tx_ring_len;
+	unsigned int tx_ring_dirty;
+
+	struct net_device_stats stats;
+
+	struct napi_struct napi;
+	struct net_device *net_dev;
+};
+
+#endif /* TANGO2_PCINET_H_H_ */
diff -Nruw linux-2.6.31.7-fbx/drivers/platform/intelce./boards/Kconfig linux-2.6.31.7-fbx/drivers/platform/intelce/boards/Kconfig
--- linux-2.6.31.7-fbx/drivers/platform/intelce./boards/Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/intelce/boards/Kconfig	2010-03-18 18:28:50.822832587 +0100
@@ -0,0 +1,20 @@
+config INTELCE_FALCON_FALLS
+	bool "IntelCE 4100 Falcon Falls suport"
+	select I2C
+	select I2C_PXA
+	---help---
+	  Support for the IntelCE 4100 Falcon Falls devices.
+	
+	  If you have such a board, say Y here, otherwise say N.
+
+config FBX6HD
+	bool "Freebox 6HD support"
+	select I2C
+	select LEDS_CLASS
+	select LEDS_GPIO
+	select INTELCE_GPIO
+	default y
+	---help---
+	  Support for the Freebox 6HD board devices.
+	
+	  If you have such a board, say Y here, otherwise say N.
diff -Nruw linux-2.6.31.7-fbx/drivers/platform/intelce./boards/Makefile linux-2.6.31.7-fbx/drivers/platform/intelce/boards/Makefile
--- linux-2.6.31.7-fbx/drivers/platform/intelce./boards/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/intelce/boards/Makefile	2010-10-25 13:43:57.021443297 +0200
@@ -0,0 +1,2 @@
+obj-$(CONFIG_INTELCE_FALCON_FALLS)	+= falcon-falls.o
+obj-$(CONFIG_FBX6HD)			+= fbx6hd.o
diff -Nruw linux-2.6.31.7-fbx/drivers/platform/intelce./Kconfig linux-2.6.31.7-fbx/drivers/platform/intelce/Kconfig
--- linux-2.6.31.7-fbx/drivers/platform/intelce./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/intelce/Kconfig	2010-10-25 13:43:57.021443297 +0200
@@ -0,0 +1,42 @@
+#
+# IntelCE devices configuration
+#
+
+menu "IntelCE devices"
+	depends on ARCH_GEN3 && PCI
+
+config INTELCE_CLOCK
+	tristate "Clock support"
+	---help---
+	  IntelCE 3100/4100 Clock support.
+
+config INTELCE_SSP
+	tristate "SSP support"
+	depends on SPI
+	---help---
+	  IntelCE 3100/4100 SSP support.
+
+config INTELCE_GPIO
+	tristate "GPIO support"
+	select ARCH_REQUIRE_GPIOLIB
+	---help---
+	  IntelCE 3100/4100 GPIO support.
+
+config INTELCE_DFX
+	tristate "DFX reporting support"
+	---help---
+	  IntelCE 3100/4100 DFX fuse reporting support.
+
+config INTELCE_NOR
+	tristate "NOR flash support"
+	depends on MTD
+	select MTD_PARTITIONS
+	select MTD_REDBOOT_PARTS
+	select MTD_CFI
+	select MTD_CFI_INTELEXT
+	---help---
+	  IntelCE 3100/4100 NOR Flash support.
+
+source "drivers/platform/intelce/boards/Kconfig"
+
+endmenu
diff -Nruw linux-2.6.31.7-fbx/drivers/platform/intelce./Makefile linux-2.6.31.7-fbx/drivers/platform/intelce/Makefile
--- linux-2.6.31.7-fbx/drivers/platform/intelce./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/intelce/Makefile	2010-10-25 13:43:57.021443297 +0200
@@ -0,0 +1,9 @@
+# Makefile for the IntelCE drivers
+
+obj-$(CONFIG_INTELCE_CLOCK)	+= clock.o
+obj-$(CONFIG_INTELCE_SSP)	+= ssp-intelce.o
+obj-$(CONFIG_INTELCE_GPIO)	+= gpio-intelce.o
+obj-$(CONFIG_INTELCE_NOR)	+= nor.o
+obj-$(CONFIG_INTELCE_DFX)	+= dfx.o
+
+obj-y				+= boards/
diff -Nruw linux-2.6.31.7-fbx/drivers/platform/tango2./fb.c linux-2.6.31.7-fbx/drivers/platform/tango2/fb.c
--- linux-2.6.31.7-fbx/drivers/platform/tango2./fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/tango2/fb.c	2010-03-18 18:28:50.822832587 +0100
@@ -0,0 +1,164 @@
+/*
+ * tango2fb - SMP863x framebuffer driver.
+ *
+ * Copyright (C) 2008 Clement Vasseur <cvasseur@freebox.fr>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+
+#include <asm/mach-tango2/tango2_regs.h>
+
+static const struct fb_var_screeninfo tango2fb_default __initdata = {
+	.xres		= 640,
+	.yres		= 480,
+	.xres_virtual	= 640,
+	.yres_virtual	= 480,
+	.bits_per_pixel	= 8,
+	.red		= { 0, 8, 0 },
+	.green		= { 0, 8, 0 },
+	.blue		= { 0, 8, 0 },
+	.activate	= FB_ACTIVATE_TEST,
+	.height		= -1,
+	.width		= -1,
+	.pixclock	= 20000,
+	.left_margin	= 64,
+	.right_margin	= 64,
+	.upper_margin	= 32,
+	.lower_margin	= 32,
+	.hsync_len	= 64,
+	.vsync_len	= 2,
+	.vmode		= FB_VMODE_NONINTERLACED,
+};
+
+static const struct fb_fix_screeninfo tango2fb_fix __initdata = {
+	.id		= "Tango2 FB",
+	.type		= FB_TYPE_PACKED_PIXELS,
+	.visual		= FB_VISUAL_TRUECOLOR,
+	.xpanstep	= 0,
+	.ypanstep	= 0,
+	.ywrapstep	= 0,
+	.accel		= FB_ACCEL_NONE,
+
+	.smem_start	= 0,
+	.smem_len	= 0,
+	.mmio_start	= REG_BASE_irq_handler_block,
+	.mmio_len	= 65536,
+};
+
+static struct fb_ops tango2fb_ops = {
+	.fb_check_var	= NULL /*tango2fb_check_var*/,
+	.fb_set_par	= NULL /*tango2fb_set_par*/,
+	.fb_setcolreg	= NULL /*tango2fb_setcolreg*/,
+	.fb_pan_display	= NULL /*tango2fb_pan_display*/,
+	.fb_fillrect	= NULL /*cfb_fillrect*/,
+	.fb_copyarea	= NULL /*cfb_copyarea*/,
+	.fb_imageblit	= NULL /*cfb_imageblit*/,
+	.fb_mmap	= NULL /*tango2fb_mmap*/,
+};
+
+static int __init tango2fb_probe(struct platform_device *dev)
+{
+	struct fb_info *info;
+	int retval = -ENOMEM;
+
+	info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
+	if (!info)
+		goto err;
+
+	info->screen_base = NULL;
+	info->fbops = &tango2fb_ops;
+
+	retval = fb_find_mode(&info->var, info, NULL, NULL, 0, NULL, 8);
+
+	if (!retval || (retval == 4))
+		info->var = tango2fb_default;
+	info->fix = tango2fb_fix;
+	info->pseudo_palette = info->par;
+	info->par = NULL;
+	info->flags = FBINFO_FLAG_DEFAULT;
+
+	retval = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (retval < 0)
+		goto err1;
+
+	retval = register_framebuffer(info);
+	if (retval < 0)
+		goto err2;
+	platform_set_drvdata(dev, info);
+
+	printk(KERN_INFO "fb%d: Tango2 frame buffer device\n",
+			info->node);
+	return 0;
+err2:
+	fb_dealloc_cmap(&info->cmap);
+err1:
+	framebuffer_release(info);
+err:
+	return retval;
+}
+
+static int tango2fb_remove(struct platform_device *dev)
+{
+	struct fb_info *info = platform_get_drvdata(dev);
+
+	if (info) {
+		unregister_framebuffer(info);
+		framebuffer_release(info);
+	}
+
+	return 0;
+}
+
+static struct platform_driver tango2fb_driver = {
+	.probe  = tango2fb_probe,
+	.remove = tango2fb_remove,
+	.driver = {
+		.name   = "tango2fb",
+	},
+};
+
+static struct platform_device *tango2fb_device;
+
+static int __init tango2fb_init(void)
+{
+	int ret = 0;
+
+	ret = platform_driver_register(&tango2fb_driver);
+
+	if (!ret) {
+		tango2fb_device = platform_device_alloc("tango2fb", 0);
+
+		if (tango2fb_device)
+			ret = platform_device_add(tango2fb_device);
+		else
+			ret = -ENOMEM;
+
+		if (ret) {
+			platform_device_put(tango2fb_device);
+			platform_driver_unregister(&tango2fb_driver);
+		}
+	}
+
+	return ret;
+}
+
+static void __exit tango2fb_exit(void)
+{
+	platform_device_unregister(tango2fb_device);
+	platform_driver_unregister(&tango2fb_driver);
+}
+
+module_init(tango2fb_init);
+module_exit(tango2fb_exit);
+
+MODULE_LICENSE("GPL");
diff -Nruw linux-2.6.31.7-fbx/drivers/platform/tango2./fip.c linux-2.6.31.7-fbx/drivers/platform/tango2/fip.c
--- linux-2.6.31.7-fbx/drivers/platform/tango2./fip.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/tango2/fip.c	2010-03-18 18:28:50.822832587 +0100
@@ -0,0 +1,761 @@
+/*
+ * tango2_fip - SMP863x front panel interface.
+ *
+ * Copyright (C) 2007 Clement Vasseur <cvasseur@freebox.fr>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/ctype.h>
+
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_xenv.h>
+
+
+/* FIP register definitions */
+#define FIP_BASE				(REG_BASE_system_block + 0x500)
+#define FIP_COMMAND				0x40
+#define FIP_DISPLAY_DATA			0x44
+#define FIP_LED_DATA				0x48
+#define FIP_KEY_DATA1				0x4c
+#define FIP_KEY_DATA2				0x50
+#define FIP_SWITCH_DATA				0x54
+#define FIP_CONFIG				0x58
+#define FIP_INT					0x5c
+
+#define FIP_BUSY				0x200
+#define FIP_ENABLE				0x400
+#define FIP_RD_INT_EN				0x20000
+#define FIP_WR_INT_EN				0x10000
+
+/* FIP commands */
+#define FIP_CMD_DISP_MODE_08DIGITS_20SEGMENTS		0x00
+#define FIP_CMD_DISP_MODE_09DIGITS_19SEGMENTS		0x08
+#define FIP_CMD_DISP_MODE_10DIGITS_18SEGMENTS		0x09
+#define FIP_CMD_DISP_MODE_11DIGITS_17SEGMENTS		0x0a
+#define FIP_CMD_DISP_MODE_12DIGITS_16SEGMENTS		0x0b
+#define FIP_CMD_DISP_MODE_13DIGITS_15SEGMENTS		0x0c
+#define FIP_CMD_DISP_MODE_14DIGITS_14SEGMENTS		0x0d
+#define FIP_CMD_DISP_MODE_15DIGITS_13SEGMENTS		0x0e
+#define FIP_CMD_DISP_MODE_16DIGITS_12SEGMENTS		0x0f
+#define FIP_CMD_DATA_SET_RW_MODE_WRITE_DISPLAY		0x40
+#define FIP_CMD_DATA_SET_RW_MODE_WRITE_LED_PORT		0x41
+#define FIP_CMD_DATA_SET_RW_MODE_READ_KEYS		0x42
+#define FIP_CMD_DATA_SET_RW_MODE_READ_SWITCHES		0x43
+#define FIP_CMD_DATA_SET_ADR_MODE_INCREMENT_ADR		0x40
+#define FIP_CMD_DATA_SET_ADR_MODE_FIXED_ADR		0x44
+#define FIP_CMD_DATA_SET_OP_MODE_NORMAL_OPERATION	0x40
+#define FIP_CMD_DATA_SET_OP_MODE_TEST_MODE		0x48
+#define FIP_CMD_ADR_SETTING				0xC0
+#define FIP_CMD_DISP_CTRL_PULSE_WIDTH_1_16		0x80
+#define FIP_CMD_DISP_CTRL_PULSE_WIDTH_2_16		0x81
+#define FIP_CMD_DISP_CTRL_PULSE_WIDTH_4_16		0x82
+#define FIP_CMD_DISP_CTRL_PULSE_WIDTH_10_16		0x83
+#define FIP_CMD_DISP_CTRL_PULSE_WIDTH_11_16		0x84
+#define FIP_CMD_DISP_CTRL_PULSE_WIDTH_12_16		0x85
+#define FIP_CMD_DISP_CTRL_PULSE_WIDTH_13_16		0x86
+#define FIP_CMD_DISP_CTRL_PULSE_WIDTH_14_16		0x87
+#define FIP_CMD_DISP_CTRL_TURN_DISPLAY_OFF_MASK		0x87
+#define FIP_CMD_DISP_CTRL_TURN_DISPLAY_ON		0x88
+
+#define PFX		"tango2_fip: "
+
+
+/* board specific definitions */
+#define FIP_DIVIDER		40
+#define FIP_RAM			48
+#define FIP_KEYS_CODE		KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, KEY_OK
+#define FIP_KEYS_BIT		0x20, 0x1, 0x40, 0x2, 0x10
+#define FIP_DEFAULT_POLL	10
+#define FIP_DEFAULT_BRIGHTNESS	7
+#define FIP_DEFAULT_LEDS	1, 0, 0, 1, 1
+#define FIP_DISPLAY_MODE	FIP_CMD_DISP_MODE_14DIGITS_14SEGMENTS
+#define FIP_NUM_SYMBOLS		8
+#define FIP_NUM_CHARACTERS	74
+#define FIP_NUM_POSITIONS	9
+
+
+static const struct {
+	int addr;
+	int bit;
+} symbols[FIP_NUM_SYMBOLS] = {
+	{ 0x1b, 0 }, // wifi
+	{ 0x1b, 1 }, // mail
+	{ 0x1c, 5 }, // play
+	{ 0x1c, 4 }, // pause
+	{ 0x1b, 2 }, // record
+	{ 0x1c, 3 }, // right arrow
+	{ 0x1c, 2 }, // center bar
+	{ 0x1c, 1 }, // left arrow
+};
+
+
+#define DIGIT_L(b7,b6,b5,b4,b3,b2,b1,b0)	((b7 << 7) | (b6 << 6) | \
+						 (b5 << 5) | (b4 << 4) | \
+						 (b3 << 3) | (b2 << 2) | \
+						 (b1 << 1) | b0)
+
+#define DIGIT_H(b5,b4,b3,b2,b1,b0)		((b5 << 5) | (b4 << 4) | \
+						 (b3 << 3) | (b2 << 2) | \
+						 (b1 << 1) | b0)
+
+/* sequence must match fipcharacters */
+static const char fipcharactersmap[FIP_NUM_CHARACTERS + 1] =
+	" ()+-/0123456789<>"
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZ\\_"
+	"abcdefghijklmnopqrstuvwxyz|";
+
+/* the format is lower byte, higher byte */
+static const char fipcharacters[FIP_NUM_CHARACTERS][2] = {
+#include "fip_chars.h"
+};
+
+
+/* global state */
+static unsigned int brightness = FIP_DEFAULT_BRIGHTNESS;
+static int led[5] = { FIP_DEFAULT_LEDS };
+static unsigned int poll_per_sec = FIP_DEFAULT_POLL;
+static int input_used = 0;
+static int symbol[FIP_NUM_SYMBOLS];
+static unsigned char ram[FIP_RAM];
+static uint8_t sw;
+
+
+static struct platform_driver fip_driver = {
+	.driver = {
+		.name = "fip",
+	},
+};
+
+static struct platform_device *pdev;
+static struct input_dev *input_dev;
+static struct timer_list fip_timer;
+
+
+/*
+ * read from FIP register at offset
+ */
+static unsigned int fip_read(unsigned int offset)
+{
+	return gbus_read_uint32(pGBus, FIP_BASE + offset);
+}
+
+static int is_fip_busy(void)
+{
+	return (fip_read(FIP_CONFIG) & FIP_BUSY) != 0;
+}
+
+/*
+ * wait for the FIP state machine to be idle
+ */
+static void fip_wait_ready(void)
+{
+	while (is_fip_busy())
+		;
+}
+
+/*
+ * write val to FIP register at offset
+ */
+static void fip_write(unsigned int offset, unsigned int val)
+{
+	fip_wait_ready();
+	gbus_write_uint32(pGBus, FIP_BASE + offset, val);
+}
+
+
+static void fip_push_key(unsigned int keys)
+{
+	const int key[] = { FIP_KEYS_CODE };
+	const int bit[] = { FIP_KEYS_BIT };
+	static unsigned int old_keys = -1;
+	int i;
+
+	// mask unwired bits
+	keys &= ~0x88888888;
+
+	if (keys == old_keys)
+		return;
+
+	old_keys = keys;
+
+	for (i = 0; i < ARRAY_SIZE(key); i++)
+		input_report_key(input_dev, key[i], (keys & bit[i]) ? 1 : 0);
+
+	input_sync(input_dev);
+}
+
+static irqreturn_t fip_isr(int irq, void *dev_id)
+{
+	unsigned int status;
+	unsigned int keys;
+
+	if (irq != IRQ_FIP)
+		return IRQ_NONE;
+
+	/* clear the interrupt */
+	status = fip_read(FIP_INT) & 0x3;
+	fip_write(FIP_INT, status);
+
+	/* handle read request */
+	if (!is_fip_busy()) {
+		if (status & 0x2) {
+			keys = fip_read(FIP_KEY_DATA1);
+			fip_push_key(keys);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void fip_fill(int data)
+{
+	int addr;
+
+	/* select write to display and fixed addressing */
+	fip_write(FIP_COMMAND,
+			FIP_CMD_DATA_SET_OP_MODE_NORMAL_OPERATION |
+			FIP_CMD_DATA_SET_ADR_MODE_FIXED_ADR |
+			FIP_CMD_DATA_SET_RW_MODE_WRITE_DISPLAY);
+
+	for (addr = 0; addr < FIP_RAM; addr++) {
+		ram[addr] = data;
+		fip_write(FIP_DISPLAY_DATA, data);
+		fip_write(FIP_COMMAND, FIP_CMD_ADR_SETTING | addr);
+	}
+}
+
+static void fip_clear(void)
+{
+	fip_fill(0);
+}
+
+static void fip_write_led(void)
+{
+	int led_data;
+	int i;
+
+	led_data = 0;
+
+	for (i = 0; i < sizeof (led) / sizeof (*led); i++)
+		led_data |= (led[i] << i);
+
+	fip_write(FIP_LED_DATA, led_data);
+	fip_write(FIP_COMMAND, FIP_CMD_DATA_SET_RW_MODE_WRITE_LED_PORT);
+}
+
+/*
+ * initialize the front panel
+ */
+static void fip_on(void)
+{
+	static int on = 0;
+
+	if (on)
+		return;
+
+	/* disable FIP and interrupt first */
+	fip_write(FIP_CONFIG, 0);
+
+	/* clear FIP interrupt status */
+	fip_write(FIP_INT, 3);
+
+	/* get switch data */
+	fip_write(FIP_CONFIG, FIP_DIVIDER | FIP_ENABLE);
+	fip_write(FIP_COMMAND, FIP_CMD_DATA_SET_RW_MODE_READ_SWITCHES);
+	fip_wait_ready();
+	sw = fip_read(FIP_SWITCH_DATA);
+
+	/* enable FIP and interrupts */
+	fip_write(FIP_CONFIG, FIP_DIVIDER | FIP_ENABLE | FIP_RD_INT_EN);
+
+	/* initialize led states */
+	fip_write_led();
+
+	/* select write to display and fixed addressing */
+	fip_write(FIP_COMMAND, FIP_CMD_DATA_SET_OP_MODE_NORMAL_OPERATION |
+			       FIP_CMD_DATA_SET_ADR_MODE_FIXED_ADR |
+			       FIP_CMD_DATA_SET_RW_MODE_WRITE_DISPLAY);
+
+        /* clear display RAM */
+	fip_clear();
+
+        /* select display mode */
+	fip_write(FIP_COMMAND, FIP_DISPLAY_MODE);
+
+	/* select brightness of display and turn it on */
+	fip_write(FIP_COMMAND, FIP_CMD_DISP_CTRL_TURN_DISPLAY_ON | brightness);
+
+	on = 1;
+}
+
+/*
+ * shutdown the front panel
+ */
+static void fip_off(void)
+{
+	fip_clear();
+
+	/* disable FIP and interrupt */
+	fip_write(FIP_CONFIG, 0);
+}
+
+
+static void fip_write_byte(int addr)
+{
+	/* select write to display and fixed addressing */
+	fip_write(FIP_COMMAND, FIP_CMD_DATA_SET_OP_MODE_NORMAL_OPERATION |
+			       FIP_CMD_DATA_SET_ADR_MODE_FIXED_ADR |
+			       FIP_CMD_DATA_SET_RW_MODE_WRITE_DISPLAY);
+
+	fip_write(FIP_DISPLAY_DATA, ram[addr]);
+	fip_write(FIP_COMMAND, FIP_CMD_ADR_SETTING | addr);
+}
+
+
+static void fip_set_led(int num, int state)
+{
+	if (num < 0 || num > 4)
+		return;
+
+	fip_on();
+
+	led[num] = 1 - !!state;
+	fip_write_led();
+}
+
+
+static int fip_get_sw(int num)
+{
+	if (num < 0 || num > 3)
+		return 0;
+
+	fip_on();
+
+	return (sw & (1 << num)) != 0;
+}
+
+
+static void fip_set_symbol(int n, int v)
+{
+	if (n < 0 || n >= FIP_NUM_SYMBOLS)
+		return;
+
+	fip_on();
+
+	symbol[n] = !!v;
+
+	if (v)
+		ram[symbols[n].addr] |= 1 << symbols[n].bit;
+	else
+		ram[symbols[n].addr] &= ~(1 << symbols[n].bit);
+
+	fip_write_byte(symbols[n].addr);
+}
+
+
+static int fip_set_character(int pos, int ch)
+{
+	int i, offset;
+
+	if (pos < 0 || pos >= FIP_NUM_POSITIONS)
+		return 0;
+
+	fip_on();
+
+	for (i = 0; i < FIP_NUM_CHARACTERS; i++)
+		if (ch == fipcharactersmap[i]) {
+
+			offset = 24 - (3 * pos);
+			if (fipcharacters[i][0] != ram[offset]) {
+				ram[offset] = fipcharacters[i][0];
+				fip_write_byte(offset);
+			}
+
+			offset++;
+			if (fipcharacters[i][1] != ram[offset]) {
+				ram[offset] = fipcharacters[i][1];
+				fip_write_byte(offset);
+			}
+
+			return 1;
+		}
+
+	offset = 24 - (3 * pos);
+	if (fipcharacters[0][0] != ram[offset]) {
+		ram[offset] = fipcharacters[0][0];
+		fip_write_byte(offset);
+	}
+
+	offset++;
+	if (fipcharacters[0][1] != ram[offset]) {
+		ram[offset] = fipcharacters[0][1];
+		fip_write_byte(offset);
+	}
+
+	return 1;
+}
+
+static void fip_set_brightness(unsigned val)
+{
+	if (val > 7)
+		val = 7;
+
+	fip_on();
+
+	brightness = val;
+	fip_write(FIP_COMMAND, FIP_CMD_DISP_CTRL_TURN_DISPLAY_ON | val);
+}
+
+static void fip_set_string(const char *str)
+{
+	int pos;
+
+	pos = 0;
+	while (*str != '\0' && *str != '\n')
+		pos += fip_set_character(pos, *str++);
+	while (pos < FIP_NUM_POSITIONS)
+		fip_set_character(pos++, ' ');
+}
+
+static ssize_t show_brightness(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", brightness);
+}
+
+static ssize_t store_brightness(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	unsigned val;
+
+	if (sscanf(buf, "%u", &val) == 1)
+		fip_set_brightness(val);
+	return count;
+}
+
+
+static ssize_t store_text(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	fip_set_string(buf);
+	return count;
+}
+
+static ssize_t show_led(struct device *dev,
+			struct device_attribute *attr,
+			char *buf)
+{
+	buf[0] = (led[attr->attr.name[3] - '0' - 1] == 0) ? '1' : '0';
+	buf[1] = '\n';
+	return 2;
+}
+
+static ssize_t store_led(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	if (*buf == '0' || *buf == '1')
+		fip_set_led(attr->attr.name[3] - '0' - 1, (*buf - '0') & 1);
+	return 1;
+}
+
+static ssize_t show_sw(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	buf[0] = (fip_get_sw(attr->attr.name[2] - '0' - 1) == 0) ? '0' : '1';
+	buf[1] = '\n';
+	return 2;
+}
+
+static ssize_t show_test(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	ssize_t count;
+	int i;
+
+	count = 0;
+	for (i = 0; i < ARRAY_SIZE(ram); i++)
+		count += snprintf(buf + count, PAGE_SIZE - count,
+				"0x%02x%s", ram[i],
+				((i + 1) % 12) ? ", " : ",\n");
+
+	return count;
+}
+
+static ssize_t store_test(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	switch (*buf) {
+		case '0':
+			fip_clear();
+			break;
+		case '1':
+			fip_fill(0xff);
+			break;
+	}
+
+	return count;
+}
+
+static ssize_t show_raw(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	ssize_t count;
+	int i;
+
+	count = 0;
+	for (i = 0; i < ARRAY_SIZE(ram); i++)
+		count += snprintf(buf + count, PAGE_SIZE - count,
+				"0x%02x%s", ram[i],
+				((i + 1) % 12) ? ", " : ",\n");
+
+	return count;
+}
+
+static unsigned hex(char c)
+{
+	static const char *tab = "0123456789abcdef";
+	unsigned n;
+
+	c = tolower(c);
+	for (n = 0; n < 16; n++)
+		if (tab[n] == c)
+			return n;
+
+	return 0;
+}
+
+static ssize_t store_raw(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	size_t n;
+	int i;
+
+	i = 0;
+	n = count;
+	fip_clear();
+
+	/* select write to display and fixed addressing */
+	fip_write(FIP_COMMAND,
+			FIP_CMD_DATA_SET_OP_MODE_NORMAL_OPERATION |
+			FIP_CMD_DATA_SET_ADR_MODE_FIXED_ADR |
+			FIP_CMD_DATA_SET_RW_MODE_WRITE_DISPLAY);
+
+	while (n >= 2 && i < ARRAY_SIZE(ram)) {
+		ram[i] = (hex(buf[0]) << 4) + hex(buf[1]);
+		fip_write(FIP_DISPLAY_DATA, ram[i]);
+		fip_write(FIP_COMMAND, FIP_CMD_ADR_SETTING | i);
+		buf += 2;
+		n -= 2;
+		i++;
+	}
+
+	return count;
+}
+
+static ssize_t show_symbols(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	ssize_t count;
+	int i;
+
+	count = 0;
+	for (i = 0; i < sizeof (symbols) / sizeof (*symbols); i++)
+		count += snprintf(buf + count,
+				PAGE_SIZE - count, "%d\n", symbol[i]);
+
+	return count;
+}
+
+
+static ssize_t store_symbols(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	int n;
+	int v;
+
+	while (sscanf(buf, "%d %d\n", &n, &v) == 2) {
+		while (*buf++ != '\n')
+			;
+		fip_set_symbol(n, v);
+	}
+
+	return count;
+}
+
+static DEVICE_ATTR(text, S_IWUSR, NULL, store_text);
+static DEVICE_ATTR(led1, S_IWUSR | S_IRUSR, show_led, store_led);
+static DEVICE_ATTR(led2, S_IWUSR | S_IRUSR, show_led, store_led);
+static DEVICE_ATTR(led3, S_IWUSR | S_IRUSR, show_led, store_led);
+static DEVICE_ATTR(led4, S_IWUSR | S_IRUSR, show_led, store_led);
+static DEVICE_ATTR(led5, S_IWUSR | S_IRUSR, show_led, store_led);
+static DEVICE_ATTR(sw1, S_IRUSR, show_sw, NULL);
+static DEVICE_ATTR(sw2, S_IRUSR, show_sw, NULL);
+static DEVICE_ATTR(sw3, S_IRUSR, show_sw, NULL);
+static DEVICE_ATTR(sw4, S_IRUSR, show_sw, NULL);
+static DEVICE_ATTR(test, S_IWUSR | S_IRUSR, show_test, store_test);
+static DEVICE_ATTR(raw, S_IWUSR | S_IRUSR, show_raw, store_raw);
+static DEVICE_ATTR(symbols, S_IWUSR | S_IRUSR, show_symbols, store_symbols);
+static DEVICE_ATTR(brightness, S_IWUSR | S_IRUSR,
+		show_brightness, store_brightness);
+
+static struct device_attribute *fip_attrs[] = {
+	&dev_attr_text,
+	&dev_attr_led1,
+	&dev_attr_led2,
+	&dev_attr_led3,
+	&dev_attr_led4,
+	&dev_attr_led5,
+	&dev_attr_sw1,
+	&dev_attr_sw2,
+	&dev_attr_sw3,
+	&dev_attr_sw4,
+	&dev_attr_test,
+	&dev_attr_raw,
+	&dev_attr_symbols,
+	&dev_attr_brightness,
+};
+
+static void fip_poll_key(unsigned long data)
+{
+	/* send command - later ISR will pick up the interrupt
+	   and read the keys */
+
+	if (!is_fip_busy())
+		fip_write(FIP_COMMAND, FIP_CMD_DATA_SET_RW_MODE_READ_KEYS);
+
+	mod_timer(&fip_timer, jiffies + (HZ / poll_per_sec));
+}
+
+static int input_open(struct input_dev *dev)
+{
+	if (input_used++)
+		return 0;
+
+	setup_timer(&fip_timer, fip_poll_key, 0);
+	mod_timer(&fip_timer, jiffies + (HZ / poll_per_sec));
+
+	return 0;
+}
+
+static void input_close(struct input_dev *dev)
+{
+	if (!--input_used)
+		del_timer(&fip_timer);
+}
+
+static int __init fip_init(void)
+{
+	const int keys[] = { FIP_KEYS_CODE };
+	int err;
+	int i;
+
+	if (tango2_fip_enabled() == 0)
+		return 0;
+
+	printk(KERN_INFO PFX "SMP863x front panel interface driver\n");
+
+	if (request_irq(IRQ_FIP, fip_isr, 0, "tango2_fip", NULL)) {
+		printk(KERN_ERR PFX "cannot register IRQ (%d)\n", IRQ_FIP);
+		return -EIO;
+	}
+
+	if (platform_driver_register(&fip_driver)) {
+		printk(KERN_ERR PFX "driver registration failed\n");
+		err = -ENODEV;
+		goto out_irq;
+	}
+
+	if (IS_ERR
+		(pdev = platform_device_register_simple("fip", -1, NULL, 0))) {
+		printk(KERN_ERR PFX "device registration failed\n");
+		err = PTR_ERR(pdev);
+		goto out_driver;
+	}
+
+	if ((input_dev = input_allocate_device()) == NULL) {
+		printk(KERN_ERR PFX "cannot allocate input device\n");
+		err = -ENOMEM;
+		goto out_device;
+	}
+
+	input_dev->name = "Tango2 front panel";
+	input_dev->open = input_open;
+	input_dev->close = input_close;
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+
+	for (i = 0; i < sizeof (keys) / sizeof (*keys); i++)
+		set_bit(keys[i], input_dev->keybit);
+
+	if (input_register_device(input_dev)) {
+		printk(KERN_ERR PFX "cannot register input device\n");
+		input_free_device(input_dev);
+		err = -ENODEV;
+		goto out_device;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(fip_attrs); i++)
+		if (device_create_file(&pdev->dev, fip_attrs[i]) != 0) {
+			printk(KERN_ERR PFX "cannot create sysfs attribute\n");
+			input_free_device(input_dev);
+			err = -ENODEV;
+			goto out_device;
+		}
+
+	return 0;
+
+
+out_device:
+	platform_device_unregister(pdev);
+out_driver:
+	platform_driver_unregister(&fip_driver);
+out_irq:
+	free_irq(IRQ_FIP, NULL);
+	return err;
+}
+
+static void __exit fip_exit(void)
+{
+	int i;
+
+	if (tango2_fip_enabled() == 0)
+		return;
+
+	fip_off();
+
+	for (i = 0; i < sizeof (fip_attrs) / sizeof (*fip_attrs); i++)
+		device_remove_file(&pdev->dev, fip_attrs[i]);
+
+	free_irq(IRQ_FIP, NULL);
+
+	input_unregister_device(input_dev);
+	input_free_device(input_dev);
+
+	platform_device_unregister(pdev);
+	platform_driver_unregister(&fip_driver);
+}
+
+
+module_init(fip_init);
+module_exit(fip_exit);
+
+MODULE_AUTHOR("Clement Vasseur <cvasseur@freebox.fr>");
+MODULE_DESCRIPTION("SMP863x front panel interface driver");
+MODULE_LICENSE("GPL");
diff -Nruw linux-2.6.31.7-fbx/drivers/platform/tango2./fip_chars.h linux-2.6.31.7-fbx/drivers/platform/tango2/fip_chars.h
--- linux-2.6.31.7-fbx/drivers/platform/tango2./fip_chars.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/tango2/fip_chars.h	2010-03-18 18:28:50.822832587 +0100
@@ -0,0 +1,73 @@
+{DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,0,0,0,0,0)}, //  
+{DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,0,1,0,1,0)}, // (
+{DIGIT_L(1,0,0,0,0,0,0,0), DIGIT_H(1,0,0,0,0,0)}, // )
+{DIGIT_L(0,1,0,0,0,0,0,0), DIGIT_H(0,1,0,1,0,1)}, // +
+{DIGIT_L(0,1,0,0,0,0,0,0), DIGIT_H(0,0,0,1,0,0)}, // -
+{DIGIT_L(1,0,0,0,0,0,0,0), DIGIT_H(0,0,1,0,0,0)}, // /
+{DIGIT_L(0,0,1,1,1,1,1,1), DIGIT_H(0,0,0,0,0,0)}, // 0
+{DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,1,0,0,0,1)}, // 1
+{DIGIT_L(0,1,0,1,1,0,1,1), DIGIT_H(0,0,0,1,0,0)}, // 2
+{DIGIT_L(0,1,0,0,1,1,1,1), DIGIT_H(0,0,0,1,0,0)}, // 3
+{DIGIT_L(0,1,1,0,0,1,1,0), DIGIT_H(0,0,0,1,0,0)}, // 4
+{DIGIT_L(0,1,1,0,1,1,0,1), DIGIT_H(0,0,0,1,0,0)}, // 5
+{DIGIT_L(0,1,1,1,1,1,0,1), DIGIT_H(0,0,0,1,0,0)}, // 6
+{DIGIT_L(0,0,0,0,0,1,1,1), DIGIT_H(0,0,0,0,0,0)}, // 7
+{DIGIT_L(0,1,1,1,1,1,1,1), DIGIT_H(0,0,0,1,0,0)}, // 8
+{DIGIT_L(0,1,1,0,1,1,1,1), DIGIT_H(0,0,0,1,0,0)}, // 9
+{DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,0,1,0,1,0)}, // <
+{DIGIT_L(1,0,0,0,0,0,0,0), DIGIT_H(1,0,0,0,0,0)}, // >
+{DIGIT_L(0,1,1,1,0,1,1,1), DIGIT_H(0,0,0,1,0,0)}, // A
+{DIGIT_L(0,0,0,0,1,1,1,1), DIGIT_H(0,1,0,1,0,1)}, // B
+{DIGIT_L(0,0,1,1,1,0,0,1), DIGIT_H(0,0,0,0,0,0)}, // C
+{DIGIT_L(0,0,0,0,1,1,1,1), DIGIT_H(0,1,0,0,0,1)}, // D
+{DIGIT_L(0,1,1,1,1,0,0,1), DIGIT_H(0,0,0,1,0,0)}, // E
+{DIGIT_L(0,1,1,1,0,0,0,1), DIGIT_H(0,0,0,1,0,0)}, // F
+{DIGIT_L(0,1,1,1,1,1,0,1), DIGIT_H(0,0,0,1,0,0)}, // G
+{DIGIT_L(0,1,1,1,0,1,1,0), DIGIT_H(0,0,0,1,0,0)}, // H
+{DIGIT_L(0,0,0,0,1,0,0,1), DIGIT_H(0,1,0,0,0,1)}, // I
+{DIGIT_L(0,0,0,0,1,1,1,0), DIGIT_H(0,0,0,0,0,0)}, // J
+{DIGIT_L(0,1,1,1,0,0,0,0), DIGIT_H(0,0,1,0,1,0)}, // K
+{DIGIT_L(0,0,1,1,1,0,0,0), DIGIT_H(0,0,0,0,0,0)}, // L
+{DIGIT_L(0,0,1,1,0,1,1,0), DIGIT_H(1,0,1,0,0,0)}, // M
+{DIGIT_L(0,0,1,1,0,1,1,0), DIGIT_H(1,0,0,0,1,0)}, // N
+{DIGIT_L(0,0,1,1,1,1,1,1), DIGIT_H(0,0,0,0,0,0)}, // O
+{DIGIT_L(0,1,1,1,0,0,1,1), DIGIT_H(0,0,0,1,0,0)}, // P
+{DIGIT_L(0,0,1,1,1,1,1,1), DIGIT_H(0,0,0,0,1,0)}, // Q
+{DIGIT_L(0,1,1,1,0,0,1,1), DIGIT_H(0,0,0,1,1,0)}, // R
+{DIGIT_L(0,1,1,0,1,1,0,1), DIGIT_H(0,0,0,1,0,0)}, // S
+{DIGIT_L(0,0,0,0,0,0,0,1), DIGIT_H(0,1,0,0,0,1)}, // T
+{DIGIT_L(0,0,1,1,1,1,1,0), DIGIT_H(0,0,0,0,0,0)}, // U
+{DIGIT_L(0,0,0,0,0,1,1,0), DIGIT_H(1,0,0,0,1,0)}, // V
+{DIGIT_L(1,0,1,1,0,1,1,0), DIGIT_H(0,0,0,0,1,0)}, // W
+{DIGIT_L(1,0,0,0,0,0,0,0), DIGIT_H(1,0,1,0,1,0)}, // X
+{DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(1,0,1,0,0,1)}, // Y
+{DIGIT_L(1,0,0,0,1,0,0,1), DIGIT_H(0,0,1,0,0,0)}, // Z
+{DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(1,0,0,0,1,0)}, // backslash
+{DIGIT_L(0,0,0,0,1,0,0,0), DIGIT_H(0,0,0,0,0,0)}, // _
+{DIGIT_L(0,1,0,1,1,1,0,0), DIGIT_H(0,0,0,1,0,0)}, // a
+{DIGIT_L(0,1,1,1,1,1,0,0), DIGIT_H(0,0,0,1,0,0)}, // b
+{DIGIT_L(0,1,0,1,1,0,0,0), DIGIT_H(0,0,0,1,0,0)}, // c
+{DIGIT_L(0,1,0,1,1,1,1,0), DIGIT_H(0,0,0,1,0,0)}, // d
+{DIGIT_L(0,1,1,1,1,0,1,1), DIGIT_H(0,0,0,1,0,0)}, // e
+{DIGIT_L(0,1,1,1,0,0,0,1), DIGIT_H(0,0,0,0,0,0)}, // f
+{DIGIT_L(0,1,1,0,1,1,1,1), DIGIT_H(0,0,0,1,0,0)}, // g
+{DIGIT_L(0,1,1,1,0,1,0,0), DIGIT_H(0,0,0,1,0,0)}, // h
+{DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,0,0,0,0,1)}, // i
+{DIGIT_L(0,0,0,0,1,1,0,0), DIGIT_H(0,0,0,0,0,0)}, // j
+{DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,1,0,1,1,1)}, // k
+{DIGIT_L(0,0,1,1,0,0,0,0), DIGIT_H(0,0,0,0,0,0)}, // l
+{DIGIT_L(0,1,0,1,0,1,0,0), DIGIT_H(0,0,0,1,0,1)}, // m
+{DIGIT_L(0,1,0,1,0,1,0,0), DIGIT_H(0,0,0,1,0,0)}, // n
+{DIGIT_L(0,1,0,1,1,1,0,0), DIGIT_H(0,0,0,1,0,0)}, // o
+{DIGIT_L(0,1,1,1,0,0,1,1), DIGIT_H(0,0,0,1,0,0)}, // p
+{DIGIT_L(0,1,1,0,0,1,1,1), DIGIT_H(0,0,0,1,0,0)}, // q
+{DIGIT_L(0,1,0,1,0,0,0,0), DIGIT_H(0,0,0,0,0,0)}, // r
+{DIGIT_L(0,1,1,0,1,1,0,1), DIGIT_H(0,0,0,1,0,0)}, // s
+{DIGIT_L(0,1,1,1,1,0,0,0), DIGIT_H(0,0,0,0,0,0)}, // t
+{DIGIT_L(0,0,0,1,1,1,0,0), DIGIT_H(0,0,0,0,0,0)}, // u
+{DIGIT_L(0,0,0,0,0,1,0,0), DIGIT_H(0,0,0,0,1,0)}, // v
+{DIGIT_L(1,0,0,1,0,1,0,0), DIGIT_H(0,0,0,0,1,0)}, // w
+{DIGIT_L(0,1,0,0,0,0,0,0), DIGIT_H(0,0,0,1,1,1)}, // x
+{DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,1,1,0,0,1)}, // y
+{DIGIT_L(0,1,0,0,1,0,0,0), DIGIT_H(0,0,0,1,0,1)}, // z
+{DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,1,0,0,0,1)}, // |
diff -Nruw linux-2.6.31.7-fbx/drivers/platform/tango2./gpio.c linux-2.6.31.7-fbx/drivers/platform/tango2/gpio.c
--- linux-2.6.31.7-fbx/drivers/platform/tango2./gpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/tango2/gpio.c	2010-03-18 18:28:50.822832587 +0100
@@ -0,0 +1,524 @@
+/*
+ * tango2_gpio: SMP863x GPIO sysfs interface driver.
+ *
+ * Copyright (C) 2007 Clement Vasseur <cvasseur@freebox.fr>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-tango2/tango2_gpio.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+
+#define PFX "tango2_gpio: "
+
+#define GPIO_ICSP_CLK	64
+#define GPIO_ICSP_DAT	12
+
+#define IR_NEC_CTRL             (REG_BASE_system_block + SYS_gpio_dir + 0x18)
+#define IR_NEC_CAPTURE_DATA     (REG_BASE_system_block + SYS_gpio_dir + 0x1c)
+#define RC5_CLK_DIV             48006
+#define IR_RC5_CTRL             (REG_BASE_system_block + SYS_gpio_dir + 0x20)
+#define IR_RC5_DECODE_CLK_DIV   (REG_BASE_system_block + SYS_gpio_dir + 0x24)
+#define IR_RC5_DECODER_DATA     (REG_BASE_system_block + SYS_gpio_dir + 0x28)
+#define IR_RC5_INT_STATUS       (REG_BASE_system_block + SYS_gpio_dir + 0x2c)
+#define IR_RC6_CTRL             (REG_BASE_system_block + SYS_gpio_dir + 0xe0)
+#define IR_RC6_T_CTRL           (REG_BASE_system_block + SYS_gpio_dir + 0xe4)
+#define IR_RC6_DATA_OUT0        (REG_BASE_system_block + SYS_gpio_dir + 0xe8)
+#define IR_RC6_DATA_OUT1        (REG_BASE_system_block + SYS_gpio_dir + 0xec)
+#define IR_RC6_DATA_OUT2        (REG_BASE_system_block + SYS_gpio_dir + 0xf0)
+#define IR_RC6_DATA_OUT3        (REG_BASE_system_block + SYS_gpio_dir + 0xf4)
+#define IR_RC6_DATA_OUT4        (REG_BASE_system_block + SYS_gpio_dir + 0xf8)
+
+#define PIC_CLOCK_UDELAY	10
+
+extern unsigned int fbx_board_id;
+
+static const struct {
+	const char *name;
+	int gpio;
+} gpios[] = {
+	{ "mute",		20 },
+	{ "scart_en",		24 },
+	{ "scart_ws",		25 },
+	{ "scart_rgb",		26 },
+	{ "sel_hd",		18 },
+	{ "icsp_clk",		GPIO_ICSP_CLK },
+	{ "icsp_dat",		GPIO_ICSP_DAT },
+	{ "fan_pwm_out",	15 },
+	{ "fan_tach",		16 },
+};
+
+static struct platform_driver gpio_driver = {
+	.driver = {
+		.name = "gpio",
+	},
+};
+
+static struct platform_device *pdev;
+
+static ssize_t store(struct device *dev,
+		     struct device_attribute *attr,
+		     const char *buf, size_t count)
+{
+	unsigned i;
+
+	if (*buf != '0' && *buf != '1')
+		return 1;
+
+	for (i = 0; i < ARRAY_SIZE(gpios); i++)
+		if (!strcmp(attr->attr.name, gpios[i].name)) {
+			em86xx_gpio_setdirection(gpios[i].gpio, GPIO_OUTPUT);
+			em86xx_gpio_write(gpios[i].gpio, *buf - '0');
+			return 1;
+		}
+
+	return 1;
+}
+
+static ssize_t store_icsp_dat_mode(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	if (*buf == '0' || *buf == '1')
+		em86xx_gpio_setdirection(GPIO_ICSP_DAT, *buf - '0');
+
+	return 1;
+}
+
+static ssize_t store_uart1_mode(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	int v;
+
+	sscanf(buf, "%u", &v);
+	em86xx_gpio_uart_mode(1, v);
+	return strlen(buf);
+}
+
+static ssize_t store_uart1_dir(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	int v;
+
+	sscanf(buf, "%u", &v);
+	em86xx_gpio_uart_dir(1, v);
+	return strlen(buf);
+}
+
+static ssize_t show(struct device *dev,
+		    struct device_attribute *attr,
+		    char *buf)
+{
+	unsigned i;
+
+	for (i = 0; i < ARRAY_SIZE(gpios); i++)
+		if (!strcmp(attr->attr.name, gpios[i].name)) {
+			em86xx_gpio_setdirection(gpios[i].gpio, GPIO_INPUT);
+			return snprintf(buf, PAGE_SIZE, "%u\n",
+					em86xx_gpio_read(gpios[i].gpio));
+		}
+
+	return 0;
+}
+
+static ssize_t store_pic(struct device *dev,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	int v;
+	int i;
+
+	sscanf(buf, "%u", &v);
+
+	v <<= 1;
+	for (i = 0; i < 16; i++) {
+		em86xx_gpio_write(GPIO_ICSP_CLK, 1);
+		em86xx_gpio_write(GPIO_ICSP_DAT, v & 1);
+		udelay(PIC_CLOCK_UDELAY);
+		em86xx_gpio_write(GPIO_ICSP_CLK, 0);
+		udelay(PIC_CLOCK_UDELAY);
+		v >>= 1;
+	}
+
+	return strlen(buf);
+}
+
+static ssize_t store_pwm(struct device *dev,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	uint32_t v;
+
+	v = simple_strtoul(buf, NULL, 0);
+
+	gbus_writel(REG_BASE_system_block + SYS_gpio15_pwm, v);
+
+	return strlen(buf);
+}
+
+static ssize_t store_cmd(struct device *dev,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	unsigned long flags;
+	int v;
+	int i;
+
+	sscanf(buf, "%u", &v);
+
+	local_irq_save(flags);
+
+	for (i = 0; i < 6; i++) {
+		em86xx_gpio_write(GPIO_ICSP_CLK, 1);
+		em86xx_gpio_write(GPIO_ICSP_DAT, v & 1);
+		udelay(PIC_CLOCK_UDELAY);
+		em86xx_gpio_write(GPIO_ICSP_CLK, 0);
+		udelay(PIC_CLOCK_UDELAY);
+		v >>= 1;
+	}
+
+	udelay(1);
+	local_irq_restore(flags);
+
+	return strlen(buf);
+}
+
+static ssize_t store_pic_load(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	const char cmd_load[] = "2";
+	const char cmd_pgm_start[] = "8";
+	const char cmd_pgm_end[] = "14";
+	unsigned long flags;
+	int v;
+	int i;
+
+	sscanf(buf, "%u", &v);
+
+	local_irq_save(flags);
+
+	store_cmd(NULL, NULL, cmd_load, 1);
+
+	v <<= 1;
+	for (i = 0; i < 16; i++) {
+		em86xx_gpio_write(GPIO_ICSP_CLK, 1);
+		em86xx_gpio_write(GPIO_ICSP_DAT, v & 1);
+		udelay(PIC_CLOCK_UDELAY);
+		em86xx_gpio_write(GPIO_ICSP_CLK, 0);
+		udelay(PIC_CLOCK_UDELAY);
+		v >>= 1;
+	}
+
+	store_cmd(NULL, NULL, cmd_pgm_start, 1);
+	udelay(3000);
+	store_cmd(NULL, NULL, cmd_pgm_end, 1);
+	udelay(100);
+
+	local_irq_restore(flags);
+
+	return strlen(buf);
+}
+
+static int64_t tic_1;
+static int64_t tic_2;
+static int64_t tic_3;
+static int64_t tic_4;
+static bool irq_enabled;
+
+static irqreturn_t cal_isr(int irq, void *dev_id)
+{
+	struct timespec ts;
+#ifdef DEBUG_ISR_TIME
+	static int64_t last_time = 0;
+#endif
+	int64_t time;
+
+	if (irq != IRQ_IR)
+		return IRQ_NONE;
+
+	getnstimeofday(&ts);
+	time = timespec_to_ns(&ts);
+
+#ifdef DEBUG_ISR_TIME
+	if (tic_1 == 0)
+		last_time = 0;
+
+	if (last_time != 0)
+		printk(KERN_DEBUG "cal_isr: %lu\n",
+		      (uint32_t) (time - last_time) / NSEC_PER_MSEC);
+	last_time = time;
+#endif
+
+	if (tic_1 == 0)
+		tic_1 = time;
+	else if (tic_2 == 0)
+		tic_2 = time;
+	else if (tic_3 == 0)
+		tic_3 = time;
+	else if (tic_4 == 0)
+		tic_4 = time;
+
+	return IRQ_HANDLED;
+}
+
+static ssize_t store_cal(struct device *dev,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	if (irq_enabled) {
+		free_irq(IRQ_IR, NULL);
+		irq_enabled = false;
+	}
+
+	// make sure interrupt is disabled
+	gbus_write_uint32(pGBus, IR_NEC_CTRL, 0);
+	gbus_write_uint32(pGBus, IR_RC5_CTRL, (gbus_read_uint32(pGBus,
+				IR_RC5_CTRL) & 0xfffffdfe) | 0x00000100);
+	gbus_write_uint32(pGBus, IR_RC6_CTRL, 0xc0000000);
+
+	tic_1 = 0;
+	tic_2 = 0;
+	tic_3 = 0;
+	tic_4 = 0;
+
+	// register the pic calibration irq handler
+	if (request_irq(IRQ_IR, cal_isr, 0, "tango2_ir", NULL))
+		printk(KERN_ERR PFX "cannot register IRQ (%d)\n", IRQ_IR);
+
+	// enable interrupts
+	em86xx_gpio_setdirection(GPIO_ICSP_DAT, 0);
+	gbus_write_uint32(pGBus, IR_NEC_CAPTURE_DATA, 0);
+	gbus_write_uint32(pGBus, IR_NEC_CTRL, 0x1f0c3b10);
+	gbus_write_uint32(pGBus, IR_RC5_DECODE_CLK_DIV, RC5_CLK_DIV);
+	gbus_write_uint32(pGBus, IR_RC5_DECODER_DATA, 0);
+	gbus_write_uint32(pGBus, IR_RC5_CTRL, 0x000002e9);
+	gbus_write_uint32(pGBus, IR_RC6_CTRL, 0xc1);
+	gbus_write_uint32(pGBus, IR_RC6_T_CTRL, (0xbb8 << 18) | 0x2ee0);
+
+	irq_enabled = true;
+
+	return count;
+}
+
+static ssize_t show_cal(struct device *dev,
+			struct device_attribute *attr,
+			char *buf)
+{
+	uint32_t res_1;
+	uint32_t res_2;
+
+	if (irq_enabled == false)
+		return 0;
+
+	if (tic_1 == 0 || tic_2 == 0 || tic_3 == 0 || tic_4 == 0)
+		return 0;
+
+	free_irq(IRQ_IR, NULL);
+	irq_enabled = false;
+
+	res_1 = tic_3 - tic_2;
+	res_2 = tic_4 - tic_3;
+
+	tic_1 = 0;
+	tic_2 = 0;
+	tic_3 = 0;
+	tic_4 = 0;
+
+	return snprintf(buf, PAGE_SIZE, "%lu:%lu\n",
+			res_1 / NSEC_PER_MSEC,
+			res_2 / NSEC_PER_MSEC);
+}
+
+static ssize_t show_pic(struct device *dev,
+			struct device_attribute *attr,
+			char *buf)
+{
+	unsigned long flags;
+	int i;
+	int v;
+
+	local_irq_save(flags);
+
+	v = 4;
+	for (i = 0; i < 6; i++) {
+		em86xx_gpio_write(GPIO_ICSP_CLK, 1);
+		em86xx_gpio_write(GPIO_ICSP_DAT, v & 1);
+		udelay(PIC_CLOCK_UDELAY);
+		em86xx_gpio_write(GPIO_ICSP_CLK, 0);
+		udelay(PIC_CLOCK_UDELAY);
+		v >>= 1;
+	}
+
+	// set ICSP_DAT GPIO in input mode
+	em86xx_gpio_setdirection(GPIO_ICSP_DAT, 0);
+
+	udelay(1);
+
+	v = 0;
+
+	for (i = 0; i < 16; i++) {
+		em86xx_gpio_write(GPIO_ICSP_CLK, 1);
+		udelay(PIC_CLOCK_UDELAY);
+		v |= em86xx_gpio_read(GPIO_ICSP_DAT) << i;
+		em86xx_gpio_write(GPIO_ICSP_CLK, 0);
+		udelay(PIC_CLOCK_UDELAY);
+	}
+
+	// set ICSP_DAT GPIO in output mode
+	em86xx_gpio_setdirection(GPIO_ICSP_DAT, 1);
+
+	local_irq_restore(flags);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", (v >> 1) & 0xfff);
+}
+
+static ssize_t show_pic_data(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	int i;
+	int v;
+
+	v = 0;
+
+	// set ICSP_DAT GPIO in input mode
+	em86xx_gpio_setdirection(GPIO_ICSP_DAT, 0);
+
+	for (i = 0; i < 16; i++) {
+		em86xx_gpio_write(GPIO_ICSP_CLK, 1);
+		udelay(PIC_CLOCK_UDELAY);
+		v |= em86xx_gpio_read(GPIO_ICSP_DAT) << i;
+		em86xx_gpio_write(GPIO_ICSP_CLK, 0);
+		udelay(PIC_CLOCK_UDELAY);
+	}
+
+	// set ICSP_DAT GPIO in output mode
+	em86xx_gpio_setdirection(GPIO_ICSP_DAT, 1);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", (v >> 1) & 0xfff);
+}
+
+static DEVICE_ATTR(mute, S_IWUSR, NULL, store);
+static DEVICE_ATTR(scart_en, S_IWUSR, NULL, store);
+static DEVICE_ATTR(scart_ws, S_IWUSR, NULL, store);
+static DEVICE_ATTR(scart_rgb, S_IWUSR, NULL, store);
+static DEVICE_ATTR(sel_hd, S_IWUSR, NULL, store);
+static DEVICE_ATTR(icsp_clk, S_IWUSR | S_IRUSR, show, store);
+static DEVICE_ATTR(icsp_dat, S_IWUSR | S_IRUSR, show, store);
+static DEVICE_ATTR(uart1_mode, S_IWUSR, NULL, store_uart1_mode);
+static DEVICE_ATTR(uart1_dir, S_IWUSR, NULL, store_uart1_dir);
+static DEVICE_ATTR(icsp_dat_mode, S_IWUSR, NULL, store_icsp_dat_mode);
+static DEVICE_ATTR(fan_pwm_out, S_IWUSR, NULL, store);
+static DEVICE_ATTR(pic_load, S_IWUSR, NULL, store_pic_load);
+static DEVICE_ATTR(pic_write, S_IWUSR, NULL, store_pic);
+static DEVICE_ATTR(pic_read, S_IRUSR, show_pic, NULL);
+static DEVICE_ATTR(pic_data, S_IRUSR, show_pic_data, NULL);
+static DEVICE_ATTR(pic_cmd, S_IWUSR, NULL, store_cmd);
+static DEVICE_ATTR(pic_cal, S_IWUSR | S_IRUSR, show_cal, store_cal);
+static DEVICE_ATTR(fan_pwm, S_IWUSR, NULL, store_pwm);
+static DEVICE_ATTR(fan_tach, S_IRUSR, show, NULL);
+
+static struct device_attribute *gpio_attrs_1[] = {
+	&dev_attr_mute,
+	&dev_attr_scart_en,
+	&dev_attr_scart_ws,
+	&dev_attr_scart_rgb,
+	&dev_attr_sel_hd,
+};
+
+static struct device_attribute *gpio_attrs_2[] = {
+	&dev_attr_mute,
+	&dev_attr_scart_en,
+	&dev_attr_scart_ws,
+	&dev_attr_scart_rgb,
+	&dev_attr_sel_hd,
+	&dev_attr_icsp_clk,
+	&dev_attr_icsp_dat,
+	&dev_attr_uart1_mode,
+	&dev_attr_uart1_dir,
+	&dev_attr_icsp_dat_mode,
+	&dev_attr_fan_pwm_out,
+	&dev_attr_pic_load,
+	&dev_attr_pic_write,
+	&dev_attr_pic_read,
+	&dev_attr_pic_data,
+	&dev_attr_pic_cmd,
+	&dev_attr_pic_cal,
+	&dev_attr_fan_pwm,
+	&dev_attr_fan_tach,
+};
+
+static int __init gpio_init(void)
+{
+	int i;
+
+	printk(KERN_INFO PFX "SMP863x GPIO sysfs interface driver\n");
+
+	if (platform_driver_register(&gpio_driver)) {
+		printk(KERN_ERR PFX "driver registration failed\n");
+		return -ENODEV;
+	}
+
+	if (IS_ERR
+		(pdev = platform_device_register_simple("gpio", -1, NULL, 0))) {
+		printk(KERN_ERR PFX "device registration failed\n");
+		platform_driver_unregister(&gpio_driver);
+		return PTR_ERR(pdev);
+	}
+
+	if (fbx_board_id == 0) {
+		for (i = 0; i < ARRAY_SIZE(gpio_attrs_1); i++)
+			if (device_create_file(&pdev->dev,
+						gpio_attrs_1[i]) != 0)
+				goto out_sysfs_err;
+	} else {
+		for (i = 0; i < ARRAY_SIZE(gpio_attrs_2); i++)
+			if (device_create_file(&pdev->dev,
+						gpio_attrs_2[i]) != 0)
+				goto out_sysfs_err;
+	}
+
+	irq_enabled = false;
+
+	return 0;
+
+out_sysfs_err:
+	printk(KERN_ERR PFX "cannot create sysfs attribute\n");
+
+	platform_device_unregister(pdev);
+	platform_driver_unregister(&gpio_driver);
+
+	return -ENODEV;
+}
+
+static void __exit gpio_exit(void)
+{
+	int i;
+
+	if (fbx_board_id == 0)
+		for (i = 0; i < ARRAY_SIZE(gpio_attrs_1); i++)
+			device_remove_file(&pdev->dev, gpio_attrs_1[i]);
+	else
+		for (i = 0; i < ARRAY_SIZE(gpio_attrs_2); i++)
+			device_remove_file(&pdev->dev, gpio_attrs_2[i]);
+
+	platform_device_unregister(pdev);
+	platform_driver_unregister(&gpio_driver);
+}
+
+module_init(gpio_init);
+module_exit(gpio_exit);
+
+MODULE_AUTHOR("Clement Vasseur <cvasseur@freebox.fr>");
+MODULE_DESCRIPTION("SMP863x GPIO sysfs interface driver");
+MODULE_LICENSE("GPL");
diff -Nruw linux-2.6.31.7-fbx/drivers/platform/tango2./ir.c linux-2.6.31.7-fbx/drivers/platform/tango2/ir.c
--- linux-2.6.31.7-fbx/drivers/platform/tango2./ir.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/tango2/ir.c	2010-03-18 18:28:50.822832587 +0100
@@ -0,0 +1,305 @@
+/*
+ * tango2_ir - SMP863x infrared interface driver.
+ *
+ * Copyright (C) 2007 Clement Vasseur <cvasseur@freebox.fr>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-tango2/tango2_regs.h>
+#include <asm/mach-tango2/tango2_irqs.h>
+#include <asm/mach-tango2/tango2_gbus.h>
+#include <asm/mach-tango2/tango2_gpio.h>
+#include <asm/mach-tango2/tango2_xenv.h>
+
+#define SYS_gpio_base		SYS_gpio_dir
+
+/* NEC Control */
+#define IR_NEC_CTRL             (REG_BASE_system_block + SYS_gpio_base + 0x18)
+#define IR_NEC_CAPTURE_DATA	(REG_BASE_system_block + SYS_gpio_base + 0x1c)
+
+/* RC5 Control */
+#define RC5_CLK_DIV		48006	/* 48006 = 1.778ms, 36018 = 1.334ms, */
+				        /* 59994 = 2.222ms */
+#define IR_RC5_CTRL             (REG_BASE_system_block + SYS_gpio_base + 0x20)
+#define IR_RC5_DECODE_CLK_DIV	(REG_BASE_system_block + SYS_gpio_base + 0x24)
+#define IR_RC5_DECODER_DATA	(REG_BASE_system_block + SYS_gpio_base + 0x28)
+#define IR_RC5_INT_STATUS	(REG_BASE_system_block + SYS_gpio_base + 0x2c)
+
+/* RC6 Control */
+#define RC6_DWORDS		5	/* 5 dwords = 20 bytes */
+#define IR_RC6_CTRL             (REG_BASE_system_block + SYS_gpio_base + 0xe0)
+#define IR_RC6_T_CTRL           (REG_BASE_system_block + SYS_gpio_base + 0xe4)
+#define IR_RC6_DATA_OUT0        (REG_BASE_system_block + SYS_gpio_base + 0xe8)
+#define IR_RC6_DATA_OUT1        (REG_BASE_system_block + SYS_gpio_base + 0xec)
+#define IR_RC6_DATA_OUT2        (REG_BASE_system_block + SYS_gpio_base + 0xf0)
+#define IR_RC6_DATA_OUT3        (REG_BASE_system_block + SYS_gpio_base + 0xf4)
+#define IR_RC6_DATA_OUT4        (REG_BASE_system_block + SYS_gpio_base + 0xf8)
+
+#define PFX			"tango2_ir: "
+
+
+static struct platform_driver ir_driver = {
+	.driver = {
+		.name = "ir",
+	},
+};
+
+static struct platform_device *pdev;
+static struct input_dev *input_dev;
+static int input_used = 0;
+
+extern int fbx_board_id;
+
+static void push_rc6_key(unsigned long dx[RC6_DWORDS])
+{
+	unsigned int key;
+
+	key = (dx[0] & 0xffff0000) |
+		((dx[1] & 0xff) << 8) |
+		((dx[1] >> 8) & 0xff);
+
+	input_event(input_dev, EV_MSC, MSC_SCAN, key);
+	input_sync(input_dev);
+}
+
+static irqreturn_t ir_isr(int irq, void *dev_id)
+{
+	uint32_t status;
+	uint32_t data;
+
+	if (irq != IRQ_IR)
+		return IRQ_NONE;
+
+	status = gbus_read_uint32(pGBus, IR_RC6_CTRL);
+	if ((status & 0xc0000000) != 0) {
+		/* clear interrupt */
+		gbus_write_uint32(pGBus, IR_RC6_CTRL, status);
+
+		if ((status & 0x80000000) != 0) {
+			/* RC6 data is available */
+			unsigned long dx[RC6_DWORDS];
+			dx[0] = gbus_read_uint32(pGBus, IR_RC6_DATA_OUT0);
+			dx[1] = gbus_read_uint32(pGBus, IR_RC6_DATA_OUT1);
+			dx[2] = gbus_read_uint32(pGBus, IR_RC6_DATA_OUT2);
+			dx[3] = gbus_read_uint32(pGBus, IR_RC6_DATA_OUT3);
+			dx[4] = gbus_read_uint32(pGBus, IR_RC6_DATA_OUT4);
+
+#ifdef DEBUG_IR
+			printk(KERN_DEBUG "RC6 data in irq (%08lx %08lx "
+					"%08lx %08lx %08lx)\n",
+					dx[0], dx[1], dx[2], dx[3], dx[4]);
+#endif
+
+			/* force to clear RC5 interrupt status */
+			status = gbus_read_uint32(pGBus, IR_RC5_INT_STATUS);
+			/* clear interrupt if any */
+			if ((status & 0x00000003) != 0)
+				gbus_write_uint32(pGBus, IR_RC5_INT_STATUS,
+						status);
+
+			push_rc6_key(dx);
+
+			return IRQ_HANDLED;
+		}
+	}
+
+	status = gbus_read_uint32(pGBus, IR_RC5_INT_STATUS);
+	/* clear interrupt */
+	gbus_write_uint32(pGBus, IR_RC5_INT_STATUS, status);
+	status &= 0x00000003;
+
+	if (status & 0x00000001) {
+		/* RC5 irq */
+		data = gbus_read_uint32(pGBus, IR_RC5_DECODER_DATA);
+		gbus_write_uint32(pGBus, IR_RC5_DECODER_DATA, 0);
+		/* invalid RC5 decoder data */
+		if ((data & 0x80000000) != 0)
+			return IRQ_HANDLED;
+
+#ifdef DEBUG_IR
+		printk(KERN_DEBUG "RC5 data in irq (0x%08x)\n", data);
+#endif
+
+	} else if (status & 0x00000002) {
+		/* NEC irq */
+		data = gbus_read_uint32(pGBus, IR_NEC_CAPTURE_DATA);
+		gbus_write_uint32(pGBus, IR_NEC_CAPTURE_DATA, 0);
+
+#ifdef DEBUG_IR
+		printk(KERN_DEBUG "NEC data in irq (0x%08x)\n", data);
+#endif
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int input_open(struct input_dev *dev)
+{
+	if (input_used++)
+		return 0;
+
+	/* enable the NEC device (CTRL register)
+	 *	31:30 - reserved
+	 *	29:24	IR_CAPTURE_NBITS [5:0] -> set to 0x1f
+	 *	23:22 - reserved
+	 *	21:16	GPIO_INFREARED_SEL [5:0] -> set to 12
+	 *	15:14 - reserved
+	 *	13:0	IR_PREDIV_DEVIDER [13:0] -> set to 0x3b10
+	 */
+	em86xx_gpio_setdirection(12, 0);
+	printk(KERN_DEBUG PFX "enable NEC decoder\n");
+	gbus_write_uint32(pGBus, IR_NEC_CAPTURE_DATA, 0);
+	gbus_write_uint32(pGBus, IR_NEC_CTRL, 0x1f0c3b10);
+
+	/* enable the RC5 device (CTRL register)
+	 *	31:10 - reserved
+	 *	9	IR_RC5_INT_ENABLE -> set
+	 *	8	IR_NEC_INT_DISABLE
+	 *	7	IR_DEBOUNCE_SEL1 -> set
+	 *	6	IR_DEBOUNCE_SEL0 -> set
+	 *	5	IR_DEBOUNCE_ENABLE -> set
+	 *	4	IR_NEC_DISABLE
+	 *	3	IR_RSYNC_1/4 -> set
+	 *	2	IR_RSYNC_1/8
+	 *	1	IR_SIGNAL_INVERT
+	 *	0	IR_RC5_DECODE_ENABLE -> set
+	 */
+	printk(KERN_DEBUG PFX "enable RC5 decoder\n");
+	gbus_write_uint32(pGBus, IR_RC5_DECODE_CLK_DIV, RC5_CLK_DIV);
+	gbus_write_uint32(pGBus, IR_RC5_DECODER_DATA, 0);
+	gbus_write_uint32(pGBus, IR_RC5_CTRL, 0x000002e9);
+
+	/* enable the RC6 device (CTRL register)
+	 *	7	IR_RC6_DATA_IN_INT_ENABLE -> set
+	 *	6	IR_RC6_ERROR_INT_ENABLE -> set
+	 *	5:2	reserved
+	 *	1	IR_SIGNAL_INVERT
+	 *	0	IR_RC6_DECODE_ENABLE -> set
+	 * tolerance and Duration (T_CTRL register)
+	 *	31:18	Tolerance (typ. 0xbb8)
+	 *	17:0	Duration (typ. 0x2ee0)
+	 */
+	printk(KERN_DEBUG PFX "enable RC6 decoder\n");
+	gbus_write_uint32(pGBus, IR_RC6_CTRL, 0xc1);
+	gbus_write_uint32(pGBus, IR_RC6_T_CTRL, (0xbb8 << 18) | 0x2ee0);
+
+	return 0;
+}
+
+static void input_close(struct input_dev *dev)
+{
+	if (--input_used)
+		return;
+
+	/* disable the NEC device */
+	printk(KERN_DEBUG PFX "disable NEC decoder\n");
+	gbus_write_uint32(pGBus, IR_NEC_CAPTURE_DATA, 0);
+	gbus_write_uint32(pGBus, IR_NEC_CTRL, 0);
+
+	/* disable the RC5 device */
+	printk(KERN_DEBUG PFX "disable RC5 decoder\n");
+	gbus_write_uint32(pGBus,  IR_RC5_CTRL, (gbus_read_uint32(pGBus,
+				IR_RC5_CTRL) & 0xfffffdfe) | 0x00000100);
+
+	/* disable the RC6 device */
+	printk(KERN_DEBUG PFX "disable RC6 decoder\n");
+	gbus_write_uint32(pGBus, IR_RC6_CTRL, 0xc0000000);
+}
+
+static int __init ir_init(void)
+{
+	int err;
+
+	printk(KERN_INFO PFX "SMP863x infrared interface driver\n");
+
+	if (tango2_ir_enabled() == 0)
+		return 0;
+
+	/* IR is not used on fbx5b1 boards */
+	if (fbx_board_id == 0) {
+		printk(KERN_INFO PFX "ir disabled\n");
+		return 0;
+	}
+
+	/* make sure interrupt is disabled,
+	 * will be re-enabled in device open stage */
+	gbus_write_uint32(pGBus, IR_NEC_CTRL, 0);
+	gbus_write_uint32(pGBus, IR_RC5_CTRL, (gbus_read_uint32(pGBus,
+				IR_RC5_CTRL) & 0xfffffdfe) | 0x00000100);
+	gbus_write_uint32(pGBus, IR_RC6_CTRL, 0xc0000000);
+
+	if (request_irq(IRQ_IR, ir_isr, 0, "tango2_ir", NULL)) {
+		printk(KERN_ERR PFX "cannot register IRQ (%d)\n", IRQ_IR);
+		return -EIO;
+	}
+
+	if (platform_driver_register(&ir_driver)) {
+		printk(KERN_ERR PFX "driver registration failed\n");
+		err = -ENODEV;
+		goto out_irq;
+	}
+
+	if (IS_ERR
+		(pdev = platform_device_register_simple("ir", -1, NULL, 0))) {
+		printk(KERN_ERR PFX "device registration failed\n");
+		err = PTR_ERR(pdev);
+		goto out_driver;
+	}
+
+	if ((input_dev = input_allocate_device()) == NULL) {
+		printk(KERN_ERR PFX "cannot allocate input device\n");
+		err = -ENOMEM;
+		goto out_device;
+	}
+
+	input_dev->name = "Tango2 infrared";
+	input_dev->open = input_open;
+	input_dev->close = input_close;
+	input_dev->evbit[0] = BIT(EV_MSC);
+	input_dev->mscbit[0] = BIT(MSC_SCAN);
+
+	if (input_register_device(input_dev)) {
+		printk(KERN_ERR PFX "cannot register input device\n");
+		input_free_device(input_dev);
+		err = -ENODEV;
+		goto out_device;
+	}
+
+	return 0;
+
+
+out_device:
+	platform_device_unregister(pdev);
+out_driver:
+	platform_driver_unregister(&ir_driver);
+out_irq:
+	free_irq(IRQ_IR, NULL);
+	return err;
+}
+
+static void __exit ir_exit(void)
+{
+	if (tango2_ir_enabled() == 0)
+		return;
+
+	free_irq(IRQ_IR, NULL);
+
+	input_unregister_device(input_dev);
+	input_free_device(input_dev);
+
+	platform_device_unregister(pdev);
+	platform_driver_unregister(&ir_driver);
+}
+
+module_init(ir_init);
+module_exit(ir_exit);
+
+MODULE_AUTHOR("Clement Vasseur <cvasseur@freebox.fr>");
+MODULE_DESCRIPTION("SMP863x infrared input interface");
+MODULE_LICENSE("GPL");
diff -Nruw linux-2.6.31.7-fbx/drivers/platform/tango2./Kconfig linux-2.6.31.7-fbx/drivers/platform/tango2/Kconfig
--- linux-2.6.31.7-fbx/drivers/platform/tango2./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/tango2/Kconfig	2010-03-18 18:28:50.822832587 +0100
@@ -0,0 +1,30 @@
+#
+# TANGO2 devices configuration
+#
+
+menu "Tango2 devices"
+	depends on TANGO2
+
+config TANGO2_FIP
+	tristate "Front panel support"
+	select INPUT
+	---help---
+	  Tango2 FIP front panel support.
+
+config TANGO2_GPIO
+	tristate "GPIO sysfs support"
+	---help---
+	  Export GPIO attributes in sysfs.
+
+config TANGO2_IR
+	tristate "IR support"
+	---help---
+	  Tango2 IR (NEC/RC5/RC6) support.
+
+config TANGO2_FB
+	tristate "Framebuffer support"
+	depends on FB
+	---help---
+	  Tango2 framebuffer support.
+
+endmenu
diff -Nruw linux-2.6.31.7-fbx/drivers/platform/tango2./Makefile linux-2.6.31.7-fbx/drivers/platform/tango2/Makefile
--- linux-2.6.31.7-fbx/drivers/platform/tango2./Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/drivers/platform/tango2/Makefile	2010-03-18 18:28:50.822832587 +0100
@@ -0,0 +1,6 @@
+# Makefile for the TANGO2 device drivers
+
+obj-$(CONFIG_TANGO2_FIP) += fip.o
+obj-$(CONFIG_TANGO2_GPIO) += gpio.o
+obj-$(CONFIG_TANGO2_IR) += ir.o
+obj-$(CONFIG_TANGO2_FB) += fb.o
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/drivers/usb/host/ehci-tango2.c	2010-03-18 18:28:51.302926751 +0100
@@ -0,0 +1,107 @@
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-tango2/tango2_board.h>
+#include <asm/mach-tango2/tango2_usb.h>
+
+static int tango2_ehci_setup(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	int retval;
+
+	retval = ehci_halt(ehci);
+	if (retval)
+		return retval;
+
+	retval = ehci_init(hcd);
+	if (retval)
+		return retval;
+
+	hcd->has_tt = 1;
+	ehci_reset(ehci);
+	ehci_port_power(ehci, 0);
+
+	return retval;
+}
+
+static const struct hc_driver ehci_tango2_hc_driver = {
+	.description =		hcd_name,
+	.product_desc =		"SMP83xx integrated EHCI controller",
+	.hcd_priv_size =	sizeof(struct ehci_hcd),
+
+	.irq =			ehci_irq,
+	.flags =		HCD_USB2 | HCD_MEMORY,
+
+	.reset =		tango2_ehci_setup,
+	.start =		ehci_run,
+	.stop =			ehci_stop,
+	.shutdown =		ehci_shutdown,
+
+	.urb_enqueue =		ehci_urb_enqueue,
+	.urb_dequeue =		ehci_urb_dequeue,
+	.endpoint_disable =     ehci_endpoint_disable,
+
+	.get_frame_number =     ehci_get_frame,
+
+	.hub_status_data =      ehci_hub_status_data,
+	.hub_control =		ehci_hub_control,
+	.relinquish_port =      ehci_relinquish_port,
+	.port_handed_over =     ehci_port_handed_over,
+};
+
+static int __devinit ehci_hcd_tango2_drv_probe(struct platform_device *pdev)
+{
+	struct ehci_hcd *ehci;
+	struct usb_hcd *hcd;
+	int ret;
+
+	tango2_reset_usb();
+
+	hcd = usb_create_hcd(&ehci_tango2_hc_driver,
+			     &pdev->dev, "TANGO2 EHCI");
+	if (!hcd)
+		return -ENOMEM;
+
+	hcd->rsrc_start = TANGO2_EHCI_BASE_ADDR;
+	hcd->rsrc_len = hcd->rsrc_start + 0xff;
+	hcd->regs = (void *)KSEG1ADDR(TANGO2_EHCI_BASE_ADDR);
+
+	ehci = hcd_to_ehci(hcd);
+	ehci->caps = hcd->regs;
+	ehci->regs = hcd->regs +
+		HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+	ehci->sbrn = 0x20;
+
+	ret = usb_add_hcd(hcd, TANGO2_EHCI_IRQ, IRQF_DISABLED);
+	if (ret)
+		goto out;
+	return 0;
+
+out:
+	usb_put_hcd(hcd);
+	return ret;
+}
+
+static int __devexit ehci_hcd_tango2_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd;
+
+	hcd = platform_get_drvdata(pdev);
+	usb_remove_hcd(hcd);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static struct platform_driver ehci_hcd_tango2_driver = {
+	.probe		= ehci_hcd_tango2_drv_probe,
+	.remove		= __devexit_p(ehci_hcd_tango2_drv_remove),
+	.shutdown	= usb_hcd_platform_shutdown,
+	.driver		= {
+		.name	= "tango2_ehci",
+		.owner	= THIS_MODULE,
+		.bus	= &platform_bus_type
+	},
+};
+
+MODULE_ALIAS("platform:tango2_ehci");
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/drivers/usb/host/ohci-tango2.c	2010-03-18 18:28:51.312919135 +0100
@@ -0,0 +1,98 @@
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-tango2/tango2_board.h>
+#include <asm/mach-tango2/tango2_usb.h>
+
+static int __devinit tango2_ohci_start(struct usb_hcd *hcd)
+{
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	int ret;
+
+	if ((ret = ohci_init(ohci)) < 0)
+		return ret;
+
+	if ((ret = ohci_run(ohci)) < 0) {
+		err("can't start %s", ohci_to_hcd(ohci)->self.bus_name);
+		ohci_stop(hcd);
+		return ret;
+	}
+	return 0;
+}
+
+static const struct hc_driver ohci_tango2_hc_driver = {
+	.description =		hcd_name,
+	.product_desc =		"SMP83xx integrated OHCI controller",
+	.hcd_priv_size =	sizeof(struct ohci_hcd),
+
+	.irq =			ohci_irq,
+	.flags =		HCD_USB11 | HCD_MEMORY,
+	.start =		tango2_ohci_start,
+	.stop =			ohci_stop,
+	.shutdown =		ohci_shutdown,
+	.urb_enqueue =		ohci_urb_enqueue,
+	.urb_dequeue =		ohci_urb_dequeue,
+	.endpoint_disable =     ohci_endpoint_disable,
+	.get_frame_number =     ohci_get_frame,
+	.hub_status_data =      ohci_hub_status_data,
+	.hub_control =		ohci_hub_control,
+	.start_port_reset =     ohci_start_port_reset,
+};
+
+static int __devinit ohci_hcd_tango2_drv_probe(struct platform_device *pdev)
+{
+	struct ohci_hcd *ohci;
+	struct usb_hcd *hcd;
+	int ret;
+
+	tango2_reset_usb();
+
+	hcd = usb_create_hcd(&ohci_tango2_hc_driver,
+			     &pdev->dev, "TANGO2 OHCI");
+	if (!hcd)
+		return -ENOMEM;
+
+	hcd->rsrc_start = TANGO2_OHCI_BASE_ADDR;
+	hcd->rsrc_len = hcd->rsrc_start + 0xff;
+	hcd->regs = (void *)KSEG1ADDR(TANGO2_OHCI_BASE_ADDR);
+	ohci = hcd_to_ohci(hcd);
+	ohci_hcd_init(ohci);
+
+	ret = usb_add_hcd(hcd, TANGO2_OHCI_IRQ, IRQF_DISABLED);
+	if (ret)
+		goto out;
+
+	init_timer(&ohci_timer);
+	ohci_timer.function = ohci_polling;
+	ohci_timer.data = (unsigned long)hcd;
+	mod_timer(&ohci_timer, jiffies + polling_interval);
+	return 0;
+
+out:
+	usb_put_hcd(hcd);
+	return ret;
+}
+
+static int __devexit ohci_hcd_tango2_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd;
+
+	hcd = platform_get_drvdata(pdev);
+	del_timer_sync(&ohci_timer);
+	usb_remove_hcd(hcd);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static struct platform_driver ohci_hcd_tango2_driver = {
+	.probe		= ohci_hcd_tango2_drv_probe,
+	.remove		= __devexit_p(ohci_hcd_tango2_drv_remove),
+	.shutdown	= usb_hcd_platform_shutdown,
+	.driver		= {
+		.name	= "tango2_ohci",
+		.owner	= THIS_MODULE,
+		.bus	= &platform_bus_type
+	},
+};
+
+MODULE_ALIAS("platform:tango2_ohci");
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/fs/ramfs/xattr.c	2010-03-18 18:28:52.302922419 +0100
@@ -0,0 +1,194 @@
+/*
+ * xattr.c for ramfs
+ * Created by <nschichan@freebox.fr> on Wed Aug  8 11:57:18 2007
+ * Freebox SA
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/xattr.h>
+
+#include "internal.h"
+
+void ramfs_inode_purge_xattrs(struct ramfs_inode_info *rii)
+{
+	(void)rii;
+#ifdef CONFIG_RAMFS_XATTR_USER
+	while (!list_empty(&rii->xattr_user_list)) {
+		struct list_head *head;
+		struct ramfs_xattr *elem;
+
+
+		head = rii->xattr_user_list.next;
+		elem = list_entry(head, struct ramfs_xattr, list);
+		list_del(head);
+		kfree(elem->data);
+		kfree(elem->name);
+		kfree(elem);
+	}
+#endif
+
+}
+
+#ifdef CONFIG_RAMFS_XATTR_USER
+static size_t ramfs_xattr_user_list(struct inode *inode, char *list,
+				    size_t list_size,
+				    const char *name, size_t namelen)
+{
+	struct ramfs_inode_info *rii;
+	struct list_head *it;
+	int ret;
+	char *ptr;
+	char *end;
+
+	ret = 0;
+	ptr = list;
+	end = list + list_size;
+	rii = RAMFS_I(inode);
+
+	list_for_each(it, &rii->xattr_user_list) {
+		struct ramfs_xattr *elem;
+		int name_len;
+
+		elem = list_entry(it, struct ramfs_xattr, list);
+		name_len = strlen(elem->name);
+
+		if (ptr + name_len + 1 + XATTR_USER_PREFIX_LEN >= end)
+			break;
+
+		/* copy prefix in buffer */
+		memcpy(ptr, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
+		ptr += XATTR_USER_PREFIX_LEN;
+		ret += XATTR_USER_PREFIX_LEN;
+
+		/* copy attribute name in buffer */
+		memcpy(ptr, elem->name, name_len + 1);
+		ptr += name_len + 1;
+		ret += name_len + 1;
+	}
+
+	return ret;
+}
+
+static struct ramfs_xattr *ramfs_xattr_find(struct ramfs_inode_info *rii,
+					    const char *name)
+{
+	struct list_head *it;
+
+	list_for_each(it, &rii->xattr_user_list) {
+		struct ramfs_xattr *elem;
+
+		elem = list_entry(it, struct ramfs_xattr, list);
+		if (!strcmp(elem->name, name))
+			return elem;
+	}
+	return NULL;
+}
+
+static int ramfs_xattr_user_remove(struct inode *inode, const char *name)
+{
+	struct ramfs_inode_info *rii;
+	struct ramfs_xattr *elem;
+
+	rii = RAMFS_I(inode);
+	elem = ramfs_xattr_find(rii, name);
+	if (!elem)
+		return -ENODATA;
+
+	list_del(&elem->list);
+	kfree(elem->data);
+	kfree(elem->name);
+	kfree(elem);
+
+	return 0;
+}
+
+static int ramfs_xattr_user_set(struct inode *inode, const char *name,
+				const void *buffer, size_t size, int flags)
+{
+	int error;
+	struct ramfs_xattr *elem;
+	struct ramfs_inode_info *rii;
+	int new_elem;
+
+	if (buffer == NULL && size == 0)
+		return ramfs_xattr_user_remove(inode, name);
+
+	rii = RAMFS_I(inode);
+	elem = ramfs_xattr_find(rii, name);
+	if (elem) {
+		new_elem = 0;
+		if (flags & XATTR_CREATE)
+			return -EEXIST;
+		kfree(elem->data);
+		elem->data = NULL;
+	} else {
+		new_elem = 1;
+		if (flags & XATTR_REPLACE)
+			return -ENODATA;
+		elem = kzalloc(sizeof (*elem), GFP_KERNEL);
+		if (!elem)
+			return -ENOMEM;
+		elem->name = kstrdup(name, GFP_KERNEL);
+		if (!elem->name) {
+			kfree(elem);
+			return -ENOMEM;
+		}
+	}
+
+	elem->data = kmalloc(size, GFP_KERNEL);
+	if (!elem->data) {
+		error = -ENOMEM;
+		goto out_free_new_elem;
+	}
+	memcpy(elem->data, buffer, size);
+	elem->data_len = size;
+
+	if (new_elem)
+		list_add(&elem->list, &rii->xattr_user_list);
+
+	return 0;
+
+ out_free_new_elem:
+	if (elem && new_elem) {
+		if (elem->name)
+			kfree(elem->name);
+		kfree(elem);
+	}
+	return error;
+}
+
+static int ramfs_xattr_user_get(struct inode *inode, const char *name,
+				void *buffer, size_t size)
+{
+	struct ramfs_xattr *elem;
+	struct ramfs_inode_info *rii;
+	int copylen;
+
+	rii = RAMFS_I(inode);
+	elem = ramfs_xattr_find(rii, name);
+	if (elem == NULL)
+		return -ENODATA;
+	copylen = elem->data_len;
+
+	if (size < copylen)
+		copylen = size;
+	memcpy(buffer, elem->data, copylen);
+	return copylen;
+}
+
+static struct xattr_handler ramfs_user_handler = {
+	.prefix = XATTR_USER_PREFIX,
+	.list	= ramfs_xattr_user_list,
+	.get	= ramfs_xattr_user_get,
+	.set	= ramfs_xattr_user_set,
+};
+#endif
+
+struct xattr_handler *ramfs_xattr_handlers[] = {
+#ifdef CONFIG_RAMFS_XATTR_USER
+	&ramfs_user_handler,
+#endif
+	NULL,
+};
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/include/linux/fbxatm.h	2010-10-25 13:43:58.201451680 +0200
@@ -0,0 +1,202 @@
+/*
+ * Generic fbxatm definition, exported to userspace
+ */
+#ifndef LINUX_FBXATM_H_
+#define LINUX_FBXATM_H_
+
+#include <linux/types.h>
+#include <linux/if.h>
+
+#define FBXATM_IOCTL_MAGIC		0xd3
+
+/* allow userspace usage without up to date kernel headers */
+#ifndef PF_FBXATM
+#define PF_FBXATM			32
+#define AF_FBXATM			PF_FBXATM
+#endif
+
+struct fbxatm_vcc_id {
+	int				dev_idx;
+	__u32				vpi;
+	__u32				vci;
+};
+
+enum fbxatm_vcc_user {
+	FBXATM_VCC_USER_NONE = 0,
+	FBXATM_VCC_USER_2684,
+	FBXATM_VCC_USER_2684_RETX,
+	FBXATM_VCC_USER_PPPOA,
+};
+
+enum fbxatm_vcc_traffic_class {
+	FBXATM_VCC_TC_UBR_NO_PCR = 0,
+	FBXATM_VCC_TC_UBR,
+};
+
+#define FBXATM_VCC_MAX_PRIO		7
+
+struct fbxatm_vcc_qos {
+	__u32				traffic_class;
+	__u32				max_sdu;
+	__u32				max_buffered_pkt;
+	__u32				priority;
+};
+
+
+/*
+ * VCC related
+ */
+struct fbxatm_vcc_params {
+	/* ADD/DEL/GET */
+	struct fbxatm_vcc_id		id;
+
+	/* ADD/GET */
+	struct fbxatm_vcc_qos		qos;
+
+	/* GET */
+	enum fbxatm_vcc_user		user;
+};
+
+#define FBXATM_IOCADD		_IOW(FBXATM_IOCTL_MAGIC,	1,	\
+					struct fbxatm_vcc_params)
+
+#define FBXATM_IOCDEL		_IOR(FBXATM_IOCTL_MAGIC,	2,	\
+					struct fbxatm_vcc_params)
+
+#define FBXATM_IOCGET		_IOWR(FBXATM_IOCTL_MAGIC,	3,	\
+					struct fbxatm_vcc_params)
+
+
+struct fbxatm_vcc_drop_params {
+	struct fbxatm_vcc_id		id;
+	unsigned int			drop_count;
+};
+
+#define FBXATM_IOCDROP		_IOWR(FBXATM_IOCTL_MAGIC,	5,	\
+					struct fbxatm_vcc_drop_params)
+
+/*
+ * OAM related
+ */
+enum fbxatm_oam_ping_type {
+	FBXATM_OAM_PING_SEG_F4	= 0,
+	FBXATM_OAM_PING_SEG_F5,
+	FBXATM_OAM_PING_E2E_F4,
+	FBXATM_OAM_PING_E2E_F5,
+};
+
+struct fbxatm_oam_ping_req {
+	/* only dev_idx for F4 */
+	struct fbxatm_vcc_id		id;
+
+	__u8				llid[16];
+	enum fbxatm_oam_ping_type	type;
+};
+
+#define FBXATM_IOCOAMPING	_IOWR(FBXATM_IOCTL_MAGIC,	10,	\
+				      struct fbxatm_oam_ping_req)
+
+
+/*
+ * PPPOA related
+ */
+enum fbxatm_pppoa_encap {
+	FBXATM_EPPPOA_AUTODETECT = 0,
+	FBXATM_EPPPOA_VCMUX,
+	FBXATM_EPPPOA_LLC,
+};
+
+struct fbxatm_pppoa_vcc_params {
+	struct fbxatm_vcc_id		id;
+	__u32				encap;
+	__u32				cur_encap;
+};
+
+#define FBXATM_PPPOA_IOCADD	_IOW(FBXATM_IOCTL_MAGIC,	20,	\
+					struct fbxatm_pppoa_vcc_params)
+
+#define FBXATM_PPPOA_IOCDEL	_IOW(FBXATM_IOCTL_MAGIC,	21,	\
+					struct fbxatm_pppoa_vcc_params)
+
+#define FBXATM_PPPOA_IOCGET	_IOWR(FBXATM_IOCTL_MAGIC,	22,	\
+					struct fbxatm_pppoa_vcc_params)
+
+
+
+/*
+ * 2684 related
+ */
+enum fbxatm_2684_encap {
+	FBXATM_E2684_VCMUX = 0,
+	FBXATM_E2684_LLC,
+};
+
+enum fbxatm_2684_payload {
+	FBXATM_P2684_BRIDGE = 0,
+	FBXATM_P2684_ROUTED,
+};
+
+struct fbxatm_2684_vcc_params {
+	struct fbxatm_vcc_id		id;
+
+	__u32				encap;
+	__u32				payload;
+	char				dev_name[IFNAMSIZ];
+};
+
+
+#define FBXATM_2684_IOCADD	_IOW(FBXATM_IOCTL_MAGIC,	30,	\
+					struct fbxatm_2684_vcc_params)
+
+#define FBXATM_2684_IOCDEL	_IOW(FBXATM_IOCTL_MAGIC,	31,	\
+					struct fbxatm_2684_vcc_params)
+
+#define FBXATM_2684_IOCGET	_IOWR(FBXATM_IOCTL_MAGIC,	32,	\
+					struct fbxatm_2684_vcc_params)
+
+#define MAX_RETX_PORT			8
+
+struct fbxatm_2684_gretx_params {
+	int				enable;
+
+	struct fbxatm_vcc_id		retx_ports_vcc_id[MAX_RETX_PORT];
+	unsigned int			retx_ports_id[MAX_RETX_PORT];
+	unsigned int			retx_port_count;
+
+	__u32				retx_daddr;
+	__u32				retx_saddr;
+	struct fbxatm_vcc_id		retx_tx_vcc_id;
+	struct fbxatm_vcc_id		retx_ack_vcc_id;
+	__u32				rtt_daddr;
+	__u32				rtt_saddr;
+	struct fbxatm_vcc_id		rtt_tx_vcc_id;
+	struct fbxatm_vcc_id		rtt_ack_vcc_id;
+};
+
+#define FBXATM_2684_IOCSET_GRETX	_IOR(FBXATM_IOCTL_MAGIC, 33,	\
+					struct fbxatm_2684_gretx_params)
+
+#define FBXATM_2684_IOCGET_GRETX	_IOWR(FBXATM_IOCTL_MAGIC, 34,	\
+					struct fbxatm_2684_retx_params)
+
+enum fbxatm_2684_retx_action {
+	FBXATM_2684_RETX_IGNORE = 0,
+	FBXATM_2684_RETX_HANDLE,
+};
+
+struct fbxatm_2684_retx_params {
+	int				enable;
+
+	struct fbxatm_vcc_id		id;
+	__u32				action;
+	__u32				stream_id;
+};
+
+
+#define FBXATM_2684_IOCSET_RETX	_IOR(FBXATM_IOCTL_MAGIC,	35,	\
+					struct fbxatm_2684_retx_params)
+
+#define FBXATM_2684_IOCGET_RETX	_IOWR(FBXATM_IOCTL_MAGIC,	36,	\
+					struct fbxatm_2684_retx_params)
+
+#endif /* LINUX_FBXATM_H_ */
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/include/linux/fbxgpio_core.h	2010-03-18 18:28:52.402910015 +0100
@@ -0,0 +1,39 @@
+/*
+ * fbxgpio.h for linux-freebox
+ * Created by <nschichan@freebox.fr> on Wed Feb 21 22:09:46 2007
+ * Freebox SA
+ */
+
+#ifndef FBXGPIO_H
+# define FBXGPIO_H
+
+# include <linux/types.h>
+
+/* can change pin direction */
+#define FBXGPIO_PIN_DIR_RW	(1 << 0)
+#define FBXGPIO_PIN_REVERSE_POL	(1 << 1)
+
+struct fbxgpio_operations {
+	int  (*get_datain)(int gpio);
+	void (*set_dataout)(int gpio, int val);
+	int  (*get_dataout)(int gpio);
+	void (*set_direction)(int gpio, int dir);
+	int  (*get_direction)(int gpio);
+};
+
+
+struct fbxgpio_pin {
+	const struct fbxgpio_operations	*ops;
+	const char			*pin_name;
+	uint32_t			flags;
+	int				direction;
+	int				pin_num;
+	unsigned int			cur_dataout;
+	struct device			*dev;
+};
+
+
+#define GPIO_DIR_IN	0x1
+#define GPIO_DIR_OUT	0x0
+
+#endif /* !FBXGPIO_H */
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/include/linux/fbxmtd.h	2010-03-18 18:28:52.402910015 +0100
@@ -0,0 +1,208 @@
+
+#ifndef FBXMTD_H_
+# define FBXMTD_H_
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#endif
+
+#define FBXMTD_MAX_DEVICES	2
+
+/* hide all hot stuff from userland */
+#ifdef __KERNEL__
+
+struct fbxmtd_dev;
+
+/*
+ * fbxmtd partition
+ */
+struct fbxmtd_part {
+	char			*name;
+	uint32_t		offset;
+	uint32_t		size;
+	int			idx;
+	int			rw;
+
+	struct fbxmtd_dev	*dev;
+};
+
+/*
+ * fbxmtd flash sector information
+ */
+struct fbxmtd_region {
+	uint32_t		offset;
+	uint32_t		size;
+	uint32_t		count;
+};
+
+/*
+ * fbxmtd device mapping
+ */
+struct fbxmtd_dev_map {
+	/* base physical address of mtd device */
+	dma_addr_t		base_phys;
+
+	/* flash bus width (1: 8bits, 2: 16buts, 4: 32bits) */
+	unsigned int		flash_width;
+
+	/* remapped address */
+	uint8_t			*base;
+};
+
+/*
+ * fbxmtd device
+ */
+#define FBXMTD_MAX_PART		16
+
+struct fbxmtd_dev
+{
+	char			*name;
+	struct mutex		sem;
+	int			dead;
+	atomic_t		refcount;
+	int			idx;
+
+	struct fbxmtd_dev_map	map;
+
+	struct fbxmtd_part	parts[FBXMTD_MAX_PART];
+	unsigned int		part_count;
+
+
+	/* the following callback are set by chip backend */
+	int			(*erase)(struct fbxmtd_dev *dev,
+					 uint32_t offset);
+
+	int			(*chip_erase)(struct fbxmtd_dev *dev);
+
+	int			(*program)(struct fbxmtd_dev *dev,
+					   uint32_t offset, const uint8_t *buf,
+					   size_t count);
+
+	struct fbxmtd_region	*(*get_region_info)(struct fbxmtd_dev *dev);
+
+	uint32_t		(*get_size)(struct fbxmtd_dev *dev);
+
+	void			*priv_data;
+};
+
+/*
+ * notifier for partition add/dead
+ */
+#define FBXMTD_EVENT_ADD	(1 << 0)
+#define FBXMTD_EVENT_DEAD	(1 << 1)
+
+int fbxmtd_register_notifier(void (*cb)(void *, struct fbxmtd_part *,
+					uint32_t),
+			     void *cb_data, uint32_t mask);
+
+void fbxmtd_unregister_notifier(void (*cb)(void *, struct fbxmtd_part *,
+					   uint32_t));
+
+
+/*
+ * core functions
+ */
+struct fbxmtd_part *fbxmtd_get_part(unsigned int dev_idx,
+				    unsigned int part_idx);
+
+struct fbxmtd_part *fbxmtd_get_part_by_name(unsigned int dev_idx,
+					    const char *part_name);
+
+void fbxmtd_put_part(struct fbxmtd_part *part);
+
+void fbxmtd_put_device(struct fbxmtd_dev *dev);
+
+int fbxmtd_read_part(struct fbxmtd_part *part, uint32_t offset, char *buffer,
+		     unsigned int count, int can_sleep);
+
+int fbxmtd_read_dev(struct fbxmtd_dev *dev, uint32_t offset, char *buffer,
+		    unsigned int count);
+
+int fbxmtd_find_sector_boundary(struct fbxmtd_dev *dev,
+				uint32_t offset, uint32_t *boundary);
+
+int fbxmtd_find_next_sector_boundary(struct fbxmtd_dev *dev,
+				     uint32_t offset, uint32_t *boundary);
+
+int fbxmtd_write_part(struct fbxmtd_part *part, uint32_t offset, char *buffer,
+		      unsigned int count);
+
+int fbxmtd_set_partitions(struct fbxmtd_dev *dev, struct fbxmtd_part *parts,
+			  unsigned int count);
+
+struct fbxmtd_dev *fbxmtd_probe(const char *name, dma_addr_t base,
+				unsigned int flash_width);
+
+void fbxmtd_mark_dead_dev(struct fbxmtd_dev *dev);
+
+int fbxmtd_foreach_part(int (cb)(void *, struct fbxmtd_part *),
+			void *cb_data);
+
+int fbxmtd_foreach_dev(int (cb)(void *, struct fbxmtd_dev *),
+		       void *cb_data);
+
+/*
+ * generic map driver data
+ */
+struct fbxmtd_platform_data
+{
+	const char *			name;
+	int				status;
+	dma_addr_t			base;
+	uint32_t			width;
+	uint32_t			size; /* filled by map driver */
+	struct fbxmtd_platform_part	*parts;
+	uint32_t			num_parts;
+	struct fbxmtd_dev		*core_dev;
+};
+
+struct fbxmtd_platform_part
+{
+	char		*name;
+	char		*align_part;
+	uint32_t	offset;
+	uint32_t	roffset;
+	uint32_t	size;
+	uint32_t	flags;
+};
+
+/*
+ * bcm963xx map driver data
+ */
+struct fbxmtd_bcm963xx_platform_data {
+	char				*name;
+	dma_addr_t			base;
+	unsigned int			width;
+	unsigned int			psi_size;
+	u8				*boot_addr;
+	int				all_rw;
+};
+
+#endif /* __KERNEL__ */
+
+enum {
+	E_FBXMTD_NOT_PROBED,
+	E_FBXMTD_PROBED,
+	E_FBXMTD_FAULTY,
+};
+
+/* try to read image tag and set the _fs related partition */
+#define FBXMTD_PART_HAS_FS	(1 << 0)
+/* Read/Write partition */
+#define FBXMTD_PART_RW		(1 << 1)
+/* check CRC of image tag. */
+#define FBXMTD_PART_CHECK_CRC	(1 << 2)
+/*
+ * only for first partition: means that the size of the partition is
+ * the size of the flash
+ */
+#define FBXMTD_PART_MAP_ALL	(1 << 3)
+/* Adjust size automatically with the next partition */
+#define FBXMTD_PART_AUTOSIZE	(1 << 4)
+#define FBXMTD_PART_IGNORE_TAG	(1 << 5)
+#define FBXMTD_PART_SKIP_KERNEL	(1 << 6)
+
+
+#endif /* !FBXMTD_H_ */
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/include/linux/fbxmtd_map_ioctl.h	2010-03-18 18:28:52.402910015 +0100
@@ -0,0 +1,52 @@
+/*
+ * fbxmtd_map_ioctl.h for linux-freebox
+ * Created by <nschichan@freebox.fr> on Thu Feb  8 20:37:28 2007
+ * Freebox SA
+ */
+
+#ifndef FBXMTD_MAP_IOCTL_H
+# define FBXMTD_MAP_IOCTL_H
+
+/*
+ * IOCTL interface
+ */
+#define FBXMTD_MINOR	242
+
+#define FBXMTD_MAP_IOCTL_MAX_DEV	2
+#define FBXMTD_MAP_IOCTL_MAX_PART	16
+
+struct fbxmtd_map_ioctl_part
+{
+	char		name[32];
+	uint32_t	offset;
+	uint32_t	size;
+	uint32_t	flags;
+};
+
+struct fbxmtd_map_ioctl_dev
+{
+	char				name[32];
+	uint32_t			base_phys;
+	int				bus_width;
+	uint32_t			size;
+	uint32_t			status;
+	struct fbxmtd_map_ioctl_part	parts[FBXMTD_MAP_IOCTL_MAX_PART];
+	int				num_parts;
+};
+
+#define FBXMTD_MAP_IOCTL_NR	0x42
+
+struct fbxmtd_map_ioctl_query
+{
+	uint32_t	cmd;
+	uint32_t	param;
+	int		result;
+	void __user	*user_buf;
+	uint32_t	user_buf_size;
+};
+
+#define FBXMTDCTL_CMD_GET_DEVICES	0x1
+#define FBXMTDCTL_CMD_ADD_DEVICE	0x2
+#define FBXMTDCTL_CMD_DEL_DEVICE	0x3
+
+#endif /* !FBXMTD_MAP_IOCTL_H */
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/include/linux/fbxprocfs.h	2010-03-18 18:28:52.402910015 +0100
@@ -0,0 +1,45 @@
+#ifndef FBXPROCFS_H_
+#define FBXPROCFS_H_
+
+#include <linux/proc_fs.h>
+#include <asm/atomic.h>
+
+struct fbxprocfs_client
+{
+	const char *dirname;
+	struct module *owner;
+	struct proc_dir_entry *dir;
+	atomic_t refcount;
+	struct list_head list;
+};
+
+struct fbxprocfs_ro_desc {
+	char		*name;
+	unsigned long	id;
+	int	(*rfunc)(char *, char **, off_t, int, int *, void *);
+};
+
+struct fbxprocfs_rw_desc {
+	char		*name;
+	unsigned long	id;
+	int	(*rfunc)(char *, char **, off_t, int, int *, void *);
+	int	(*wfunc)(struct file *, const char *, unsigned long, void *);
+};
+
+struct fbxprocfs_client *fbxprocfs_add_client(const char *dirname,
+					      struct module *owner);
+
+int fbxprocfs_remove_client(struct fbxprocfs_client *client);
+
+
+int
+fbxprocfs_create_entries(struct fbxprocfs_client *client,
+			 const struct fbxprocfs_ro_desc *ro_desc,
+			 const struct fbxprocfs_rw_desc *rw_desc);
+
+int
+fbxprocfs_remove_entries(struct fbxprocfs_client *client,
+			 const struct fbxprocfs_ro_desc *ro_desc,
+			 const struct fbxprocfs_rw_desc *rw_desc);
+
+#endif /* FBXPROCFS_H_ */
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/include/linux/fbxserial.h	2011-05-23 16:08:41.773678768 +0200
@@ -0,0 +1,122 @@
+#ifndef FBXSERIAL_H_
+#define FBXSERIAL_H_
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+/*
+ * some part of serial may vary, we use abstract struct to store this,
+ * data content depends on type.
+ */
+#define EXTINFO_SIZE		128
+#define EXTINFO_MAX_COUNT	16
+
+/*
+ * extdev desc
+ */
+#define EXTINFO_TYPE_EXTDEV	1
+
+#define EXTDEV_TYPE_BUNDLE	1
+#define EXTDEV_TYPE_MAX		2
+
+struct fbx_serial_extinfo {
+	u32			type;
+
+	union {
+		/* extdev */
+		struct {
+			u32	type;
+			u32	model;
+			char	serial[64];
+		} extdev;
+
+		/* raw access */
+		unsigned char	data[EXTINFO_SIZE];
+	} u;
+}  __attribute__ ((packed));;
+
+
+/*
+ * master serial structure
+ */
+
+#define FBXSERIAL_VERSION	1
+
+#define FBXSERIAL_MAGIC		0x2d9521ab
+
+#define MAC_ADDR_SIZE		6
+#define RANDOM_DATA_SIZE	32
+
+/*
+ * this  is the  maximum size  we accept  to check  crc32  against, so
+ * structure may no grow larger than this
+ */
+#define FBXSERIAL_MAX_SIZE	8192
+
+struct fbx_serial {
+	u32	crc32;
+	u32	magic;
+	u32	struct_version;
+	u32	len;
+
+	/* board serial */
+	u16	type;
+	u8	version;
+	u8	manufacturer;
+	u16	year;
+	u8	week;
+	u32	number;
+	u32	flags;
+
+	/* mac address base */
+	u8	mac_addr_base[MAC_ADDR_SIZE];
+
+	/* mac address count */
+	u8	mac_count;
+
+	/* random data */
+	u8	random_data[RANDOM_DATA_SIZE];
+
+	/* last update of data (seconds since epoch) */
+	u32	last_modified;
+
+	/* count of following extinfo tag */
+	u32	extinfo_count;
+
+	/* beginning of extended info */
+	struct fbx_serial_extinfo	extinfos[EXTINFO_MAX_COUNT];
+
+} __attribute__ ((packed));
+
+
+/*
+ * default value to use in case magic is wrong (no cksum in that case)
+ */
+static inline void fbxserial_set_default(struct fbx_serial *s)
+{
+	memset(s, 0, sizeof (*s));
+	s->magic = FBXSERIAL_MAGIC;
+	s->struct_version = FBXSERIAL_VERSION;
+	s->len = sizeof (*s);
+	s->manufacturer = '_';
+	memcpy(s->mac_addr_base, "\x00\x07\xCB\x00\x00\xFD", 6);
+	s->mac_count = 1;
+}
+
+void
+fbxserialinfo_get_random(unsigned char *data, unsigned int len);
+
+void
+fbxserialinfo_get_mac_addr(unsigned char *data);
+
+int
+fbxserialinfo_read(void *data, struct fbx_serial *out);
+
+struct fbx_serial *fbxserialinfo_get(void);
+
+/*
+ * implemented in board specific code
+ */
+const struct fbx_serial *arch_get_fbxserial(void);
+
+#endif /* FBXSERIAL_H_ */
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/include/linux/LzmaDec.h	2010-03-18 18:28:52.382909970 +0100
@@ -0,0 +1,228 @@
+/* LzmaDec.h -- LZMA Decoder
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZMADEC_H
+#define __LZMADEC_H
+
+#include "LzmaTypes.h"
+
+/* #define _LZMA_PROB32 */
+/* _LZMA_PROB32 can increase the speed on some CPUs,
+   but memory usage for CLzmaDec::probs will be doubled in that case */
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+
+/* ---------- LZMA Properties ---------- */
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaProps
+{
+  unsigned lc, lp, pb;
+  UInt32 dicSize;
+} CLzmaProps;
+
+/* LzmaProps_Decode - decodes properties
+Returns:
+  SZ_OK
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
+
+
+/* ---------- LZMA Decoder state ---------- */
+
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
+   Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
+
+#define LZMA_REQUIRED_INPUT_MAX 20
+
+typedef struct
+{
+  CLzmaProps prop;
+  CLzmaProb *probs;
+  Byte *dic;
+  const Byte *buf;
+  UInt32 range, code;
+  SizeT dicPos;
+  SizeT dicBufSize;
+  UInt32 processedPos;
+  UInt32 checkDicSize;
+  unsigned state;
+  UInt32 reps[4];
+  unsigned remainLen;
+  int needFlush;
+  int needInitState;
+  UInt32 numProbs;
+  unsigned tempBufSize;
+  Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
+} CLzmaDec;
+
+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
+
+void LzmaDec_Init(CLzmaDec *p);
+
+/* There are two types of LZMA streams:
+     0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
+     1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
+
+typedef enum
+{
+  LZMA_FINISH_ANY,   /* finish at any point */
+  LZMA_FINISH_END    /* block must be finished at the end */
+} ELzmaFinishMode;
+
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
+
+   You must use LZMA_FINISH_END, when you know that current output buffer
+   covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
+
+   If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
+   and output value of destLen will be less than output buffer size limit.
+   You can check status result also.
+
+   You can use multiple checks to test data integrity after full decompression:
+     1) Check Result and "status" variable.
+     2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
+     3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
+        You must use correct finish mode in that case. */
+
+typedef enum
+{
+  LZMA_STATUS_NOT_SPECIFIED,               /* use main error code instead */
+  LZMA_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */
+  LZMA_STATUS_NOT_FINISHED,                /* stream was not finished */
+  LZMA_STATUS_NEEDS_MORE_INPUT,            /* you must provide more input bytes */
+  LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK  /* there is probability that stream was finished without end mark */
+} ELzmaStatus;
+
+/* ELzmaStatus is used only as output value for function call */
+
+
+/* ---------- Interfaces ---------- */
+
+/* There are 3 levels of interfaces:
+     1) Dictionary Interface
+     2) Buffer Interface
+     3) One Call Interface
+   You can select any of these interfaces, but don't mix functions from different
+   groups for same object. */
+
+
+/* There are two variants to allocate state for Dictionary Interface:
+     1) LzmaDec_Allocate / LzmaDec_Free
+     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
+   You can use variant 2, if you set dictionary buffer manually.
+   For Buffer Interface you must always use variant 1.
+
+LzmaDec_Allocate* can return:
+  SZ_OK
+  SZ_ERROR_MEM         - Memory allocation error
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+   
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
+
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
+
+/* ---------- Dictionary Interface ---------- */
+
+/* You can use it, if you want to eliminate the overhead for data copying from
+   dictionary to some other external buffer.
+   You must work with CLzmaDec variables directly in this interface.
+
+   STEPS:
+     LzmaDec_Constr()
+     LzmaDec_Allocate()
+     for (each new stream)
+     {
+       LzmaDec_Init()
+       while (it needs more decompression)
+       {
+         LzmaDec_DecodeToDic()
+         use data from CLzmaDec::dic and update CLzmaDec::dicPos
+       }
+     }
+     LzmaDec_Free()
+*/
+
+/* LzmaDec_DecodeToDic
+   
+   The decoding to internal dictionary buffer (CLzmaDec::dic).
+   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (dicLimit).
+  LZMA_FINISH_ANY - Decode just dicLimit bytes.
+  LZMA_FINISH_END - Stream must be finished after dicLimit.
+
+Returns:
+  SZ_OK
+    status:
+      LZMA_STATUS_FINISHED_WITH_MARK
+      LZMA_STATUS_NOT_FINISHED
+      LZMA_STATUS_NEEDS_MORE_INPUT
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+  SZ_ERROR_DATA - Data error
+*/
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- Buffer Interface ---------- */
+
+/* It's zlib-like interface.
+   See LzmaDec_DecodeToDic description for information about STEPS and return results,
+   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
+   to work with CLzmaDec variables manually.
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (*destLen).
+  LZMA_FINISH_ANY - Decode just destLen bytes.
+  LZMA_FINISH_END - Stream must be finished after (*destLen).
+*/
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaDecode
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (*destLen).
+  LZMA_FINISH_ANY - Decode just destLen bytes.
+  LZMA_FINISH_END - Stream must be finished after (*destLen).
+
+Returns:
+  SZ_OK
+    status:
+      LZMA_STATUS_FINISHED_WITH_MARK
+      LZMA_STATUS_NOT_FINISHED
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+  SZ_ERROR_DATA - Data error
+  SZ_ERROR_MEM  - Memory allocation error
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+*/
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+    ELzmaStatus *status, ISzAlloc *alloc);
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
+#endif
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/include/linux/LzmaTypes.h	2010-03-18 18:28:52.382909970 +0100
@@ -0,0 +1,209 @@
+/* Types.h -- Basic types
+2008-11-23 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_TYPES_H
+#define __7Z_TYPES_H
+
+#include <stddef.h>
+#include <linux/zconf.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#define SZ_OK 0
+
+#define SZ_ERROR_DATA 1
+#define SZ_ERROR_MEM 2
+#define SZ_ERROR_CRC 3
+#define SZ_ERROR_UNSUPPORTED 4
+#define SZ_ERROR_PARAM 5
+#define SZ_ERROR_INPUT_EOF 6
+#define SZ_ERROR_OUTPUT_EOF 7
+#define SZ_ERROR_READ 8
+#define SZ_ERROR_WRITE 9
+#define SZ_ERROR_PROGRESS 10
+#define SZ_ERROR_FAIL 11
+#define SZ_ERROR_THREAD 12
+
+#define SZ_ERROR_ARCHIVE 16
+#define SZ_ERROR_NO_ARCHIVE 17
+
+typedef int SRes;
+
+#ifdef _WIN32
+typedef DWORD WRes;
+#else
+typedef int WRes;
+#endif
+
+#ifndef RINOK
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
+#endif
+
+//typedef unsigned char Byte;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef long Int32;
+typedef unsigned long UInt32;
+#else
+typedef int Int32;
+typedef unsigned int UInt32;
+#endif
+
+#ifdef _SZ_NO_INT_64
+
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
+   NOTES: Some code will work incorrectly in that case! */
+
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#endif
+
+#endif
+
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+typedef size_t SizeT;
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+
+#ifdef _MSC_VER
+
+#if _MSC_VER >= 1300
+#define MY_NO_INLINE __declspec(noinline)
+#else
+#define MY_NO_INLINE
+#endif
+
+#define MY_CDECL __cdecl
+#define MY_STD_CALL __stdcall
+#define MY_FAST_CALL MY_NO_INLINE __fastcall
+
+#else
+
+#define MY_CDECL
+#define MY_STD_CALL
+#define MY_FAST_CALL
+
+#endif
+
+
+/* The following interfaces use first parameter as pointer to structure */
+
+typedef struct
+{
+  SRes (*Read)(void *p, void *buf, size_t *size);
+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+       (output(*size) < input(*size)) is allowed */
+} ISeqInStream;
+
+/* it can return SZ_ERROR_INPUT_EOF */
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
+
+typedef struct
+{
+  size_t (*Write)(void *p, const void *buf, size_t size);
+    /* Returns: result - the number of actually written bytes.
+       (result < size) means error */
+} ISeqOutStream;
+
+typedef enum
+{
+  SZ_SEEK_SET = 0,
+  SZ_SEEK_CUR = 1,
+  SZ_SEEK_END = 2
+} ESzSeek;
+
+typedef struct
+{
+  SRes (*Read)(void *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */
+  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ISeekInStream;
+
+typedef struct
+{
+  SRes (*Look)(void *p, void **buf, size_t *size);
+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+       (output(*size) > input(*size)) is not allowed
+       (output(*size) < input(*size)) is allowed */
+  SRes (*Skip)(void *p, size_t offset);
+    /* offset must be <= output(*size) of Look */
+
+  SRes (*Read)(void *p, void *buf, size_t *size);
+    /* reads directly (without buffer). It's same as ISeqInStream::Read */
+  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ILookInStream;
+
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
+
+/* reads via ILookInStream::Read */
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
+
+#define LookToRead_BUF_SIZE (1 << 14)
+
+typedef struct
+{
+  ILookInStream s;
+  ISeekInStream *realStream;
+  size_t pos;
+  size_t size;
+  Byte buf[LookToRead_BUF_SIZE];
+} CLookToRead;
+
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
+void LookToRead_Init(CLookToRead *p);
+
+typedef struct
+{
+  ISeqInStream s;
+  ILookInStream *realStream;
+} CSecToLook;
+
+void SecToLook_CreateVTable(CSecToLook *p);
+
+typedef struct
+{
+  ISeqInStream s;
+  ILookInStream *realStream;
+} CSecToRead;
+
+void SecToRead_CreateVTable(CSecToRead *p);
+
+typedef struct
+{
+  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
+    /* Returns: result. (result != SZ_OK) means break.
+       Value (UInt64)(Int64)-1 for size means unknown value. */
+} ICompressProgress;
+
+typedef struct
+{
+  void *(*Alloc)(void *p, size_t size);
+  void (*Free)(void *p, void *address); /* address can be 0 */
+} ISzAlloc;
+
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
+#define IAlloc_Free(p, a) (p)->Free((p), a)
+
+#endif
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/lib/fbxserial.c	2010-03-18 18:28:52.582926504 +0100
@@ -0,0 +1,117 @@
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/crc32.h>
+
+#include <asm/io.h>
+
+#include <linux/fbxserial.h>
+
+#define PFX "builtin-fbxserial: "
+
+static void __init
+fbxserialinfo_use_default(struct fbx_serial *serial)
+{
+	printk(KERN_WARNING PFX "warning: using default serial infos\n");
+	fbxserial_set_default(serial);
+}
+
+/*
+ * add trailing 0 for bundle string here.
+ */
+static void __init
+bundle_fixup(struct fbx_serial *serial)
+{
+	struct fbx_serial_extinfo *p;
+	int i;
+
+	for (i = 0; i < be32_to_cpu(serial->extinfo_count); i++) {
+
+		if (i >= EXTINFO_MAX_COUNT)
+			break;
+
+		p = &serial->extinfos[i];
+		if (be32_to_cpu(p->type) == EXTINFO_TYPE_EXTDEV &&
+		    be32_to_cpu(p->u.extdev.type) == EXTDEV_TYPE_BUNDLE) {
+			int size;
+
+			size = sizeof (p->u.extdev.serial);
+			p->u.extdev.serial[size - 1] = 0;
+		}
+	}
+}
+
+/*
+ * called from  arch code early  in the boot sequence.   This function
+ * returns 1  in case serial infos are  invalid/unreadable and default
+ * values have been used.
+ */
+int __init
+fbxserialinfo_read(void *data, struct fbx_serial *out)
+{
+	uint32_t sum;
+
+	/*
+	 * get partial serial data from flash/whatever.
+	 */
+	memcpy(out, data, sizeof (*out));
+
+	/* check magic first */
+	if (be32_to_cpu(out->magic) != FBXSERIAL_MAGIC) {
+		printk(KERN_NOTICE PFX "invalid magic (%08x, expected %08x), "
+			"using defaults !\n", be32_to_cpu(out->magic),
+		       FBXSERIAL_MAGIC);
+		goto out_default;
+	}
+
+	/* fetch size for which we have to check CRC */
+	if (be32_to_cpu(out->len) > FBXSERIAL_MAX_SIZE) {
+		printk(KERN_NOTICE PFX "structure size too big (%d), "
+		       "using defaults !\n", be32_to_cpu(out->len));
+		goto out_default;
+	}
+
+	/* compute and check checksum */
+	sum = crc32(0, data + 4, be32_to_cpu(out->len) - 4);
+
+	if (be32_to_cpu(out->crc32) != sum) {
+		printk(KERN_NOTICE PFX "invalid checksum (%08x, "
+		       "expected %08x), using defaults !\n", sum,
+		       be32_to_cpu(out->crc32));
+		goto out_default;
+	}
+
+	printk(KERN_INFO PFX "Found valid serial infos !\n");
+	bundle_fixup(out);
+	return 0;
+
+ out_default:
+	fbxserialinfo_use_default(out);
+	bundle_fixup(out);
+	return 1;
+}
+
+void
+fbxserialinfo_get_random(unsigned char *data, unsigned int len)
+{
+	const struct fbx_serial *s;
+
+	s = arch_get_fbxserial();
+
+	if (len > sizeof (s->random_data))
+		len = sizeof (s->random_data);
+
+	memcpy(data, s->random_data, len);
+}
+EXPORT_SYMBOL(fbxserialinfo_get_random);
+
+void
+fbxserialinfo_get_mac_addr(unsigned char *data)
+{
+	const struct fbx_serial *s;
+
+	s = arch_get_fbxserial();
+	memcpy(data, s->mac_addr_base, MAC_ADDR_SIZE);
+}
+EXPORT_SYMBOL(fbxserialinfo_get_mac_addr);
--- /dev/null	2011-06-03 14:51:38.633053002 +0200
+++ linux-2.6.31.7-fbx/lib/LzmaDec.c	2010-03-18 18:28:52.582926504 +0100
@@ -0,0 +1,1001 @@
+/* LzmaDec.c -- LZMA Decoder
+2008-11-06 : Igor Pavlov : Public domain */
+
+#include <linux/LzmaDec.h>
+#include <linux/string.h>
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_INIT_SIZE 5
+
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
+  { UPDATE_0(p); i = (i + i); A0; } else \
+  { UPDATE_1(p); i = (i + i) + 1; A1; }
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
+
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
+#define TREE_DECODE(probs, limit, i) \
+  { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
+
+/* #define _LZMA_SIZE_OPT */
+
+#ifdef _LZMA_SIZE_OPT
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
+#else
+#define TREE_6_DECODE(probs, i) \
+  { i = 1; \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  i -= 0x40; }
+#endif
+
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0_CHECK range = bound;
+#define UPDATE_1_CHECK range -= bound; code -= bound;
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
+  { UPDATE_0_CHECK; i = (i + i); A0; } else \
+  { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
+#define TREE_DECODE_CHECK(probs, limit, i) \
+  { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+static const Byte kLiteralNextStates[kNumStates * 2] =
+{
+  0, 0, 0, 0, 1, 2, 3,  4,  5,  6,  4,  5,
+  7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
+};
+
+#define LZMA_DIC_MIN (1 << 12)
+
+/* First LZMA-symbol is always decoded.
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
+Out:
+  Result:
+    SZ_OK - OK
+    SZ_ERROR_DATA - Error
+  p->remainLen:
+    < kMatchSpecLenStart : normal remain
+    = kMatchSpecLenStart : finished
+    = kMatchSpecLenStart + 1 : Flush marker
+    = kMatchSpecLenStart + 2 : State Init Marker
+*/
+
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+  CLzmaProb *probs = p->probs;
+
+  unsigned state = p->state;
+  UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
+  unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
+  unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
+  unsigned lc = p->prop.lc;
+
+  Byte *dic = p->dic;
+  SizeT dicBufSize = p->dicBufSize;
+  SizeT dicPos = p->dicPos;
+  
+  UInt32 processedPos = p->processedPos;
+  UInt32 checkDicSize = p->checkDicSize;
+  unsigned len = 0;
+
+  const Byte *buf = p->buf;
+  UInt32 range = p->range;
+  UInt32 code = p->code;
+
+  do
+  {
+    CLzmaProb *prob;
+    UInt32 bound;
+    unsigned ttt;
+    unsigned posState = processedPos & pbMask;
+
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+    IF_BIT_0(prob)
+    {
+      unsigned symbol;
+      UPDATE_0(prob);
+      prob = probs + Literal;
+      if (checkDicSize != 0 || processedPos != 0)
+        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
+        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+
+      if (state < kNumLitStates)
+      {
+        symbol = 1;
+        do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
+      }
+      else
+      {
+        unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+        unsigned offs = 0x100;
+        symbol = 1;
+        do
+        {
+          unsigned bit;
+          CLzmaProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & offs);
+          probLit = prob + offs + bit + symbol;
+          GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+        }
+        while (symbol < 0x100);
+      }
+      dic[dicPos++] = (Byte)symbol;
+      processedPos++;
+
+      state = kLiteralNextStates[state];
+      /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
+      continue;
+    }
+    else
+    {
+      UPDATE_1(prob);
+      prob = probs + IsRep + state;
+      IF_BIT_0(prob)
+      {
+        UPDATE_0(prob);
+        state += kNumStates;
+        prob = probs + LenCoder;
+      }
+      else
+      {
+        UPDATE_1(prob);
+        if (checkDicSize == 0 && processedPos == 0)
+          return SZ_ERROR_DATA;
+        prob = probs + IsRepG0 + state;
+        IF_BIT_0(prob)
+        {
+          UPDATE_0(prob);
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IF_BIT_0(prob)
+          {
+            UPDATE_0(prob);
+            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+            dicPos++;
+            processedPos++;
+            state = state < kNumLitStates ? 9 : 11;
+            continue;
+          }
+          UPDATE_1(prob);
+        }
+        else
+        {
+          UInt32 distance;
+          UPDATE_1(prob);
+          prob = probs + IsRepG1 + state;
+          IF_BIT_0(prob)
+          {
+            UPDATE_0(prob);
+            distance = rep1;
+          }
+          else
+          {
+            UPDATE_1(prob);
+            prob = probs + IsRepG2 + state;
+            IF_BIT_0(prob)
+            {
+              UPDATE_0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UPDATE_1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = probs + RepLenCoder;
+      }
+      {
+        unsigned limit, offset;
+        CLzmaProb *probLen = prob + LenChoice;
+        IF_BIT_0(probLen)
+        {
+          UPDATE_0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          limit = (1 << kLenNumLowBits);
+        }
+        else
+        {
+          UPDATE_1(probLen);
+          probLen = prob + LenChoice2;
+          IF_BIT_0(probLen)
+          {
+            UPDATE_0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            limit = (1 << kLenNumMidBits);
+          }
+          else
+          {
+            UPDATE_1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            limit = (1 << kLenNumHighBits);
+          }
+        }
+        TREE_DECODE(probLen, limit, len);
+        len += offset;
+      }
+
+      if (state >= kNumStates)
+      {
+        UInt32 distance;
+        prob = probs + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
+        TREE_6_DECODE(prob, distance);
+        if (distance >= kStartPosModelIndex)
+        {
+          unsigned posSlot = (unsigned)distance;
+          int numDirectBits = (int)(((distance >> 1) - 1));
+          distance = (2 | (distance & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            distance <<= numDirectBits;
+            prob = probs + SpecPos + distance - posSlot - 1;
+            {
+              UInt32 mask = 1;
+              unsigned i = 1;
+              do
+              {
+                GET_BIT2(prob + i, i, ; , distance |= mask);
+                mask <<= 1;
+              }
+              while (--numDirectBits != 0);
+            }
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              NORMALIZE
+              range >>= 1;
+              
+              {
+                UInt32 t;
+                code -= range;
+                t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
+                distance = (distance << 1) + (t + 1);
+                code += range & t;
+              }
+              /*
+              distance <<= 1;
+              if (code >= range)
+              {
+                code -= range;
+                distance |= 1;
+              }
+              */
+            }
+            while (--numDirectBits != 0);
+            prob = probs + Align;
+            distance <<= kNumAlignBits;
+            {
+              unsigned i = 1;
+              GET_BIT2(prob + i, i, ; , distance |= 1);
+              GET_BIT2(prob + i, i, ; , distance |= 2);
+              GET_BIT2(prob + i, i, ; , distance |= 4);
+              GET_BIT2(prob + i, i, ; , distance |= 8);
+            }
+            if (distance == (UInt32)0xFFFFFFFF)
+            {
+              len += kMatchSpecLenStart;
+              state -= kNumStates;
+              break;
+            }
+          }
+        }
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        rep0 = distance + 1;
+        if (checkDicSize == 0)
+        {
+          if (distance >= processedPos)
+            return SZ_ERROR_DATA;
+        }
+        else if (distance >= checkDicSize)
+          return SZ_ERROR_DATA;
+        state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
+        /* state = kLiteralNextStates[state]; */
+      }
+
+      len += kMatchMinLen;
+
+      if (limit == dicPos)
+        return SZ_ERROR_DATA;
+      {
+        SizeT rem = limit - dicPos;
+        unsigned curLen = ((rem < len) ? (unsigned)rem : len);
+        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
+
+        processedPos += curLen;
+
+        len -= curLen;
+        if (pos + curLen <= dicBufSize)
+        {
+          Byte *dest = dic + dicPos;
+          ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
+          const Byte *lim = dest + curLen;
+          dicPos += curLen;
+          do
+            *(dest) = (Byte)*(dest + src);
+          while (++dest != lim);
+        }
+        else
+        {
+          do
+          {
+            dic[dicPos++] = dic[pos];
+            if (++pos == dicBufSize)
+              pos = 0;
+          }
+          while (--curLen != 0);
+        }
+      }
+    }
+  }
+  while (dicPos < limit && buf < bufLimit);
+  NORMALIZE;
+  p->buf = buf;
+  p->range = range;
+  p->code = code;
+  p->remainLen = len;
+  p->dicPos = dicPos;
+  p->processedPos = processedPos;
+  p->reps[0] = rep0;
+  p->reps[1] = rep1;
+  p->reps[2] = rep2;
+  p->reps[3] = rep3;
+  p->state = state;
+
+  return SZ_OK;
+}
+
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
+{
+  if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
+  {
+    Byte *dic = p->dic;
+    SizeT dicPos = p->dicPos;
+    SizeT dicBufSize = p->dicBufSize;
+    unsigned len = p->remainLen;
+    UInt32 rep0 = p->reps[0];
+    if (limit - dicPos < len)
+      len = (unsigned)(limit - dicPos);
+
+    if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
+      p->checkDicSize = p->prop.dicSize;
+
+    p->processedPos += len;
+    p->remainLen -= len;
+    while (len-- != 0)
+    {
+      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+      dicPos++;
+    }
+    p->dicPos = dicPos;
+  }
+}
+
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+  do
+  {
+    SizeT limit2 = limit;
+    if (p->checkDicSize == 0)
+    {
+      UInt32 rem = p->prop.dicSize - p->processedPos;
+      if (limit - p->dicPos > rem)
+        limit2 = p->dicPos + rem;
+    }
+    RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
+    if (p->processedPos >= p->prop.dicSize)
+      p->checkDicSize = p->prop.dicSize;
+    LzmaDec_WriteRem(p, limit);
+  }
+  while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
+
+  if (p->remainLen > kMatchSpecLenStart)
+  {
+    p->remainLen = kMatchSpecLenStart;
+  }
+  return 0;
+}
+
+typedef enum
+{
+  DUMMY_ERROR, /* unexpected end of input stream */
+  DUMMY_LIT,
+  DUMMY_MATCH,
+  DUMMY_REP
+} ELzmaDummy;
+
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
+{
+  UInt32 range = p->range;
+  UInt32 code = p->code;
+  const Byte *bufLimit = buf + inSize;
+  CLzmaProb *probs = p->probs;
+  unsigned state = p->state;
+  ELzmaDummy res;
+
+  {
+    CLzmaProb *prob;
+    UInt32 bound;
+    unsigned ttt;
+    unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
+
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+    IF_BIT_0_CHECK(prob)
+    {
+      UPDATE_0_CHECK
+
+      /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
+
+      prob = probs + Literal;
+      if (p->checkDicSize != 0 || p->processedPos != 0)
+        prob += (LZMA_LIT_SIZE *
+          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
+          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+
+      if (state < kNumLitStates)
+      {
+        unsigned symbol = 1;
+        do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
+      }
+      else
+      {
+        unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
+            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
+        unsigned offs = 0x100;
+        unsigned symbol = 1;
+        do
+        {
+          unsigned bit;
+          CLzmaProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & offs);
+          probLit = prob + offs + bit + symbol;
+          GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
+        }
+        while (symbol < 0x100);
+      }
+      res = DUMMY_LIT;
+    }
+    else
+    {
+      unsigned len;
+      UPDATE_1_CHECK;
+
+      prob = probs + IsRep + state;
+      IF_BIT_0_CHECK(prob)
+      {
+        UPDATE_0_CHECK;
+        state = 0;
+        prob = probs + LenCoder;
+        res = DUMMY_MATCH;
+      }
+      else
+      {
+        UPDATE_1_CHECK;
+        res = DUMMY_REP;
+        prob = probs + IsRepG0 + state;
+        IF_BIT_0_CHECK(prob)
+        {
+          UPDATE_0_CHECK;
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IF_BIT_0_CHECK(prob)
+          {
+            UPDATE_0_CHECK;
+            NORMALIZE_CHECK;
+            return DUMMY_REP;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+          }
+        }
+        else
+        {
+          UPDATE_1_CHECK;
+          prob = probs + IsRepG1 + state;
+          IF_BIT_0_CHECK(prob)
+          {
+            UPDATE_0_CHECK;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+            prob = probs + IsRepG2 + state;
+            IF_BIT_0_CHECK(prob)
+            {
+              UPDATE_0_CHECK;
+            }
+            else
+            {
+              UPDATE_1_CHECK;
+            }
+          }
+        }
+        state = kNumStates;
+        prob = probs + RepLenCoder;
+      }
+      {
+        unsigned limit, offset;
+        CLzmaProb *probLen = prob + LenChoice;
+        IF_BIT_0_CHECK(probLen)
+        {
+          UPDATE_0_CHECK;
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          limit = 1 << kLenNumLowBits;
+        }
+        else
+        {
+          UPDATE_1_CHECK;
+          probLen = prob + LenChoice2;
+          IF_BIT_0_CHECK(probLen)
+          {
+            UPDATE_0_CHECK;
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            limit = 1 << kLenNumMidBits;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            limit = 1 << kLenNumHighBits;
+          }
+        }
+        TREE_DECODE_CHECK(probLen, limit, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        unsigned posSlot;
+        prob = probs + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+            kNumPosSlotBits);
+        TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+
+          /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
+
+          if (posSlot < kEndPosModelIndex)
+          {
+            prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              NORMALIZE_CHECK
+              range >>= 1;
+              code -= range & (((code - range) >> 31) - 1);
+              /* if (code >= range) code -= range; */
+            }
+            while (--numDirectBits != 0);
+            prob = probs + Align;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            unsigned i = 1;
+            do
+            {
+              GET_BIT_CHECK(prob + i, i);
+            }
+            while (--numDirectBits != 0);
+          }
+        }
+      }
+    }
+  }
+  NORMALIZE_CHECK;
+  return res;
+}
+
+
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
+{
+  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
+  p->range = 0xFFFFFFFF;
+  p->needFlush = 0;
+}
+
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
+{
+  p->needFlush = 1;
+  p->remainLen = 0;
+  p->tempBufSize = 0;
+
+  if (initDic)
+  {
+    p->processedPos = 0;
+    p->checkDicSize = 0;
+    p->needInitState = 1;
+  }
+  if (initState)
+    p->needInitState = 1;
+}
+
+void LzmaDec_Init(CLzmaDec *p)
+{
+  p->dicPos = 0;
+  LzmaDec_InitDicAndState(p, True, True);
+}
+
+static void LzmaDec_InitStateReal(CLzmaDec *p)
+{
+  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
+  UInt32 i;
+  CLzmaProb *probs = p->probs;
+  for (i = 0; i < numProbs; i++)
+    probs[i] = kBitModelTotal >> 1;
+  p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
+  p->state = 0;
+  p->needInitState = 0;
+}
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
+    ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+  SizeT inSize = *srcLen;
+  (*srcLen) = 0;
+  LzmaDec_WriteRem(p, dicLimit);
+  
+  *status = LZMA_STATUS_NOT_SPECIFIED;
+
+  while (p->remainLen != kMatchSpecLenStart)
+  {
+      int checkEndMarkNow;
+
+      if (p->needFlush != 0)
+      {
+        for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
+          p->tempBuf[p->tempBufSize++] = *src++;
+        if (p->tempBufSize < RC_INIT_SIZE)
+        {
+          *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+          return SZ_OK;
+        }
+        if (p->tempBuf[0] != 0)
+          return SZ_ERROR_DATA;
+
+        LzmaDec_InitRc(p, p->tempBuf);
+        p->tempBufSize = 0;
+      }
+
+      checkEndMarkNow = 0;
+      if (p->dicPos >= dicLimit)
+      {
+        if (p->remainLen == 0 && p->code == 0)
+        {
+          *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
+          return SZ_OK;
+        }
+        if (finishMode == LZMA_FINISH_ANY)
+        {
+          *status = LZMA_STATUS_NOT_FINISHED;
+          return SZ_OK;
+        }
+        if (p->remainLen != 0)
+        {
+          *status = LZMA_STATUS_NOT_FINISHED;
+          return SZ_ERROR_DATA;
+        }
+        checkEndMarkNow = 1;
+      }
+
+      if (p->needInitState)
+        LzmaDec_InitStateReal(p);
+  
+      if (p->tempBufSize == 0)
+      {
+        SizeT processed;
+        const Byte *bufLimit;
+        if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+        {
+          int dummyRes = LzmaDec_TryDummy(p, src, inSize);
+          if (dummyRes == DUMMY_ERROR)
+          {
+            memcpy(p->tempBuf, src, inSize);
+            p->tempBufSize = (unsigned)inSize;
+            (*srcLen) += inSize;
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+            return SZ_OK;
+          }
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+          {
+            *status = LZMA_STATUS_NOT_FINISHED;
+            return SZ_ERROR_DATA;
+          }
+          bufLimit = src;
+        }
+        else
+          bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
+        p->buf = src;
+        if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
+          return SZ_ERROR_DATA;
+        processed = (SizeT)(p->buf - src);
+        (*srcLen) += processed;
+        src += processed;
+        inSize -= processed;
+      }
+      else
+      {
+        unsigned rem = p->tempBufSize, lookAhead = 0;
+        while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
+          p->tempBuf[rem++] = src[lookAhead++];
+        p->tempBufSize = rem;
+        if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+        {
+          int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
+          if (dummyRes == DUMMY_ERROR)
+          {
+            (*srcLen) += lookAhead;
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+            return SZ_OK;
+          }
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+          {
+            *status = LZMA_STATUS_NOT_FINISHED;
+            return SZ_ERROR_DATA;
+          }
+        }
+        p->buf = p->tempBuf;
+        if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
+          return SZ_ERROR_DATA;
+        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
+        (*srcLen) += lookAhead;
+        src += lookAhead;
+        inSize -= lookAhead;
+        p->tempBufSize = 0;
+      }
+  }
+  if (p->code == 0)
+    *status = LZMA_STATUS_FINISHED_WITH_MARK;
+  return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
+}
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+  SizeT outSize = *destLen;
+  SizeT inSize = *srcLen;
+  *srcLen = *destLen = 0;
+  for (;;)
+  {
+    SizeT inSizeCur = inSize, outSizeCur, dicPos;
+    ELzmaFinishMode curFinishMode;
+    SRes res;
+    if (p->dicPos == p->dicBufSize)
+      p->dicPos = 0;
+    dicPos = p->dicPos;
+    if (outSize > p->dicBufSize - dicPos)
+    {
+      outSizeCur = p->dicBufSize;
+      curFinishMode = LZMA_FINISH_ANY;
+    }
+    else
+    {
+      outSizeCur = dicPos + outSize;
+      curFinishMode = finishMode;
+    }
+
+    res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
+    src += inSizeCur;
+    inSize -= inSizeCur;
+    *srcLen += inSizeCur;
+    outSizeCur = p->dicPos - dicPos;
+    memcpy(dest, p->dic + dicPos, outSizeCur);
+    dest += outSizeCur;
+    outSize -= outSizeCur;
+    *destLen += outSizeCur;
+    if (res != 0)
+      return res;
+    if (outSizeCur == 0 || outSize == 0)
+      return SZ_OK;
+  }
+}
+
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->probs);
+  p->probs = 0;
+}
+
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->dic);
+  p->dic = 0;
+}
+
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+{
+  LzmaDec_FreeProbs(p, alloc);
+  LzmaDec_FreeDict(p, alloc);
+}
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
+{
+  UInt32 dicSize;
+  Byte d;
+  
+  if (size < LZMA_PROPS_SIZE)
+    return SZ_ERROR_UNSUPPORTED;
+  else
+    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
+ 
+  if (dicSize < LZMA_DIC_MIN)
+    dicSize = LZMA_DIC_MIN;
+  p->dicSize = dicSize;
+
+  d = data[0];
+  if (d >= (9 * 5 * 5))
+    return SZ_ERROR_UNSUPPORTED;
+
+  p->lc = d % 9;
+  d /= 9;
+  p->pb = d / 5;
+  p->lp = d % 5;
+
+  return SZ_OK;
+}
+
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
+{
+  UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
+  if (p->probs == 0 || numProbs != p->numProbs)
+  {
+    LzmaDec_FreeProbs(p, alloc);
+    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
+    p->numProbs = numProbs;
+    if (p->probs == 0)
+      return SZ_ERROR_MEM;
+  }
+  return SZ_OK;
+}
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+  p->prop = propNew;
+  return SZ_OK;
+}
+
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  SizeT dicBufSize;
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+  dicBufSize = propNew.dicSize;
+  if (p->dic == 0 || dicBufSize != p->dicBufSize)
+  {
+    LzmaDec_FreeDict(p, alloc);
+    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
+    if (p->dic == 0)
+    {
+      LzmaDec_FreeProbs(p, alloc);
+      return SZ_ERROR_MEM;
+    }
+  }
+  p->dicBufSize = dicBufSize;
+  p->prop = propNew;
+  return SZ_OK;
+}
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+    ELzmaStatus *status, ISzAlloc *alloc)
+{
+  CLzmaDec p;
+  SRes res;
+  SizeT inSize = *srcLen;
+  SizeT outSize = *destLen;
+  *srcLen = *destLen = 0;
+  if (inSize < RC_INIT_SIZE)
+    return SZ_ERROR_INPUT_EOF;
+
+  LzmaDec_Construct(&p);
+  res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
+  if (res != 0)
+    return res;
+  p.dic = dest;
+  p.dicBufSize = outSize;
+
+  LzmaDec_Init(&p);
+  
+  *srcLen = inSize;
+  res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+
+  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
+    res = SZ_ERROR_INPUT_EOF;
+
+  (*destLen) = p.dicPos;
+  LzmaDec_FreeProbs(&p, alloc);
+  return res;
+}
diff -Nruw linux-2.6.31.7-fbx/net/fbxatm./Kconfig linux-2.6.31.7-fbx/net/fbxatm/Kconfig
--- linux-2.6.31.7-fbx/net/fbxatm./Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.7-fbx/net/fbxatm/Kconfig	2010-10-25 13:43:58.371445476 +0200
@@ -0,0 +1,33 @@
+menuconfig FBXATM
+	tristate "Freebox Asynchronous Transfer Mode (ATM)"
+
+if FBXATM
+
+config FBXATM_REMOTE
+	bool
+
+choice
+	prompt "mode"
+	default FBXATM_STACK
+
+config FBXATM_STACK
+	bool "standard"
+
+config FBXATM_REMOTE_STUB
+	bool "remote stub"
+	select FBXATM_REMOTE
+
+endchoice
+
+config FBXATM_2684_RETX
+	bool "support freebox retx scheme"
+	depends on FBXATM_STACK
+	default n
+
+config FBXATM_REMOTE_DRIVER
+	tristate "remote fbxatm driver"
+	depends on FBXATM_STACK
+	select FBXATM_REMOTE
+	default n
+
+endif
