All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs
@ 2011-03-30 14:07 UDel V2G Team
  2011-03-30 14:07 ` [PATCH 2/6] Allows the use of the angstrom distribution with ARM cores that do not support THUMB_INTERWORK instructions UDel V2G Team
                   ` (6 more replies)
  0 siblings, 7 replies; 20+ messages in thread
From: UDel V2G Team @ 2011-03-30 14:07 UTC (permalink / raw)
  To: openembedded-devel

* Includes conf/machine/ts75xx.conf and conf/machine/include/tune-fa526.inc
  files needed for building OE packages w/ EABI and *NO* thumb support

Signed-off-by: UDel V2G Team <v2g.udel@gmail.com>
---
 conf/machine/include/tune-fa526.inc |   22 ++++++++++++++++++++++
 conf/machine/ts75xx.conf            |   22 ++++++++++++++++++++++
 2 files changed, 44 insertions(+), 0 deletions(-)
 create mode 100755 conf/machine/include/tune-fa526.inc
 create mode 100755 conf/machine/ts75xx.conf

diff --git a/conf/machine/include/tune-fa526.inc b/conf/machine/include/tune-fa526.inc
new file mode 100755
index 0000000..a5c5008
--- /dev/null
+++ b/conf/machine/include/tune-fa526.inc
@@ -0,0 +1,22 @@
+# This tune file is for the Faraday FA526 core is used in 
+# ARM processors like the Semi STR8132/ Cavium CNS2132, which is 
+# in the Technologic Systems TS-7500 board in addition to some 
+# NAS boxes out there.
+#
+# This core basically resembles a ARM920T but has NO thumb interworking support
+# which makes it not fully EABI compliant
+#
+# Hence, we need to diable all thumb instructions here
+# Also be sure to disable all thumb flags/features/includes in the distros 
+
+FEED_ARCH = "armv4"
+BASE_PACKAGE_ARCH = "armv4" 
+
+# Ideally we want the following CFLAGS for our architecture.
+# Angstorm will automtically add the thumb flags, so don't include them here
+# TARGET_CC_ARCH += "-march=armv4 -mno-thumb-interwork -mno-thumb -mfloat-abi=soft"
+TARGET_CC_ARCH += "-march=armv4 -mfloat-abi=soft"
+
+PACKAGE_EXTRA_ARCHS += "armv4"
+LDFLAGS += "-Xlinker --fix-v4bx -Xassembler --fix-v4bx"
+THUMB_INTERWORK = "no"
diff --git a/conf/machine/ts75xx.conf b/conf/machine/ts75xx.conf
new file mode 100755
index 0000000..d76548d
--- /dev/null
+++ b/conf/machine/ts75xx.conf
@@ -0,0 +1,22 @@
+#@TYPE: Machine
+#@Name: Technologic Systems TS-75xx SBC
+#@DESCRIPTION: Machine configuration for Technologic Systems TS-75xx SBC
+
+TARGET_ARCH = "arm"
+
+MACHINE_FEATURES = "kernel26 ext2 usbhost"
+
+# This requires cavium fa526 patch set to function
+# See the linux-ts75xx directory for the patches
+PREFERRED_PROVIDER_virtual/kernel = "linux-ts75xx"
+PREFERRED_VERSION_linux = "2.6.35"
+
+SERIAL_CONSOLE = "115200 ttyS0"
+USE_VT = "0"
+
+# Uses the traditional TS-7500 bootloader process
+# See the ts75xx-initrd-image.bb recipe for building
+# an initrd script that only uses EABI userspace utilities
+CMDLINE = "root=/dev/ram0 init=/linuxrc console=/dev/ttyS0,115200 lpj=958464"
+
+require conf/machine/include/tune-fa526.inc
-- 
1.7.3.4




^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/6] Allows the use of the angstrom distribution with ARM cores that do not support THUMB_INTERWORK instructions
  2011-03-30 14:07 [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
@ 2011-03-30 14:07 ` UDel V2G Team
  2011-03-30 15:04   ` Koen Kooi
  2011-03-31 20:57   ` Khem Raj
  2011-03-30 14:07 ` [PATCH 3/6] Add kernel support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 20+ messages in thread
From: UDel V2G Team @ 2011-03-30 14:07 UTC (permalink / raw)
  To: openembedded-devel

* Setting THUMB_INTERWORK = "yes" precludes the building of
  any angstrom distribution for cores that do not support
  thumb and thumb_interwork since the distro definitions
  take precedence over any local settings.

Signed-off-by: UDel V2G Team <v2g.udel@gmail.com>
---
 conf/distro/include/angstrom.inc |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/conf/distro/include/angstrom.inc b/conf/distro/include/angstrom.inc
index 5a02723..9ec1dc7 100644
--- a/conf/distro/include/angstrom.inc
+++ b/conf/distro/include/angstrom.inc
@@ -54,7 +54,7 @@ ARM_INSTRUCTION_SET = "${ANGSTROM_ARM_INSTRUCTION_SET}"
 #    but requires more instructions (140% for 70% smaller code) so may be
 #    slower.
 
-THUMB_INTERWORK = "yes"
+THUMB_INTERWORK ?= "yes"
 # "yes" "no"
 #    Whether to compile with code to allow interworking between the two
 #    instruction sets.  This allows thumb code to be executed on a primarily
-- 
1.7.3.4




^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/6] Add kernel support for the Technologic Systems TS7500 ARM SBCs
  2011-03-30 14:07 [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
  2011-03-30 14:07 ` [PATCH 2/6] Allows the use of the angstrom distribution with ARM cores that do not support THUMB_INTERWORK instructions UDel V2G Team
@ 2011-03-30 14:07 ` UDel V2G Team
  2011-03-30 14:45   ` Marcin Juszkiewicz
  2011-04-02  8:53   ` Petr Štetiar
  2011-03-30 14:07 ` [PATCH 4/6] Add recipes for building TS75xx userspace utilities UDel V2G Team
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 20+ messages in thread
From: UDel V2G Team @ 2011-03-30 14:07 UTC (permalink / raw)
  To: openembedded-devel

* Adds a custom kernel with all the patches for the Cavium FA 526 core

Signed-off-by: UDel V2G Team <v2g.udel@gmail.com>
---
 .../ts75xx/cavium-userspace-irq-2.6.35.patch       |  181 +
 recipes/linux/linux-ts75xx-2.6.35/ts75xx/defconfig | 1603 +
 .../linux/linux-ts75xx-2.6.35/ts75xx/defconfig.bak | 1521 +
 .../ts75xx/ts7500-2.6.35.11.patch                  |85527 ++++++++++++++++++++
 .../ts75xx/unionfs-2.5.8_for_2.6.35.11.patch       |11286 +++
 recipes/linux/linux-ts75xx_2.6.35.bb               |  141 +
 6 files changed, 100259 insertions(+), 0 deletions(-)
 create mode 100644 recipes/linux/linux-ts75xx-2.6.35/ts75xx/cavium-userspace-irq-2.6.35.patch
 create mode 100644 recipes/linux/linux-ts75xx-2.6.35/ts75xx/defconfig
 create mode 100644 recipes/linux/linux-ts75xx-2.6.35/ts75xx/defconfig.bak
 create mode 100644 recipes/linux/linux-ts75xx-2.6.35/ts75xx/ts7500-2.6.35.11.patch
 create mode 100644 recipes/linux/linux-ts75xx-2.6.35/ts75xx/unionfs-2.5.8_for_2.6.35.11.patch
 create mode 100644 recipes/linux/linux-ts75xx_2.6.35.bb

diff --git a/recipes/linux/linux-ts75xx-2.6.35/ts75xx/cavium-userspace-irq-2.6.35.patch b/recipes/linux/linux-ts75xx-2.6.35/ts75xx/cavium-userspace-irq-2.6.35.patch
new file mode 100644
index 0000000..5240ca9
--- /dev/null
+++ b/recipes/linux/linux-ts75xx-2.6.35/ts75xx/cavium-userspace-irq-2.6.35.patch
@@ -0,0 +1,181 @@
+--- linux-2.6.35/kernel/irq/proc.c	2010-08-01 18:11:14.000000000 -0400
++++ linux-2.6.35.11-ts7500/kernel/irq/proc.c	2011-02-27 01:18:59.000000000 -0500
+@@ -11,6 +11,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+ #include <linux/interrupt.h>
++#include <linux/poll.h>
+ 
+ #include "internals.h"
+ 
+@@ -265,21 +266,165 @@
+ 
+ #define MAX_NAMELEN 10
+ 
++struct irq_proc {
++  unsigned long irq;
++  wait_queue_head_t q;
++  atomic_t count;
++  char devname[TASK_COMM_LEN];
++};
++
++static irqreturn_t irq_proc_irq_handler(int irq, void *vidp)
++{
++  struct irq_proc *idp = (struct irq_proc *)vidp;
++  unsigned long stamp;
++
++  BUG_ON(idp->irq != irq);
++  
++  disable_irq_nosync(irq);
++  atomic_inc(&idp->count);
++  
++  wake_up(&idp->q);
++  return IRQ_HANDLED;
++}
++
++
++/*
++ * Signal to userspace an interrupt has occured.
++ */
++static ssize_t irq_proc_read(struct file *filp, char  __user *bufp, size_t len, loff_t *ppos)
++{
++  struct irq_proc *ip = (struct irq_proc *)filp->private_data;
++  struct irq_desc *idp = irq_desc + ip->irq; 
++  int pending;
++
++  DEFINE_WAIT(wait);
++
++  if (len < sizeof(int))
++    return -EINVAL;
++
++  pending = atomic_read(&ip->count);
++  if (pending == 0) {
++    if (idp->status & IRQ_DISABLED)
++      enable_irq(ip->irq);
++    if (filp->f_flags & O_NONBLOCK)
++      return -EWOULDBLOCK;
++  }
++
++  while (pending == 0) {
++    prepare_to_wait(&ip->q, &wait, TASK_INTERRUPTIBLE);
++    pending = atomic_read(&ip->count);
++    if (pending == 0)
++      schedule();
++    finish_wait(&ip->q, &wait);
++    if (signal_pending(current))
++      return -ERESTARTSYS;
++  }
++
++  if (copy_to_user(bufp, &pending, sizeof pending))
++    return -EFAULT;
++
++  *ppos += sizeof pending;
++
++  atomic_sub(pending, &ip->count);
++  return sizeof pending;
++}
++
++
++static int irq_proc_open(struct inode *inop, struct file *filp)
++{
++  struct irq_proc *ip;
++  struct proc_dir_entry *ent = PDE(inop);
++  int error;
++
++  ip = kmalloc(sizeof *ip, GFP_KERNEL);
++  if (ip == NULL)
++    return -ENOMEM;
++
++  memset(ip, 0, sizeof(*ip));
++  strcpy(ip->devname, current->comm);
++  init_waitqueue_head(&ip->q);
++  atomic_set(&ip->count, 0);
++  ip->irq = (unsigned long)ent->data;
++
++  error = request_irq(ip->irq,
++		      irq_proc_irq_handler,
++		      0,
++		      ip->devname,
++		      ip);
++  if (error < 0) {
++    kfree(ip);
++    return error;
++  }
++  filp->private_data = (void *)ip;
++
++  return 0;
++}
++
++static int irq_proc_release(struct inode *inop, struct file *filp)
++{
++  struct irq_proc *ip = (struct irq_proc *)filp->private_data;
++
++  free_irq(ip->irq, ip);
++  filp->private_data = NULL;
++  kfree(ip);
++  return 0;
++}
++
++static unsigned int irq_proc_poll(struct file *filp, struct poll_table_struct *wait)
++{
++  struct irq_proc *ip = (struct irq_proc *)filp->private_data;
++  struct irq_desc *idp = irq_desc + ip->irq;    
++
++  if (atomic_read(&ip->count) > 0)
++    return POLLIN | POLLRDNORM; /* readable */
++
++  /* if interrupts disabled and we don't have one to process... */
++  if (idp->status & IRQ_DISABLED)
++    enable_irq(ip->irq);
++
++  poll_wait(filp, &ip->q, wait);
++
++  if (atomic_read(&ip->count) > 0)
++    return POLLIN | POLLRDNORM; /* readable */
++
++  return 0;
++}
++
++static struct file_operations irq_proc_file_operations = {
++  .read = irq_proc_read,
++  .open = irq_proc_open,
++  .release = irq_proc_release,
++  .poll = irq_proc_poll,
++};
++
+ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
+ {
++	struct proc_dir_entry *entry;
+ 	char name [MAX_NAMELEN];
+ 
+-	if (!root_irq_dir || (desc->chip == &no_irq_chip) || desc->dir)
++	if (!root_irq_dir)
+ 		return;
+ 
+ 	memset(name, 0, MAX_NAMELEN);
+ 	sprintf(name, "%d", irq);
+ 
+ 	/* create /proc/irq/1234 */
+-	desc->dir = proc_mkdir(name, root_irq_dir);
+-	if (!desc->dir)
+-		return;
+-
++	if (!irq_desc[irq].dir) {
++		/* create /proc/irq/1234 */
++		irq_desc[irq].dir = proc_mkdir(name, root_irq_dir);
++		
++		/*
++		 * Create handles for user-mode interrupt handlers
++		 * if the kernel hasn't already grabbed the IRQ
++		 */
++		entry = create_proc_entry("irq", 0600, irq_desc[irq].dir);
++ 		if (entry) {
++ 			entry->data = (void *)(unsigned long)irq;
++ 			entry->read_proc = NULL;
++ 			entry->write_proc = NULL;
++ 			entry->proc_fops = &irq_proc_file_operations;
++ 		}
++	}
+ #ifdef CONFIG_SMP
+ 	/* create /proc/irq/<irq>/smp_affinity */
+ 	proc_create_data("smp_affinity", 0600, desc->dir,
diff --git a/recipes/linux/linux-ts75xx-2.6.35/ts75xx/defconfig b/recipes/linux/linux-ts75xx-2.6.35/ts75xx/defconfig
new file mode 100644
index 0000000..3423e40
--- /dev/null
+++ b/recipes/linux/linux-ts75xx-2.6.35/ts75xx/defconfig
@@ -0,0 +1,1603 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.35.11
+# Wed Mar 23 14:22:38 2011
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION="${LOCALVERSION}"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_STR9100 is not set
+CONFIG_ARCH_STR8100=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+CONFIG_CONSOLE_BAUD_RATE=115200
+
+#
+# STR8100 Options
+#
+CONFIG_VIC_INTERRUPT=y
+# CONFIG_STR8100_DRAM_16M is not set
+# CONFIG_STR8100_DRAM_32M is not set
+CONFIG_STR8100_DRAM_64M=y
+CONFIG_STR8100_PCI33M=y
+# CONFIG_STR8100_PCI66M is not set
+# CONFIG_STR8100_DMA is not set
+# CONFIG_STR8100_HSDMA is not set
+CONFIG_STR8100_INFO=y
+# CONFIG_STR8100_USBD_REBOOT_INTHANDLER is not set
+# CONFIG_STR8100_I2S is not set
+# CONFIG_STR8100_I2S_DEMO is not set
+# CONFIG_STR8100_I2S_WM8772_DEMO is not set
+# CONFIG_LE88221_CONTROL is not set
+# CONFIG_STR8100_PCM_LEGERITY_2PHONE_DEMO is not set
+# CONFIG_STR8100_RTC is not set
+CONFIG_STR8100_GPIO=y
+CONFIG_STR8100_GPIO_INTERRUPT=y
+# CONFIG_STR8100_GPIO_GENERIC_INTERFACE is not set
+
+#
+# Flash MAP
+#
+# CONFIG_STR8100_FLASH_PART is not set
+
+#
+# Third Party Support
+#
+# CONFIG_STR8100_EWC_SUPPORT is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_FA526=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_CACHE_FA=y
+CONFIG_CPU_COPY_FA=y
+CONFIG_CPU_TLB_FA=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+CONFIG_CPU_FA_BTB=y
+# CONFIG_CPU_FA_WB_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+
+#
+# Bus support
+#
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/ram0 init=/linuxrc console=/dev/ttyS0,115200 lpj=958464 debug"
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+CONFIG_FPE_FASTFPE=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=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_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# 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=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_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=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+# CONFIG_NF_CT_PROTO_DCCP is not set
+CONFIG_NF_CT_PROTO_GRE=m
+# CONFIG_NF_CT_PROTO_SCTP is not set
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+# CONFIG_NF_CONNTRACK_FTP is not set
+# CONFIG_NF_CONNTRACK_H323 is not set
+# CONFIG_NF_CONNTRACK_IRC is not set
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+CONFIG_NF_CONNTRACK_PPTP=m
+# CONFIG_NF_CONNTRACK_SANE is not set
+# CONFIG_NF_CONNTRACK_SIP is not set
+# CONFIG_NF_CONNTRACK_TFTP is not set
+# CONFIG_NF_CT_NETLINK is not set
+# CONFIG_NETFILTER_TPROXY is not set
+CONFIG_NETFILTER_XTABLES=m
+
+#
+# Xtables combined modules
+#
+CONFIG_NETFILTER_XT_MARK=m
+# CONFIG_NETFILTER_XT_CONNMARK is not set
+
+#
+# Xtables targets
+#
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_CT is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+
+#
+# Xtables matches
+#
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_HL=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+# 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_NF_DEFRAG_IPV4=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+# CONFIG_NF_NAT_SNMP_BASIC is not set
+CONFIG_NF_NAT_PROTO_GRE=m
+# CONFIG_NF_NAT_FTP is not set
+# CONFIG_NF_NAT_IRC is not set
+# CONFIG_NF_NAT_TFTP is not set
+# CONFIG_NF_NAT_AMANDA is not set
+CONFIG_NF_NAT_PPTP=m
+# CONFIG_NF_NAT_H323 is not set
+# CONFIG_NF_NAT_SIP is not set
+CONFIG_IP_NF_MANGLE=m
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_NF_CONNTRACK_IPV6 is not set
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+
+#
+# Some wireless drivers require a rate control algorithm
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=m
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=m
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+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=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_FAST_BRIDGE is not set
+# 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_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
+# CONFIG_ENIC is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGB is not set
+# 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_QLCNIC is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
+
+#
+# CNS2100 NIC support
+#
+CONFIG_STAR_NIC=y
+CONFIG_STAR_NIC_PHY_INTERNAL_PHY=y
+# CONFIG_STAR_NIC_PHY_VSC8601 is not set
+# CONFIG_STAR_NIC_PHY_IP101A is not set
+# CONFIG_STAR_NIC_PHY_IP1001 is not set
+# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=m
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_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=m
+CONFIG_SERIO_SERPORT=m
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 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_N_GSM is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_CTSRTS is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM 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_RAMOOPS is not set
+# CONFIG_I2C is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_STR8100=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB=m
+CONFIG_SSB_SPROM=y
+CONFIG_SSB_PCIHOST_POSSIBLE=y
+CONFIG_SSB_PCIHOST=y
+# CONFIG_SSB_B43_PCI_BRIDGE is not set
+# CONFIG_SSB_SILENT is not set
+# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+CONFIG_SSB_DRIVER_PCICORE=y
+CONFIG_MFD_SUPPORT=y
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_AB8500_CORE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGA_ARB is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=m
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_3M_PCT is not set
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CANDO 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_EGALAX is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON 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=m
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG_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=m
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_HCD_SSB is not set
+# 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=m
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# 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_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_ZIO 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_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_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+CONFIG_USB_GADGET_R8A66597=y
+CONFIG_USB_R8A66597=m
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_WEBCAM is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_XIP=y
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY 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
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+CONFIG_UNION_FS=m
+# CONFIG_UNION_FS_XATTR is not set
+# CONFIG_UNION_FS_DEBUG is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=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_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_STRIP_ASM_SYMS=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_MANAGER_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/recipes/linux/linux-ts75xx-2.6.35/ts75xx/defconfig.bak b/recipes/linux/linux-ts75xx-2.6.35/ts75xx/defconfig.bak
new file mode 100644
index 0000000..71a3a82
--- /dev/null
+++ b/recipes/linux/linux-ts75xx-2.6.35/ts75xx/defconfig.bak
@@ -0,0 +1,1521 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.35.11
+# Sat Feb 26 21:00:50 2011
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_STR9100 is not set
+CONFIG_ARCH_STR8100=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+CONFIG_CONSOLE_BAUD_RATE=115200
+
+#
+# STR8100 Options
+#
+CONFIG_VIC_INTERRUPT=y
+# CONFIG_STR8100_DRAM_16M is not set
+# CONFIG_STR8100_DRAM_32M is not set
+CONFIG_STR8100_DRAM_64M=y
+CONFIG_STR8100_PCI33M=y
+# CONFIG_STR8100_PCI66M is not set
+# CONFIG_STR8100_DMA is not set
+# CONFIG_STR8100_HSDMA is not set
+CONFIG_STR8100_INFO=y
+# CONFIG_STR8100_USBD_REBOOT_INTHANDLER is not set
+# CONFIG_STR8100_I2S is not set
+# CONFIG_STR8100_I2S_DEMO is not set
+# CONFIG_STR8100_I2S_WM8772_DEMO is not set
+# CONFIG_LE88221_CONTROL is not set
+# CONFIG_STR8100_PCM_LEGERITY_2PHONE_DEMO is not set
+# CONFIG_STR8100_RTC is not set
+CONFIG_STR8100_GPIO=y
+CONFIG_STR8100_GPIO_INTERRUPT=y
+# CONFIG_STR8100_GPIO_GENERIC_INTERFACE is not set
+
+#
+# Flash MAP
+#
+# CONFIG_STR8100_FLASH_PART is not set
+
+#
+# Third Party Support
+#
+# CONFIG_STR8100_EWC_SUPPORT is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_FA526=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_CACHE_FA=y
+CONFIG_CPU_COPY_FA=y
+CONFIG_CPU_TLB_FA=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+CONFIG_CPU_FA_BTB=y
+# CONFIG_CPU_FA_WB_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+
+#
+# Bus support
+#
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/ram0 init=/linuxrc lpj=958464 console=null"
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+CONFIG_FPE_FASTFPE=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=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_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# 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=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+# CONFIG_IP_NF_PPTP is not set
+# CONFIG_IP_NF_H323 is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+# CONFIG_IP_NF_MATCH_DSCP is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+# CONFIG_IP_NF_TARGET_TCPMSS is not set
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+
+#
+# Some wireless drivers require a rate control algorithm
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=m
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=m
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+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=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_FAST_BRIDGE is not set
+# 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_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
+# CONFIG_ENIC is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGB is not set
+# 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_QLCNIC is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
+
+#
+# CNS2100 NIC support
+#
+CONFIG_STAR_NIC=y
+CONFIG_STAR_NIC_PHY_INTERNAL_PHY=y
+# CONFIG_STAR_NIC_PHY_VSC8601 is not set
+# CONFIG_STAR_NIC_PHY_IP101A is not set
+# CONFIG_STAR_NIC_PHY_IP1001 is not set
+# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=m
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_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=m
+CONFIG_SERIO_SERPORT=m
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=m
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 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_N_GSM is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_CTSRTS is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM 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_RAMOOPS is not set
+# CONFIG_I2C is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_STR8100=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB=m
+CONFIG_SSB_SPROM=y
+CONFIG_SSB_PCIHOST_POSSIBLE=y
+CONFIG_SSB_PCIHOST=y
+# CONFIG_SSB_B43_PCI_BRIDGE is not set
+# CONFIG_SSB_SILENT is not set
+# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+CONFIG_SSB_DRIVER_PCICORE=y
+CONFIG_MFD_SUPPORT=y
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_AB8500_CORE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGA_ARB is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=m
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_3M_PCT is not set
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CANDO 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_EGALAX is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON 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=m
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG_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=m
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_HCD_SSB is not set
+# 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=m
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# 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_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_ZIO 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_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_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+CONFIG_USB_GADGET_R8A66597=y
+CONFIG_USB_R8A66597=m
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_WEBCAM is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_XIP=y
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=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_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_STRIP_ASM_SYMS=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_MANAGER_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/recipes/linux/linux-ts75xx-2.6.35/ts75xx/ts7500-2.6.35.11.patch b/recipes/linux/linux-ts75xx-2.6.35/ts75xx/ts7500-2.6.35.11.patch
new file mode 100644
index 0000000..97fcd7b
--- /dev/null
+++ b/recipes/linux/linux-ts75xx-2.6.35/ts75xx/ts7500-2.6.35.11.patch
@@ -0,0 +1,85527 @@
+diff -rupN linux-2.6.35.11/arch/arm/boot/bootp/bootp.lds linux-2.6.35.11-ts7500/arch/arm/boot/bootp/bootp.lds
+--- linux-2.6.35.11/arch/arm/boot/bootp/bootp.lds	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/bootp/bootp.lds	2011-03-14 11:18:24.000000000 -0400
+@@ -17,6 +17,8 @@ SECTIONS
+    *(.start)
+    *(.text)
+    initrd_size = initrd_end - initrd_start;
++/* scott.kernel */
++   kernel_size = kernel_end - kernel_start;   
+    _etext = .;
+   }
+ 
+diff -rupN linux-2.6.35.11/arch/arm/boot/bootp/init.S linux-2.6.35.11-ts7500/arch/arm/boot/bootp/init.S
+--- linux-2.6.35.11/arch/arm/boot/bootp/init.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/bootp/init.S	2011-03-14 11:18:24.000000000 -0400
+@@ -22,9 +22,13 @@
+ 
+ _start:		add	lr, pc, #-0x8		@ lr = current load addr
+ 		adr	r13, data
+-		ldmia	r13!, {r4-r6}		@ r5 = dest, r6 = length
++		ldmia	r13!, {r4-r6}		@ r5 = initrd_phys, r6 = initrd_size
+ 		add	r4, r4, lr		@ r4 = initrd_start + load addr
+ 		bl	move			@ move the initrd
++		ldmia	r13!, {r4-r6}		@ r5 = kernel_phys, r6 = kernel_size
++		add	r4, r4, lr		@ r4 = kernel_start + load addr
++		mov	r12, r5			@ save kernel_phys to r12
++		bl	move			@ move the kernel
+ 
+ /*
+  * Setup the initrd parameters to pass to the kernel.  This can only be
+@@ -49,7 +53,7 @@ _start:		add	lr, pc, #-0x8		@ lr = curre
+ /*
+  * find the end of the tag list, and then add an INITRD tag on the end.
+  * If there is already an INITRD tag, then we ignore it; the last INITRD
+- * tag takes precedence.
++ * tag takes precidence.
+  */
+ taglist:	ldr	r10, [r9, #0]		@ tag length
+ 		teq	r10, #0			@ last tag (zero length)?
+@@ -58,7 +62,11 @@ taglist:	ldr	r10, [r9, #0]		@ tag length
+ 
+ 		mov	r5, #4			@ Size of initrd tag (4 words)
+ 		stmia	r9, {r5, r6, r7, r8, r10}
++/* scott.kernel */
++		mov	pc, r12
++/* scott.kernel 
+ 		b	kernel_start		@ call kernel
++*/
+ 
+ /*
+  * Move the block of memory length r6 from address r4 to address r5
+@@ -77,6 +85,10 @@ move:		ldmia	r4!, {r7 - r10}		@ move 32-
+ data:		.word	initrd_start		@ source initrd address
+ 		.word	initrd_phys		@ destination initrd address
+ 		.word	initrd_size		@ initrd size
++/* scott.kernel */
++		.word	kernel_start		@ source kernel address
++		.word	kernel_phys		@ destination kernel address
++		.word	kernel_size		@ kernel size
+ 
+ 		.word	0x54410001		@ r5 = ATAG_CORE
+ 		.word	0x54420005		@ r6 = ATAG_INITRD2
+diff -rupN linux-2.6.35.11/arch/arm/boot/bootp/init.S.old linux-2.6.35.11-ts7500/arch/arm/boot/bootp/init.S.old
+--- linux-2.6.35.11/arch/arm/boot/bootp/init.S.old	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/bootp/init.S.old	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,86 @@
++/*
++ *  linux/arch/arm/boot/bootp/init.S
++ *
++ *  Copyright (C) 2000-2003 Russell King.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  "Header" file for splitting kernel + initrd.  Note that we pass
++ *  r0 through to r3 straight through.
++ *
++ *  This demonstrates how to append code to the start of the kernel
++ *  zImage, and boot the kernel without copying it around.  This
++ *  example would be simpler; if we didn't have an object of unknown
++ *  size immediately following the kernel, we could build this into
++ *  a binary blob, and concatenate the zImage using the cat command.
++ */
++		.section .start,#alloc,#execinstr
++		.type	_start, #function
++		.globl	_start
++
++_start:		add	lr, pc, #-0x8		@ lr = current load addr
++		adr	r13, data
++		ldmia	r13!, {r4-r6}		@ r5 = dest, r6 = length
++		add	r4, r4, lr		@ r4 = initrd_start + load addr
++		bl	move			@ move the initrd
++
++/*
++ * Setup the initrd parameters to pass to the kernel.  This can only be
++ * passed in via the tagged list.
++ */
++		ldmia	r13, {r5-r9}		@ get size and addr of initrd
++						@ r5 = ATAG_CORE
++						@ r6 = ATAG_INITRD2
++						@ r7 = initrd start
++						@ r8 = initrd end
++						@ r9 = param_struct address
++
++		ldr	r10, [r9, #4]		@ get first tag
++		teq	r10, r5			@ is it ATAG_CORE?
++/*
++ * If we didn't find a valid tag list, create a dummy ATAG_CORE entry.
++ */
++		movne	r10, #0			@ terminator
++		movne	r4, #2			@ Size of this entry (2 words)
++		stmneia	r9, {r4, r5, r10}	@ Size, ATAG_CORE, terminator
++
++/*
++ * find the end of the tag list, and then add an INITRD tag on the end.
++ * If there is already an INITRD tag, then we ignore it; the last INITRD
++ * tag takes precedence.
++ */
++taglist:	ldr	r10, [r9, #0]		@ tag length
++		teq	r10, #0			@ last tag (zero length)?
++		addne	r9, r9, r10, lsl #2
++		bne	taglist
++
++		mov	r5, #4			@ Size of initrd tag (4 words)
++		stmia	r9, {r5, r6, r7, r8, r10}
++		b	kernel_start		@ call kernel
++
++/*
++ * Move the block of memory length r6 from address r4 to address r5
++ */
++move:		ldmia	r4!, {r7 - r10}		@ move 32-bytes at a time
++		stmia	r5!, {r7 - r10}
++		ldmia	r4!, {r7 - r10}
++		stmia	r5!, {r7 - r10}
++		subs	r6, r6, #8 * 4
++		bcs	move
++		mov	pc, lr
++
++		.size	_start, . - _start
++
++		.type	data,#object
++data:		.word	initrd_start		@ source initrd address
++		.word	initrd_phys		@ destination initrd address
++		.word	initrd_size		@ initrd size
++
++		.word	0x54410001		@ r5 = ATAG_CORE
++		.word	0x54420005		@ r6 = ATAG_INITRD2
++		.word	initrd_phys		@ r7
++		.word	initrd_size		@ r8
++		.word	params_phys		@ r9
++		.size	data, . - data
+diff -rupN linux-2.6.35.11/arch/arm/boot/bootp/Makefile linux-2.6.35.11-ts7500/arch/arm/boot/bootp/Makefile
+--- linux-2.6.35.11/arch/arm/boot/bootp/Makefile	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/bootp/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -7,6 +7,7 @@
+ 
+ LDFLAGS_bootp	:=-p --no-undefined -X \
+ 		 --defsym initrd_phys=$(INITRD_PHYS) \
++ 		 --defsym kernel_phys=$(KERNEL_PHYS) \
+ 		 --defsym params_phys=$(PARAMS_PHYS) -T
+ AFLAGS_initrd.o :=-DINITRD=\"$(INITRD)\"
+ 
+diff -rupN linux-2.6.35.11/arch/arm/boot/compressed/head.S linux-2.6.35.11-ts7500/arch/arm/boot/compressed/head.S
+--- linux-2.6.35.11/arch/arm/boot/compressed/head.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/compressed/head.S	2011-03-14 11:18:24.000000000 -0400
+@@ -71,6 +71,21 @@ wait:		mrc	p14, 0, pc, c0, c1, 0
+ 		mov	\rb, #0x50000000
+ 		add	\rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
+ 		.endm
++#elif defined(CONFIG_ARCH_STR9100)
++		.macro	loadsp, rb
++		mov	\rb, #0x78000000
++		.endm
++		.macro	writeb, rb
++		strb	\rb, [r3, #0]
++		.endm
++#elif defined(CONFIG_ARCH_STR8100)
++		.macro	loadsp, rb
++		mov	\rb, #0x78000000		
++		.endm      
++		
++		.macro	writeb, rb
++		strb	\rb, [r3, #0]
++		.endm      
+ #else
+ 		.macro	loadsp,	rb, tmp
+ 		addruart \rb, \tmp
+@@ -444,6 +459,15 @@ __setup_mmu:	sub	r3, r4, #16384		@ Page
+ 		mov	pc, lr
+ ENDPROC(__setup_mmu)
+ 
++
++/* added by ivan wang for no cache support */
++__armv4_no_mmu_cache:
++		orr	r0,r0,#0
++		orr	r0,r0,#0
++		mov	pc,lr
++		orr	r0,r0,#0
++		orr	r0,r0,#0
++
+ __armv4_mmu_cache_on:
+ 		mov	r12, lr
+ #ifdef CONFIG_MMU
+@@ -530,6 +554,13 @@ __common_mmu_cache_on:
+ 		.align	5			@ cache line aligned
+ 1:		mcr	p15, 0, r0, c1, c0, 0	@ load control register
+ 		mrc	p15, 0, r0, c1, c0, 0	@ and read it back to
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++		/* FA520/FA526 need > 2 nops */
++		mov     r0,r0
++		mov     r0,r0
++      mov     r0,r0
++		mov     r0,r0
++#endif      
+ 		sub	pc, lr, r0, lsr #32	@ properly flush pipeline
+ #endif
+ 
+@@ -712,12 +743,13 @@ proc_types:
+ 		b	__armv5tej_mmu_cache_flush
+ #endif
+ 
++#if (0)
+ 		.word	0x66015261		@ FA526
+ 		.word	0xff01fff1
+ 		W(b)	__fa526_cache_on
+ 		W(b)	__armv4_mmu_cache_off
+ 		W(b)	__fa526_cache_flush
+-
++#endif
+ 		@ These match on the architecture ID
+ 
+ 		.word	0x00020000		@ ARMv4T
+@@ -726,6 +758,18 @@ proc_types:
+ 		W(b)	__armv4_mmu_cache_off
+ 		W(b)	__armv4_mmu_cache_flush
+ 
++#if (1)      
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++		.word	0x66015261		@ FA526, ARMv4
++		.word	0xff01fff1
++		W(b)	__armv4_mmu_cache_on
++      @W(b)	__fa526_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__armv4_mmu_cache_flush
++      @W(b)	__fa526_cache_flush 
++#endif      
++#endif
++
+ 		.word	0x00050000		@ ARMv5TE
+ 		.word	0x000f0000
+ 		W(b)	__armv4_mmu_cache_on
+@@ -801,6 +845,13 @@ __armv4_mmu_cache_off:
+ 		mrc	p15, 0, r0, c1, c0
+ 		bic	r0, r0, #0x000d
+ 		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++		/* FA520/FA526 need > 2 nops */
++		mov	r0,r0
++		mov	r0,r0
++      mov     r0,r0
++		mov     r0,r0
++#endif      
+ 		mov	r0, #0
+ 		mcr	p15, 0, r0, c7, c7	@ invalidate whole cache v4
+ 		mcr	p15, 0, r0, c8, c7	@ invalidate whole TLB v4
+@@ -970,6 +1021,10 @@ __armv4_mmu_cache_flush:
+ 		mov	r11, #8
+ 		mov	r11, r11, lsl r3	@ cache line size in bytes
+ no_cache_id:
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++		mov	r1,#0
++		mcr	p15, 0, r1, c7, c10, 0	@ clean D cache
++#endif
+ 		mov	r1, pc
+ 		bic	r1, r1, #63		@ align to longest cache line
+ 		add	r2, r1, r2
+diff -rupN linux-2.6.35.11/arch/arm/boot/compressed/head.S.orig linux-2.6.35.11-ts7500/arch/arm/boot/compressed/head.S.orig
+--- linux-2.6.35.11/arch/arm/boot/compressed/head.S.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/compressed/head.S.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,1072 @@
++/*
++ *  linux/arch/arm/boot/compressed/head.S
++ *
++ *  Copyright (C) 1996-2002 Russell King
++ *  Copyright (C) 2004 Hyok S. Choi (MPU support)
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/linkage.h>
++
++/*
++ * Debugging stuff
++ *
++ * Note that these macros must not contain any code which is not
++ * 100% relocatable.  Any attempt to do so will result in a crash.
++ * Please select one of the following when turning on debugging.
++ */
++#ifdef DEBUG
++
++#if defined(CONFIG_DEBUG_ICEDCC)
++
++#ifdef CONFIG_CPU_V6
++		.macro	loadsp, rb, tmp
++		.endm
++		.macro	writeb, ch, rb
++		mcr	p14, 0, \ch, c0, c5, 0
++		.endm
++#elif defined(CONFIG_CPU_V7)
++		.macro	loadsp, rb, tmp
++		.endm
++		.macro	writeb, ch, rb
++wait:		mrc	p14, 0, pc, c0, c1, 0
++		bcs	wait
++		mcr	p14, 0, \ch, c0, c5, 0
++		.endm
++#elif defined(CONFIG_CPU_XSCALE)
++		.macro	loadsp, rb, tmp
++		.endm
++		.macro	writeb, ch, rb
++		mcr	p14, 0, \ch, c8, c0, 0
++		.endm
++#else
++		.macro	loadsp, rb, tmp
++		.endm
++		.macro	writeb, ch, rb
++		mcr	p14, 0, \ch, c1, c0, 0
++		.endm
++#endif
++
++#else
++
++#include <mach/debug-macro.S>
++
++		.macro	writeb,	ch, rb
++		senduart \ch, \rb
++		.endm
++
++#if defined(CONFIG_ARCH_SA1100)
++		.macro	loadsp, rb, tmp
++		mov	\rb, #0x80000000	@ physical base address
++#ifdef CONFIG_DEBUG_LL_SER3
++		add	\rb, \rb, #0x00050000	@ Ser3
++#else
++		add	\rb, \rb, #0x00010000	@ Ser1
++#endif
++		.endm
++#elif defined(CONFIG_ARCH_S3C2410)
++		.macro loadsp, rb, tmp
++		mov	\rb, #0x50000000
++		add	\rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
++		.endm
++#else
++		.macro	loadsp,	rb, tmp
++		addruart \rb, \tmp
++		.endm
++#endif
++#endif
++#endif
++
++		.macro	kputc,val
++		mov	r0, \val
++		bl	putc
++		.endm
++
++		.macro	kphex,val,len
++		mov	r0, \val
++		mov	r1, #\len
++		bl	phex
++		.endm
++
++		.macro	debug_reloc_start
++#ifdef DEBUG
++		kputc	#'\n'
++		kphex	r6, 8		/* processor id */
++		kputc	#':'
++		kphex	r7, 8		/* architecture id */
++#ifdef CONFIG_CPU_CP15
++		kputc	#':'
++		mrc	p15, 0, r0, c1, c0
++		kphex	r0, 8		/* control reg */
++#endif
++		kputc	#'\n'
++		kphex	r5, 8		/* decompressed kernel start */
++		kputc	#'-'
++		kphex	r9, 8		/* decompressed kernel end  */
++		kputc	#'>'
++		kphex	r4, 8		/* kernel execution address */
++		kputc	#'\n'
++#endif
++		.endm
++
++		.macro	debug_reloc_end
++#ifdef DEBUG
++		kphex	r5, 8		/* end of kernel */
++		kputc	#'\n'
++		mov	r0, r4
++		bl	memdump		/* dump 256 bytes at start of kernel */
++#endif
++		.endm
++
++		.section ".start", #alloc, #execinstr
++/*
++ * sort out different calling conventions
++ */
++		.align
++start:
++		.type	start,#function
++		.rept	8
++		mov	r0, r0
++		.endr
++
++		b	1f
++		.word	0x016f2818		@ Magic numbers to help the loader
++		.word	start			@ absolute load/run zImage address
++		.word	_edata			@ zImage end address
++1:		mov	r7, r1			@ save architecture ID
++		mov	r8, r2			@ save atags pointer
++
++#ifndef __ARM_ARCH_2__
++		/*
++		 * Booting from Angel - need to enter SVC mode and disable
++		 * FIQs/IRQs (numeric definitions from angel arm.h source).
++		 * We only do this if we were in user mode on entry.
++		 */
++		mrs	r2, cpsr		@ get current mode
++		tst	r2, #3			@ not user?
++		bne	not_angel
++		mov	r0, #0x17		@ angel_SWIreason_EnterSVC
++ ARM(		swi	0x123456	)	@ angel_SWI_ARM
++ THUMB(		svc	0xab		)	@ angel_SWI_THUMB
++not_angel:
++		mrs	r2, cpsr		@ turn off interrupts to
++		orr	r2, r2, #0xc0		@ prevent angel from running
++		msr	cpsr_c, r2
++#else
++		teqp	pc, #0x0c000003		@ turn off interrupts
++#endif
++
++		/*
++		 * Note that some cache flushing and other stuff may
++		 * be needed here - is there an Angel SWI call for this?
++		 */
++
++		/*
++		 * some architecture specific code can be inserted
++		 * by the linker here, but it should preserve r7, r8, and r9.
++		 */
++
++		.text
++		adr	r0, LC0
++ ARM(		ldmia	r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
++ THUMB(		ldmia	r0, {r1, r2, r3, r4, r5, r6, r11, ip}	)
++ THUMB(		ldr	sp, [r0, #32]				)
++		subs	r0, r0, r1		@ calculate the delta offset
++
++						@ if delta is zero, we are
++		beq	not_relocated		@ running at the address we
++						@ were linked at.
++
++		/*
++		 * We're running at a different address.  We need to fix
++		 * up various pointers:
++		 *   r5 - zImage base address (_start)
++		 *   r6 - size of decompressed image
++		 *   r11 - GOT start
++		 *   ip - GOT end
++		 */
++		add	r5, r5, r0
++		add	r11, r11, r0
++		add	ip, ip, r0
++
++#ifndef CONFIG_ZBOOT_ROM
++		/*
++		 * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
++		 * we need to fix up pointers into the BSS region.
++		 *   r2 - BSS start
++		 *   r3 - BSS end
++		 *   sp - stack pointer
++		 */
++		add	r2, r2, r0
++		add	r3, r3, r0
++		add	sp, sp, r0
++
++		/*
++		 * Relocate all entries in the GOT table.
++		 */
++1:		ldr	r1, [r11, #0]		@ relocate entries in the GOT
++		add	r1, r1, r0		@ table.  This fixes up the
++		str	r1, [r11], #4		@ C references.
++		cmp	r11, ip
++		blo	1b
++#else
++
++		/*
++		 * Relocate entries in the GOT table.  We only relocate
++		 * the entries that are outside the (relocated) BSS region.
++		 */
++1:		ldr	r1, [r11, #0]		@ relocate entries in the GOT
++		cmp	r1, r2			@ entry < bss_start ||
++		cmphs	r3, r1			@ _end < entry
++		addlo	r1, r1, r0		@ table.  This fixes up the
++		str	r1, [r11], #4		@ C references.
++		cmp	r11, ip
++		blo	1b
++#endif
++
++not_relocated:	mov	r0, #0
++1:		str	r0, [r2], #4		@ clear bss
++		str	r0, [r2], #4
++		str	r0, [r2], #4
++		str	r0, [r2], #4
++		cmp	r2, r3
++		blo	1b
++
++		/*
++		 * The C runtime environment should now be setup
++		 * sufficiently.  Turn the cache on, set up some
++		 * pointers, and start decompressing.
++		 */
++		bl	cache_on
++
++		mov	r1, sp			@ malloc space above stack
++		add	r2, sp, #0x10000	@ 64k max
++
++/*
++ * Check to see if we will overwrite ourselves.
++ *   r4 = final kernel address
++ *   r5 = start of this image
++ *   r6 = size of decompressed image
++ *   r2 = end of malloc space (and therefore this image)
++ * We basically want:
++ *   r4 >= r2 -> OK
++ *   r4 + image length <= r5 -> OK
++ */
++		cmp	r4, r2
++		bhs	wont_overwrite
++		add	r0, r4, r6
++		cmp	r0, r5
++		bls	wont_overwrite
++
++		mov	r5, r2			@ decompress after malloc space
++		mov	r0, r5
++		mov	r3, r7
++		bl	decompress_kernel
++
++		add	r0, r0, #127 + 128	@ alignment + stack
++		bic	r0, r0, #127		@ align the kernel length
++/*
++ * r0     = decompressed kernel length
++ * r1-r3  = unused
++ * r4     = kernel execution address
++ * r5     = decompressed kernel start
++ * r7     = architecture ID
++ * r8     = atags pointer
++ * r9-r12,r14 = corrupted
++ */
++		add	r1, r5, r0		@ end of decompressed kernel
++		adr	r2, reloc_start
++		ldr	r3, LC1
++		add	r3, r2, r3
++1:		ldmia	r2!, {r9 - r12, r14}	@ copy relocation code
++		stmia	r1!, {r9 - r12, r14}
++		ldmia	r2!, {r9 - r12, r14}
++		stmia	r1!, {r9 - r12, r14}
++		cmp	r2, r3
++		blo	1b
++		mov	sp, r1
++		add	sp, sp, #128		@ relocate the stack
++
++		bl	cache_clean_flush
++ ARM(		add	pc, r5, r0		) @ call relocation code
++ THUMB(		add	r12, r5, r0		)
++ THUMB(		mov	pc, r12			) @ call relocation code
++
++/*
++ * We're not in danger of overwriting ourselves.  Do this the simple way.
++ *
++ * r4     = kernel execution address
++ * r7     = architecture ID
++ */
++wont_overwrite:	mov	r0, r4
++		mov	r3, r7
++		bl	decompress_kernel
++		b	call_kernel
++
++		.align	2
++		.type	LC0, #object
++LC0:		.word	LC0			@ r1
++		.word	__bss_start		@ r2
++		.word	_end			@ r3
++		.word	zreladdr		@ r4
++		.word	_start			@ r5
++		.word	_image_size		@ r6
++		.word	_got_start		@ r11
++		.word	_got_end		@ ip
++		.word	user_stack+4096		@ sp
++LC1:		.word	reloc_end - reloc_start
++		.size	LC0, . - LC0
++
++#ifdef CONFIG_ARCH_RPC
++		.globl	params
++params:		ldr	r0, =params_phys
++		mov	pc, lr
++		.ltorg
++		.align
++#endif
++
++/*
++ * Turn on the cache.  We need to setup some page tables so that we
++ * can have both the I and D caches on.
++ *
++ * We place the page tables 16k down from the kernel execution address,
++ * and we hope that nothing else is using it.  If we're using it, we
++ * will go pop!
++ *
++ * On entry,
++ *  r4 = kernel execution address
++ *  r7 = architecture number
++ *  r8 = atags pointer
++ *  r9 = run-time address of "start"  (???)
++ * On exit,
++ *  r1, r2, r3, r9, r10, r12 corrupted
++ * This routine must preserve:
++ *  r4, r5, r6, r7, r8
++ */
++		.align	5
++cache_on:	mov	r3, #8			@ cache_on function
++		b	call_cache_fn
++
++/*
++ * Initialize the highest priority protection region, PR7
++ * to cover all 32bit address and cacheable and bufferable.
++ */
++__armv4_mpu_cache_on:
++		mov	r0, #0x3f		@ 4G, the whole
++		mcr	p15, 0, r0, c6, c7, 0	@ PR7 Area Setting
++		mcr 	p15, 0, r0, c6, c7, 1
++
++		mov	r0, #0x80		@ PR7
++		mcr	p15, 0, r0, c2, c0, 0	@ D-cache on
++		mcr	p15, 0, r0, c2, c0, 1	@ I-cache on
++		mcr	p15, 0, r0, c3, c0, 0	@ write-buffer on
++
++		mov	r0, #0xc000
++		mcr	p15, 0, r0, c5, c0, 1	@ I-access permission
++		mcr	p15, 0, r0, c5, c0, 0	@ D-access permission
++
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
++		mcr	p15, 0, r0, c7, c5, 0	@ flush(inval) I-Cache
++		mcr	p15, 0, r0, c7, c6, 0	@ flush(inval) D-Cache
++		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
++						@ ...I .... ..D. WC.M
++		orr	r0, r0, #0x002d		@ .... .... ..1. 11.1
++		orr	r0, r0, #0x1000		@ ...1 .... .... ....
++
++		mcr	p15, 0, r0, c1, c0, 0	@ write control reg
++
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c5, 0	@ flush(inval) I-Cache
++		mcr	p15, 0, r0, c7, c6, 0	@ flush(inval) D-Cache
++		mov	pc, lr
++
++__armv3_mpu_cache_on:
++		mov	r0, #0x3f		@ 4G, the whole
++		mcr	p15, 0, r0, c6, c7, 0	@ PR7 Area Setting
++
++		mov	r0, #0x80		@ PR7
++		mcr	p15, 0, r0, c2, c0, 0	@ cache on
++		mcr	p15, 0, r0, c3, c0, 0	@ write-buffer on
++
++		mov	r0, #0xc000
++		mcr	p15, 0, r0, c5, c0, 0	@ access permission
++
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
++		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
++						@ .... .... .... WC.M
++		orr	r0, r0, #0x000d		@ .... .... .... 11.1
++		mov	r0, #0
++		mcr	p15, 0, r0, c1, c0, 0	@ write control reg
++
++		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
++		mov	pc, lr
++
++__setup_mmu:	sub	r3, r4, #16384		@ Page directory size
++		bic	r3, r3, #0xff		@ Align the pointer
++		bic	r3, r3, #0x3f00
++/*
++ * Initialise the page tables, turning on the cacheable and bufferable
++ * bits for the RAM area only.
++ */
++		mov	r0, r3
++		mov	r9, r0, lsr #18
++		mov	r9, r9, lsl #18		@ start of RAM
++		add	r10, r9, #0x10000000	@ a reasonable RAM size
++		mov	r1, #0x12
++		orr	r1, r1, #3 << 10
++		add	r2, r3, #16384
++1:		cmp	r1, r9			@ if virt > start of RAM
++		orrhs	r1, r1, #0x0c		@ set cacheable, bufferable
++		cmp	r1, r10			@ if virt > end of RAM
++		bichs	r1, r1, #0x0c		@ clear cacheable, bufferable
++		str	r1, [r0], #4		@ 1:1 mapping
++		add	r1, r1, #1048576
++		teq	r0, r2
++		bne	1b
++/*
++ * If ever we are running from Flash, then we surely want the cache
++ * to be enabled also for our execution instance...  We map 2MB of it
++ * so there is no map overlap problem for up to 1 MB compressed kernel.
++ * If the execution is in RAM then we would only be duplicating the above.
++ */
++		mov	r1, #0x1e
++		orr	r1, r1, #3 << 10
++		mov	r2, pc, lsr #20
++		orr	r1, r1, r2, lsl #20
++		add	r0, r3, r2, lsl #2
++		str	r1, [r0], #4
++		add	r1, r1, #1048576
++		str	r1, [r0]
++		mov	pc, lr
++ENDPROC(__setup_mmu)
++
++__armv4_mmu_cache_on:
++		mov	r12, lr
++#ifdef CONFIG_MMU
++		bl	__setup_mmu
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
++		mcr	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
++		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
++		orr	r0, r0, #0x5000		@ I-cache enable, RR cache replacement
++		orr	r0, r0, #0x0030
++#ifdef CONFIG_CPU_ENDIAN_BE8
++		orr	r0, r0, #1 << 25	@ big-endian page tables
++#endif
++		bl	__common_mmu_cache_on
++		mov	r0, #0
++		mcr	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
++#endif
++		mov	pc, r12
++
++__armv7_mmu_cache_on:
++		mov	r12, lr
++#ifdef CONFIG_MMU
++		mrc	p15, 0, r11, c0, c1, 4	@ read ID_MMFR0
++		tst	r11, #0xf		@ VMSA
++		blne	__setup_mmu
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
++		tst	r11, #0xf		@ VMSA
++		mcrne	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
++#endif
++		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
++		orr	r0, r0, #0x5000		@ I-cache enable, RR cache replacement
++		orr	r0, r0, #0x003c		@ write buffer
++#ifdef CONFIG_MMU
++#ifdef CONFIG_CPU_ENDIAN_BE8
++		orr	r0, r0, #1 << 25	@ big-endian page tables
++#endif
++		orrne	r0, r0, #1		@ MMU enabled
++		movne	r1, #-1
++		mcrne	p15, 0, r3, c2, c0, 0	@ load page table pointer
++		mcrne	p15, 0, r1, c3, c0, 0	@ load domain access control
++#endif
++		mcr	p15, 0, r0, c1, c0, 0	@ load control register
++		mrc	p15, 0, r0, c1, c0, 0	@ and read it back
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c5, 4	@ ISB
++		mov	pc, r12
++
++__fa526_cache_on:
++		mov	r12, lr
++		bl	__setup_mmu
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c7, 0	@ Invalidate whole cache
++		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
++		mcr	p15, 0, r0, c8, c7, 0	@ flush UTLB
++		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
++		orr	r0, r0, #0x1000		@ I-cache enable
++		bl	__common_mmu_cache_on
++		mov	r0, #0
++		mcr	p15, 0, r0, c8, c7, 0	@ flush UTLB
++		mov	pc, r12
++
++__arm6_mmu_cache_on:
++		mov	r12, lr
++		bl	__setup_mmu
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
++		mcr	p15, 0, r0, c5, c0, 0	@ invalidate whole TLB v3
++		mov	r0, #0x30
++		bl	__common_mmu_cache_on
++		mov	r0, #0
++		mcr	p15, 0, r0, c5, c0, 0	@ invalidate whole TLB v3
++		mov	pc, r12
++
++__common_mmu_cache_on:
++#ifndef CONFIG_THUMB2_KERNEL
++#ifndef DEBUG
++		orr	r0, r0, #0x000d		@ Write buffer, mmu
++#endif
++		mov	r1, #-1
++		mcr	p15, 0, r3, c2, c0, 0	@ load page table pointer
++		mcr	p15, 0, r1, c3, c0, 0	@ load domain access control
++		b	1f
++		.align	5			@ cache line aligned
++1:		mcr	p15, 0, r0, c1, c0, 0	@ load control register
++		mrc	p15, 0, r0, c1, c0, 0	@ and read it back to
++		sub	pc, lr, r0, lsr #32	@ properly flush pipeline
++#endif
++
++/*
++ * All code following this line is relocatable.  It is relocated by
++ * the above code to the end of the decompressed kernel image and
++ * executed there.  During this time, we have no stacks.
++ *
++ * r0     = decompressed kernel length
++ * r1-r3  = unused
++ * r4     = kernel execution address
++ * r5     = decompressed kernel start
++ * r7     = architecture ID
++ * r8     = atags pointer
++ * r9-r12,r14 = corrupted
++ */
++		.align	5
++reloc_start:	add	r9, r5, r0
++		sub	r9, r9, #128		@ do not copy the stack
++		debug_reloc_start
++		mov	r1, r4
++1:
++		.rept	4
++		ldmia	r5!, {r0, r2, r3, r10 - r12, r14}	@ relocate kernel
++		stmia	r1!, {r0, r2, r3, r10 - r12, r14}
++		.endr
++
++		cmp	r5, r9
++		blo	1b
++		mov	sp, r1
++		add	sp, sp, #128		@ relocate the stack
++		debug_reloc_end
++
++call_kernel:	bl	cache_clean_flush
++		bl	cache_off
++		mov	r0, #0			@ must be zero
++		mov	r1, r7			@ restore architecture number
++		mov	r2, r8			@ restore atags pointer
++		mov	pc, r4			@ call kernel
++
++/*
++ * Here follow the relocatable cache support functions for the
++ * various processors.  This is a generic hook for locating an
++ * entry and jumping to an instruction at the specified offset
++ * from the start of the block.  Please note this is all position
++ * independent code.
++ *
++ *  r1  = corrupted
++ *  r2  = corrupted
++ *  r3  = block offset
++ *  r9  = corrupted
++ *  r12 = corrupted
++ */
++
++call_cache_fn:	adr	r12, proc_types
++#ifdef CONFIG_CPU_CP15
++		mrc	p15, 0, r9, c0, c0	@ get processor ID
++#else
++		ldr	r9, =CONFIG_PROCESSOR_ID
++#endif
++1:		ldr	r1, [r12, #0]		@ get value
++		ldr	r2, [r12, #4]		@ get mask
++		eor	r1, r1, r9		@ (real ^ match)
++		tst	r1, r2			@       & mask
++ ARM(		addeq	pc, r12, r3		) @ call cache function
++ THUMB(		addeq	r12, r3			)
++ THUMB(		moveq	pc, r12			) @ call cache function
++		add	r12, r12, #4*5
++		b	1b
++
++/*
++ * Table for cache operations.  This is basically:
++ *   - CPU ID match
++ *   - CPU ID mask
++ *   - 'cache on' method instruction
++ *   - 'cache off' method instruction
++ *   - 'cache flush' method instruction
++ *
++ * We match an entry using: ((real_id ^ match) & mask) == 0
++ *
++ * Writethrough caches generally only need 'on' and 'off'
++ * methods.  Writeback caches _must_ have the flush method
++ * defined.
++ */
++		.align	2
++		.type	proc_types,#object
++proc_types:
++		.word	0x41560600		@ ARM6/610
++		.word	0xffffffe0
++		W(b)	__arm6_mmu_cache_off	@ works, but slow
++		W(b)	__arm6_mmu_cache_off
++		mov	pc, lr
++ THUMB(		nop				)
++@		b	__arm6_mmu_cache_on		@ untested
++@		b	__arm6_mmu_cache_off
++@		b	__armv3_mmu_cache_flush
++
++		.word	0x00000000		@ old ARM ID
++		.word	0x0000f000
++		mov	pc, lr
++ THUMB(		nop				)
++		mov	pc, lr
++ THUMB(		nop				)
++		mov	pc, lr
++ THUMB(		nop				)
++
++		.word	0x41007000		@ ARM7/710
++		.word	0xfff8fe00
++		W(b)	__arm7_mmu_cache_off
++		W(b)	__arm7_mmu_cache_off
++		mov	pc, lr
++ THUMB(		nop				)
++
++		.word	0x41807200		@ ARM720T (writethrough)
++		.word	0xffffff00
++		W(b)	__armv4_mmu_cache_on
++		W(b)	__armv4_mmu_cache_off
++		mov	pc, lr
++ THUMB(		nop				)
++
++		.word	0x41007400		@ ARM74x
++		.word	0xff00ff00
++		W(b)	__armv3_mpu_cache_on
++		W(b)	__armv3_mpu_cache_off
++		W(b)	__armv3_mpu_cache_flush
++		
++		.word	0x41009400		@ ARM94x
++		.word	0xff00ff00
++		W(b)	__armv4_mpu_cache_on
++		W(b)	__armv4_mpu_cache_off
++		W(b)	__armv4_mpu_cache_flush
++
++		.word	0x00007000		@ ARM7 IDs
++		.word	0x0000f000
++		mov	pc, lr
++ THUMB(		nop				)
++		mov	pc, lr
++ THUMB(		nop				)
++		mov	pc, lr
++ THUMB(		nop				)
++
++		@ Everything from here on will be the new ID system.
++
++		.word	0x4401a100		@ sa110 / sa1100
++		.word	0xffffffe0
++		W(b)	__armv4_mmu_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__armv4_mmu_cache_flush
++
++		.word	0x6901b110		@ sa1110
++		.word	0xfffffff0
++		W(b)	__armv4_mmu_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__armv4_mmu_cache_flush
++
++		.word	0x56056900
++		.word	0xffffff00		@ PXA9xx
++		W(b)	__armv4_mmu_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__armv4_mmu_cache_flush
++
++		.word	0x56158000		@ PXA168
++		.word	0xfffff000
++		W(b)	__armv4_mmu_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__armv5tej_mmu_cache_flush
++
++		.word	0x56050000		@ Feroceon
++		.word	0xff0f0000
++		W(b)	__armv4_mmu_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__armv5tej_mmu_cache_flush
++
++#ifdef CONFIG_CPU_FEROCEON_OLD_ID
++		/* this conflicts with the standard ARMv5TE entry */
++		.long	0x41009260		@ Old Feroceon
++		.long	0xff00fff0
++		b	__armv4_mmu_cache_on
++		b	__armv4_mmu_cache_off
++		b	__armv5tej_mmu_cache_flush
++#endif
++
++		.word	0x66015261		@ FA526
++		.word	0xff01fff1
++		W(b)	__fa526_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__fa526_cache_flush
++
++		@ These match on the architecture ID
++
++		.word	0x00020000		@ ARMv4T
++		.word	0x000f0000
++		W(b)	__armv4_mmu_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__armv4_mmu_cache_flush
++
++		.word	0x00050000		@ ARMv5TE
++		.word	0x000f0000
++		W(b)	__armv4_mmu_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__armv4_mmu_cache_flush
++
++		.word	0x00060000		@ ARMv5TEJ
++		.word	0x000f0000
++		W(b)	__armv4_mmu_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__armv5tej_mmu_cache_flush
++
++		.word	0x0007b000		@ ARMv6
++		.word	0x000ff000
++		W(b)	__armv4_mmu_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__armv6_mmu_cache_flush
++
++		.word	0x560f5810		@ Marvell PJ4 ARMv6
++		.word	0xff0ffff0
++		W(b)	__armv4_mmu_cache_on
++		W(b)	__armv4_mmu_cache_off
++		W(b)	__armv6_mmu_cache_flush
++
++		.word	0x000f0000		@ new CPU Id
++		.word	0x000f0000
++		W(b)	__armv7_mmu_cache_on
++		W(b)	__armv7_mmu_cache_off
++		W(b)	__armv7_mmu_cache_flush
++
++		.word	0			@ unrecognised type
++		.word	0
++		mov	pc, lr
++ THUMB(		nop				)
++		mov	pc, lr
++ THUMB(		nop				)
++		mov	pc, lr
++ THUMB(		nop				)
++
++		.size	proc_types, . - proc_types
++
++/*
++ * Turn off the Cache and MMU.  ARMv3 does not support
++ * reading the control register, but ARMv4 does.
++ *
++ * On exit, r0, r1, r2, r3, r9, r12 corrupted
++ * This routine must preserve: r4, r6, r7
++ */
++		.align	5
++cache_off:	mov	r3, #12			@ cache_off function
++		b	call_cache_fn
++
++__armv4_mpu_cache_off:
++		mrc	p15, 0, r0, c1, c0
++		bic	r0, r0, #0x000d
++		mcr	p15, 0, r0, c1, c0	@ turn MPU and cache off
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
++		mcr	p15, 0, r0, c7, c6, 0	@ flush D-Cache
++		mcr	p15, 0, r0, c7, c5, 0	@ flush I-Cache
++		mov	pc, lr
++
++__armv3_mpu_cache_off:
++		mrc	p15, 0, r0, c1, c0
++		bic	r0, r0, #0x000d
++		mcr	p15, 0, r0, c1, c0, 0	@ turn MPU and cache off
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
++		mov	pc, lr
++
++__armv4_mmu_cache_off:
++#ifdef CONFIG_MMU
++		mrc	p15, 0, r0, c1, c0
++		bic	r0, r0, #0x000d
++		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c7	@ invalidate whole cache v4
++		mcr	p15, 0, r0, c8, c7	@ invalidate whole TLB v4
++#endif
++		mov	pc, lr
++
++__armv7_mmu_cache_off:
++		mrc	p15, 0, r0, c1, c0
++#ifdef CONFIG_MMU
++		bic	r0, r0, #0x000d
++#else
++		bic	r0, r0, #0x000c
++#endif
++		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
++		mov	r12, lr
++		bl	__armv7_mmu_cache_flush
++		mov	r0, #0
++#ifdef CONFIG_MMU
++		mcr	p15, 0, r0, c8, c7, 0	@ invalidate whole TLB
++#endif
++		mcr	p15, 0, r0, c7, c5, 6	@ invalidate BTC
++		mcr	p15, 0, r0, c7, c10, 4	@ DSB
++		mcr	p15, 0, r0, c7, c5, 4	@ ISB
++		mov	pc, r12
++
++__arm6_mmu_cache_off:
++		mov	r0, #0x00000030		@ ARM6 control reg.
++		b	__armv3_mmu_cache_off
++
++__arm7_mmu_cache_off:
++		mov	r0, #0x00000070		@ ARM7 control reg.
++		b	__armv3_mmu_cache_off
++
++__armv3_mmu_cache_off:
++		mcr	p15, 0, r0, c1, c0, 0	@ turn MMU and cache off
++		mov	r0, #0
++		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
++		mcr	p15, 0, r0, c5, c0, 0	@ invalidate whole TLB v3
++		mov	pc, lr
++
++/*
++ * Clean and flush the cache to maintain consistency.
++ *
++ * On exit,
++ *  r1, r2, r3, r9, r11, r12 corrupted
++ * This routine must preserve:
++ *  r0, r4, r5, r6, r7
++ */
++		.align	5
++cache_clean_flush:
++		mov	r3, #16
++		b	call_cache_fn
++
++__armv4_mpu_cache_flush:
++		mov	r2, #1
++		mov	r3, #0
++		mcr	p15, 0, ip, c7, c6, 0	@ invalidate D cache
++		mov	r1, #7 << 5		@ 8 segments
++1:		orr	r3, r1, #63 << 26	@ 64 entries
++2:		mcr	p15, 0, r3, c7, c14, 2	@ clean & invalidate D index
++		subs	r3, r3, #1 << 26
++		bcs	2b			@ entries 63 to 0
++		subs 	r1, r1, #1 << 5
++		bcs	1b			@ segments 7 to 0
++
++		teq	r2, #0
++		mcrne	p15, 0, ip, c7, c5, 0	@ invalidate I cache
++		mcr	p15, 0, ip, c7, c10, 4	@ drain WB
++		mov	pc, lr
++		
++__fa526_cache_flush:
++		mov	r1, #0
++		mcr	p15, 0, r1, c7, c14, 0	@ clean and invalidate D cache
++		mcr	p15, 0, r1, c7, c5, 0	@ flush I cache
++		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
++		mov	pc, lr
++
++__armv6_mmu_cache_flush:
++		mov	r1, #0
++		mcr	p15, 0, r1, c7, c14, 0	@ clean+invalidate D
++		mcr	p15, 0, r1, c7, c5, 0	@ invalidate I+BTB
++		mcr	p15, 0, r1, c7, c15, 0	@ clean+invalidate unified
++		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
++		mov	pc, lr
++
++__armv7_mmu_cache_flush:
++		mrc	p15, 0, r10, c0, c1, 5	@ read ID_MMFR1
++		tst	r10, #0xf << 16		@ hierarchical cache (ARMv7)
++		mov	r10, #0
++		beq	hierarchical
++		mcr	p15, 0, r10, c7, c14, 0	@ clean+invalidate D
++		b	iflush
++hierarchical:
++		mcr	p15, 0, r10, c7, c10, 5	@ DMB
++		stmfd	sp!, {r0-r7, r9-r11}
++		mrc	p15, 1, r0, c0, c0, 1	@ read clidr
++		ands	r3, r0, #0x7000000	@ extract loc from clidr
++		mov	r3, r3, lsr #23		@ left align loc bit field
++		beq	finished		@ if loc is 0, then no need to clean
++		mov	r10, #0			@ start clean at cache level 0
++loop1:
++		add	r2, r10, r10, lsr #1	@ work out 3x current cache level
++		mov	r1, r0, lsr r2		@ extract cache type bits from clidr
++		and	r1, r1, #7		@ mask of the bits for current cache only
++		cmp	r1, #2			@ see what cache we have at this level
++		blt	skip			@ skip if no cache, or just i-cache
++		mcr	p15, 2, r10, c0, c0, 0	@ select current cache level in cssr
++		mcr	p15, 0, r10, c7, c5, 4	@ isb to sych the new cssr&csidr
++		mrc	p15, 1, r1, c0, c0, 0	@ read the new csidr
++		and	r2, r1, #7		@ extract the length of the cache lines
++		add	r2, r2, #4		@ add 4 (line length offset)
++		ldr	r4, =0x3ff
++		ands	r4, r4, r1, lsr #3	@ find maximum number on the way size
++		clz	r5, r4			@ find bit position of way size increment
++		ldr	r7, =0x7fff
++		ands	r7, r7, r1, lsr #13	@ extract max number of the index size
++loop2:
++		mov	r9, r4			@ create working copy of max way size
++loop3:
++ ARM(		orr	r11, r10, r9, lsl r5	) @ factor way and cache number into r11
++ ARM(		orr	r11, r11, r7, lsl r2	) @ factor index number into r11
++ THUMB(		lsl	r6, r9, r5		)
++ THUMB(		orr	r11, r10, r6		) @ factor way and cache number into r11
++ THUMB(		lsl	r6, r7, r2		)
++ THUMB(		orr	r11, r11, r6		) @ factor index number into r11
++		mcr	p15, 0, r11, c7, c14, 2	@ clean & invalidate by set/way
++		subs	r9, r9, #1		@ decrement the way
++		bge	loop3
++		subs	r7, r7, #1		@ decrement the index
++		bge	loop2
++skip:
++		add	r10, r10, #2		@ increment cache number
++		cmp	r3, r10
++		bgt	loop1
++finished:
++		ldmfd	sp!, {r0-r7, r9-r11}
++		mov	r10, #0			@ swith back to cache level 0
++		mcr	p15, 2, r10, c0, c0, 0	@ select current cache level in cssr
++iflush:
++		mcr	p15, 0, r10, c7, c10, 4	@ DSB
++		mcr	p15, 0, r10, c7, c5, 0	@ invalidate I+BTB
++		mcr	p15, 0, r10, c7, c10, 4	@ DSB
++		mcr	p15, 0, r10, c7, c5, 4	@ ISB
++		mov	pc, lr
++
++__armv5tej_mmu_cache_flush:
++1:		mrc	p15, 0, r15, c7, c14, 3	@ test,clean,invalidate D cache
++		bne	1b
++		mcr	p15, 0, r0, c7, c5, 0	@ flush I cache
++		mcr	p15, 0, r0, c7, c10, 4	@ drain WB
++		mov	pc, lr
++
++__armv4_mmu_cache_flush:
++		mov	r2, #64*1024		@ default: 32K dcache size (*2)
++		mov	r11, #32		@ default: 32 byte line size
++		mrc	p15, 0, r3, c0, c0, 1	@ read cache type
++		teq	r3, r9			@ cache ID register present?
++		beq	no_cache_id
++		mov	r1, r3, lsr #18
++		and	r1, r1, #7
++		mov	r2, #1024
++		mov	r2, r2, lsl r1		@ base dcache size *2
++		tst	r3, #1 << 14		@ test M bit
++		addne	r2, r2, r2, lsr #1	@ +1/2 size if M == 1
++		mov	r3, r3, lsr #12
++		and	r3, r3, #3
++		mov	r11, #8
++		mov	r11, r11, lsl r3	@ cache line size in bytes
++no_cache_id:
++		mov	r1, pc
++		bic	r1, r1, #63		@ align to longest cache line
++		add	r2, r1, r2
++1:
++ ARM(		ldr	r3, [r1], r11		) @ s/w flush D cache
++ THUMB(		ldr     r3, [r1]		) @ s/w flush D cache
++ THUMB(		add     r1, r1, r11		)
++		teq	r1, r2
++		bne	1b
++
++		mcr	p15, 0, r1, c7, c5, 0	@ flush I cache
++		mcr	p15, 0, r1, c7, c6, 0	@ flush D cache
++		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
++		mov	pc, lr
++
++__armv3_mmu_cache_flush:
++__armv3_mpu_cache_flush:
++		mov	r1, #0
++		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
++		mov	pc, lr
++
++/*
++ * Various debugging routines for printing hex characters and
++ * memory, which again must be relocatable.
++ */
++#ifdef DEBUG
++		.align	2
++		.type	phexbuf,#object
++phexbuf:	.space	12
++		.size	phexbuf, . - phexbuf
++
++phex:		adr	r3, phexbuf
++		mov	r2, #0
++		strb	r2, [r3, r1]
++1:		subs	r1, r1, #1
++		movmi	r0, r3
++		bmi	puts
++		and	r2, r0, #15
++		mov	r0, r0, lsr #4
++		cmp	r2, #10
++		addge	r2, r2, #7
++		add	r2, r2, #'0'
++		strb	r2, [r3, r1]
++		b	1b
++
++puts:		loadsp	r3, r1
++1:		ldrb	r2, [r0], #1
++		teq	r2, #0
++		moveq	pc, lr
++2:		writeb	r2, r3
++		mov	r1, #0x00020000
++3:		subs	r1, r1, #1
++		bne	3b
++		teq	r2, #'\n'
++		moveq	r2, #'\r'
++		beq	2b
++		teq	r0, #0
++		bne	1b
++		mov	pc, lr
++putc:
++		mov	r2, r0
++		mov	r0, #0
++		loadsp	r3, r1
++		b	2b
++
++memdump:	mov	r12, r0
++		mov	r10, lr
++		mov	r11, #0
++2:		mov	r0, r11, lsl #2
++		add	r0, r0, r12
++		mov	r1, #8
++		bl	phex
++		mov	r0, #':'
++		bl	putc
++1:		mov	r0, #' '
++		bl	putc
++		ldr	r0, [r12, r11, lsl #2]
++		mov	r1, #8
++		bl	phex
++		and	r0, r11, #7
++		teq	r0, #3
++		moveq	r0, #' '
++		bleq	putc
++		and	r0, r11, #7
++		add	r11, r11, #1
++		teq	r0, #7
++		bne	1b
++		mov	r0, #'\n'
++		bl	putc
++		cmp	r11, #64
++		blt	2b
++		mov	pc, r10
++#endif
++
++		.ltorg
++reloc_end:
++
++		.align
++		.section ".stack", "w"
++user_stack:	.space	4096
+diff -rupN linux-2.6.35.11/arch/arm/boot/compressed/head-str8100.S linux-2.6.35.11-ts7500/arch/arm/boot/compressed/head-str8100.S
+--- linux-2.6.35.11/arch/arm/boot/compressed/head-str8100.S	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/compressed/head-str8100.S	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,7 @@
++#include <asm/mach-types.h>
++
++		.section	".start", "ax"
++
++__str8100_start:
++		mov	r7, #(MACH_TYPE_STR8100 & 0xFF00)
++		orr	r7, r7, #(MACH_TYPE_STR8100 & 0x00FF)
+diff -rupN linux-2.6.35.11/arch/arm/boot/compressed/head-str9100.S linux-2.6.35.11-ts7500/arch/arm/boot/compressed/head-str9100.S
+--- linux-2.6.35.11/arch/arm/boot/compressed/head-str9100.S	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/compressed/head-str9100.S	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,7 @@
++#include <asm/mach-types.h>
++
++		.section	".start", "ax"
++
++__str9100_start:
++		mov	r7, #(MACH_TYPE_STR9100 & 0xFF00)
++		orr	r7, r7, #(MACH_TYPE_STR9100 & 0x00FF)
+diff -rupN linux-2.6.35.11/arch/arm/boot/compressed/Makefile linux-2.6.35.11-ts7500/arch/arm/boot/compressed/Makefile
+--- linux-2.6.35.11/arch/arm/boot/compressed/Makefile	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/compressed/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -48,6 +48,14 @@ else
+ endif
+ endif
+ 
++ifeq ($(CONFIG_ARCH_STR9100),y)
++OBJS		+= head-str9100.o
++endif
++
++ifeq ($(CONFIG_ARCH_STR8100),y)
++OBJS		+= head-str8100.o
++endif
++
+ #
+ # We now have a PIC decompressor implementation.  Decompressors running
+ # from RAM should not define ZTEXTADDR.  Decompressors running directly
+diff -rupN linux-2.6.35.11/arch/arm/boot/compressed/Makefile.orig linux-2.6.35.11-ts7500/arch/arm/boot/compressed/Makefile.orig
+--- linux-2.6.35.11/arch/arm/boot/compressed/Makefile.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/compressed/Makefile.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,129 @@
++#
++# linux/arch/arm/boot/compressed/Makefile
++#
++# create a compressed vmlinuz image from the original vmlinux
++#
++
++HEAD	= head.o
++OBJS	= misc.o decompress.o
++FONTC	= $(srctree)/drivers/video/console/font_acorn_8x8.c
++
++#
++# Architecture dependencies
++#
++ifeq ($(CONFIG_ARCH_ACORN),y)
++OBJS		+= ll_char_wr.o font.o
++endif
++
++ifeq ($(CONFIG_ARCH_SHARK),y)
++OBJS		+= head-shark.o ofw-shark.o
++endif
++
++ifeq ($(CONFIG_ARCH_L7200),y)
++OBJS		+= head-l7200.o
++endif
++
++ifeq ($(CONFIG_ARCH_P720T),y)
++# Borrow this code from SA1100
++OBJS		+= head-sa1100.o
++endif
++
++ifeq ($(CONFIG_ARCH_SA1100),y)
++OBJS		+= head-sa1100.o
++endif
++
++ifeq ($(CONFIG_CPU_XSCALE),y)
++OBJS		+= head-xscale.o
++endif
++
++ifeq ($(CONFIG_PXA_SHARPSL),y)
++OBJS		+= head-sharpsl.o
++endif
++
++ifeq ($(CONFIG_CPU_ENDIAN_BE32),y)
++ifeq ($(CONFIG_CPU_CP15),y)
++OBJS		+= big-endian.o
++else
++# The endian should be set by h/w design.
++endif
++endif
++
++#
++# We now have a PIC decompressor implementation.  Decompressors running
++# from RAM should not define ZTEXTADDR.  Decompressors running directly
++# from ROM or Flash must define ZTEXTADDR (preferably via the config)
++# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
++ifeq ($(CONFIG_ZBOOT_ROM),y)
++ZTEXTADDR	:= $(CONFIG_ZBOOT_ROM_TEXT)
++ZBSSADDR	:= $(CONFIG_ZBOOT_ROM_BSS)
++else
++ZTEXTADDR	:= 0
++ZBSSADDR	:= ALIGN(4)
++endif
++
++SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
++
++suffix_$(CONFIG_KERNEL_GZIP) = gzip
++suffix_$(CONFIG_KERNEL_LZO)  = lzo
++suffix_$(CONFIG_KERNEL_LZMA) = lzma
++
++targets       := vmlinux vmlinux.lds \
++		 piggy.$(suffix_y) piggy.$(suffix_y).o \
++		 font.o font.c head.o misc.o $(OBJS)
++
++# Make sure files are removed during clean
++extra-y       += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S
++
++ifeq ($(CONFIG_FUNCTION_TRACER),y)
++ORIG_CFLAGS := $(KBUILD_CFLAGS)
++KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
++endif
++
++EXTRA_CFLAGS  := -fpic -fno-builtin
++EXTRA_AFLAGS  := -Wa,-march=all
++
++# Supply ZRELADDR, INITRD_PHYS and PARAMS_PHYS to the decompressor via
++# linker symbols.  We only define initrd_phys and params_phys if the
++# machine class defined the corresponding makefile variable.
++LDFLAGS_vmlinux := --defsym zreladdr=$(ZRELADDR)
++ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
++LDFLAGS_vmlinux += --be8
++endif
++ifneq ($(INITRD_PHYS),)
++LDFLAGS_vmlinux += --defsym initrd_phys=$(INITRD_PHYS)
++endif
++ifneq ($(PARAMS_PHYS),)
++LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS)
++endif
++# ?
++LDFLAGS_vmlinux += -p
++# Report unresolved symbol references
++LDFLAGS_vmlinux += --no-undefined
++# Delete all temporary local symbols
++LDFLAGS_vmlinux += -X
++# Next argument is a linker script
++LDFLAGS_vmlinux += -T
++
++# For __aeabi_uidivmod
++lib1funcs = $(obj)/lib1funcs.o
++
++$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
++	$(call cmd,shipped)
++
++$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
++	 	$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
++	$(call if_changed,ld)
++	@:
++
++$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
++	$(call if_changed,$(suffix_y))
++
++$(obj)/piggy.$(suffix_y).o:  $(obj)/piggy.$(suffix_y) FORCE
++
++CFLAGS_font.o := -Dstatic=
++
++$(obj)/font.c: $(FONTC)
++	$(call cmd,shipped)
++
++$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
++	@sed "$(SEDFLAGS)" < $< > $@
+diff -rupN linux-2.6.35.11/arch/arm/boot/compressed/misc.c linux-2.6.35.11-ts7500/arch/arm/boot/compressed/misc.c
+--- linux-2.6.35.11/arch/arm/boot/compressed/misc.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/compressed/misc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -101,8 +101,11 @@ static void icedcc_putc(int ch)
+ #endif
+ 
+ #define putc(ch)	icedcc_putc(ch)
++#define flush()	do { } while (0)
+ #endif
+ 
++#if defined(CONFIG_ARCH_STR8100) || defined(CONFIG_ARCH_STR9100)
++#else
+ static void putstr(const char *ptr)
+ {
+ 	char c;
+@@ -115,6 +118,7 @@ static void putstr(const char *ptr)
+ 
+ 	flush();
+ }
++#endif
+ 
+ #endif
+ 
+@@ -188,24 +192,38 @@ extern void do_decompress(u8 *input, int
+ 
+ #ifndef STANDALONE_DEBUG
+ 
++
+ unsigned long
+ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
+ 		unsigned long free_mem_ptr_end_p,
+ 		int arch_id)
+ {
++  extern void *foobar(int);
+ 	unsigned char *tmp;
+ 
+ 	output_data		= (unsigned char *)output_start;
+ 	free_mem_ptr		= free_mem_ptr_p;
+ 	free_mem_end_ptr	= free_mem_ptr_end_p;
+ 	__machine_arch_type	= arch_id;
+-
++      
++     
++   //putstr("\n\rfree_mem_ptr =        0x"); ser_puts_hex32((unsigned long)free_mem_ptr);
++   //putstr("\n\rfree_mem_end_ptr =    0x"); ser_puts_hex32((unsigned long)free_mem_end_ptr);
++   //putstr("\n\r__machine_arch_type = 0x"); ser_puts_hex32((unsigned long)__machine_arch_type);
++   //putstr("\n\r");
++   
+ 	arch_decomp_setup();
+ 
+ 	tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
+ 	output_ptr = get_unaligned_le32(tmp);
+ 
+ 	putstr("Uncompressing Linux...");
++   
++   //putstr("\n\rinput_data =        0x"); ser_puts_hex32((unsigned long)input_data);
++   //putstr("\n\rinput_data_end =    0x"); ser_puts_hex32((unsigned long)input_data_end);
++   //putstr("\n\routput_data =       0x"); ser_puts_hex32((unsigned long)output_data);
++   //putstr("\n\r");
++   
+ 	do_decompress(input_data, input_data_end - input_data,
+ 			output_data, error);
+ 	putstr(" done, booting the kernel.\n");
+diff -rupN linux-2.6.35.11/arch/arm/boot/compressed/misc.c.orig linux-2.6.35.11-ts7500/arch/arm/boot/compressed/misc.c.orig
+--- linux-2.6.35.11/arch/arm/boot/compressed/misc.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/compressed/misc.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,228 @@
++/*
++ * misc.c
++ * 
++ * This is a collection of several routines from gzip-1.0.3 
++ * adapted for Linux.
++ *
++ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
++ *
++ * Modified for ARM Linux by Russell King
++ *
++ * Nicolas Pitre <nico@visuaide.com>  1999/04/14 :
++ *  For this code to run directly from Flash, all constant variables must
++ *  be marked with 'const' and all other variables initialized at run-time 
++ *  only.  This way all non constant variables will end up in the bss segment,
++ *  which should point to addresses in RAM and cleared to 0 on start.
++ *  This allows for a much quicker boot time.
++ */
++
++unsigned int __machine_arch_type;
++
++#define _LINUX_STRING_H_
++
++#include <linux/compiler.h>	/* for inline */
++#include <linux/types.h>	/* for size_t */
++#include <linux/stddef.h>	/* for NULL */
++#include <linux/linkage.h>
++#include <asm/string.h>
++
++#include <asm/unaligned.h>
++
++#ifdef STANDALONE_DEBUG
++#define putstr printf
++#else
++
++static void putstr(const char *ptr);
++extern void error(char *x);
++
++#include <mach/uncompress.h>
++
++#ifdef CONFIG_DEBUG_ICEDCC
++
++#ifdef CONFIG_CPU_V6
++
++static void icedcc_putc(int ch)
++{
++	int status, i = 0x4000000;
++
++	do {
++		if (--i < 0)
++			return;
++
++		asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (status));
++	} while (status & (1 << 29));
++
++	asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
++}
++
++#elif defined(CONFIG_CPU_V7)
++
++static void icedcc_putc(int ch)
++{
++	asm(
++	"wait:	mrc	p14, 0, pc, c0, c1, 0			\n\
++		bcs	wait					\n\
++		mcr     p14, 0, %0, c0, c5, 0			"
++	: : "r" (ch));
++}
++
++#elif defined(CONFIG_CPU_XSCALE)
++
++static void icedcc_putc(int ch)
++{
++	int status, i = 0x4000000;
++
++	do {
++		if (--i < 0)
++			return;
++
++		asm volatile ("mrc p14, 0, %0, c14, c0, 0" : "=r" (status));
++	} while (status & (1 << 28));
++
++	asm("mcr p14, 0, %0, c8, c0, 0" : : "r" (ch));
++}
++
++#else
++
++static void icedcc_putc(int ch)
++{
++	int status, i = 0x4000000;
++
++	do {
++		if (--i < 0)
++			return;
++
++		asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
++	} while (status & 2);
++
++	asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch));
++}
++
++#endif
++
++#define putc(ch)	icedcc_putc(ch)
++#endif
++
++static void putstr(const char *ptr)
++{
++	char c;
++
++	while ((c = *ptr++) != '\0') {
++		if (c == '\n')
++			putc('\r');
++		putc(c);
++	}
++
++	flush();
++}
++
++#endif
++
++void *memcpy(void *__dest, __const void *__src, size_t __n)
++{
++	int i = 0;
++	unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
++
++	for (i = __n >> 3; i > 0; i--) {
++		*d++ = *s++;
++		*d++ = *s++;
++		*d++ = *s++;
++		*d++ = *s++;
++		*d++ = *s++;
++		*d++ = *s++;
++		*d++ = *s++;
++		*d++ = *s++;
++	}
++
++	if (__n & 1 << 2) {
++		*d++ = *s++;
++		*d++ = *s++;
++		*d++ = *s++;
++		*d++ = *s++;
++	}
++
++	if (__n & 1 << 1) {
++		*d++ = *s++;
++		*d++ = *s++;
++	}
++
++	if (__n & 1)
++		*d++ = *s++;
++
++	return __dest;
++}
++
++/*
++ * gzip delarations
++ */
++extern char input_data[];
++extern char input_data_end[];
++
++unsigned char *output_data;
++unsigned long output_ptr;
++
++unsigned long free_mem_ptr;
++unsigned long free_mem_end_ptr;
++
++#ifndef arch_error
++#define arch_error(x)
++#endif
++
++void error(char *x)
++{
++	arch_error(x);
++
++	putstr("\n\n");
++	putstr(x);
++	putstr("\n\n -- System halted");
++
++	while(1);	/* Halt */
++}
++
++asmlinkage void __div0(void)
++{
++	error("Attempting division by 0!");
++}
++
++extern void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
++
++#ifndef STANDALONE_DEBUG
++
++unsigned long
++decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
++		unsigned long free_mem_ptr_end_p,
++		int arch_id)
++{
++	unsigned char *tmp;
++
++	output_data		= (unsigned char *)output_start;
++	free_mem_ptr		= free_mem_ptr_p;
++	free_mem_end_ptr	= free_mem_ptr_end_p;
++	__machine_arch_type	= arch_id;
++
++	arch_decomp_setup();
++
++	tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
++	output_ptr = get_unaligned_le32(tmp);
++
++	putstr("Uncompressing Linux...");
++	do_decompress(input_data, input_data_end - input_data,
++			output_data, error);
++	putstr(" done, booting the kernel.\n");
++	return output_ptr;
++}
++#else
++
++char output_buffer[1500*1024];
++
++int main()
++{
++	output_data = output_buffer;
++
++	putstr("Uncompressing Linux...");
++	decompress(input_data, input_data_end - input_data,
++			NULL, NULL, output_data, NULL, error);
++	putstr("done.\n");
++	return 0;
++}
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/boot/Makefile linux-2.6.35.11-ts7500/arch/arm/boot/Makefile
+--- linux-2.6.35.11/arch/arm/boot/Makefile	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/boot/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -24,8 +24,10 @@ endif
+ ZRELADDR    := $(zreladdr-y)
+ PARAMS_PHYS := $(params_phys-y)
+ INITRD_PHYS := $(initrd_phys-y)
++# scott.kernel
++KERNEL_PHYS := $(kernel_phys-y)
+ 
+-export ZRELADDR INITRD_PHYS PARAMS_PHYS
++export ZRELADDR INITRD_PHYS KERNEL_PHYS PARAMS_PHYS
+ 
+ targets := Image zImage xipImage bootpImage uImage
+ 
+diff -rupN linux-2.6.35.11/arch/arm/configs/ts7500_defconfig linux-2.6.35.11-ts7500/arch/arm/configs/ts7500_defconfig
+--- linux-2.6.35.11/arch/arm/configs/ts7500_defconfig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/configs/ts7500_defconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,1423 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.36
++# Wed Nov 10 09:28:19 2010
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_CONSTRUCTORS=y
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_LOCK_KERNEL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_LZO is not set
++# CONFIG_SWAP is not set
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_RCU=y
++# CONFIG_TREE_PREEMPT_RCU is not set
++# CONFIG_TINY_RCU is not set
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_FANOUT=32
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++# CONFIG_NAMESPACES is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++# CONFIG_RD_BZIP2 is not set
++# CONFIG_RD_LZMA is not set
++# CONFIG_RD_LZO is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_EMBEDDED=y
++CONFIG_UID16=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_PERF_EVENTS is not set
++# CONFIG_PERF_COUNTERS is not set
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_PCI_QUIRKS=y
++CONFIG_COMPAT_BRK=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
++
++#
++# GCOV-based kernel profiling
++#
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_BLOCK=y
++# CONFIG_LBDAF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++# CONFIG_IOSCHED_CFQ is not set
++CONFIG_DEFAULT_DEADLINE=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="deadline"
++# CONFIG_INLINE_SPIN_TRYLOCK is not set
++# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
++# CONFIG_INLINE_SPIN_LOCK is not set
++# CONFIG_INLINE_SPIN_LOCK_BH is not set
++# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
++# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
++# CONFIG_INLINE_SPIN_UNLOCK is not set
++# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
++# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
++# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
++# CONFIG_INLINE_READ_TRYLOCK is not set
++# CONFIG_INLINE_READ_LOCK is not set
++# CONFIG_INLINE_READ_LOCK_BH is not set
++# CONFIG_INLINE_READ_LOCK_IRQ is not set
++# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
++# CONFIG_INLINE_READ_UNLOCK is not set
++# CONFIG_INLINE_READ_UNLOCK_BH is not set
++# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
++# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
++# CONFIG_INLINE_WRITE_TRYLOCK is not set
++# CONFIG_INLINE_WRITE_LOCK is not set
++# CONFIG_INLINE_WRITE_LOCK_BH is not set
++# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
++# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
++# CONFIG_INLINE_WRITE_UNLOCK is not set
++# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
++# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
++# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
++# CONFIG_MUTEX_SPIN_ON_OWNER is not set
++# CONFIG_FREEZER is not set
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_STR9100 is not set
++CONFIG_ARCH_STR8100=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_VEXPRESS is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_BCMRING is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CNS3XXX is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_STMP3XXX is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_LPC32XX is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_NUC93X is not set
++# CONFIG_ARCH_TEGRA is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P6440 is not set
++# CONFIG_ARCH_S5P6442 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++# CONFIG_ARCH_S5PV310 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_U8500 is not set
++# CONFIG_ARCH_NOMADIK is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_PLAT_SPEAR is not set
++CONFIG_CONSOLE_BAUD_RATE=115200
++
++#
++# STR8100 Options
++#
++CONFIG_VIC_INTERRUPT=y
++# CONFIG_STR8100_DRAM_16M is not set
++# CONFIG_STR8100_DRAM_32M is not set
++CONFIG_STR8100_DRAM_64M=y
++CONFIG_STR8100_PCI33M=y
++# CONFIG_STR8100_PCI66M is not set
++# CONFIG_STR8100_DMA is not set
++# CONFIG_STR8100_HSDMA is not set
++CONFIG_STR8100_INFO=y
++# CONFIG_STR8100_USBD_REBOOT_INTHANDLER is not set
++# CONFIG_STR8100_I2S is not set
++# CONFIG_STR8100_I2S_DEMO is not set
++# CONFIG_STR8100_I2S_WM8772_DEMO is not set
++# CONFIG_LE88221_CONTROL is not set
++# CONFIG_STR8100_PCM_LEGERITY_2PHONE_DEMO is not set
++# CONFIG_STR8100_RTC is not set
++CONFIG_STR8100_GPIO=y
++CONFIG_STR8100_GPIO_INTERRUPT=y
++# CONFIG_STR8100_GPIO_GENERIC_INTERFACE is not set
++
++#
++# Flash MAP
++#
++# CONFIG_STR8100_FLASH_PART is not set
++
++#
++# Third Party Support
++#
++# CONFIG_STR8100_EWC_SUPPORT is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_FA526=y
++CONFIG_CPU_32v4=y
++CONFIG_CPU_ABRT_EV4=y
++CONFIG_CPU_PABRT_LEGACY=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_CACHE_FA=y
++CONFIG_CPU_COPY_FA=y
++CONFIG_CPU_TLB_FA=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++CONFIG_CPU_FA_BTB=y
++# CONFIG_CPU_FA_WB_DISABLE is not set
++# CONFIG_CPU_BPREDICT_DISABLE is not set
++CONFIG_ARM_L1_CACHE_SHIFT=5
++
++#
++# Bus support
++#
++CONFIG_PCI=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCI_STUB is not set
++# CONFIG_PCI_IOV is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_HZ=100
++# CONFIG_AEABI is not set
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++# CONFIG_HIGHMEM is not set
++# CONFIG_SPARSE_IRQ is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_HAVE_MEMBLOCK=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=999999
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++# CONFIG_CC_STACKPROTECTOR is not set
++# CONFIG_DEPRECATED_PARAM_STRUCT is not set
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="root=/dev/ram0 init=/linuxrc lpj=958464 console=null"
++# CONFIG_CMDLINE_FORCE is not set
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++# CONFIG_AUTO_ZRELADDR is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=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_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++CONFIG_INET_LRO=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=m
++# 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=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=m
++# CONFIG_IPV6_SIT_6RD is not set
++CONFIG_IPV6_NDISC_NODETYPE=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_IPV6_MROUTE is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++# CONFIG_CFG80211 is not set
++# CONFIG_LIB80211 is not set
++
++#
++# CFG80211 needs to be enabled for MAC80211
++#
++
++#
++# Some wireless drivers require a rate control algorithm
++#
++# CONFIG_WIMAX is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_DEVTMPFS is not set
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=m
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=m
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++# CONFIG_BLK_DEV_LOOP is not set
++# CONFIG_BLK_DEV_DRBD is not set
++CONFIG_BLK_DEV_NBD=y
++# CONFIG_BLK_DEV_SX8 is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=4
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MISC_DEVICES is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=m
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=m
++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=m
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=m
++# CONFIG_CHR_DEV_SCH is not set
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++
++#
++# You can enable one or both FireWire driver stacks.
++#
++
++#
++# The newer stack is recommended.
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_FIREWIRE_NOSY is not set
++# CONFIG_I2O is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_ARCNET is not set
++# CONFIG_PHYLIB is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++# CONFIG_FAST_BRIDGE is not set
++# 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_CHELSIO_T4_DEPENDS=y
++# CONFIG_CHELSIO_T4 is not set
++CONFIG_CHELSIO_T4VF_DEPENDS=y
++# CONFIG_CHELSIO_T4VF 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_QLCNIC is not set
++# CONFIG_QLGE is not set
++# CONFIG_SFC is not set
++# CONFIG_BE2NET is not set
++
++#
++# CNS2100 NIC support
++#
++CONFIG_STAR_NIC=y
++CONFIG_STAR_NIC_PHY_INTERNAL_PHY=y
++# CONFIG_STAR_NIC_PHY_VSC8601 is not set
++# CONFIG_STAR_NIC_PHY_IP101A is not set
++# CONFIG_STAR_NIC_PHY_IP1001 is not set
++# CONFIG_TR is not set
++CONFIG_WLAN=y
++# CONFIG_ATMEL is not set
++# CONFIG_PRISM54 is not set
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_HOSTAP is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_USB_IPHETH is not set
++# CONFIG_WAN is not set
++
++#
++# CAIF transport drivers
++#
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NET_FC is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_VMXNET3 is not set
++# CONFIG_ISDN is not set
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=m
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=m
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++# CONFIG_INPUT_EVDEV is not set
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=m
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=m
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_SENTELIC is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_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=m
++CONFIG_SERIO_SERPORT=m
++# CONFIG_SERIO_PCIPS2 is not set
++CONFIG_SERIO_LIBPS2=m
++# CONFIG_SERIO_RAW is not set
++# CONFIG_SERIO_ALTERA_PS2 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_N_GSM is not set
++# CONFIG_NOZOMI is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_PCI is not set
++CONFIG_SERIAL_8250_NR_UARTS=2
++CONFIG_SERIAL_8250_RUNTIME_UARTS=2
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_CTSRTS is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_MAX3100 is not set
++# CONFIG_SERIAL_MAX3107 is not set
++# CONFIG_SERIAL_MFD_HSU is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_HW_RANDOM_TIMERIOMEM 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_RAMOOPS is not set
++# CONFIG_I2C is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++CONFIG_SPI_BITBANG=y
++CONFIG_SPI_STR8100=y
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB=m
++CONFIG_SSB_SPROM=y
++CONFIG_SSB_PCIHOST_POSSIBLE=y
++CONFIG_SSB_PCIHOST=y
++# CONFIG_SSB_B43_PCI_BRIDGE is not set
++# CONFIG_SSB_SILENT is not set
++# CONFIG_SSB_DEBUG is not set
++CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
++CONFIG_SSB_DRIVER_PCICORE=y
++CONFIG_MFD_SUPPORT=y
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_MC13783 is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_AB8500_CORE is not set
++# CONFIG_LPC_SCH is not set
++# CONFIG_MFD_RDC321X is not set
++# CONFIG_MFD_JANZ_CMODIO is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_MEDIA_SUPPORT is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGA_ARB is not set
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++# CONFIG_SOUND is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=m
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=m
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# USB HID Boot Protocol drivers
++#
++# CONFIG_USB_KBD is not set
++# CONFIG_USB_MOUSE is not set
++
++#
++# Special HID drivers
++#
++# CONFIG_HID_3M_PCT is not set
++# CONFIG_HID_A4TECH is not set
++# CONFIG_HID_ACRUX_FF is not set
++# CONFIG_HID_APPLE is not set
++# CONFIG_HID_BELKIN is not set
++# CONFIG_HID_CANDO 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_EGALAX is not set
++# CONFIG_HID_EZKEY is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_TWINHAN is not set
++# CONFIG_HID_KENSINGTON is not set
++# CONFIG_HID_LOGITECH is not set
++# CONFIG_HID_MICROSOFT is not set
++# CONFIG_HID_MOSART is not set
++# CONFIG_HID_MONTEREY is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_QUANTA is not set
++# CONFIG_HID_ROCCAT is not set
++# CONFIG_HID_ROCCAT_KONE is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_STANTUM is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON 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=m
++# CONFIG_USB_DEBUG is not set
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DEVICEFS is not set
++# CONFIG_USB_DEVICE_CLASS is not set
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG_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=m
++# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++CONFIG_USB_OHCI_HCD=m
++# CONFIG_USB_OHCI_HCD_SSB is not set
++# 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=m
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_WHCI_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++CONFIG_USB_SERIAL=m
++# CONFIG_USB_EZUSB is not set
++CONFIG_USB_SERIAL_GENERIC=y
++# CONFIG_USB_SERIAL_AIRCABLE is not set
++# CONFIG_USB_SERIAL_ARK3116 is not set
++# CONFIG_USB_SERIAL_BELKIN is not set
++# CONFIG_USB_SERIAL_CH341 is not set
++# CONFIG_USB_SERIAL_WHITEHEAT is not set
++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
++# CONFIG_USB_SERIAL_CP210X is not set
++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
++# CONFIG_USB_SERIAL_EMPEG is not set
++# CONFIG_USB_SERIAL_FTDI_SIO is not set
++# CONFIG_USB_SERIAL_FUNSOFT is not set
++# CONFIG_USB_SERIAL_VISOR is not set
++# CONFIG_USB_SERIAL_IPAQ is not set
++# CONFIG_USB_SERIAL_IR is not set
++# CONFIG_USB_SERIAL_EDGEPORT is not set
++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
++# CONFIG_USB_SERIAL_GARMIN is not set
++# CONFIG_USB_SERIAL_IPW is not set
++# CONFIG_USB_SERIAL_IUU is not set
++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
++# CONFIG_USB_SERIAL_KEYSPAN is not set
++# CONFIG_USB_SERIAL_KLSI is not set
++# CONFIG_USB_SERIAL_KOBIL_SCT is not set
++# CONFIG_USB_SERIAL_MCT_U232 is not set
++# CONFIG_USB_SERIAL_MOS7720 is not set
++# CONFIG_USB_SERIAL_MOS7840 is not set
++# CONFIG_USB_SERIAL_MOTOROLA is not set
++# CONFIG_USB_SERIAL_NAVMAN is not set
++# CONFIG_USB_SERIAL_PL2303 is not set
++# CONFIG_USB_SERIAL_OTI6858 is not set
++# CONFIG_USB_SERIAL_QCAUX is not set
++# CONFIG_USB_SERIAL_QUALCOMM is not set
++# CONFIG_USB_SERIAL_SPCP8X5 is not set
++# CONFIG_USB_SERIAL_HP4X is not set
++# 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_VIVOPAY_SERIAL is not set
++# CONFIG_USB_SERIAL_ZIO is not set
++# CONFIG_USB_SERIAL_SSU100 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_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_GADGET=m
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++CONFIG_USB_GADGET_R8A66597=y
++CONFIG_USB_R8A66597=m
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_CI13XXX is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++# CONFIG_USB_GADGET_LANGWELL is not set
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++CONFIG_USB_GADGET_DUALSPEED=y
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_ETH is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++# CONFIG_USB_FILE_STORAGE is not set
++# CONFIG_USB_MASS_STORAGE is not set
++# CONFIG_USB_G_SERIAL is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_MULTI is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_DBGP is not set
++
++#
++# OTG and related infrastructure
++#
++# CONFIG_USB_ULPI is not set
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_UWB is not set
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_INFINIBAND is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++# CONFIG_DMADEVICES is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# CONFIG_STAGING is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++CONFIG_EXT2_FS_XIP=y
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_XIP=y
++CONFIG_JBD=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FILE_LOCKING=y
++# CONFIG_FSNOTIFY is not set
++# CONFIG_DNOTIFY is not set
++# CONFIG_INOTIFY_USER is not set
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++# CONFIG_MSDOS_FS is not set
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_POSIX_ACL is not set
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++# CONFIG_MISC_FILESYSTEMS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++# CONFIG_ROOT_NFS is not set
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=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_CEPH_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++# CONFIG_EFI_PARTITION is not set
++# CONFIG_SYSV68_PARTITION is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++# CONFIG_NLS_ASCII is not set
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++# CONFIG_ENABLE_MUST_CHECK is not set
++CONFIG_FRAME_WARN=1024
++# CONFIG_MAGIC_SYSRQ is not set
++CONFIG_STRIP_ASM_SYMS=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_HARDLOCKUP_DETECTOR is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++# CONFIG_DEBUG_MEMORY_INIT is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++# CONFIG_FTRACE is not set
++# CONFIG_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++# CONFIG_OC_ETM is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_DEFAULT_SECURITY=""
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=m
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG=m
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++# CONFIG_CRYPTO_CBC is not set
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_GHASH is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++CONFIG_CRYPTO_MICHAEL_MIC=m
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=m
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=m
++# CONFIG_CRYPTO_ANUBIS is not set
++CONFIG_CRYPTO_ARC4=y
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++CONFIG_CRYPTO_ANSI_CPRNG=m
++# 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=m
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++CONFIG_NLATTR=y
++CONFIG_GENERIC_ATOMIC64=y
+diff -rupN linux-2.6.35.11/arch/arm/include/asm/page.h linux-2.6.35.11-ts7500/arch/arm/include/asm/page.h
+--- linux-2.6.35.11/arch/arm/include/asm/page.h	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/include/asm/page.h	2011-03-14 11:18:24.000000000 -0400
+@@ -84,6 +84,17 @@
+ # endif
+ #endif
+ 
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++#ifdef CONFIG_CPU_COPY_FA
++# ifdef _USER
++#  define MULTI_USER 1
++# else
++#  define _USER fa
++# endif
++#endif
++#endif
++
++
+ #ifdef CONFIG_CPU_SA1100
+ # ifdef _USER
+ #  define MULTI_USER 1
+diff -rupN linux-2.6.35.11/arch/arm/include/asm/pci.h linux-2.6.35.11-ts7500/arch/arm/include/asm/pci.h
+--- linux-2.6.35.11/arch/arm/include/asm/pci.h	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/include/asm/pci.h	2011-03-14 11:18:24.000000000 -0400
+@@ -75,6 +75,16 @@ static inline int pci_get_legacy_ide_irq
+ 	return 0;
+ }
+ 
++
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++#define HAVE_ARCH_PCI_MWI
++static inline int pcibios_prep_mwi(struct pci_dev *dev)
++{
++	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x08);
++	return 0;
++}
++#endif
++
+ #endif /* __KERNEL__ */
+  
+ #endif
+diff -rupN linux-2.6.35.11/arch/arm/include/asm/tlbflush.h linux-2.6.35.11-ts7500/arch/arm/include/asm/tlbflush.h
+--- linux-2.6.35.11/arch/arm/include/asm/tlbflush.h	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/include/asm/tlbflush.h	2011-03-14 11:18:24.000000000 -0400
+@@ -39,7 +39,7 @@
+ #define TLB_V6_D_ASID	(1 << 17)
+ #define TLB_V6_I_ASID	(1 << 18)
+ 
+-#define TLB_BTB		(1 << 28)
++//#define TLB_BTB		(1 << 28)
+ 
+ /* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */
+ #define TLB_V7_UIS_PAGE	(1 << 19)
+@@ -53,6 +53,12 @@
+ #define TLB_DCLEAN	(1 << 30)
+ #define TLB_WB		(1 << 31)
+ 
++
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++#define TLB_DINVAL	(1 << 28)
++#define TLB_BTB		(1 << 29)
++#endif
++
+ /*
+  *	MMU TLB Model
+  *	=============
+@@ -100,6 +106,29 @@
+ # define v4_always_flags	(-1UL)
+ #endif
+ 
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++#ifdef CONFIG_CPU_FA_BTB
++#define __TLB_BTB      TLB_BTB
++#else
++#define __TLB_BTB      0
++#endif
++
++#ifdef CONFIG_CPU_FA_WB_DISABLE
++#define __TLB_WB       0
++#else
++#define __TLB_WB       TLB_WB
++#endif
++
++/* Fix buggy CPU which doesn't invalidate Dcache properly */
++#ifdef CONFIG_CPU_FA520
++#define __TLB_DINVAL   TLB_DINVAL
++#elif defined(CONFIG_CPU_FA526)
++//#define __TLB_DINVAL   TLB_DINVAL
++#define __TLB_DINVAL   0
++#else
++#define __TLB_DINVAL   0
++#endif
++
+ #define fa_tlb_flags	(TLB_WB | TLB_BTB | TLB_DCLEAN | \
+ 			 TLB_V4_U_FULL | TLB_V4_U_PAGE)
+ 
+@@ -115,6 +144,7 @@
+ # define fa_possible_flags	0
+ # define fa_always_flags	(-1UL)
+ #endif
++#endif
+ 
+ #define v4wbi_tlb_flags	(TLB_WB | TLB_DCLEAN | \
+ 			 TLB_V4_I_FULL | TLB_V4_D_FULL | \
+@@ -297,24 +327,36 @@ extern struct cpu_tlb_fns cpu_tlb;
+  * implemented the "%?" method, but this has been discontinued due to too
+  * many people getting it wrong.
+  */
+-#define possible_tlb_flags	(v3_possible_flags | \
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++#define possible_tlb_flags      (v3_possible_flags | \
+ 				 v4_possible_flags | \
+ 				 v4wbi_possible_flags | \
+-				 fr_possible_flags | \
+ 				 v4wb_possible_flags | \
+ 				 fa_possible_flags | \
+-				 v6wbi_possible_flags | \
+-				 v7wbi_possible_flags)
++				 v6wbi_possible_flags)
++#else
++#define possible_tlb_flags	(v3_possible_flags | \
++				 v4_possible_flags | \
++				 v4wbi_possible_flags | \
++				 v4wb_possible_flags | \
++				 v6wbi_possible_flags)
++#endif
+ 
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
+ #define always_tlb_flags	(v3_always_flags & \
+ 				 v4_always_flags & \
+ 				 v4wbi_always_flags & \
+-				 fr_always_flags & \
+ 				 v4wb_always_flags & \
+ 				 fa_always_flags & \
+-				 v6wbi_always_flags & \
+-				 v7wbi_always_flags)
+-
++				 v6wbi_always_flags)
++#else
++#define always_tlb_flags	(v3_always_flags & \
++				 v4_always_flags & \
++				 v4wbi_always_flags & \
++				 v4wb_always_flags & \
++				 v6wbi_always_flags)
++#endif
++             
+ #define tlb_flag(f)	((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
+ 
+ static inline void local_flush_tlb_all(void)
+@@ -322,6 +364,11 @@ static inline void local_flush_tlb_all(v
+ 	const int zero = 0;
+ 	const unsigned int __tlb_flag = __cpu_tlb_flags;
+ 
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++	if (tlb_flag(TLB_DINVAL))
++		asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero) : "cc");
++#endif   
++   
+ 	if (tlb_flag(TLB_WB))
+ 		dsb();
+ 
+@@ -333,9 +380,28 @@ static inline void local_flush_tlb_all(v
+ 		asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
+ 	if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
+ 		asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
+-	if (tlb_flag(TLB_V7_UIS_FULL))
+-		asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
+ 
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++	if (tlb_flag(TLB_BTB)) {
++		asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
++		asm("mov r0, r0" : : );
++		asm("mov r0, r0" : : );
++	}
++#endif
++
++//	if (tlb_flag(TLB_V7_UIS_FULL))
++	//	asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
++   
++   if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
++		     TLB_V6_I_PAGE | TLB_V6_D_PAGE |
++		     TLB_V6_I_ASID | TLB_V6_D_ASID)) {
++		/* flush the branch target cache */
++		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
++		dsb();
++		isb();
++	}
++
++#if (0)   
+ 	if (tlb_flag(TLB_BTB)) {
+ 		/* flush the branch target cache */
+ 		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+@@ -348,6 +414,7 @@ static inline void local_flush_tlb_all(v
+ 		dsb();
+ 		isb();
+ 	}
++#endif   
+ }
+ 
+ static inline void local_flush_tlb_mm(struct mm_struct *mm)
+@@ -356,6 +423,11 @@ static inline void local_flush_tlb_mm(st
+ 	const int asid = ASID(mm);
+ 	const unsigned int __tlb_flag = __cpu_tlb_flags;
+ 
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++	if (tlb_flag(TLB_DINVAL))
++		asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero) : "cc");
++#endif
++
+ 	if (tlb_flag(TLB_WB))
+ 		dsb();
+ 
+@@ -395,6 +467,7 @@ static inline void local_flush_tlb_mm(st
+ 		dsb();
+ 		isb();
+ 	}
++
+ }
+ 
+ static inline void
+@@ -404,7 +477,12 @@ local_flush_tlb_page(struct vm_area_stru
+ 	const unsigned int __tlb_flag = __cpu_tlb_flags;
+ 
+ 	uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
+-
++   
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++	if (tlb_flag(TLB_DINVAL))
++		asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero) : "cc"); // clean & invalidate data cache all
++#endif
++   
+ 	if (tlb_flag(TLB_WB))
+ 		dsb();
+ 
+@@ -445,6 +523,7 @@ local_flush_tlb_page(struct vm_area_stru
+ 		dsb();
+ 		isb();
+ 	}
++
+ }
+ 
+ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
+@@ -454,6 +533,11 @@ static inline void local_flush_tlb_kerne
+ 
+ 	kaddr &= PAGE_MASK;
+ 
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++	if (tlb_flag(TLB_DINVAL))
++		asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero) : "cc");
++#endif
++
+ 	if (tlb_flag(TLB_WB))
+ 		dsb();
+ 
+@@ -474,9 +558,28 @@ static inline void local_flush_tlb_kerne
+ 		asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
+ 	if (tlb_flag(TLB_V6_I_PAGE))
+ 		asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
+-	if (tlb_flag(TLB_V7_UIS_PAGE))
+-		asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc");
++   
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++	if (tlb_flag(TLB_BTB)) {
++		asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
++		asm("mov r0, r0" : : );
++		asm("mov r0, r0" : : );
++	}
++#endif
+ 
++	//if (tlb_flag(TLB_V7_UIS_PAGE))
++		//asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc");
++      
++      if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
++		     TLB_V6_I_PAGE | TLB_V6_D_PAGE |
++		     TLB_V6_I_ASID | TLB_V6_D_ASID)) {
++		/* flush the branch target cache */
++		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
++		dsb();
++		isb();
++	}
++   
++#if (0)
+ 	if (tlb_flag(TLB_BTB)) {
+ 		/* flush the branch target cache */
+ 		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+@@ -489,6 +592,7 @@ static inline void local_flush_tlb_kerne
+ 		dsb();
+ 		isb();
+ 	}
++#endif   
+ }
+ 
+ /*
+@@ -507,30 +611,53 @@ static inline void local_flush_tlb_kerne
+ static inline void flush_pmd_entry(pmd_t *pmd)
+ {
+ 	const unsigned int __tlb_flag = __cpu_tlb_flags;
++   const int zero = 0;
+ 
+ 	if (tlb_flag(TLB_DCLEAN))
+ 		asm("mcr	p15, 0, %0, c7, c10, 1	@ flush_pmd"
+ 			: : "r" (pmd) : "cc");
+ 
++/*         
+ 	if (tlb_flag(TLB_L2CLEAN_FR))
+ 		asm("mcr	p15, 1, %0, c15, c9, 1  @ L2 flush_pmd"
+ 			: : "r" (pmd) : "cc");
+-
++*/
+ 	if (tlb_flag(TLB_WB))
+ 		dsb();
++   
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++	if (tlb_flag(TLB_BTB)) {
++		asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
++		asm("mov r0, r0" : : );
++		asm("mov r0, r0" : : );
++	}
++#endif
++
+ }
+ 
+ static inline void clean_pmd_entry(pmd_t *pmd)
+ {
+ 	const unsigned int __tlb_flag = __cpu_tlb_flags;
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++	const unsigned int zero = 0;
++#endif
+ 
+ 	if (tlb_flag(TLB_DCLEAN))
+ 		asm("mcr	p15, 0, %0, c7, c10, 1	@ flush_pmd"
+ 			: : "r" (pmd) : "cc");
+-
++/*
+ 	if (tlb_flag(TLB_L2CLEAN_FR))
+ 		asm("mcr	p15, 1, %0, c15, c9, 1  @ L2 flush_pmd"
+ 			: : "r" (pmd) : "cc");
++*/
++
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++	if (tlb_flag(TLB_BTB)) {
++		asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
++		asm("mov r0, r0" : : );
++		asm("mov r0, r0" : : );
++	}
++#endif         
+ }
+ 
+ #undef tlb_flag
+@@ -571,4 +698,5 @@ extern void update_mmu_cache(struct vm_a
+ 
+ #endif /* CONFIG_MMU */
+ 
+-#endif
++#endif /* _ASMARM_TLBFLUSH_H */
++
+diff -rupN linux-2.6.35.11/arch/arm/Kconfig linux-2.6.35.11-ts7500/arch/arm/Kconfig
+--- linux-2.6.35.11/arch/arm/Kconfig	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -160,7 +160,8 @@ config ARCH_MAY_HAVE_PC_FDC
+ 
+ config ZONE_DMA
+ 	bool
+-
++   default y if !ARCH_STR8100
++	
+ config NEED_DMA_MAP_STATE
+        def_bool y
+ 
+@@ -210,6 +211,20 @@ choice
+ 	prompt "ARM system type"
+ 	default ARCH_VERSATILE
+ 
++config ARCH_STR9100
++	bool "Star-STR9100"
++	select PCI
++	help
++	  Star STR9100 is a platform based on Faraday's ARM9 compatible processor
++	  architecture.
++
++config ARCH_STR8100
++	bool "Star-STR8100"
++	select PCI
++	help
++	  Star STR8100 is a platform based on Faraday's ARM9 compatible processor
++	  architecture.
++     
+ config ARCH_AAEC2000
+ 	bool "Agilent AAEC-2000 based"
+ 	select CPU_ARM920T
+@@ -901,6 +916,14 @@ source "arch/arm/mach-s5p6442/Kconfig"
+ 
+ source "arch/arm/mach-s5pc100/Kconfig"
+ 
++if ARCH_STR9100
++source "arch/arm/mach-str9100/Kconfig"
++endif
++
++if ARCH_STR8100
++source "arch/arm/mach-str8100/Kconfig"
++endif
++
+ source "arch/arm/mach-s5pv210/Kconfig"
+ 
+ source "arch/arm/mach-shmobile/Kconfig"
+diff -rupN linux-2.6.35.11/arch/arm/Kconfig.orig linux-2.6.35.11-ts7500/arch/arm/Kconfig.orig
+--- linux-2.6.35.11/arch/arm/Kconfig.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/Kconfig.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,1691 @@
++#
++# For a description of the syntax of this configuration file,
++# see Documentation/kbuild/kconfig-language.txt.
++#
++
++mainmenu "Linux Kernel Configuration"
++
++config ARM
++	bool
++	default y
++	select HAVE_AOUT
++	select HAVE_IDE
++	select RTC_LIB
++	select SYS_SUPPORTS_APM_EMULATION
++	select GENERIC_ATOMIC64 if (!CPU_32v6K)
++	select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
++	select HAVE_ARCH_KGDB
++	select HAVE_KPROBES if (!XIP_KERNEL)
++	select HAVE_KRETPROBES if (HAVE_KPROBES)
++	select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
++	select HAVE_GENERIC_DMA_COHERENT
++	select HAVE_KERNEL_GZIP
++	select HAVE_KERNEL_LZO
++	select HAVE_KERNEL_LZMA
++	select HAVE_PERF_EVENTS
++	select PERF_USE_VMALLOC
++	help
++	  The ARM series is a line of low-power-consumption RISC chip designs
++	  licensed by ARM Ltd and targeted at embedded applications and
++	  handhelds such as the Compaq IPAQ.  ARM-based PCs are no longer
++	  manufactured, but legacy ARM-based PC hardware remains popular in
++	  Europe.  There is an ARM Linux project with a web page at
++	  <http://www.arm.linux.org.uk/>.
++
++config HAVE_PWM
++	bool
++
++config SYS_SUPPORTS_APM_EMULATION
++	bool
++
++config GENERIC_GPIO
++	bool
++
++config GENERIC_TIME
++	bool
++	default y
++
++config ARCH_USES_GETTIMEOFFSET
++	bool
++	default n
++
++config GENERIC_CLOCKEVENTS
++	bool
++
++config GENERIC_CLOCKEVENTS_BROADCAST
++	bool
++	depends on GENERIC_CLOCKEVENTS
++	default y if SMP && !LOCAL_TIMERS
++
++config HAVE_TCM
++	bool
++	select GENERIC_ALLOCATOR
++
++config HAVE_PROC_CPU
++	bool
++
++config NO_IOPORT
++	bool
++
++config EISA
++	bool
++	---help---
++	  The Extended Industry Standard Architecture (EISA) bus was
++	  developed as an open alternative to the IBM MicroChannel bus.
++
++	  The EISA bus provided some of the features of the IBM MicroChannel
++	  bus while maintaining backward compatibility with cards made for
++	  the older ISA bus.  The EISA bus saw limited use between 1988 and
++	  1995 when it was made obsolete by the PCI bus.
++
++	  Say Y here if you are building a kernel for an EISA-based machine.
++
++	  Otherwise, say N.
++
++config SBUS
++	bool
++
++config MCA
++	bool
++	help
++	  MicroChannel Architecture is found in some IBM PS/2 machines and
++	  laptops.  It is a bus system similar to PCI or ISA. See
++	  <file:Documentation/mca.txt> (and especially the web page given
++	  there) before attempting to build an MCA bus kernel.
++
++config GENERIC_HARDIRQS
++	bool
++	default y
++
++config STACKTRACE_SUPPORT
++	bool
++	default y
++
++config HAVE_LATENCYTOP_SUPPORT
++	bool
++	depends on !SMP
++	default y
++
++config LOCKDEP_SUPPORT
++	bool
++	default y
++
++config TRACE_IRQFLAGS_SUPPORT
++	bool
++	default y
++
++config HARDIRQS_SW_RESEND
++	bool
++	default y
++
++config GENERIC_IRQ_PROBE
++	bool
++	default y
++
++config GENERIC_LOCKBREAK
++	bool
++	default y
++	depends on SMP && PREEMPT
++
++config RWSEM_GENERIC_SPINLOCK
++	bool
++	default y
++
++config RWSEM_XCHGADD_ALGORITHM
++	bool
++
++config ARCH_HAS_ILOG2_U32
++	bool
++
++config ARCH_HAS_ILOG2_U64
++	bool
++
++config ARCH_HAS_CPUFREQ
++	bool
++	help
++	  Internal node to signify that the ARCH has CPUFREQ support
++	  and that the relevant menu configurations are displayed for
++	  it.
++
++config GENERIC_HWEIGHT
++	bool
++	default y
++
++config GENERIC_CALIBRATE_DELAY
++	bool
++	default y
++
++config ARCH_MAY_HAVE_PC_FDC
++	bool
++
++config ZONE_DMA
++	bool
++
++config NEED_DMA_MAP_STATE
++       def_bool y
++
++config GENERIC_ISA_DMA
++	bool
++
++config FIQ
++	bool
++
++config ARCH_MTD_XIP
++	bool
++
++config GENERIC_HARDIRQS_NO__DO_IRQ
++	def_bool y
++
++config ARM_L1_CACHE_SHIFT_6
++	bool
++	help
++	  Setting ARM L1 cache line size to 64 Bytes.
++
++config VECTORS_BASE
++	hex
++	default 0xffff0000 if MMU || CPU_HIGH_VECTOR
++	default DRAM_BASE if REMAP_VECTORS_TO_RAM
++	default 0x00000000
++	help
++	  The base address of exception vectors.
++
++source "init/Kconfig"
++
++source "kernel/Kconfig.freezer"
++
++menu "System Type"
++
++config MMU
++	bool "MMU-based Paged Memory Management Support"
++	default y
++	help
++	  Select if you want MMU-based virtualised addressing space
++	  support by paged memory management. If unsure, say 'Y'.
++
++#
++# The "ARM system type" choice list is ordered alphabetically by option
++# text.  Please add new entries in the option alphabetic order.
++#
++choice
++	prompt "ARM system type"
++	default ARCH_VERSATILE
++
++config ARCH_AAEC2000
++	bool "Agilent AAEC-2000 based"
++	select CPU_ARM920T
++	select ARM_AMBA
++	select HAVE_CLK
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  This enables support for systems based on the Agilent AAEC-2000
++
++config ARCH_INTEGRATOR
++	bool "ARM Ltd. Integrator family"
++	select ARM_AMBA
++	select ARCH_HAS_CPUFREQ
++	select COMMON_CLKDEV
++	select ICST
++	select GENERIC_CLOCKEVENTS
++	select PLAT_VERSATILE
++	help
++	  Support for ARM's Integrator platform.
++
++config ARCH_REALVIEW
++	bool "ARM Ltd. RealView family"
++	select ARM_AMBA
++	select COMMON_CLKDEV
++	select ICST
++	select GENERIC_CLOCKEVENTS
++	select ARCH_WANT_OPTIONAL_GPIOLIB
++	select PLAT_VERSATILE
++	select ARM_TIMER_SP804
++	select GPIO_PL061 if GPIOLIB
++	help
++	  This enables support for ARM Ltd RealView boards.
++
++config ARCH_VERSATILE
++	bool "ARM Ltd. Versatile family"
++	select ARM_AMBA
++	select ARM_VIC
++	select COMMON_CLKDEV
++	select ICST
++	select GENERIC_CLOCKEVENTS
++	select ARCH_WANT_OPTIONAL_GPIOLIB
++	select PLAT_VERSATILE
++	select ARM_TIMER_SP804
++	help
++	  This enables support for ARM Ltd Versatile board.
++
++config ARCH_VEXPRESS
++	bool "ARM Ltd. Versatile Express family"
++	select ARCH_WANT_OPTIONAL_GPIOLIB
++	select ARM_AMBA
++	select ARM_TIMER_SP804
++	select COMMON_CLKDEV
++	select GENERIC_CLOCKEVENTS
++	select HAVE_CLK
++	select ICST
++	select PLAT_VERSATILE
++	help
++	  This enables support for the ARM Ltd Versatile Express boards.
++
++config ARCH_AT91
++	bool "Atmel AT91"
++	select ARCH_REQUIRE_GPIOLIB
++	select HAVE_CLK
++	help
++	  This enables support for systems based on the Atmel AT91RM9200,
++	  AT91SAM9 and AT91CAP9 processors.
++
++config ARCH_BCMRING
++	bool "Broadcom BCMRING"
++	depends on MMU
++	select CPU_V6
++	select ARM_AMBA
++	select COMMON_CLKDEV
++	select GENERIC_CLOCKEVENTS
++	select ARCH_WANT_OPTIONAL_GPIOLIB
++	help
++	  Support for Broadcom's BCMRing platform.
++
++config ARCH_CLPS711X
++	bool "Cirrus Logic CLPS711x/EP721x-based"
++	select CPU_ARM720T
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Support for Cirrus Logic 711x/721x based boards.
++
++config ARCH_CNS3XXX
++	bool "Cavium Networks CNS3XXX family"
++	select CPU_V6
++	select GENERIC_CLOCKEVENTS
++	select ARM_GIC
++	help
++	  Support for Cavium Networks CNS3XXX platform.
++
++config ARCH_GEMINI
++	bool "Cortina Systems Gemini"
++	select CPU_FA526
++	select ARCH_REQUIRE_GPIOLIB
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Support for the Cortina Systems Gemini family SoCs
++
++config ARCH_EBSA110
++	bool "EBSA-110"
++	select CPU_SA110
++	select ISA
++	select NO_IOPORT
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  This is an evaluation board for the StrongARM processor available
++	  from Digital. It has limited hardware on-board, including an
++	  Ethernet interface, two PCMCIA sockets, two serial ports and a
++	  parallel port.
++
++config ARCH_EP93XX
++	bool "EP93xx-based"
++	select CPU_ARM920T
++	select ARM_AMBA
++	select ARM_VIC
++	select COMMON_CLKDEV
++	select ARCH_REQUIRE_GPIOLIB
++	select ARCH_HAS_HOLES_MEMORYMODEL
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  This enables support for the Cirrus EP93xx series of CPUs.
++
++config ARCH_FOOTBRIDGE
++	bool "FootBridge"
++	select CPU_SA110
++	select FOOTBRIDGE
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Support for systems based on the DC21285 companion chip
++	  ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
++
++config ARCH_MXC
++	bool "Freescale MXC/iMX-based"
++	select GENERIC_CLOCKEVENTS
++	select ARCH_REQUIRE_GPIOLIB
++	select COMMON_CLKDEV
++	help
++	  Support for Freescale MXC/iMX-based family of processors
++
++config ARCH_STMP3XXX
++	bool "Freescale STMP3xxx"
++	select CPU_ARM926T
++	select COMMON_CLKDEV
++	select ARCH_REQUIRE_GPIOLIB
++	select GENERIC_CLOCKEVENTS
++	select USB_ARCH_HAS_EHCI
++	help
++	  Support for systems based on the Freescale 3xxx CPUs.
++
++config ARCH_NETX
++	bool "Hilscher NetX based"
++	select CPU_ARM926T
++	select ARM_VIC
++	select GENERIC_CLOCKEVENTS
++	help
++	  This enables support for systems based on the Hilscher NetX Soc
++
++config ARCH_H720X
++	bool "Hynix HMS720x-based"
++	select CPU_ARM720T
++	select ISA_DMA_API
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  This enables support for systems based on the Hynix HMS720x
++
++config ARCH_IOP13XX
++	bool "IOP13xx-based"
++	depends on MMU
++	select CPU_XSC3
++	select PLAT_IOP
++	select PCI
++	select ARCH_SUPPORTS_MSI
++	select VMSPLIT_1G
++	help
++	  Support for Intel's IOP13XX (XScale) family of processors.
++
++config ARCH_IOP32X
++	bool "IOP32x-based"
++	depends on MMU
++	select CPU_XSCALE
++	select PLAT_IOP
++	select PCI
++	select ARCH_REQUIRE_GPIOLIB
++	help
++	  Support for Intel's 80219 and IOP32X (XScale) family of
++	  processors.
++
++config ARCH_IOP33X
++	bool "IOP33x-based"
++	depends on MMU
++	select CPU_XSCALE
++	select PLAT_IOP
++	select PCI
++	select ARCH_REQUIRE_GPIOLIB
++	help
++	  Support for Intel's IOP33X (XScale) family of processors.
++
++config ARCH_IXP23XX
++ 	bool "IXP23XX-based"
++	depends on MMU
++	select CPU_XSC3
++ 	select PCI
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Support for Intel's IXP23xx (XScale) family of processors.
++
++config ARCH_IXP2000
++	bool "IXP2400/2800-based"
++	depends on MMU
++	select CPU_XSCALE
++	select PCI
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Support for Intel's IXP2400/2800 (XScale) family of processors.
++
++config ARCH_IXP4XX
++	bool "IXP4xx-based"
++	depends on MMU
++	select CPU_XSCALE
++	select GENERIC_GPIO
++	select GENERIC_CLOCKEVENTS
++	select DMABOUNCE if PCI
++	help
++	  Support for Intel's IXP4XX (XScale) family of processors.
++
++config ARCH_L7200
++	bool "LinkUp-L7200"
++	select CPU_ARM720T
++	select FIQ
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Say Y here if you intend to run this kernel on a LinkUp Systems
++	  L7200 Software Development Board which uses an ARM720T processor.
++	  Information on this board can be obtained at:
++
++	  <http://www.linkupsys.com/>
++
++	  If you have any questions or comments about the Linux kernel port
++	  to this board, send e-mail to <sjhill@cotw.com>.
++
++config ARCH_DOVE
++	bool "Marvell Dove"
++	select PCI
++	select ARCH_REQUIRE_GPIOLIB
++	select GENERIC_CLOCKEVENTS
++	select PLAT_ORION
++	help
++	  Support for the Marvell Dove SoC 88AP510
++
++config ARCH_KIRKWOOD
++	bool "Marvell Kirkwood"
++	select CPU_FEROCEON
++	select PCI
++	select ARCH_REQUIRE_GPIOLIB
++	select GENERIC_CLOCKEVENTS
++	select PLAT_ORION
++	help
++	  Support for the following Marvell Kirkwood series SoCs:
++	  88F6180, 88F6192 and 88F6281.
++
++config ARCH_LOKI
++	bool "Marvell Loki (88RC8480)"
++	select CPU_FEROCEON
++	select GENERIC_CLOCKEVENTS
++	select PLAT_ORION
++	help
++	  Support for the Marvell Loki (88RC8480) SoC.
++
++config ARCH_MV78XX0
++	bool "Marvell MV78xx0"
++	select CPU_FEROCEON
++	select PCI
++	select ARCH_REQUIRE_GPIOLIB
++	select GENERIC_CLOCKEVENTS
++	select PLAT_ORION
++	help
++	  Support for the following Marvell MV78xx0 series SoCs:
++	  MV781x0, MV782x0.
++
++config ARCH_ORION5X
++	bool "Marvell Orion"
++	depends on MMU
++	select CPU_FEROCEON
++	select PCI
++	select ARCH_REQUIRE_GPIOLIB
++	select GENERIC_CLOCKEVENTS
++	select PLAT_ORION
++	help
++	  Support for the following Marvell Orion 5x series SoCs:
++	  Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
++	  Orion-2 (5281), Orion-1-90 (6183).
++
++config ARCH_MMP
++	bool "Marvell PXA168/910/MMP2"
++	depends on MMU
++	select ARCH_REQUIRE_GPIOLIB
++	select COMMON_CLKDEV
++	select GENERIC_CLOCKEVENTS
++	select TICK_ONESHOT
++	select PLAT_PXA
++	help
++	  Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
++
++config ARCH_KS8695
++	bool "Micrel/Kendin KS8695"
++	select CPU_ARM922T
++	select ARCH_REQUIRE_GPIOLIB
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
++	  System-on-Chip devices.
++
++config ARCH_NS9XXX
++	bool "NetSilicon NS9xxx"
++	select CPU_ARM926T
++	select GENERIC_GPIO
++	select GENERIC_CLOCKEVENTS
++	select HAVE_CLK
++	help
++	  Say Y here if you intend to run this kernel on a NetSilicon NS9xxx
++	  System.
++
++	  <http://www.digi.com/products/microprocessors/index.jsp>
++
++config ARCH_W90X900
++	bool "Nuvoton W90X900 CPU"
++	select CPU_ARM926T
++	select ARCH_REQUIRE_GPIOLIB
++	select COMMON_CLKDEV
++	select GENERIC_CLOCKEVENTS
++	help
++	  Support for Nuvoton (Winbond logic dept.) ARM9 processor,
++	  At present, the w90x900 has been renamed nuc900, regarding
++	  the ARM series product line, you can login the following
++	  link address to know more.
++
++	  <http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
++		ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
++
++config ARCH_NUC93X
++	bool "Nuvoton NUC93X CPU"
++	select CPU_ARM926T
++	select COMMON_CLKDEV
++	help
++	  Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
++	  low-power and high performance MPEG-4/JPEG multimedia controller chip.
++
++config ARCH_PNX4008
++	bool "Philips Nexperia PNX4008 Mobile"
++	select CPU_ARM926T
++	select COMMON_CLKDEV
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  This enables support for Philips PNX4008 mobile platform.
++
++config ARCH_PXA
++	bool "PXA2xx/PXA3xx-based"
++	depends on MMU
++	select ARCH_MTD_XIP
++	select ARCH_HAS_CPUFREQ
++	select COMMON_CLKDEV
++	select ARCH_REQUIRE_GPIOLIB
++	select GENERIC_CLOCKEVENTS
++	select TICK_ONESHOT
++	select PLAT_PXA
++	help
++	  Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
++
++config ARCH_MSM
++	bool "Qualcomm MSM"
++	select HAVE_CLK
++	select GENERIC_CLOCKEVENTS
++	help
++	  Support for Qualcomm MSM/QSD based systems.  This runs on the
++	  apps processor of the MSM/QSD and depends on a shared memory
++	  interface to the modem processor which runs the baseband
++	  stack and controls some vital subsystems
++	  (clock and power control, etc).
++
++config ARCH_SHMOBILE
++	bool "Renesas SH-Mobile"
++	help
++	  Support for Renesas's SH-Mobile ARM platforms
++
++config ARCH_RPC
++	bool "RiscPC"
++	select ARCH_ACORN
++	select FIQ
++	select TIMER_ACORN
++	select ARCH_MAY_HAVE_PC_FDC
++	select HAVE_PATA_PLATFORM
++	select ISA_DMA_API
++	select NO_IOPORT
++	select ARCH_SPARSEMEM_ENABLE
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  On the Acorn Risc-PC, Linux can support the internal IDE disk and
++	  CD-ROM interface, serial and parallel port, and the floppy drive.
++
++config ARCH_SA1100
++	bool "SA1100-based"
++	select CPU_SA1100
++	select ISA
++	select ARCH_SPARSEMEM_ENABLE
++	select ARCH_MTD_XIP
++	select ARCH_HAS_CPUFREQ
++	select CPU_FREQ
++	select GENERIC_CLOCKEVENTS
++	select HAVE_CLK
++	select TICK_ONESHOT
++	select ARCH_REQUIRE_GPIOLIB
++	help
++	  Support for StrongARM 11x0 based boards.
++
++config ARCH_S3C2410
++	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, S3C2450"
++	select GENERIC_GPIO
++	select ARCH_HAS_CPUFREQ
++	select HAVE_CLK
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Samsung S3C2410X CPU based systems, such as the Simtec Electronics
++	  BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
++	  the Samsung SMDK2410 development board (and derivatives).
++
++	  Note, the S3C2416 and the S3C2450 are so close that they even share
++	  the same SoC ID code. This means that there is no seperate machine
++	  directory (no arch/arm/mach-s3c2450) as the S3C2416 was first.
++
++config ARCH_S3C64XX
++	bool "Samsung S3C64XX"
++	select PLAT_SAMSUNG
++	select CPU_V6
++	select ARM_VIC
++	select HAVE_CLK
++	select NO_IOPORT
++	select ARCH_USES_GETTIMEOFFSET
++	select ARCH_HAS_CPUFREQ
++	select ARCH_REQUIRE_GPIOLIB
++	select SAMSUNG_CLKSRC
++	select SAMSUNG_IRQ_VIC_TIMER
++	select SAMSUNG_IRQ_UART
++	select S3C_GPIO_TRACK
++	select S3C_GPIO_PULL_UPDOWN
++	select S3C_GPIO_CFG_S3C24XX
++	select S3C_GPIO_CFG_S3C64XX
++	select S3C_DEV_NAND
++	select USB_ARCH_HAS_OHCI
++	select SAMSUNG_GPIOLIB_4BIT
++	help
++	  Samsung S3C64XX series based systems
++
++config ARCH_S5P6440
++	bool "Samsung S5P6440"
++	select CPU_V6
++	select GENERIC_GPIO
++	select HAVE_CLK
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Samsung S5P6440 CPU based systems
++
++config ARCH_S5P6442
++	bool "Samsung S5P6442"
++	select CPU_V6
++	select GENERIC_GPIO
++	select HAVE_CLK
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Samsung S5P6442 CPU based systems
++
++config ARCH_S5PC100
++	bool "Samsung S5PC100"
++	select GENERIC_GPIO
++	select HAVE_CLK
++	select CPU_V7
++	select ARM_L1_CACHE_SHIFT_6
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Samsung S5PC100 series based systems
++
++config ARCH_S5PV210
++	bool "Samsung S5PV210/S5PC110"
++	select CPU_V7
++	select GENERIC_GPIO
++	select HAVE_CLK
++	select ARM_L1_CACHE_SHIFT_6
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Samsung S5PV210/S5PC110 series based systems
++
++config ARCH_SHARK
++	bool "Shark"
++	select CPU_SA110
++	select ISA
++	select ISA_DMA
++	select ZONE_DMA
++	select PCI
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Support for the StrongARM based Digital DNARD machine, also known
++	  as "Shark" (<http://www.shark-linux.de/shark.html>).
++
++config ARCH_LH7A40X
++	bool "Sharp LH7A40X"
++	select CPU_ARM922T
++	select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM
++	select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM
++	select ARCH_USES_GETTIMEOFFSET
++	help
++	  Say Y here for systems based on one of the Sharp LH7A40X
++	  System on a Chip processors.  These CPUs include an ARM922T
++	  core with a wide array of integrated devices for
++	  hand-held and low-power applications.
++
++config ARCH_U300
++	bool "ST-Ericsson U300 Series"
++	depends on MMU
++	select CPU_ARM926T
++	select HAVE_TCM
++	select ARM_AMBA
++	select ARM_VIC
++	select GENERIC_CLOCKEVENTS
++	select COMMON_CLKDEV
++	select GENERIC_GPIO
++	help
++	  Support for ST-Ericsson U300 series mobile platforms.
++
++config ARCH_U8500
++	bool "ST-Ericsson U8500 Series"
++	select CPU_V7
++	select ARM_AMBA
++	select GENERIC_CLOCKEVENTS
++	select COMMON_CLKDEV
++	select ARCH_REQUIRE_GPIOLIB
++	help
++	  Support for ST-Ericsson's Ux500 architecture
++
++config ARCH_NOMADIK
++	bool "STMicroelectronics Nomadik"
++	select ARM_AMBA
++	select ARM_VIC
++	select CPU_ARM926T
++	select COMMON_CLKDEV
++	select GENERIC_CLOCKEVENTS
++	select ARCH_REQUIRE_GPIOLIB
++	help
++	  Support for the Nomadik platform by ST-Ericsson
++
++config ARCH_DAVINCI
++	bool "TI DaVinci"
++	select GENERIC_CLOCKEVENTS
++	select ARCH_REQUIRE_GPIOLIB
++	select ZONE_DMA
++	select HAVE_IDE
++	select COMMON_CLKDEV
++	select GENERIC_ALLOCATOR
++	select ARCH_HAS_HOLES_MEMORYMODEL
++	help
++	  Support for TI's DaVinci platform.
++
++config ARCH_OMAP
++	bool "TI OMAP"
++	select HAVE_CLK
++	select ARCH_REQUIRE_GPIOLIB
++	select ARCH_HAS_CPUFREQ
++	select GENERIC_CLOCKEVENTS
++	select ARCH_HAS_HOLES_MEMORYMODEL
++	help
++	  Support for TI's OMAP platform (OMAP1 and OMAP2).
++
++config PLAT_SPEAR
++	bool "ST SPEAr"
++	select ARM_AMBA
++	select ARCH_REQUIRE_GPIOLIB
++	select COMMON_CLKDEV
++	select GENERIC_CLOCKEVENTS
++	select HAVE_CLK
++	help
++	  Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
++
++endchoice
++
++#
++# This is sorted alphabetically by mach-* pathname.  However, plat-*
++# Kconfigs may be included either alphabetically (according to the
++# plat- suffix) or along side the corresponding mach-* source.
++#
++source "arch/arm/mach-aaec2000/Kconfig"
++
++source "arch/arm/mach-at91/Kconfig"
++
++source "arch/arm/mach-bcmring/Kconfig"
++
++source "arch/arm/mach-clps711x/Kconfig"
++
++source "arch/arm/mach-cns3xxx/Kconfig"
++
++source "arch/arm/mach-davinci/Kconfig"
++
++source "arch/arm/mach-dove/Kconfig"
++
++source "arch/arm/mach-ep93xx/Kconfig"
++
++source "arch/arm/mach-footbridge/Kconfig"
++
++source "arch/arm/mach-gemini/Kconfig"
++
++source "arch/arm/mach-h720x/Kconfig"
++
++source "arch/arm/mach-integrator/Kconfig"
++
++source "arch/arm/mach-iop32x/Kconfig"
++
++source "arch/arm/mach-iop33x/Kconfig"
++
++source "arch/arm/mach-iop13xx/Kconfig"
++
++source "arch/arm/mach-ixp4xx/Kconfig"
++
++source "arch/arm/mach-ixp2000/Kconfig"
++
++source "arch/arm/mach-ixp23xx/Kconfig"
++
++source "arch/arm/mach-kirkwood/Kconfig"
++
++source "arch/arm/mach-ks8695/Kconfig"
++
++source "arch/arm/mach-lh7a40x/Kconfig"
++
++source "arch/arm/mach-loki/Kconfig"
++
++source "arch/arm/mach-msm/Kconfig"
++
++source "arch/arm/mach-mv78xx0/Kconfig"
++
++source "arch/arm/plat-mxc/Kconfig"
++
++source "arch/arm/mach-netx/Kconfig"
++
++source "arch/arm/mach-nomadik/Kconfig"
++source "arch/arm/plat-nomadik/Kconfig"
++
++source "arch/arm/mach-ns9xxx/Kconfig"
++
++source "arch/arm/mach-nuc93x/Kconfig"
++
++source "arch/arm/plat-omap/Kconfig"
++
++source "arch/arm/mach-omap1/Kconfig"
++
++source "arch/arm/mach-omap2/Kconfig"
++
++source "arch/arm/mach-orion5x/Kconfig"
++
++source "arch/arm/mach-pxa/Kconfig"
++source "arch/arm/plat-pxa/Kconfig"
++
++source "arch/arm/mach-mmp/Kconfig"
++
++source "arch/arm/mach-realview/Kconfig"
++
++source "arch/arm/mach-sa1100/Kconfig"
++
++source "arch/arm/plat-samsung/Kconfig"
++source "arch/arm/plat-s3c24xx/Kconfig"
++source "arch/arm/plat-s5p/Kconfig"
++
++source "arch/arm/plat-spear/Kconfig"
++
++if ARCH_S3C2410
++source "arch/arm/mach-s3c2400/Kconfig"
++source "arch/arm/mach-s3c2410/Kconfig"
++source "arch/arm/mach-s3c2412/Kconfig"
++source "arch/arm/mach-s3c2416/Kconfig"
++source "arch/arm/mach-s3c2440/Kconfig"
++source "arch/arm/mach-s3c2443/Kconfig"
++endif
++
++if ARCH_S3C64XX
++source "arch/arm/mach-s3c64xx/Kconfig"
++endif
++
++source "arch/arm/mach-s5p6440/Kconfig"
++
++source "arch/arm/mach-s5p6442/Kconfig"
++
++source "arch/arm/mach-s5pc100/Kconfig"
++
++source "arch/arm/mach-s5pv210/Kconfig"
++
++source "arch/arm/mach-shmobile/Kconfig"
++
++source "arch/arm/plat-stmp3xxx/Kconfig"
++
++source "arch/arm/mach-u300/Kconfig"
++
++source "arch/arm/mach-ux500/Kconfig"
++
++source "arch/arm/mach-versatile/Kconfig"
++
++source "arch/arm/mach-vexpress/Kconfig"
++
++source "arch/arm/mach-w90x900/Kconfig"
++
++# Definitions to make life easier
++config ARCH_ACORN
++	bool
++
++config PLAT_IOP
++	bool
++	select GENERIC_CLOCKEVENTS
++
++config PLAT_ORION
++	bool
++
++config PLAT_PXA
++	bool
++
++config PLAT_VERSATILE
++	bool
++
++config ARM_TIMER_SP804
++	bool
++
++source arch/arm/mm/Kconfig
++
++config IWMMXT
++	bool "Enable iWMMXt support"
++	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
++	default y if PXA27x || PXA3xx || ARCH_MMP
++	help
++	  Enable support for iWMMXt context switching at run time if
++	  running on a CPU that supports it.
++
++#  bool 'Use XScale PMU as timer source' CONFIG_XSCALE_PMU_TIMER
++config XSCALE_PMU
++	bool
++	depends on CPU_XSCALE && !XSCALE_PMU_TIMER
++	default y
++
++config CPU_HAS_PMU
++	depends on (CPU_V6 || CPU_V7 || XSCALE_PMU) && \
++		   (!ARCH_OMAP3 || OMAP3_EMU)
++	default y
++	bool
++
++if !MMU
++source "arch/arm/Kconfig-nommu"
++endif
++
++config ARM_ERRATA_411920
++	bool "ARM errata: Invalidation of the Instruction Cache operation can fail"
++	depends on CPU_V6 && !SMP
++	help
++	  Invalidation of the Instruction Cache operation can
++	  fail. This erratum is present in 1136 (before r1p4), 1156 and 1176.
++	  It does not affect the MPCore. This option enables the ARM Ltd.
++	  recommended workaround.
++
++config ARM_ERRATA_430973
++	bool "ARM errata: Stale prediction on replaced interworking branch"
++	depends on CPU_V7
++	help
++	  This option enables the workaround for the 430973 Cortex-A8
++	  (r1p0..r1p2) erratum. If a code sequence containing an ARM/Thumb
++	  interworking branch is replaced with another code sequence at the
++	  same virtual address, whether due to self-modifying code or virtual
++	  to physical address re-mapping, Cortex-A8 does not recover from the
++	  stale interworking branch prediction. This results in Cortex-A8
++	  executing the new code sequence in the incorrect ARM or Thumb state.
++	  The workaround enables the BTB/BTAC operations by setting ACTLR.IBE
++	  and also flushes the branch target cache at every context switch.
++	  Note that setting specific bits in the ACTLR register may not be
++	  available in non-secure mode.
++
++config ARM_ERRATA_458693
++	bool "ARM errata: Processor deadlock when a false hazard is created"
++	depends on CPU_V7
++	help
++	  This option enables the workaround for the 458693 Cortex-A8 (r2p0)
++	  erratum. For very specific sequences of memory operations, it is
++	  possible for a hazard condition intended for a cache line to instead
++	  be incorrectly associated with a different cache line. This false
++	  hazard might then cause a processor deadlock. The workaround enables
++	  the L1 caching of the NEON accesses and disables the PLD instruction
++	  in the ACTLR register. Note that setting specific bits in the ACTLR
++	  register may not be available in non-secure mode.
++
++config ARM_ERRATA_460075
++	bool "ARM errata: Data written to the L2 cache can be overwritten with stale data"
++	depends on CPU_V7
++	help
++	  This option enables the workaround for the 460075 Cortex-A8 (r2p0)
++	  erratum. Any asynchronous access to the L2 cache may encounter a
++	  situation in which recent store transactions to the L2 cache are lost
++	  and overwritten with stale memory contents from external memory. The
++	  workaround disables the write-allocate mode for the L2 cache via the
++	  ACTLR register. Note that setting specific bits in the ACTLR register
++	  may not be available in non-secure mode.
++
++config PL310_ERRATA_588369
++	bool "Clean & Invalidate maintenance operations do not invalidate clean lines"
++	depends on CACHE_L2X0 && ARCH_OMAP4
++	help
++	   The PL310 L2 cache controller implements three types of Clean &
++	   Invalidate maintenance operations: by Physical Address
++	   (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
++	   They are architecturally defined to behave as the execution of a
++	   clean operation followed immediately by an invalidate operation,
++	   both performing to the same memory location. This functionality
++	   is not correctly implemented in PL310 as clean lines are not
++	   invalidated as a result of these operations. Note that this errata
++	   uses Texas Instrument's secure monitor api.
++
++config ARM_ERRATA_720789
++	bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID"
++	depends on CPU_V7 && SMP
++	help
++	  This option enables the workaround for the 720789 Cortex-A9 (prior to
++	  r2p0) erratum. A faulty ASID can be sent to the other CPUs for the
++	  broadcasted CP15 TLB maintenance operations TLBIASIDIS and TLBIMVAIS.
++	  As a consequence of this erratum, some TLB entries which should be
++	  invalidated are not, resulting in an incoherency in the system page
++	  tables. The workaround changes the TLB flushing routines to invalidate
++	  entries regardless of the ASID.
++endmenu
++
++source "arch/arm/common/Kconfig"
++
++config FORCE_MAX_ZONEORDER
++	int
++	depends on SA1111
++	default "9"
++
++menu "Bus support"
++
++config ARM_AMBA
++	bool
++
++config ISA
++	bool
++	help
++	  Find out whether you have ISA slots on your motherboard.  ISA is the
++	  name of a bus system, i.e. the way the CPU talks to the other stuff
++	  inside your box.  Other bus systems are PCI, EISA, MicroChannel
++	  (MCA) or VESA.  ISA is an older system, now being displaced by PCI;
++	  newer boards don't support it.  If you have ISA, say Y, otherwise N.
++
++# Select ISA DMA controller support
++config ISA_DMA
++	bool
++	select ISA_DMA_API
++
++# Select ISA DMA interface
++config ISA_DMA_API
++	bool
++
++config PCI
++	bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE
++	help
++	  Find out whether you have a PCI motherboard. PCI is the name of a
++	  bus system, i.e. the way the CPU talks to the other stuff inside
++	  your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
++	  VESA. If you have PCI, say Y, otherwise N.
++
++config PCI_DOMAINS
++	bool
++	depends on PCI
++
++config PCI_SYSCALL
++	def_bool PCI
++
++# Select the host bridge type
++config PCI_HOST_VIA82C505
++	bool
++	depends on PCI && ARCH_SHARK
++	default y
++
++config PCI_HOST_ITE8152
++	bool
++	depends on PCI && MACH_ARMCORE
++	default y
++	select DMABOUNCE
++
++source "drivers/pci/Kconfig"
++
++source "drivers/pcmcia/Kconfig"
++
++endmenu
++
++menu "Kernel Features"
++
++source "kernel/time/Kconfig"
++
++config SMP
++	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
++	depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
++		 MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
++		 ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
++	depends on GENERIC_CLOCKEVENTS
++	select USE_GENERIC_SMP_HELPERS
++	select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
++	help
++	  This enables support for systems with more than one CPU. If you have
++	  a system with only one CPU, like most personal computers, say N. If
++	  you have a system with more than one CPU, say Y.
++
++	  If you say N here, the kernel will run on single and multiprocessor
++	  machines, but will use only one CPU of a multiprocessor machine. If
++	  you say Y here, the kernel will run on many, but not all, single
++	  processor machines. On a single processor machine, the kernel will
++	  run faster if you say N here.
++
++	  See also <file:Documentation/i386/IO-APIC.txt>,
++	  <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
++	  <http://www.linuxdoc.org/docs.html#howto>.
++
++	  If you don't know what to do here, say N.
++
++config HAVE_ARM_SCU
++	bool
++	depends on SMP
++	help
++	  This option enables support for the ARM system coherency unit
++
++config HAVE_ARM_TWD
++	bool
++	depends on SMP
++	help
++	  This options enables support for the ARM timer and watchdog unit
++
++choice
++	prompt "Memory split"
++	default VMSPLIT_3G
++	help
++	  Select the desired split between kernel and user memory.
++
++	  If you are not absolutely sure what you are doing, leave this
++	  option alone!
++
++	config VMSPLIT_3G
++		bool "3G/1G user/kernel split"
++	config VMSPLIT_2G
++		bool "2G/2G user/kernel split"
++	config VMSPLIT_1G
++		bool "1G/3G user/kernel split"
++endchoice
++
++config PAGE_OFFSET
++	hex
++	default 0x40000000 if VMSPLIT_1G
++	default 0x80000000 if VMSPLIT_2G
++	default 0xC0000000
++
++config NR_CPUS
++	int "Maximum number of CPUs (2-32)"
++	range 2 32
++	depends on SMP
++	default "4"
++
++config HOTPLUG_CPU
++	bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
++	depends on SMP && HOTPLUG && EXPERIMENTAL
++	help
++	  Say Y here to experiment with turning CPUs off and on.  CPUs
++	  can be controlled through /sys/devices/system/cpu.
++
++config LOCAL_TIMERS
++	bool "Use local timer interrupts"
++	depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
++		REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500)
++	default y
++	select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500)
++	help
++	  Enable support for local timers on SMP platforms, rather then the
++	  legacy IPI broadcast method.  Local timers allows the system
++	  accounting to be spread across the timer interval, preventing a
++	  "thundering herd" at every timer tick.
++
++source kernel/Kconfig.preempt
++
++config HZ
++	int
++	default 128 if ARCH_L7200
++	default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PV210
++	default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
++	default AT91_TIMER_HZ if ARCH_AT91
++	default 100
++
++config THUMB2_KERNEL
++	bool "Compile the kernel in Thumb-2 mode"
++	depends on CPU_V7 && EXPERIMENTAL
++	select AEABI
++	select ARM_ASM_UNIFIED
++	help
++	  By enabling this option, the kernel will be compiled in
++	  Thumb-2 mode. A compiler/assembler that understand the unified
++	  ARM-Thumb syntax is needed.
++
++	  If unsure, say N.
++
++config ARM_ASM_UNIFIED
++	bool
++
++config AEABI
++	bool "Use the ARM EABI to compile the kernel"
++	help
++	  This option allows for the kernel to be compiled using the latest
++	  ARM ABI (aka EABI).  This is only useful if you are using a user
++	  space environment that is also compiled with EABI.
++
++	  Since there are major incompatibilities between the legacy ABI and
++	  EABI, especially with regard to structure member alignment, this
++	  option also changes the kernel syscall calling convention to
++	  disambiguate both ABIs and allow for backward compatibility support
++	  (selected with CONFIG_OABI_COMPAT).
++
++	  To use this you need GCC version 4.0.0 or later.
++
++config OABI_COMPAT
++	bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
++	depends on AEABI && EXPERIMENTAL
++	default y
++	help
++	  This option preserves the old syscall interface along with the
++	  new (ARM EABI) one. It also provides a compatibility layer to
++	  intercept syscalls that have structure arguments which layout
++	  in memory differs between the legacy ABI and the new ARM EABI
++	  (only for non "thumb" binaries). This option adds a tiny
++	  overhead to all syscalls and produces a slightly larger kernel.
++	  If you know you'll be using only pure EABI user space then you
++	  can say N here. If this option is not selected and you attempt
++	  to execute a legacy ABI binary then the result will be
++	  UNPREDICTABLE (in fact it can be predicted that it won't work
++	  at all). If in doubt say Y.
++
++config ARCH_HAS_HOLES_MEMORYMODEL
++	bool
++
++# Discontigmem is deprecated
++config ARCH_DISCONTIGMEM_ENABLE
++	bool
++
++config ARCH_SPARSEMEM_ENABLE
++	bool
++
++config ARCH_SPARSEMEM_DEFAULT
++	def_bool ARCH_SPARSEMEM_ENABLE
++
++config ARCH_SELECT_MEMORY_MODEL
++	def_bool ARCH_DISCONTIGMEM_ENABLE && ARCH_SPARSEMEM_ENABLE
++
++config NODES_SHIFT
++	int
++	default "4" if ARCH_LH7A40X
++	default "2"
++	depends on NEED_MULTIPLE_NODES
++
++config HIGHMEM
++	bool "High Memory Support (EXPERIMENTAL)"
++	depends on MMU && EXPERIMENTAL
++	help
++	  The address space of ARM processors is only 4 Gigabytes large
++	  and it has to accommodate user address space, kernel address
++	  space as well as some memory mapped IO. That means that, if you
++	  have a large amount of physical memory and/or IO, not all of the
++	  memory can be "permanently mapped" by the kernel. The physical
++	  memory that is not permanently mapped is called "high memory".
++
++	  Depending on the selected kernel/user memory split, minimum
++	  vmalloc space and actual amount of RAM, you may not need this
++	  option which should result in a slightly faster kernel.
++
++	  If unsure, say n.
++
++config HIGHPTE
++	bool "Allocate 2nd-level pagetables from highmem"
++	depends on HIGHMEM
++	depends on !OUTER_CACHE
++
++config HW_PERF_EVENTS
++	bool "Enable hardware performance counter support for perf events"
++	depends on PERF_EVENTS && CPU_HAS_PMU
++	default y
++	help
++	  Enable hardware performance counter support for perf events. If
++	  disabled, perf events will use software events only.
++
++source "mm/Kconfig"
++
++config LEDS
++	bool "Timer and CPU usage LEDs"
++	depends on ARCH_CDB89712 || ARCH_EBSA110 || \
++		   ARCH_EBSA285 || ARCH_INTEGRATOR || \
++		   ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
++		   ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
++		   ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
++		   ARCH_AT91 || ARCH_DAVINCI || \
++		   ARCH_KS8695 || MACH_RD88F5182 || ARCH_REALVIEW
++	help
++	  If you say Y here, the LEDs on your machine will be used
++	  to provide useful information about your current system status.
++
++	  If you are compiling a kernel for a NetWinder or EBSA-285, you will
++	  be able to select which LEDs are active using the options below. If
++	  you are compiling a kernel for the EBSA-110 or the LART however, the
++	  red LED will simply flash regularly to indicate that the system is
++	  still functional. It is safe to say Y here if you have a CATS
++	  system, but the driver will do nothing.
++
++config LEDS_TIMER
++	bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
++			    OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
++			    || MACH_OMAP_PERSEUS2
++	depends on LEDS
++	depends on !GENERIC_CLOCKEVENTS
++	default y if ARCH_EBSA110
++	help
++	  If you say Y here, one of the system LEDs (the green one on the
++	  NetWinder, the amber one on the EBSA285, or the red one on the LART)
++	  will flash regularly to indicate that the system is still
++	  operational. This is mainly useful to kernel hackers who are
++	  debugging unstable kernels.
++
++	  The LART uses the same LED for both Timer LED and CPU usage LED
++	  functions. You may choose to use both, but the Timer LED function
++	  will overrule the CPU usage LED.
++
++config LEDS_CPU
++	bool "CPU usage LED" if (!ARCH_CDB89712 && !ARCH_EBSA110 && \
++			!ARCH_OMAP) \
++			|| OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
++			|| MACH_OMAP_PERSEUS2
++	depends on LEDS
++	help
++	  If you say Y here, the red LED will be used to give a good real
++	  time indication of CPU usage, by lighting whenever the idle task
++	  is not currently executing.
++
++	  The LART uses the same LED for both Timer LED and CPU usage LED
++	  functions. You may choose to use both, but the Timer LED function
++	  will overrule the CPU usage LED.
++
++config ALIGNMENT_TRAP
++	bool
++	depends on CPU_CP15_MMU
++	default y if !ARCH_EBSA110
++	select HAVE_PROC_CPU if PROC_FS
++	help
++	  ARM processors cannot fetch/store information which is not
++	  naturally aligned on the bus, i.e., a 4 byte fetch must start at an
++	  address divisible by 4. On 32-bit ARM processors, these non-aligned
++	  fetch/store instructions will be emulated in software if you say
++	  here, which has a severe performance impact. This is necessary for
++	  correct operation of some network protocols. With an IP-only
++	  configuration it is safe to say N, otherwise say Y.
++
++config UACCESS_WITH_MEMCPY
++	bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user() (EXPERIMENTAL)"
++	depends on MMU && EXPERIMENTAL
++	default y if CPU_FEROCEON
++	help
++	  Implement faster copy_to_user and clear_user methods for CPU
++	  cores where a 8-word STM instruction give significantly higher
++	  memory write throughput than a sequence of individual 32bit stores.
++
++	  A possible side effect is a slight increase in scheduling latency
++	  between threads sharing the same address space if they invoke
++	  such copy operations with large buffers.
++
++	  However, if the CPU data cache is using a write-allocate mode,
++	  this option is unlikely to provide any performance gain.
++
++endmenu
++
++menu "Boot options"
++
++# Compressed boot loader in ROM.  Yes, we really want to ask about
++# TEXT and BSS so we preserve their values in the config files.
++config ZBOOT_ROM_TEXT
++	hex "Compressed ROM boot loader base address"
++	default "0"
++	help
++	  The physical address at which the ROM-able zImage is to be
++	  placed in the target.  Platforms which normally make use of
++	  ROM-able zImage formats normally set this to a suitable
++	  value in their defconfig file.
++
++	  If ZBOOT_ROM is not enabled, this has no effect.
++
++config ZBOOT_ROM_BSS
++	hex "Compressed ROM boot loader BSS address"
++	default "0"
++	help
++	  The base address of an area of read/write memory in the target
++	  for the ROM-able zImage which must be available while the
++	  decompressor is running. It must be large enough to hold the
++	  entire decompressed kernel plus an additional 128 KiB.
++	  Platforms which normally make use of ROM-able zImage formats
++	  normally set this to a suitable value in their defconfig file.
++
++	  If ZBOOT_ROM is not enabled, this has no effect.
++
++config ZBOOT_ROM
++	bool "Compressed boot loader in ROM/flash"
++	depends on ZBOOT_ROM_TEXT != ZBOOT_ROM_BSS
++	help
++	  Say Y here if you intend to execute your compressed kernel image
++	  (zImage) directly from ROM or flash.  If unsure, say N.
++
++config CMDLINE
++	string "Default kernel command string"
++	default ""
++	help
++	  On some architectures (EBSA110 and CATS), there is currently no way
++	  for the boot loader to pass arguments to the kernel. For these
++	  architectures, you should supply some command-line options at build
++	  time by entering them here. As a minimum, you should specify the
++	  memory size and the root device (e.g., mem=64M root=/dev/nfs).
++
++config CMDLINE_FORCE
++	bool "Always use the default kernel command string"
++	depends on CMDLINE != ""
++	help
++	  Always use the default kernel command string, even if the boot
++	  loader passes other arguments to the kernel.
++	  This is useful if you cannot or don't want to change the
++	  command-line options your boot loader passes to the kernel.
++
++	  If unsure, say N.
++
++config XIP_KERNEL
++	bool "Kernel Execute-In-Place from ROM"
++	depends on !ZBOOT_ROM
++	help
++	  Execute-In-Place allows the kernel to run from non-volatile storage
++	  directly addressable by the CPU, such as NOR flash. This saves RAM
++	  space since the text section of the kernel is not loaded from flash
++	  to RAM.  Read-write sections, such as the data section and stack,
++	  are still copied to RAM.  The XIP kernel is not compressed since
++	  it has to run directly from flash, so it will take more space to
++	  store it.  The flash address used to link the kernel object files,
++	  and for storing it, is configuration dependent. Therefore, if you
++	  say Y here, you must know the proper physical address where to
++	  store the kernel image depending on your own flash memory usage.
++
++	  Also note that the make target becomes "make xipImage" rather than
++	  "make zImage" or "make Image".  The final kernel binary to put in
++	  ROM memory will be arch/arm/boot/xipImage.
++
++	  If unsure, say N.
++
++config XIP_PHYS_ADDR
++	hex "XIP Kernel Physical Location"
++	depends on XIP_KERNEL
++	default "0x00080000"
++	help
++	  This is the physical address in your flash memory the kernel will
++	  be linked for and stored to.  This address is dependent on your
++	  own flash usage.
++
++config KEXEC
++	bool "Kexec system call (EXPERIMENTAL)"
++	depends on EXPERIMENTAL
++	help
++	  kexec is a system call that implements the ability to shutdown your
++	  current kernel, and to start another kernel.  It is like a reboot
++	  but it is independent of the system firmware.   And like a reboot
++	  you can start any kernel with it, not just Linux.
++
++	  It is an ongoing process to be certain the hardware in a machine
++	  is properly shutdown, so do not be surprised if this code does not
++	  initially work for you.  It may help to enable device hotplugging
++	  support.
++
++config ATAGS_PROC
++	bool "Export atags in procfs"
++	depends on KEXEC
++	default y
++	help
++	  Should the atags used to boot the kernel be exported in an "atags"
++	  file in procfs. Useful with kexec.
++
++endmenu
++
++menu "CPU Power Management"
++
++if ARCH_HAS_CPUFREQ
++
++source "drivers/cpufreq/Kconfig"
++
++config CPU_FREQ_SA1100
++	bool
++
++config CPU_FREQ_SA1110
++	bool
++
++config CPU_FREQ_INTEGRATOR
++	tristate "CPUfreq driver for ARM Integrator CPUs"
++	depends on ARCH_INTEGRATOR && CPU_FREQ
++	default y
++	help
++	  This enables the CPUfreq driver for ARM Integrator CPUs.
++
++	  For details, take a look at <file:Documentation/cpu-freq>.
++
++	  If in doubt, say Y.
++
++config CPU_FREQ_PXA
++	bool
++	depends on CPU_FREQ && ARCH_PXA && PXA25x
++	default y
++	select CPU_FREQ_DEFAULT_GOV_USERSPACE
++
++config CPU_FREQ_S3C64XX
++	bool "CPUfreq support for Samsung S3C64XX CPUs"
++	depends on CPU_FREQ && CPU_S3C6410
++
++config CPU_FREQ_S3C
++	bool
++	help
++	  Internal configuration node for common cpufreq on Samsung SoC
++
++config CPU_FREQ_S3C24XX
++	bool "CPUfreq driver for Samsung S3C24XX series CPUs"
++	depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL
++	select CPU_FREQ_S3C
++	help
++	  This enables the CPUfreq driver for the Samsung S3C24XX family
++	  of CPUs.
++
++	  For details, take a look at <file:Documentation/cpu-freq>.
++
++	  If in doubt, say N.
++
++config CPU_FREQ_S3C24XX_PLL
++	bool "Support CPUfreq changing of PLL frequency"
++	depends on CPU_FREQ_S3C24XX && EXPERIMENTAL
++	help
++	  Compile in support for changing the PLL frequency from the
++	  S3C24XX series CPUfreq driver. The PLL takes time to settle
++	  after a frequency change, so by default it is not enabled.
++
++	  This also means that the PLL tables for the selected CPU(s) will
++	  be built which may increase the size of the kernel image.
++
++config CPU_FREQ_S3C24XX_DEBUG
++	bool "Debug CPUfreq Samsung driver core"
++	depends on CPU_FREQ_S3C24XX
++	help
++	  Enable s3c_freq_dbg for the Samsung S3C CPUfreq core
++
++config CPU_FREQ_S3C24XX_IODEBUG
++	bool "Debug CPUfreq Samsung driver IO timing"
++	depends on CPU_FREQ_S3C24XX
++	help
++	  Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core
++
++config CPU_FREQ_S3C24XX_DEBUGFS
++	bool "Export debugfs for CPUFreq"
++	depends on CPU_FREQ_S3C24XX && DEBUG_FS
++	help
++	  Export status information via debugfs.
++
++endif
++
++source "drivers/cpuidle/Kconfig"
++
++endmenu
++
++menu "Floating point emulation"
++
++comment "At least one emulation must be selected"
++
++config FPE_NWFPE
++	bool "NWFPE math emulation"
++	depends on !AEABI || OABI_COMPAT
++	---help---
++	  Say Y to include the NWFPE floating point emulator in the kernel.
++	  This is necessary to run most binaries. Linux does not currently
++	  support floating point hardware so you need to say Y here even if
++	  your machine has an FPA or floating point co-processor podule.
++
++	  You may say N here if you are going to load the Acorn FPEmulator
++	  early in the bootup.
++
++config FPE_NWFPE_XP
++	bool "Support extended precision"
++	depends on FPE_NWFPE
++	help
++	  Say Y to include 80-bit support in the kernel floating-point
++	  emulator.  Otherwise, only 32 and 64-bit support is compiled in.
++	  Note that gcc does not generate 80-bit operations by default,
++	  so in most cases this option only enlarges the size of the
++	  floating point emulator without any good reason.
++
++	  You almost surely want to say N here.
++
++config FPE_FASTFPE
++	bool "FastFPE math emulation (EXPERIMENTAL)"
++	depends on (!AEABI || OABI_COMPAT) && !CPU_32v3 && EXPERIMENTAL
++	---help---
++	  Say Y here to include the FAST floating point emulator in the kernel.
++	  This is an experimental much faster emulator which now also has full
++	  precision for the mantissa.  It does not support any exceptions.
++	  It is very simple, and approximately 3-6 times faster than NWFPE.
++
++	  It should be sufficient for most programs.  It may be not suitable
++	  for scientific calculations, but you have to check this for yourself.
++	  If you do not feel you need a faster FP emulation you should better
++	  choose NWFPE.
++
++config VFP
++	bool "VFP-format floating point maths"
++	depends on CPU_V6 || CPU_ARM926T || CPU_V7 || CPU_FEROCEON
++	help
++	  Say Y to include VFP support code in the kernel. This is needed
++	  if your hardware includes a VFP unit.
++
++	  Please see <file:Documentation/arm/VFP/release-notes.txt> for
++	  release notes and additional status information.
++
++	  Say N if your target does not have VFP hardware.
++
++config VFPv3
++	bool
++	depends on VFP
++	default y if CPU_V7
++
++config NEON
++	bool "Advanced SIMD (NEON) Extension support"
++	depends on VFPv3 && CPU_V7
++	help
++	  Say Y to include support code for NEON, the ARMv7 Advanced SIMD
++	  Extension.
++
++endmenu
++
++menu "Userspace binary formats"
++
++source "fs/Kconfig.binfmt"
++
++config ARTHUR
++	tristate "RISC OS personality"
++	depends on !AEABI
++	help
++	  Say Y here to include the kernel code necessary if you want to run
++	  Acorn RISC OS/Arthur binaries under Linux. This code is still very
++	  experimental; if this sounds frightening, say N and sleep in peace.
++	  You can also say M here to compile this support as a module (which
++	  will be called arthur).
++
++endmenu
++
++menu "Power management options"
++
++source "kernel/power/Kconfig"
++
++config ARCH_SUSPEND_POSSIBLE
++	def_bool y
++
++endmenu
++
++source "net/Kconfig"
++
++source "drivers/Kconfig"
++
++source "fs/Kconfig"
++
++source "arch/arm/Kconfig.debug"
++
++source "security/Kconfig"
++
++source "crypto/Kconfig"
++
++source "lib/Kconfig"
+diff -rupN linux-2.6.35.11/arch/arm/kernel/bios32.c linux-2.6.35.11-ts7500/arch/arm/kernel/bios32.c
+--- linux-2.6.35.11/arch/arm/kernel/bios32.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/bios32.c	2011-03-14 11:18:24.000000000 -0400
+@@ -360,7 +360,7 @@ pbus_assign_bus_resources(struct pci_bus
+  * pcibios_fixup_bus - Called after each bus is probed,
+  * but before its children are examined.
+  */
+-void pcibios_fixup_bus(struct pci_bus *bus)
++void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+ {
+ 	struct pci_sys_data *root = bus->sysdata;
+ 	struct pci_dev *dev;
+diff -rupN linux-2.6.35.11/arch/arm/kernel/entry-armv.S linux-2.6.35.11-ts7500/arch/arm/kernel/entry-armv.S
+--- linux-2.6.35.11/arch/arm/kernel/entry-armv.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/entry-armv.S	2011-03-14 11:18:24.000000000 -0400
+@@ -30,6 +30,11 @@
+  */
+ 	.macro	irq_handler
+ 	get_irqnr_preamble r5, lr
++#ifdef CONFIG_VIC_INTERRUPT
++	get_irqnr_and_base r0, r6, r5, lr
++	mov	r1, sp
++	bl	asm_do_IRQ
++#else   
+ 1:	get_irqnr_and_base r0, r6, r5, lr
+ 	movne	r1, sp
+ 	@
+@@ -37,6 +42,7 @@
+ 	@
+ 	adrne	lr, BSYM(1b)
+ 	bne	asm_do_IRQ
++#endif
+ 
+ #ifdef CONFIG_SMP
+ 	/*
+diff -rupN linux-2.6.35.11/arch/arm/kernel/entry-armv.S.orig linux-2.6.35.11-ts7500/arch/arm/kernel/entry-armv.S.orig
+--- linux-2.6.35.11/arch/arm/kernel/entry-armv.S.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/entry-armv.S.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,1249 @@
++/*
++ *  linux/arch/arm/kernel/entry-armv.S
++ *
++ *  Copyright (C) 1996,1997,1998 Russell King.
++ *  ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk)
++ *  nommu support by Hyok S. Choi (hyok.choi@samsung.com)
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  Low-level vector interface routines
++ *
++ *  Note:  there is a StrongARM bug in the STMIA rn, {regs}^ instruction
++ *  that causes it to save wrong values...  Be aware!
++ */
++
++#include <asm/memory.h>
++#include <asm/glue.h>
++#include <asm/vfpmacros.h>
++#include <mach/entry-macro.S>
++#include <asm/thread_notify.h>
++#include <asm/unwind.h>
++#include <asm/unistd.h>
++
++#include "entry-header.S"
++
++/*
++ * Interrupt handling.  Preserves r7, r8, r9
++ */
++	.macro	irq_handler
++	get_irqnr_preamble r5, lr
++1:	get_irqnr_and_base r0, r6, r5, lr
++	movne	r1, sp
++	@
++	@ routine called with r0 = irq number, r1 = struct pt_regs *
++	@
++	adrne	lr, BSYM(1b)
++	bne	asm_do_IRQ
++
++#ifdef CONFIG_SMP
++	/*
++	 * XXX
++	 *
++	 * this macro assumes that irqstat (r6) and base (r5) are
++	 * preserved from get_irqnr_and_base above
++	 */
++	test_for_ipi r0, r6, r5, lr
++	movne	r0, sp
++	adrne	lr, BSYM(1b)
++	bne	do_IPI
++
++#ifdef CONFIG_LOCAL_TIMERS
++	test_for_ltirq r0, r6, r5, lr
++	movne	r0, sp
++	adrne	lr, BSYM(1b)
++	bne	do_local_timer
++#endif
++#endif
++
++	.endm
++
++#ifdef CONFIG_KPROBES
++	.section	.kprobes.text,"ax",%progbits
++#else
++	.text
++#endif
++
++/*
++ * Invalid mode handlers
++ */
++	.macro	inv_entry, reason
++	sub	sp, sp, #S_FRAME_SIZE
++ ARM(	stmib	sp, {r1 - lr}		)
++ THUMB(	stmia	sp, {r0 - r12}		)
++ THUMB(	str	sp, [sp, #S_SP]		)
++ THUMB(	str	lr, [sp, #S_LR]		)
++	mov	r1, #\reason
++	.endm
++
++__pabt_invalid:
++	inv_entry BAD_PREFETCH
++	b	common_invalid
++ENDPROC(__pabt_invalid)
++
++__dabt_invalid:
++	inv_entry BAD_DATA
++	b	common_invalid
++ENDPROC(__dabt_invalid)
++
++__irq_invalid:
++	inv_entry BAD_IRQ
++	b	common_invalid
++ENDPROC(__irq_invalid)
++
++__und_invalid:
++	inv_entry BAD_UNDEFINSTR
++
++	@
++	@ XXX fall through to common_invalid
++	@
++
++@
++@ common_invalid - generic code for failed exception (re-entrant version of handlers)
++@
++common_invalid:
++	zero_fp
++
++	ldmia	r0, {r4 - r6}
++	add	r0, sp, #S_PC		@ here for interlock avoidance
++	mov	r7, #-1			@  ""   ""    ""        ""
++	str	r4, [sp]		@ save preserved r0
++	stmia	r0, {r5 - r7}		@ lr_<exception>,
++					@ cpsr_<exception>, "old_r0"
++
++	mov	r0, sp
++	b	bad_mode
++ENDPROC(__und_invalid)
++
++/*
++ * SVC mode handlers
++ */
++
++#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
++#define SPFIX(code...) code
++#else
++#define SPFIX(code...)
++#endif
++
++	.macro	svc_entry, stack_hole=0
++ UNWIND(.fnstart		)
++ UNWIND(.save {r0 - pc}		)
++	sub	sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
++#ifdef CONFIG_THUMB2_KERNEL
++ SPFIX(	str	r0, [sp]	)	@ temporarily saved
++ SPFIX(	mov	r0, sp		)
++ SPFIX(	tst	r0, #4		)	@ test original stack alignment
++ SPFIX(	ldr	r0, [sp]	)	@ restored
++#else
++ SPFIX(	tst	sp, #4		)
++#endif
++ SPFIX(	subeq	sp, sp, #4	)
++	stmia	sp, {r1 - r12}
++
++	ldmia	r0, {r1 - r3}
++	add	r5, sp, #S_SP - 4	@ here for interlock avoidance
++	mov	r4, #-1			@  ""  ""      ""       ""
++	add	r0, sp, #(S_FRAME_SIZE + \stack_hole - 4)
++ SPFIX(	addeq	r0, r0, #4	)
++	str	r1, [sp, #-4]!		@ save the "real" r0 copied
++					@ from the exception stack
++
++	mov	r1, lr
++
++	@
++	@ We are now ready to fill in the remaining blanks on the stack:
++	@
++	@  r0 - sp_svc
++	@  r1 - lr_svc
++	@  r2 - lr_<exception>, already fixed up for correct return/restart
++	@  r3 - spsr_<exception>
++	@  r4 - orig_r0 (see pt_regs definition in ptrace.h)
++	@
++	stmia	r5, {r0 - r4}
++	.endm
++
++	.align	5
++__dabt_svc:
++	svc_entry
++
++	@
++	@ get ready to re-enable interrupts if appropriate
++	@
++	mrs	r9, cpsr
++	tst	r3, #PSR_I_BIT
++	biceq	r9, r9, #PSR_I_BIT
++
++	@
++	@ Call the processor-specific abort handler:
++	@
++	@  r2 - aborted context pc
++	@  r3 - aborted context cpsr
++	@
++	@ The abort handler must return the aborted address in r0, and
++	@ the fault status register in r1.  r9 must be preserved.
++	@
++#ifdef MULTI_DABORT
++	ldr	r4, .LCprocfns
++	mov	lr, pc
++	ldr	pc, [r4, #PROCESSOR_DABT_FUNC]
++#else
++	bl	CPU_DABORT_HANDLER
++#endif
++
++	@
++	@ set desired IRQ state, then call main handler
++	@
++	msr	cpsr_c, r9
++	mov	r2, sp
++	bl	do_DataAbort
++
++	@
++	@ IRQs off again before pulling preserved data off the stack
++	@
++	disable_irq_notrace
++
++	@
++	@ restore SPSR and restart the instruction
++	@
++	ldr	r2, [sp, #S_PSR]
++	svc_exit r2				@ return from exception
++ UNWIND(.fnend		)
++ENDPROC(__dabt_svc)
++
++	.align	5
++__irq_svc:
++	svc_entry
++
++#ifdef CONFIG_TRACE_IRQFLAGS
++	bl	trace_hardirqs_off
++#endif
++#ifdef CONFIG_PREEMPT
++	get_thread_info tsk
++	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
++	add	r7, r8, #1			@ increment it
++	str	r7, [tsk, #TI_PREEMPT]
++#endif
++
++	irq_handler
++#ifdef CONFIG_PREEMPT
++	str	r8, [tsk, #TI_PREEMPT]		@ restore preempt count
++	ldr	r0, [tsk, #TI_FLAGS]		@ get flags
++	teq	r8, #0				@ if preempt count != 0
++	movne	r0, #0				@ force flags to 0
++	tst	r0, #_TIF_NEED_RESCHED
++	blne	svc_preempt
++#endif
++	ldr	r4, [sp, #S_PSR]		@ irqs are already disabled
++#ifdef CONFIG_TRACE_IRQFLAGS
++	tst	r4, #PSR_I_BIT
++	bleq	trace_hardirqs_on
++#endif
++	svc_exit r4				@ return from exception
++ UNWIND(.fnend		)
++ENDPROC(__irq_svc)
++
++	.ltorg
++
++#ifdef CONFIG_PREEMPT
++svc_preempt:
++	mov	r8, lr
++1:	bl	preempt_schedule_irq		@ irq en/disable is done inside
++	ldr	r0, [tsk, #TI_FLAGS]		@ get new tasks TI_FLAGS
++	tst	r0, #_TIF_NEED_RESCHED
++	moveq	pc, r8				@ go again
++	b	1b
++#endif
++
++	.align	5
++__und_svc:
++#ifdef CONFIG_KPROBES
++	@ If a kprobe is about to simulate a "stmdb sp..." instruction,
++	@ it obviously needs free stack space which then will belong to
++	@ the saved context.
++	svc_entry 64
++#else
++	svc_entry
++#endif
++
++	@
++	@ call emulation code, which returns using r9 if it has emulated
++	@ the instruction, or the more conventional lr if we are to treat
++	@ this as a real undefined instruction
++	@
++	@  r0 - instruction
++	@
++#ifndef	CONFIG_THUMB2_KERNEL
++	ldr	r0, [r2, #-4]
++#else
++	ldrh	r0, [r2, #-2]			@ Thumb instruction at LR - 2
++	and	r9, r0, #0xf800
++	cmp	r9, #0xe800			@ 32-bit instruction if xx >= 0
++	ldrhhs	r9, [r2]			@ bottom 16 bits
++	orrhs	r0, r9, r0, lsl #16
++#endif
++	adr	r9, BSYM(1f)
++	bl	call_fpe
++
++	mov	r0, sp				@ struct pt_regs *regs
++	bl	do_undefinstr
++
++	@
++	@ IRQs off again before pulling preserved data off the stack
++	@
++1:	disable_irq_notrace
++
++	@
++	@ restore SPSR and restart the instruction
++	@
++	ldr	r2, [sp, #S_PSR]		@ Get SVC cpsr
++	svc_exit r2				@ return from exception
++ UNWIND(.fnend		)
++ENDPROC(__und_svc)
++
++	.align	5
++__pabt_svc:
++	svc_entry
++
++	@
++	@ re-enable interrupts if appropriate
++	@
++	mrs	r9, cpsr
++	tst	r3, #PSR_I_BIT
++	biceq	r9, r9, #PSR_I_BIT
++
++	mov	r0, r2			@ pass address of aborted instruction.
++#ifdef MULTI_PABORT
++	ldr	r4, .LCprocfns
++	mov	lr, pc
++	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
++#else
++	bl	CPU_PABORT_HANDLER
++#endif
++	msr	cpsr_c, r9			@ Maybe enable interrupts
++	mov	r2, sp				@ regs
++	bl	do_PrefetchAbort		@ call abort handler
++
++	@
++	@ IRQs off again before pulling preserved data off the stack
++	@
++	disable_irq_notrace
++
++	@
++	@ restore SPSR and restart the instruction
++	@
++	ldr	r2, [sp, #S_PSR]
++	svc_exit r2				@ return from exception
++ UNWIND(.fnend		)
++ENDPROC(__pabt_svc)
++
++	.align	5
++.LCcralign:
++	.word	cr_alignment
++#ifdef MULTI_DABORT
++.LCprocfns:
++	.word	processor
++#endif
++.LCfp:
++	.word	fp_enter
++
++/*
++ * User mode handlers
++ *
++ * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE
++ */
++
++#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7)
++#error "sizeof(struct pt_regs) must be a multiple of 8"
++#endif
++
++	.macro	usr_entry
++ UNWIND(.fnstart	)
++ UNWIND(.cantunwind	)	@ don't unwind the user space
++	sub	sp, sp, #S_FRAME_SIZE
++ ARM(	stmib	sp, {r1 - r12}	)
++ THUMB(	stmia	sp, {r0 - r12}	)
++
++	ldmia	r0, {r1 - r3}
++	add	r0, sp, #S_PC		@ here for interlock avoidance
++	mov	r4, #-1			@  ""  ""     ""        ""
++
++	str	r1, [sp]		@ save the "real" r0 copied
++					@ from the exception stack
++
++	@
++	@ We are now ready to fill in the remaining blanks on the stack:
++	@
++	@  r2 - lr_<exception>, already fixed up for correct return/restart
++	@  r3 - spsr_<exception>
++	@  r4 - orig_r0 (see pt_regs definition in ptrace.h)
++	@
++	@ Also, separately save sp_usr and lr_usr
++	@
++	stmia	r0, {r2 - r4}
++ ARM(	stmdb	r0, {sp, lr}^			)
++ THUMB(	store_user_sp_lr r0, r1, S_SP - S_PC	)
++
++	@
++	@ Enable the alignment trap while in kernel mode
++	@
++	alignment_trap r0
++
++	@
++	@ Clear FP to mark the first stack frame
++	@
++	zero_fp
++	.endm
++
++	.macro	kuser_cmpxchg_check
++#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
++#ifndef CONFIG_MMU
++#warning "NPTL on non MMU needs fixing"
++#else
++	@ Make sure our user space atomic helper is restarted
++	@ if it was interrupted in a critical region.  Here we
++	@ perform a quick test inline since it should be false
++	@ 99.9999% of the time.  The rest is done out of line.
++	cmp	r2, #TASK_SIZE
++	blhs	kuser_cmpxchg_fixup
++#endif
++#endif
++	.endm
++
++	.align	5
++__dabt_usr:
++	usr_entry
++	kuser_cmpxchg_check
++
++	@
++	@ Call the processor-specific abort handler:
++	@
++	@  r2 - aborted context pc
++	@  r3 - aborted context cpsr
++	@
++	@ The abort handler must return the aborted address in r0, and
++	@ the fault status register in r1.
++	@
++#ifdef MULTI_DABORT
++	ldr	r4, .LCprocfns
++	mov	lr, pc
++	ldr	pc, [r4, #PROCESSOR_DABT_FUNC]
++#else
++	bl	CPU_DABORT_HANDLER
++#endif
++
++	@
++	@ IRQs on, then call the main handler
++	@
++	enable_irq
++	mov	r2, sp
++	adr	lr, BSYM(ret_from_exception)
++	b	do_DataAbort
++ UNWIND(.fnend		)
++ENDPROC(__dabt_usr)
++
++	.align	5
++__irq_usr:
++	usr_entry
++	kuser_cmpxchg_check
++
++	get_thread_info tsk
++#ifdef CONFIG_PREEMPT
++	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
++	add	r7, r8, #1			@ increment it
++	str	r7, [tsk, #TI_PREEMPT]
++#endif
++
++	irq_handler
++#ifdef CONFIG_PREEMPT
++	ldr	r0, [tsk, #TI_PREEMPT]
++	str	r8, [tsk, #TI_PREEMPT]
++	teq	r0, r7
++ ARM(	strne	r0, [r0, -r0]	)
++ THUMB(	movne	r0, #0		)
++ THUMB(	strne	r0, [r0]	)
++#endif
++
++	mov	why, #0
++	b	ret_to_user
++ UNWIND(.fnend		)
++ENDPROC(__irq_usr)
++
++	.ltorg
++
++	.align	5
++__und_usr:
++	usr_entry
++
++	@
++	@ fall through to the emulation code, which returns using r9 if
++	@ it has emulated the instruction, or the more conventional lr
++	@ if we are to treat this as a real undefined instruction
++	@
++	@  r0 - instruction
++	@
++	adr	r9, BSYM(ret_from_exception)
++	adr	lr, BSYM(__und_usr_unknown)
++	tst	r3, #PSR_T_BIT			@ Thumb mode?
++	itet	eq				@ explicit IT needed for the 1f label
++	subeq	r4, r2, #4			@ ARM instr at LR - 4
++	subne	r4, r2, #2			@ Thumb instr at LR - 2
++1:	ldreqt	r0, [r4]
++#ifdef CONFIG_CPU_ENDIAN_BE8
++	reveq	r0, r0				@ little endian instruction
++#endif
++	beq	call_fpe
++	@ Thumb instruction
++#if __LINUX_ARM_ARCH__ >= 7
++2:
++ ARM(	ldrht	r5, [r4], #2	)
++ THUMB(	ldrht	r5, [r4]	)
++ THUMB(	add	r4, r4, #2	)
++	and	r0, r5, #0xf800			@ mask bits 111x x... .... ....
++	cmp	r0, #0xe800			@ 32bit instruction if xx != 0
++	blo	__und_usr_unknown
++3:	ldrht	r0, [r4]
++	add	r2, r2, #2			@ r2 is PC + 2, make it PC + 4
++	orr	r0, r0, r5, lsl #16
++#else
++	b	__und_usr_unknown
++#endif
++ UNWIND(.fnend		)
++ENDPROC(__und_usr)
++
++	@
++	@ fallthrough to call_fpe
++	@
++
++/*
++ * The out of line fixup for the ldrt above.
++ */
++	.pushsection .fixup, "ax"
++4:	mov	pc, r9
++	.popsection
++	.pushsection __ex_table,"a"
++	.long	1b, 4b
++#if __LINUX_ARM_ARCH__ >= 7
++	.long	2b, 4b
++	.long	3b, 4b
++#endif
++	.popsection
++
++/*
++ * Check whether the instruction is a co-processor instruction.
++ * If yes, we need to call the relevant co-processor handler.
++ *
++ * Note that we don't do a full check here for the co-processor
++ * instructions; all instructions with bit 27 set are well
++ * defined.  The only instructions that should fault are the
++ * co-processor instructions.  However, we have to watch out
++ * for the ARM6/ARM7 SWI bug.
++ *
++ * NEON is a special case that has to be handled here. Not all
++ * NEON instructions are co-processor instructions, so we have
++ * to make a special case of checking for them. Plus, there's
++ * five groups of them, so we have a table of mask/opcode pairs
++ * to check against, and if any match then we branch off into the
++ * NEON handler code.
++ *
++ * Emulators may wish to make use of the following registers:
++ *  r0  = instruction opcode.
++ *  r2  = PC+4
++ *  r9  = normal "successful" return address
++ *  r10 = this threads thread_info structure.
++ *  lr  = unrecognised instruction return address
++ */
++	@
++	@ Fall-through from Thumb-2 __und_usr
++	@
++#ifdef CONFIG_NEON
++	adr	r6, .LCneon_thumb_opcodes
++	b	2f
++#endif
++call_fpe:
++#ifdef CONFIG_NEON
++	adr	r6, .LCneon_arm_opcodes
++2:
++	ldr	r7, [r6], #4			@ mask value
++	cmp	r7, #0				@ end mask?
++	beq	1f
++	and	r8, r0, r7
++	ldr	r7, [r6], #4			@ opcode bits matching in mask
++	cmp	r8, r7				@ NEON instruction?
++	bne	2b
++	get_thread_info r10
++	mov	r7, #1
++	strb	r7, [r10, #TI_USED_CP + 10]	@ mark CP#10 as used
++	strb	r7, [r10, #TI_USED_CP + 11]	@ mark CP#11 as used
++	b	do_vfp				@ let VFP handler handle this
++1:
++#endif
++	tst	r0, #0x08000000			@ only CDP/CPRT/LDC/STC have bit 27
++	tstne	r0, #0x04000000			@ bit 26 set on both ARM and Thumb-2
++#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
++	and	r8, r0, #0x0f000000		@ mask out op-code bits
++	teqne	r8, #0x0f000000			@ SWI (ARM6/7 bug)?
++#endif
++	moveq	pc, lr
++	get_thread_info r10			@ get current thread
++	and	r8, r0, #0x00000f00		@ mask out CP number
++ THUMB(	lsr	r8, r8, #8		)
++	mov	r7, #1
++	add	r6, r10, #TI_USED_CP
++ ARM(	strb	r7, [r6, r8, lsr #8]	)	@ set appropriate used_cp[]
++ THUMB(	strb	r7, [r6, r8]		)	@ set appropriate used_cp[]
++#ifdef CONFIG_IWMMXT
++	@ Test if we need to give access to iWMMXt coprocessors
++	ldr	r5, [r10, #TI_FLAGS]
++	rsbs	r7, r8, #(1 << 8)		@ CP 0 or 1 only
++	movcss	r7, r5, lsr #(TIF_USING_IWMMXT + 1)
++	bcs	iwmmxt_task_enable
++#endif
++ ARM(	add	pc, pc, r8, lsr #6	)
++ THUMB(	lsl	r8, r8, #2		)
++ THUMB(	add	pc, r8			)
++	nop
++
++	movw_pc	lr				@ CP#0
++	W(b)	do_fpe				@ CP#1 (FPE)
++	W(b)	do_fpe				@ CP#2 (FPE)
++	movw_pc	lr				@ CP#3
++#ifdef CONFIG_CRUNCH
++	b	crunch_task_enable		@ CP#4 (MaverickCrunch)
++	b	crunch_task_enable		@ CP#5 (MaverickCrunch)
++	b	crunch_task_enable		@ CP#6 (MaverickCrunch)
++#else
++	movw_pc	lr				@ CP#4
++	movw_pc	lr				@ CP#5
++	movw_pc	lr				@ CP#6
++#endif
++	movw_pc	lr				@ CP#7
++	movw_pc	lr				@ CP#8
++	movw_pc	lr				@ CP#9
++#ifdef CONFIG_VFP
++	W(b)	do_vfp				@ CP#10 (VFP)
++	W(b)	do_vfp				@ CP#11 (VFP)
++#else
++	movw_pc	lr				@ CP#10 (VFP)
++	movw_pc	lr				@ CP#11 (VFP)
++#endif
++	movw_pc	lr				@ CP#12
++	movw_pc	lr				@ CP#13
++	movw_pc	lr				@ CP#14 (Debug)
++	movw_pc	lr				@ CP#15 (Control)
++
++#ifdef CONFIG_NEON
++	.align	6
++
++.LCneon_arm_opcodes:
++	.word	0xfe000000			@ mask
++	.word	0xf2000000			@ opcode
++
++	.word	0xff100000			@ mask
++	.word	0xf4000000			@ opcode
++
++	.word	0x00000000			@ mask
++	.word	0x00000000			@ opcode
++
++.LCneon_thumb_opcodes:
++	.word	0xef000000			@ mask
++	.word	0xef000000			@ opcode
++
++	.word	0xff100000			@ mask
++	.word	0xf9000000			@ opcode
++
++	.word	0x00000000			@ mask
++	.word	0x00000000			@ opcode
++#endif
++
++do_fpe:
++	enable_irq
++	ldr	r4, .LCfp
++	add	r10, r10, #TI_FPSTATE		@ r10 = workspace
++	ldr	pc, [r4]			@ Call FP module USR entry point
++
++/*
++ * The FP module is called with these registers set:
++ *  r0  = instruction
++ *  r2  = PC+4
++ *  r9  = normal "successful" return address
++ *  r10 = FP workspace
++ *  lr  = unrecognised FP instruction return address
++ */
++
++	.pushsection .data
++ENTRY(fp_enter)
++	.word	no_fp
++	.popsection
++
++ENTRY(no_fp)
++	mov	pc, lr
++ENDPROC(no_fp)
++
++__und_usr_unknown:
++	enable_irq
++	mov	r0, sp
++	adr	lr, BSYM(ret_from_exception)
++	b	do_undefinstr
++ENDPROC(__und_usr_unknown)
++
++	.align	5
++__pabt_usr:
++	usr_entry
++
++	mov	r0, r2			@ pass address of aborted instruction.
++#ifdef MULTI_PABORT
++	ldr	r4, .LCprocfns
++	mov	lr, pc
++	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
++#else
++	bl	CPU_PABORT_HANDLER
++#endif
++	enable_irq				@ Enable interrupts
++	mov	r2, sp				@ regs
++	bl	do_PrefetchAbort		@ call abort handler
++ UNWIND(.fnend		)
++	/* fall through */
++/*
++ * This is the return code to user mode for abort handlers
++ */
++ENTRY(ret_from_exception)
++ UNWIND(.fnstart	)
++ UNWIND(.cantunwind	)
++	get_thread_info tsk
++	mov	why, #0
++	b	ret_to_user
++ UNWIND(.fnend		)
++ENDPROC(__pabt_usr)
++ENDPROC(ret_from_exception)
++
++/*
++ * Register switch for ARMv3 and ARMv4 processors
++ * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
++ * previous and next are guaranteed not to be the same.
++ */
++ENTRY(__switch_to)
++ UNWIND(.fnstart	)
++ UNWIND(.cantunwind	)
++	add	ip, r1, #TI_CPU_SAVE
++	ldr	r3, [r2, #TI_TP_VALUE]
++ ARM(	stmia	ip!, {r4 - sl, fp, sp, lr} )	@ Store most regs on stack
++ THUMB(	stmia	ip!, {r4 - sl, fp}	   )	@ Store most regs on stack
++ THUMB(	str	sp, [ip], #4		   )
++ THUMB(	str	lr, [ip], #4		   )
++#ifdef CONFIG_MMU
++	ldr	r6, [r2, #TI_CPU_DOMAIN]
++#endif
++#if defined(CONFIG_HAS_TLS_REG)
++	mcr	p15, 0, r3, c13, c0, 3		@ set TLS register
++#elif !defined(CONFIG_TLS_REG_EMUL)
++	mov	r4, #0xffff0fff
++	str	r3, [r4, #-15]			@ TLS val at 0xffff0ff0
++#endif
++#ifdef CONFIG_MMU
++	mcr	p15, 0, r6, c3, c0, 0		@ Set domain register
++#endif
++	mov	r5, r0
++	add	r4, r2, #TI_CPU_SAVE
++	ldr	r0, =thread_notify_head
++	mov	r1, #THREAD_NOTIFY_SWITCH
++	bl	atomic_notifier_call_chain
++ THUMB(	mov	ip, r4			   )
++	mov	r0, r5
++ ARM(	ldmia	r4, {r4 - sl, fp, sp, pc}  )	@ Load all regs saved previously
++ THUMB(	ldmia	ip!, {r4 - sl, fp}	   )	@ Load all regs saved previously
++ THUMB(	ldr	sp, [ip], #4		   )
++ THUMB(	ldr	pc, [ip]		   )
++ UNWIND(.fnend		)
++ENDPROC(__switch_to)
++
++	__INIT
++
++/*
++ * User helpers.
++ *
++ * These are segment of kernel provided user code reachable from user space
++ * at a fixed address in kernel memory.  This is used to provide user space
++ * with some operations which require kernel help because of unimplemented
++ * native feature and/or instructions in many ARM CPUs. The idea is for
++ * this code to be executed directly in user mode for best efficiency but
++ * which is too intimate with the kernel counter part to be left to user
++ * libraries.  In fact this code might even differ from one CPU to another
++ * depending on the available  instruction set and restrictions like on
++ * SMP systems.  In other words, the kernel reserves the right to change
++ * this code as needed without warning. Only the entry points and their
++ * results are guaranteed to be stable.
++ *
++ * Each segment is 32-byte aligned and will be moved to the top of the high
++ * vector page.  New segments (if ever needed) must be added in front of
++ * existing ones.  This mechanism should be used only for things that are
++ * really small and justified, and not be abused freely.
++ *
++ * User space is expected to implement those things inline when optimizing
++ * for a processor that has the necessary native support, but only if such
++ * resulting binaries are already to be incompatible with earlier ARM
++ * processors due to the use of unsupported instructions other than what
++ * is provided here.  In other words don't make binaries unable to run on
++ * earlier processors just for the sake of not using these kernel helpers
++ * if your compiled code is not going to use the new instructions for other
++ * purpose.
++ */
++ THUMB(	.arm	)
++
++	.macro	usr_ret, reg
++#ifdef CONFIG_ARM_THUMB
++	bx	\reg
++#else
++	mov	pc, \reg
++#endif
++	.endm
++
++	.align	5
++	.globl	__kuser_helper_start
++__kuser_helper_start:
++
++/*
++ * Reference prototype:
++ *
++ *	void __kernel_memory_barrier(void)
++ *
++ * Input:
++ *
++ *	lr = return address
++ *
++ * Output:
++ *
++ *	none
++ *
++ * Clobbered:
++ *
++ *	none
++ *
++ * Definition and user space usage example:
++ *
++ *	typedef void (__kernel_dmb_t)(void);
++ *	#define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0)
++ *
++ * Apply any needed memory barrier to preserve consistency with data modified
++ * manually and __kuser_cmpxchg usage.
++ *
++ * This could be used as follows:
++ *
++ * #define __kernel_dmb() \
++ *         asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \
++ *	        : : : "r0", "lr","cc" )
++ */
++
++__kuser_memory_barrier:				@ 0xffff0fa0
++	smp_dmb
++	usr_ret	lr
++
++	.align	5
++
++/*
++ * Reference prototype:
++ *
++ *	int __kernel_cmpxchg(int oldval, int newval, int *ptr)
++ *
++ * Input:
++ *
++ *	r0 = oldval
++ *	r1 = newval
++ *	r2 = ptr
++ *	lr = return address
++ *
++ * Output:
++ *
++ *	r0 = returned value (zero or non-zero)
++ *	C flag = set if r0 == 0, clear if r0 != 0
++ *
++ * Clobbered:
++ *
++ *	r3, ip, flags
++ *
++ * Definition and user space usage example:
++ *
++ *	typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
++ *	#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
++ *
++ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
++ * Return zero if *ptr was changed or non-zero if no exchange happened.
++ * The C flag is also set if *ptr was changed to allow for assembly
++ * optimization in the calling code.
++ *
++ * Notes:
++ *
++ *    - This routine already includes memory barriers as needed.
++ *
++ * For example, a user space atomic_add implementation could look like this:
++ *
++ * #define atomic_add(ptr, val) \
++ *	({ register unsigned int *__ptr asm("r2") = (ptr); \
++ *	   register unsigned int __result asm("r1"); \
++ *	   asm volatile ( \
++ *	       "1: @ atomic_add\n\t" \
++ *	       "ldr	r0, [r2]\n\t" \
++ *	       "mov	r3, #0xffff0fff\n\t" \
++ *	       "add	lr, pc, #4\n\t" \
++ *	       "add	r1, r0, %2\n\t" \
++ *	       "add	pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \
++ *	       "bcc	1b" \
++ *	       : "=&r" (__result) \
++ *	       : "r" (__ptr), "rIL" (val) \
++ *	       : "r0","r3","ip","lr","cc","memory" ); \
++ *	   __result; })
++ */
++
++__kuser_cmpxchg:				@ 0xffff0fc0
++
++#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
++
++	/*
++	 * Poor you.  No fast solution possible...
++	 * The kernel itself must perform the operation.
++	 * A special ghost syscall is used for that (see traps.c).
++	 */
++	stmfd	sp!, {r7, lr}
++	ldr	r7, =1f			@ it's 20 bits
++	swi	__ARM_NR_cmpxchg
++	ldmfd	sp!, {r7, pc}
++1:	.word	__ARM_NR_cmpxchg
++
++#elif __LINUX_ARM_ARCH__ < 6
++
++#ifdef CONFIG_MMU
++
++	/*
++	 * The only thing that can break atomicity in this cmpxchg
++	 * implementation is either an IRQ or a data abort exception
++	 * causing another process/thread to be scheduled in the middle
++	 * of the critical sequence.  To prevent this, code is added to
++	 * the IRQ and data abort exception handlers to set the pc back
++	 * to the beginning of the critical section if it is found to be
++	 * within that critical section (see kuser_cmpxchg_fixup).
++	 */
++1:	ldr	r3, [r2]			@ load current val
++	subs	r3, r3, r0			@ compare with oldval
++2:	streq	r1, [r2]			@ store newval if eq
++	rsbs	r0, r3, #0			@ set return val and C flag
++	usr_ret	lr
++
++	.text
++kuser_cmpxchg_fixup:
++	@ Called from kuser_cmpxchg_check macro.
++	@ r2 = address of interrupted insn (must be preserved).
++	@ sp = saved regs. r7 and r8 are clobbered.
++	@ 1b = first critical insn, 2b = last critical insn.
++	@ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b.
++	mov	r7, #0xffff0fff
++	sub	r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg)))
++	subs	r8, r2, r7
++	rsbcss	r8, r8, #(2b - 1b)
++	strcs	r7, [sp, #S_PC]
++	mov	pc, lr
++	.previous
++
++#else
++#warning "NPTL on non MMU needs fixing"
++	mov	r0, #-1
++	adds	r0, r0, #0
++	usr_ret	lr
++#endif
++
++#else
++
++	smp_dmb
++1:	ldrex	r3, [r2]
++	subs	r3, r3, r0
++	strexeq	r3, r1, [r2]
++	teqeq	r3, #1
++	beq	1b
++	rsbs	r0, r3, #0
++	/* beware -- each __kuser slot must be 8 instructions max */
++#ifdef CONFIG_SMP
++	b	__kuser_memory_barrier
++#else
++	usr_ret	lr
++#endif
++
++#endif
++
++	.align	5
++
++/*
++ * Reference prototype:
++ *
++ *	int __kernel_get_tls(void)
++ *
++ * Input:
++ *
++ *	lr = return address
++ *
++ * Output:
++ *
++ *	r0 = TLS value
++ *
++ * Clobbered:
++ *
++ *	none
++ *
++ * Definition and user space usage example:
++ *
++ *	typedef int (__kernel_get_tls_t)(void);
++ *	#define __kernel_get_tls (*(__kernel_get_tls_t *)0xffff0fe0)
++ *
++ * Get the TLS value as previously set via the __ARM_NR_set_tls syscall.
++ *
++ * This could be used as follows:
++ *
++ * #define __kernel_get_tls() \
++ *	({ register unsigned int __val asm("r0"); \
++ *         asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \
++ *	        : "=r" (__val) : : "lr","cc" ); \
++ *	   __val; })
++ */
++
++__kuser_get_tls:				@ 0xffff0fe0
++
++#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL)
++	ldr	r0, [pc, #(16 - 8)]		@ TLS stored at 0xffff0ff0
++#else
++	mrc	p15, 0, r0, c13, c0, 3		@ read TLS register
++#endif
++	usr_ret	lr
++
++	.rep	5
++	.word	0			@ pad up to __kuser_helper_version
++	.endr
++
++/*
++ * Reference declaration:
++ *
++ *	extern unsigned int __kernel_helper_version;
++ *
++ * Definition and user space usage example:
++ *
++ *	#define __kernel_helper_version (*(unsigned int *)0xffff0ffc)
++ *
++ * User space may read this to determine the curent number of helpers
++ * available.
++ */
++
++__kuser_helper_version:				@ 0xffff0ffc
++	.word	((__kuser_helper_end - __kuser_helper_start) >> 5)
++
++	.globl	__kuser_helper_end
++__kuser_helper_end:
++
++ THUMB(	.thumb	)
++
++/*
++ * Vector stubs.
++ *
++ * This code is copied to 0xffff0200 so we can use branches in the
++ * vectors, rather than ldr's.  Note that this code must not
++ * exceed 0x300 bytes.
++ *
++ * Common stub entry macro:
++ *   Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
++ *
++ * SP points to a minimal amount of processor-private memory, the address
++ * of which is copied into r0 for the mode specific abort handler.
++ */
++	.macro	vector_stub, name, mode, correction=0
++	.align	5
++
++vector_\name:
++	.if \correction
++	sub	lr, lr, #\correction
++	.endif
++
++	@
++	@ Save r0, lr_<exception> (parent PC) and spsr_<exception>
++	@ (parent CPSR)
++	@
++	stmia	sp, {r0, lr}		@ save r0, lr
++	mrs	lr, spsr
++	str	lr, [sp, #8]		@ save spsr
++
++	@
++	@ Prepare for SVC32 mode.  IRQs remain disabled.
++	@
++	mrs	r0, cpsr
++	eor	r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)
++	msr	spsr_cxsf, r0
++
++	@
++	@ the branch table must immediately follow this code
++	@
++	and	lr, lr, #0x0f
++ THUMB(	adr	r0, 1f			)
++ THUMB(	ldr	lr, [r0, lr, lsl #2]	)
++	mov	r0, sp
++ ARM(	ldr	lr, [pc, lr, lsl #2]	)
++	movs	pc, lr			@ branch to handler in SVC mode
++ENDPROC(vector_\name)
++
++	.align	2
++	@ handler addresses follow this label
++1:
++	.endm
++
++	.globl	__stubs_start
++__stubs_start:
++/*
++ * Interrupt dispatcher
++ */
++	vector_stub	irq, IRQ_MODE, 4
++
++	.long	__irq_usr			@  0  (USR_26 / USR_32)
++	.long	__irq_invalid			@  1  (FIQ_26 / FIQ_32)
++	.long	__irq_invalid			@  2  (IRQ_26 / IRQ_32)
++	.long	__irq_svc			@  3  (SVC_26 / SVC_32)
++	.long	__irq_invalid			@  4
++	.long	__irq_invalid			@  5
++	.long	__irq_invalid			@  6
++	.long	__irq_invalid			@  7
++	.long	__irq_invalid			@  8
++	.long	__irq_invalid			@  9
++	.long	__irq_invalid			@  a
++	.long	__irq_invalid			@  b
++	.long	__irq_invalid			@  c
++	.long	__irq_invalid			@  d
++	.long	__irq_invalid			@  e
++	.long	__irq_invalid			@  f
++
++/*
++ * Data abort dispatcher
++ * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
++ */
++	vector_stub	dabt, ABT_MODE, 8
++
++	.long	__dabt_usr			@  0  (USR_26 / USR_32)
++	.long	__dabt_invalid			@  1  (FIQ_26 / FIQ_32)
++	.long	__dabt_invalid			@  2  (IRQ_26 / IRQ_32)
++	.long	__dabt_svc			@  3  (SVC_26 / SVC_32)
++	.long	__dabt_invalid			@  4
++	.long	__dabt_invalid			@  5
++	.long	__dabt_invalid			@  6
++	.long	__dabt_invalid			@  7
++	.long	__dabt_invalid			@  8
++	.long	__dabt_invalid			@  9
++	.long	__dabt_invalid			@  a
++	.long	__dabt_invalid			@  b
++	.long	__dabt_invalid			@  c
++	.long	__dabt_invalid			@  d
++	.long	__dabt_invalid			@  e
++	.long	__dabt_invalid			@  f
++
++/*
++ * Prefetch abort dispatcher
++ * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
++ */
++	vector_stub	pabt, ABT_MODE, 4
++
++	.long	__pabt_usr			@  0 (USR_26 / USR_32)
++	.long	__pabt_invalid			@  1 (FIQ_26 / FIQ_32)
++	.long	__pabt_invalid			@  2 (IRQ_26 / IRQ_32)
++	.long	__pabt_svc			@  3 (SVC_26 / SVC_32)
++	.long	__pabt_invalid			@  4
++	.long	__pabt_invalid			@  5
++	.long	__pabt_invalid			@  6
++	.long	__pabt_invalid			@  7
++	.long	__pabt_invalid			@  8
++	.long	__pabt_invalid			@  9
++	.long	__pabt_invalid			@  a
++	.long	__pabt_invalid			@  b
++	.long	__pabt_invalid			@  c
++	.long	__pabt_invalid			@  d
++	.long	__pabt_invalid			@  e
++	.long	__pabt_invalid			@  f
++
++/*
++ * Undef instr entry dispatcher
++ * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
++ */
++	vector_stub	und, UND_MODE
++
++	.long	__und_usr			@  0 (USR_26 / USR_32)
++	.long	__und_invalid			@  1 (FIQ_26 / FIQ_32)
++	.long	__und_invalid			@  2 (IRQ_26 / IRQ_32)
++	.long	__und_svc			@  3 (SVC_26 / SVC_32)
++	.long	__und_invalid			@  4
++	.long	__und_invalid			@  5
++	.long	__und_invalid			@  6
++	.long	__und_invalid			@  7
++	.long	__und_invalid			@  8
++	.long	__und_invalid			@  9
++	.long	__und_invalid			@  a
++	.long	__und_invalid			@  b
++	.long	__und_invalid			@  c
++	.long	__und_invalid			@  d
++	.long	__und_invalid			@  e
++	.long	__und_invalid			@  f
++
++	.align	5
++
++/*=============================================================================
++ * Undefined FIQs
++ *-----------------------------------------------------------------------------
++ * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
++ * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg.
++ * Basically to switch modes, we *HAVE* to clobber one register...  brain
++ * damage alert!  I don't think that we can execute any code in here in any
++ * other mode than FIQ...  Ok you can switch to another mode, but you can't
++ * get out of that mode without clobbering one register.
++ */
++vector_fiq:
++	disable_fiq
++	subs	pc, lr, #4
++
++/*=============================================================================
++ * Address exception handler
++ *-----------------------------------------------------------------------------
++ * These aren't too critical.
++ * (they're not supposed to happen, and won't happen in 32-bit data mode).
++ */
++
++vector_addrexcptn:
++	b	vector_addrexcptn
++
++/*
++ * We group all the following data together to optimise
++ * for CPUs with separate I & D caches.
++ */
++	.align	5
++
++.LCvswi:
++	.word	vector_swi
++
++	.globl	__stubs_end
++__stubs_end:
++
++	.equ	stubs_offset, __vectors_start + 0x200 - __stubs_start
++
++	.globl	__vectors_start
++__vectors_start:
++ ARM(	swi	SYS_ERROR0	)
++ THUMB(	svc	#0		)
++ THUMB(	nop			)
++	W(b)	vector_und + stubs_offset
++	W(ldr)	pc, .LCvswi + stubs_offset
++	W(b)	vector_pabt + stubs_offset
++	W(b)	vector_dabt + stubs_offset
++	W(b)	vector_addrexcptn + stubs_offset
++	W(b)	vector_irq + stubs_offset
++	W(b)	vector_fiq + stubs_offset
++
++	.globl	__vectors_end
++__vectors_end:
++
++	.data
++
++	.globl	cr_alignment
++	.globl	cr_no_alignment
++cr_alignment:
++	.space	4
++cr_no_alignment:
++	.space	4
+diff -rupN linux-2.6.35.11/arch/arm/kernel/head-common.S linux-2.6.35.11-ts7500/arch/arm/kernel/head-common.S
+--- linux-2.6.35.11/arch/arm/kernel/head-common.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/head-common.S	2011-03-14 11:18:24.000000000 -0400
+@@ -39,6 +39,16 @@ __switch_data:
+  *  r9  = processor ID
+  */
+ __mmap_switched:
++
++# We come here right after the MMU is enabled
++
++#ifdef CONFIG_DEBUG_LL
++@   stmfd sp!, {r0, r1, r2, r3, r9, lr}
++@   adr	r0, str_mmap_switched
++@	bl	printascii
++@   ldmfd sp!, {r0, r1, r2, r3, r9, lr}
++#endif
++
+ 	adr	r3, __switch_data + 4
+ 
+ 	ldmia	r3!, {r4, r5, r6, r7}
+@@ -53,6 +63,7 @@ __mmap_switched:
+ 	strcc	fp, [r6],#4
+ 	bcc	1b
+ 
++   
+  ARM(	ldmia	r3, {r4, r5, r6, r7, sp})
+  THUMB(	ldmia	r3, {r4, r5, r6, r7}	)
+  THUMB(	ldr	sp, [r3, #16]		)
+@@ -61,7 +72,23 @@ __mmap_switched:
+ 	str	r2, [r6]			@ Save atags pointer
+ 	bic	r4, r0, #CR_A			@ Clear 'A' bit
+ 	stmia	r7, {r0, r4}			@ Save control register values
++   
++#ifdef CONFIG_DEBUG_LL
++   stmfd sp!, {r0, r1, r2, r3, r9, lr}
++   adr	r0, str_mmap_switched_done
++	bl	printascii
++   ldmfd sp!, {r0, r1, r2, r3, r9, lr}
++#endif
++
++
+ 	b	start_kernel
++
++#ifdef CONFIG_DEBUG_LL
++str_mmap_switched: .asciz "str_mmap_switched\n"   
++str_mmap_switched_done: .asciz "str_mmap_switched_done\n"
++.align 4
++#endif   
++   
+ ENDPROC(__mmap_switched)
+ 
+ /*
+@@ -74,7 +101,7 @@ ENDPROC(__mmap_switched)
+  * machine ID for example).
+  */
+ __error_p:
+-#ifdef CONFIG_DEBUG_LL
++#ifdef CONFIG_DEBUG_LL   
+ 	adr	r0, str_p1
+ 	bl	printascii
+ 	mov	r0, r9
+diff -rupN linux-2.6.35.11/arch/arm/kernel/head.S linux-2.6.35.11-ts7500/arch/arm/kernel/head.S
+--- linux-2.6.35.11/arch/arm/kernel/head.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/head.S	2011-03-14 11:18:24.000000000 -0400
+@@ -22,6 +22,10 @@
+ #include <asm/thread_info.h>
+ #include <asm/system.h>
+ 
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++//#define PROCINFO_INITFUNC	12
++#endif
++
+ #if (PHYS_OFFSET & 0x001fffff)
+ #error "PHYS_OFFSET must be at an even 2MiB boundary!"
+ #endif
+@@ -78,16 +82,75 @@
+ ENTRY(stext)
+ 	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
+ 						@ and irqs disabled
++
++                       
++#ifdef CONFIG_DEBUG_LL
++   stmfd sp!, {r0, r1, r2}
++   mov r6, r1   
++   adr	r0, str_kernel_start
++	bl	printascii
++   adr   r0, str_machine_id
++   bl	printascii
++   mov r0, r6
++   bl printhex8
++   mov r0, #'\n'
++   bl printch
++   ldmfd sp!, {r0, r1, r2}
++#endif
++                  
+ 	mrc	p15, 0, r9, c0, c0		@ get processor id
++   
++#ifdef CONFIG_DEBUG_LL
++   stmfd sp!, {r0, r1, r2}  
++   adr	r0, str_processor_id
++	bl	printascii
++   mov r0, r9
++   bl printhex8
++   mov r0, #'\n'
++   bl printch
++   ldmfd sp!, {r0, r1, r2}
++#endif   
++   
+ 	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
+ 	movs	r10, r5				@ invalid processor (r5=0)?
+ 	beq	__error_p			@ yes, error 'p'
+ 	bl	__lookup_machine_type		@ r5=machinfo
+ 	movs	r8, r5				@ invalid machine (r5=0)?
+-	beq	__error_a			@ yes, error 'a'
++	beq	__error_a			@ yes, error 'a'   
+ 	bl	__vet_atags
+ 	bl	__create_page_tables
+ 
++   
++###########################
++
++	mov	ip, #0	
++	mcr	p15, 0, ip, c7,c14, 2		@ clean/flush D-cache
++	mcr	p15, 0, ip, c7, c10, 4		@ drain write buffer
++	mcr	p15, 0, ip, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++   nop 
++   nop
++   
++#################################
++   
++#ifdef CONFIG_DEBUG_LL
++   stmfd sp!, {r0, r1, r2}  
++   adr	r0, str_procinfo_at
++	bl	printascii
++   mov r0, r10
++   bl printhex8
++   mov r0, #'\n'   
++   bl printch
++   adr	r0, str_initfunc_offset
++	bl	printascii
++   mov r0, #PROCINFO_INITFUNC
++   bl printhex8
++   mov r0, #'\n'   
++   bl printch
++   ldmfd sp!, {r0, r1, r2}
++#endif      
++   
+ 	/*
+ 	 * The following calls CPU specific code in a position independent
+ 	 * manner.  See arch/arm/mm/proc-*.S for details.  r10 = base of
+@@ -101,6 +164,15 @@ ENTRY(stext)
+  ARM(	add	pc, r10, #PROCINFO_INITFUNC	)
+  THUMB(	add	r12, r10, #PROCINFO_INITFUNC	)
+  THUMB(	mov	pc, r12				)
++
++#ifdef CONFIG_DEBUG_LL
++str_kernel_start: .asciz "kernel_start\n"   
++str_machine_id: .asciz "machine ID: 0x"
++str_processor_id: .asciz "processor ID: 0x"
++str_procinfo_at:  .asciz "procinfo at:  0x"
++str_initfunc_offset:  .asciz "PROCINFO_INITFUNC:  0x"
++.align 4
++#endif   
+ ENDPROC(stext)
+ 
+ #if defined(CONFIG_SMP)
+@@ -158,6 +230,13 @@ __secondary_data:
+  * registers.
+  */
+ __enable_mmu:
++#ifdef CONFIG_DEBUG_LL
++@   stmfd sp!, {r0, r1, r2, r3, r6, r13, lr}
++@   adr	r0, str_enable_mmu
++@	bl	printascii
++@   ldmfd sp!, {r0, r1, r2, r3, r6, r13, lr}
++#endif
++
+ #ifdef CONFIG_ALIGNMENT_TRAP
+ 	orr	r0, r0, #CR_A
+ #else
+@@ -179,6 +258,12 @@ __enable_mmu:
+ 	mcr	p15, 0, r5, c3, c0, 0		@ load domain access register
+ 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
+ 	b	__turn_mmu_on
++   
++#ifdef CONFIG_DEBUG_LL   
++str_enable_mmu: .asciz "__enable_mmu\n"
++str_enable_mmu_done: .asciz "__enable_mmu done\n"
++.align 4
++#endif
+ ENDPROC(__enable_mmu)
+ 
+ /*
+@@ -196,10 +281,19 @@ ENDPROC(__enable_mmu)
+ __turn_mmu_on:
+ 	mov	r0, r0
+ 	mcr	p15, 0, r0, c1, c0, 0		@ write control reg
++#if defined(CONFIG_CPU_FA520) || defined(CONFIG_CPU_FA526) || defined(CONFIG_CPU_FA626)
++	nop
++	nop
++	nop
++	nop
++#endif   
+ 	mrc	p15, 0, r3, c0, c0, 0		@ read id reg
++   
+ 	mov	r3, r3
+-	mov	r3, r13
++   mov	r3, r3
++	mov	r3, r13   
+ 	mov	pc, r3
++   
+ ENDPROC(__turn_mmu_on)
+ 
+ 
+@@ -217,6 +311,12 @@ ENDPROC(__turn_mmu_on)
+  *  r4 = physical page table address
+  */
+ __create_page_tables:
++#ifdef CONFIG_DEBUG_LL
++   mov r6, lr
++   adr	r0, str_create_page_tables
++	bl	printascii
++   mov lr, r6
++#endif
+ 	pgtbl	r4				@ page table address
+ 
+ 	/*
+@@ -281,14 +381,15 @@ __create_page_tables:
+ 	/*
+ 	 * Then map first 1MB of ram in case it contains our boot params.
+ 	 */
+-	add	r0, r4, #PAGE_OFFSET >> 18
++	add	r0, r4, #PAGE_OFFSET >> 18   
+ 	orr	r6, r7, #(PHYS_OFFSET & 0xff000000)
+ 	.if	(PHYS_OFFSET & 0x00f00000)
+ 	orr	r6, r6, #(PHYS_OFFSET & 0x00f00000)
+ 	.endif
+ 	str	r6, [r0]
+ 
+-#ifdef CONFIG_DEBUG_LL
++@#if defined(CONFIG_DEBUG_LL) || defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++#if defined(CONFIG_DEBUG_LL)
+ 	ldr	r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
+ 	/*
+ 	 * Map in IO space for serial debugging.
+@@ -329,7 +430,20 @@ __create_page_tables:
+ 	str	r3, [r0]
+ #endif
+ #endif
++
++#ifdef CONFIG_DEBUG_LL
++   mov r6, lr
++   adr	r0, str_create_page_tables_done
++	bl	printascii
++   mov lr, r6
++#endif
++
+ 	mov	pc, lr
++#ifdef CONFIG_DEBUG_LL
++str_create_page_tables: .asciz "create_page_tables\n"   
++str_create_page_tables_done: .asciz "create_page_tables_done\n"
++.align 4
++#endif
+ ENDPROC(__create_page_tables)
+ 	.ltorg
+ 
+diff -rupN linux-2.6.35.11/arch/arm/kernel/process.c linux-2.6.35.11-ts7500/arch/arm/kernel/process.c
+--- linux-2.6.35.11/arch/arm/kernel/process.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/process.c	2011-03-14 11:18:24.000000000 -0400
+@@ -126,9 +126,17 @@ EXPORT_SYMBOL_GPL(arm_pm_restart);
+  */
+ static void default_idle(void)
+ {
++#ifndef CONFIG_CPU_FA_IDLE
++                local_irq_disable();
++#endif
++
+ 	if (!need_resched())
+ 		arch_idle();
+-	local_irq_enable();
++//	local_irq_enable();
++#ifndef CONFIG_CPU_FA_IDLE
++        local_irq_enable();
++#endif
++
+ }
+ 
+ void (*pm_idle)(void) = default_idle;
+diff -rupN linux-2.6.35.11/arch/arm/kernel/process.c.orig linux-2.6.35.11-ts7500/arch/arm/kernel/process.c.orig
+--- linux-2.6.35.11/arch/arm/kernel/process.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/process.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,428 @@
++/*
++ *  linux/arch/arm/kernel/process.c
++ *
++ *  Copyright (C) 1996-2000 Russell King - Converted to ARM.
++ *  Original Copyright (C) 1995  Linus Torvalds
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <stdarg.h>
++
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/stddef.h>
++#include <linux/unistd.h>
++#include <linux/user.h>
++#include <linux/delay.h>
++#include <linux/reboot.h>
++#include <linux/interrupt.h>
++#include <linux/kallsyms.h>
++#include <linux/init.h>
++#include <linux/cpu.h>
++#include <linux/elfcore.h>
++#include <linux/pm.h>
++#include <linux/tick.h>
++#include <linux/utsname.h>
++#include <linux/uaccess.h>
++
++#include <asm/leds.h>
++#include <asm/processor.h>
++#include <asm/system.h>
++#include <asm/thread_notify.h>
++#include <asm/stacktrace.h>
++#include <asm/mach/time.h>
++
++static const char *processor_modes[] = {
++  "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
++  "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
++  "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
++  "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
++};
++
++static const char *isa_modes[] = {
++  "ARM" , "Thumb" , "Jazelle", "ThumbEE"
++};
++
++extern void setup_mm_for_reboot(char mode);
++
++static volatile int hlt_counter;
++
++#include <mach/system.h>
++
++void disable_hlt(void)
++{
++	hlt_counter++;
++}
++
++EXPORT_SYMBOL(disable_hlt);
++
++void enable_hlt(void)
++{
++	hlt_counter--;
++}
++
++EXPORT_SYMBOL(enable_hlt);
++
++static int __init nohlt_setup(char *__unused)
++{
++	hlt_counter = 1;
++	return 1;
++}
++
++static int __init hlt_setup(char *__unused)
++{
++	hlt_counter = 0;
++	return 1;
++}
++
++__setup("nohlt", nohlt_setup);
++__setup("hlt", hlt_setup);
++
++void arm_machine_restart(char mode, const char *cmd)
++{
++	/*
++	 * Clean and disable cache, and turn off interrupts
++	 */
++	cpu_proc_fin();
++
++	/*
++	 * Tell the mm system that we are going to reboot -
++	 * we may need it to insert some 1:1 mappings so that
++	 * soft boot works.
++	 */
++	setup_mm_for_reboot(mode);
++
++	/*
++	 * Now call the architecture specific reboot code.
++	 */
++	arch_reset(mode, cmd);
++
++	/*
++	 * Whoops - the architecture was unable to reboot.
++	 * Tell the user!
++	 */
++	mdelay(1000);
++	printk("Reboot failed -- System halted\n");
++	while (1);
++}
++
++/*
++ * Function pointers to optional machine specific functions
++ */
++void (*pm_power_off)(void);
++EXPORT_SYMBOL(pm_power_off);
++
++void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
++EXPORT_SYMBOL_GPL(arm_pm_restart);
++
++
++/*
++ * This is our default idle handler.  We need to disable
++ * interrupts here to ensure we don't miss a wakeup call.
++ */
++static void default_idle(void)
++{
++	if (!need_resched())
++		arch_idle();
++	local_irq_enable();
++}
++
++void (*pm_idle)(void) = default_idle;
++EXPORT_SYMBOL(pm_idle);
++
++/*
++ * The idle thread, has rather strange semantics for calling pm_idle,
++ * but this is what x86 does and we need to do the same, so that
++ * things like cpuidle get called in the same way.  The only difference
++ * is that we always respect 'hlt_counter' to prevent low power idle.
++ */
++void cpu_idle(void)
++{
++	local_fiq_enable();
++
++	/* endless idle loop with no priority at all */
++	while (1) {
++		tick_nohz_stop_sched_tick(1);
++		leds_event(led_idle_start);
++		while (!need_resched()) {
++#ifdef CONFIG_HOTPLUG_CPU
++			if (cpu_is_offline(smp_processor_id()))
++				cpu_die();
++#endif
++
++			local_irq_disable();
++			if (hlt_counter) {
++				local_irq_enable();
++				cpu_relax();
++			} else {
++				stop_critical_timings();
++				pm_idle();
++				start_critical_timings();
++				/*
++				 * This will eventually be removed - pm_idle
++				 * functions should always return with IRQs
++				 * enabled.
++				 */
++				WARN_ON(irqs_disabled());
++				local_irq_enable();
++			}
++		}
++		leds_event(led_idle_end);
++		tick_nohz_restart_sched_tick();
++		preempt_enable_no_resched();
++		schedule();
++		preempt_disable();
++	}
++}
++
++static char reboot_mode = 'h';
++
++int __init reboot_setup(char *str)
++{
++	reboot_mode = str[0];
++	return 1;
++}
++
++__setup("reboot=", reboot_setup);
++
++void machine_halt(void)
++{
++}
++
++
++void machine_power_off(void)
++{
++	if (pm_power_off)
++		pm_power_off();
++}
++
++void machine_restart(char *cmd)
++{
++	arm_pm_restart(reboot_mode, cmd);
++}
++
++void __show_regs(struct pt_regs *regs)
++{
++	unsigned long flags;
++	char buf[64];
++
++	printk("CPU: %d    %s  (%s %.*s)\n",
++		raw_smp_processor_id(), print_tainted(),
++		init_utsname()->release,
++		(int)strcspn(init_utsname()->version, " "),
++		init_utsname()->version);
++	print_symbol("PC is at %s\n", instruction_pointer(regs));
++	print_symbol("LR is at %s\n", regs->ARM_lr);
++	printk("pc : [<%08lx>]    lr : [<%08lx>]    psr: %08lx\n"
++	       "sp : %08lx  ip : %08lx  fp : %08lx\n",
++		regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
++		regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
++	printk("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
++		regs->ARM_r10, regs->ARM_r9,
++		regs->ARM_r8);
++	printk("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
++		regs->ARM_r7, regs->ARM_r6,
++		regs->ARM_r5, regs->ARM_r4);
++	printk("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
++		regs->ARM_r3, regs->ARM_r2,
++		regs->ARM_r1, regs->ARM_r0);
++
++	flags = regs->ARM_cpsr;
++	buf[0] = flags & PSR_N_BIT ? 'N' : 'n';
++	buf[1] = flags & PSR_Z_BIT ? 'Z' : 'z';
++	buf[2] = flags & PSR_C_BIT ? 'C' : 'c';
++	buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
++	buf[4] = '\0';
++
++	printk("Flags: %s  IRQs o%s  FIQs o%s  Mode %s  ISA %s  Segment %s\n",
++		buf, interrupts_enabled(regs) ? "n" : "ff",
++		fast_interrupts_enabled(regs) ? "n" : "ff",
++		processor_modes[processor_mode(regs)],
++		isa_modes[isa_mode(regs)],
++		get_fs() == get_ds() ? "kernel" : "user");
++#ifdef CONFIG_CPU_CP15
++	{
++		unsigned int ctrl;
++
++		buf[0] = '\0';
++#ifdef CONFIG_CPU_CP15_MMU
++		{
++			unsigned int transbase, dac;
++			asm("mrc p15, 0, %0, c2, c0\n\t"
++			    "mrc p15, 0, %1, c3, c0\n"
++			    : "=r" (transbase), "=r" (dac));
++			snprintf(buf, sizeof(buf), "  Table: %08x  DAC: %08x",
++			  	transbase, dac);
++		}
++#endif
++		asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));
++
++		printk("Control: %08x%s\n", ctrl, buf);
++	}
++#endif
++}
++
++void show_regs(struct pt_regs * regs)
++{
++	printk("\n");
++	printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
++	__show_regs(regs);
++	__backtrace();
++}
++
++ATOMIC_NOTIFIER_HEAD(thread_notify_head);
++
++EXPORT_SYMBOL_GPL(thread_notify_head);
++
++/*
++ * Free current thread data structures etc..
++ */
++void exit_thread(void)
++{
++	thread_notify(THREAD_NOTIFY_EXIT, current_thread_info());
++}
++
++void flush_thread(void)
++{
++	struct thread_info *thread = current_thread_info();
++	struct task_struct *tsk = current;
++
++	memset(thread->used_cp, 0, sizeof(thread->used_cp));
++	memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
++	memset(&thread->fpstate, 0, sizeof(union fp_state));
++
++	thread_notify(THREAD_NOTIFY_FLUSH, thread);
++}
++
++void release_thread(struct task_struct *dead_task)
++{
++}
++
++asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
++
++int
++copy_thread(unsigned long clone_flags, unsigned long stack_start,
++	    unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
++{
++	struct thread_info *thread = task_thread_info(p);
++	struct pt_regs *childregs = task_pt_regs(p);
++
++	*childregs = *regs;
++	childregs->ARM_r0 = 0;
++	childregs->ARM_sp = stack_start;
++
++	memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
++	thread->cpu_context.sp = (unsigned long)childregs;
++	thread->cpu_context.pc = (unsigned long)ret_from_fork;
++
++	if (clone_flags & CLONE_SETTLS)
++		thread->tp_value = regs->ARM_r3;
++
++	return 0;
++}
++
++/*
++ * Fill in the task's elfregs structure for a core dump.
++ */
++int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
++{
++	elf_core_copy_regs(elfregs, task_pt_regs(t));
++	return 1;
++}
++
++/*
++ * fill in the fpe structure for a core dump...
++ */
++int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
++{
++	struct thread_info *thread = current_thread_info();
++	int used_math = thread->used_cp[1] | thread->used_cp[2];
++
++	if (used_math)
++		memcpy(fp, &thread->fpstate.soft, sizeof (*fp));
++
++	return used_math != 0;
++}
++EXPORT_SYMBOL(dump_fpu);
++
++/*
++ * Shuffle the argument into the correct register before calling the
++ * thread function.  r4 is the thread argument, r5 is the pointer to
++ * the thread function, and r6 points to the exit function.
++ */
++extern void kernel_thread_helper(void);
++asm(	".pushsection .text\n"
++"	.align\n"
++"	.type	kernel_thread_helper, #function\n"
++"kernel_thread_helper:\n"
++#ifdef CONFIG_TRACE_IRQFLAGS
++"	bl	trace_hardirqs_on\n"
++#endif
++"	msr	cpsr_c, r7\n"
++"	mov	r0, r4\n"
++"	mov	lr, r6\n"
++"	mov	pc, r5\n"
++"	.size	kernel_thread_helper, . - kernel_thread_helper\n"
++"	.popsection");
++
++#ifdef CONFIG_ARM_UNWIND
++extern void kernel_thread_exit(long code);
++asm(	".pushsection .text\n"
++"	.align\n"
++"	.type	kernel_thread_exit, #function\n"
++"kernel_thread_exit:\n"
++"	.fnstart\n"
++"	.cantunwind\n"
++"	bl	do_exit\n"
++"	nop\n"
++"	.fnend\n"
++"	.size	kernel_thread_exit, . - kernel_thread_exit\n"
++"	.popsection");
++#else
++#define kernel_thread_exit	do_exit
++#endif
++
++/*
++ * Create a kernel thread.
++ */
++pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
++{
++	struct pt_regs regs;
++
++	memset(&regs, 0, sizeof(regs));
++
++	regs.ARM_r4 = (unsigned long)arg;
++	regs.ARM_r5 = (unsigned long)fn;
++	regs.ARM_r6 = (unsigned long)kernel_thread_exit;
++	regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
++	regs.ARM_pc = (unsigned long)kernel_thread_helper;
++	regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
++
++	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
++}
++EXPORT_SYMBOL(kernel_thread);
++
++unsigned long get_wchan(struct task_struct *p)
++{
++	struct stackframe frame;
++	int count = 0;
++	if (!p || p == current || p->state == TASK_RUNNING)
++		return 0;
++
++	frame.fp = thread_saved_fp(p);
++	frame.sp = thread_saved_sp(p);
++	frame.lr = 0;			/* recovered from the stack */
++	frame.pc = thread_saved_pc(p);
++	do {
++		int ret = unwind_frame(&frame);
++		if (ret < 0)
++			return 0;
++		if (!in_sched_functions(frame.pc))
++			return frame.pc;
++	} while (count ++ < 16);
++	return 0;
++}
+diff -rupN linux-2.6.35.11/arch/arm/kernel/setup.c linux-2.6.35.11-ts7500/arch/arm/kernel/setup.c
+--- linux-2.6.35.11/arch/arm/kernel/setup.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/setup.c	2011-03-14 11:18:24.000000000 -0400
+@@ -370,6 +370,7 @@ static struct machine_desc * __init setu
+ {
+ 	struct machine_desc *list;
+ 
++   //printk("setup_machine()\n");
+ 	/*
+ 	 * locate machine in the list of supported machines.
+ 	 */
+@@ -656,6 +657,7 @@ static void (*init_machine)(void) __init
+ 
+ static int __init customize_machine(void)
+ {
++   printk("customize_machine(), calling init_machine()\n");
+ 	/* customizes platform devices, or adds new ones */
+ 	if (init_machine)
+ 		init_machine();
+@@ -667,8 +669,10 @@ void __init setup_arch(char **cmdline_p)
+ {
+ 	struct tag *tags = (struct tag *)&init_tags;
+ 	struct machine_desc *mdesc;
+-	char *from = default_command_line;
++	char *from = default_command_line;               
+ 
++   //printk("setup_arch()\n");
++   
+ 	unwind_init();
+ 
+ 	setup_processor();
+@@ -726,6 +730,22 @@ void __init setup_arch(char **cmdline_p)
+ 	cpu_init();
+ 	tcm_init();
+ 
++#ifdef CONFIG_ARCH_STR9100
++	{
++		extern void __init str9100_early_init(void);
++
++		str9100_early_init();
++	}
++#endif
++
++#ifdef CONFIG_ARCH_STR8100
++	{
++		extern void __init str8100_early_init(void);
++
++		str8100_early_init();
++	}
++#endif   
++   
+ 	/*
+ 	 * Set up various architecture-specific pointers
+ 	 */
+@@ -760,9 +780,11 @@ subsys_initcall(topology_init);
+ 
+ #ifdef CONFIG_HAVE_PROC_CPU
+ static int __init proc_cpu_init(void)
+-{
++{   
+ 	struct proc_dir_entry *res;
+ 
++   printk("proc_cpu_init()\n");
++   
+ 	res = proc_mkdir("cpu", NULL);
+ 	if (!res)
+ 		return -ENOMEM;
+diff -rupN linux-2.6.35.11/arch/arm/kernel/setup.c.orig linux-2.6.35.11-ts7500/arch/arm/kernel/setup.c.orig
+--- linux-2.6.35.11/arch/arm/kernel/setup.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/setup.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,876 @@
++/*
++ *  linux/arch/arm/kernel/setup.c
++ *
++ *  Copyright (C) 1995-2001 Russell King
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/stddef.h>
++#include <linux/ioport.h>
++#include <linux/delay.h>
++#include <linux/utsname.h>
++#include <linux/initrd.h>
++#include <linux/console.h>
++#include <linux/bootmem.h>
++#include <linux/seq_file.h>
++#include <linux/screen_info.h>
++#include <linux/init.h>
++#include <linux/root_dev.h>
++#include <linux/cpu.h>
++#include <linux/interrupt.h>
++#include <linux/smp.h>
++#include <linux/fs.h>
++#include <linux/proc_fs.h>
++
++#include <asm/unified.h>
++#include <asm/cpu.h>
++#include <asm/cputype.h>
++#include <asm/elf.h>
++#include <asm/procinfo.h>
++#include <asm/sections.h>
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/cacheflush.h>
++#include <asm/cachetype.h>
++#include <asm/tlbflush.h>
++
++#include <asm/mach/arch.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/time.h>
++#include <asm/traps.h>
++#include <asm/unwind.h>
++
++#include "compat.h"
++#include "atags.h"
++#include "tcm.h"
++
++#ifndef MEM_SIZE
++#define MEM_SIZE	(16*1024*1024)
++#endif
++
++#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
++char fpe_type[8];
++
++static int __init fpe_setup(char *line)
++{
++	memcpy(fpe_type, line, 8);
++	return 1;
++}
++
++__setup("fpe=", fpe_setup);
++#endif
++
++extern void paging_init(struct machine_desc *desc);
++extern void reboot_setup(char *str);
++
++unsigned int processor_id;
++EXPORT_SYMBOL(processor_id);
++unsigned int __machine_arch_type;
++EXPORT_SYMBOL(__machine_arch_type);
++unsigned int cacheid;
++EXPORT_SYMBOL(cacheid);
++
++unsigned int __atags_pointer __initdata;
++
++unsigned int system_rev;
++EXPORT_SYMBOL(system_rev);
++
++unsigned int system_serial_low;
++EXPORT_SYMBOL(system_serial_low);
++
++unsigned int system_serial_high;
++EXPORT_SYMBOL(system_serial_high);
++
++unsigned int elf_hwcap;
++EXPORT_SYMBOL(elf_hwcap);
++
++
++#ifdef MULTI_CPU
++struct processor processor;
++#endif
++#ifdef MULTI_TLB
++struct cpu_tlb_fns cpu_tlb;
++#endif
++#ifdef MULTI_USER
++struct cpu_user_fns cpu_user;
++#endif
++#ifdef MULTI_CACHE
++struct cpu_cache_fns cpu_cache;
++#endif
++#ifdef CONFIG_OUTER_CACHE
++struct outer_cache_fns outer_cache;
++EXPORT_SYMBOL(outer_cache);
++#endif
++
++struct stack {
++	u32 irq[3];
++	u32 abt[3];
++	u32 und[3];
++} ____cacheline_aligned;
++
++static struct stack stacks[NR_CPUS];
++
++char elf_platform[ELF_PLATFORM_SIZE];
++EXPORT_SYMBOL(elf_platform);
++
++static const char *cpu_name;
++static const char *machine_name;
++static char __initdata cmd_line[COMMAND_LINE_SIZE];
++
++static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
++static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
++#define ENDIANNESS ((char)endian_test.l)
++
++DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
++
++/*
++ * Standard memory resources
++ */
++static struct resource mem_res[] = {
++	{
++		.name = "Video RAM",
++		.start = 0,
++		.end = 0,
++		.flags = IORESOURCE_MEM
++	},
++	{
++		.name = "Kernel text",
++		.start = 0,
++		.end = 0,
++		.flags = IORESOURCE_MEM
++	},
++	{
++		.name = "Kernel data",
++		.start = 0,
++		.end = 0,
++		.flags = IORESOURCE_MEM
++	}
++};
++
++#define video_ram   mem_res[0]
++#define kernel_code mem_res[1]
++#define kernel_data mem_res[2]
++
++static struct resource io_res[] = {
++	{
++		.name = "reserved",
++		.start = 0x3bc,
++		.end = 0x3be,
++		.flags = IORESOURCE_IO | IORESOURCE_BUSY
++	},
++	{
++		.name = "reserved",
++		.start = 0x378,
++		.end = 0x37f,
++		.flags = IORESOURCE_IO | IORESOURCE_BUSY
++	},
++	{
++		.name = "reserved",
++		.start = 0x278,
++		.end = 0x27f,
++		.flags = IORESOURCE_IO | IORESOURCE_BUSY
++	}
++};
++
++#define lp0 io_res[0]
++#define lp1 io_res[1]
++#define lp2 io_res[2]
++
++static const char *proc_arch[] = {
++	"undefined/unknown",
++	"3",
++	"4",
++	"4T",
++	"5",
++	"5T",
++	"5TE",
++	"5TEJ",
++	"6TEJ",
++	"7",
++	"?(11)",
++	"?(12)",
++	"?(13)",
++	"?(14)",
++	"?(15)",
++	"?(16)",
++	"?(17)",
++};
++
++int cpu_architecture(void)
++{
++	int cpu_arch;
++
++	if ((read_cpuid_id() & 0x0008f000) == 0) {
++		cpu_arch = CPU_ARCH_UNKNOWN;
++	} else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
++		cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
++	} else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
++		cpu_arch = (read_cpuid_id() >> 16) & 7;
++		if (cpu_arch)
++			cpu_arch += CPU_ARCH_ARMv3;
++	} else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
++		unsigned int mmfr0;
++
++		/* Revised CPUID format. Read the Memory Model Feature
++		 * Register 0 and check for VMSAv7 or PMSAv7 */
++		asm("mrc	p15, 0, %0, c0, c1, 4"
++		    : "=r" (mmfr0));
++		if ((mmfr0 & 0x0000000f) == 0x00000003 ||
++		    (mmfr0 & 0x000000f0) == 0x00000030)
++			cpu_arch = CPU_ARCH_ARMv7;
++		else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
++			 (mmfr0 & 0x000000f0) == 0x00000020)
++			cpu_arch = CPU_ARCH_ARMv6;
++		else
++			cpu_arch = CPU_ARCH_UNKNOWN;
++	} else
++		cpu_arch = CPU_ARCH_UNKNOWN;
++
++	return cpu_arch;
++}
++
++static void __init cacheid_init(void)
++{
++	unsigned int cachetype = read_cpuid_cachetype();
++	unsigned int arch = cpu_architecture();
++
++	if (arch >= CPU_ARCH_ARMv6) {
++		if ((cachetype & (7 << 29)) == 4 << 29) {
++			/* ARMv7 register format */
++			cacheid = CACHEID_VIPT_NONALIASING;
++			if ((cachetype & (3 << 14)) == 1 << 14)
++				cacheid |= CACHEID_ASID_TAGGED;
++		} else if (cachetype & (1 << 23))
++			cacheid = CACHEID_VIPT_ALIASING;
++		else
++			cacheid = CACHEID_VIPT_NONALIASING;
++	} else {
++		cacheid = CACHEID_VIVT;
++	}
++
++	printk("CPU: %s data cache, %s instruction cache\n",
++		cache_is_vivt() ? "VIVT" :
++		cache_is_vipt_aliasing() ? "VIPT aliasing" :
++		cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
++		cache_is_vivt() ? "VIVT" :
++		icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
++		cache_is_vipt_aliasing() ? "VIPT aliasing" :
++		cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
++}
++
++/*
++ * These functions re-use the assembly code in head.S, which
++ * already provide the required functionality.
++ */
++extern struct proc_info_list *lookup_processor_type(unsigned int);
++extern struct machine_desc *lookup_machine_type(unsigned int);
++
++static void __init setup_processor(void)
++{
++	struct proc_info_list *list;
++
++	/*
++	 * locate processor in the list of supported processor
++	 * types.  The linker builds this table for us from the
++	 * entries in arch/arm/mm/proc-*.S
++	 */
++	list = lookup_processor_type(read_cpuid_id());
++	if (!list) {
++		printk("CPU configuration botched (ID %08x), unable "
++		       "to continue.\n", read_cpuid_id());
++		while (1);
++	}
++
++	cpu_name = list->cpu_name;
++
++#ifdef MULTI_CPU
++	processor = *list->proc;
++#endif
++#ifdef MULTI_TLB
++	cpu_tlb = *list->tlb;
++#endif
++#ifdef MULTI_USER
++	cpu_user = *list->user;
++#endif
++#ifdef MULTI_CACHE
++	cpu_cache = *list->cache;
++#endif
++
++	printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
++	       cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
++	       proc_arch[cpu_architecture()], cr_alignment);
++
++	sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
++	sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
++	elf_hwcap = list->elf_hwcap;
++#ifndef CONFIG_ARM_THUMB
++	elf_hwcap &= ~HWCAP_THUMB;
++#endif
++
++	cacheid_init();
++	cpu_proc_init();
++}
++
++/*
++ * cpu_init - initialise one CPU.
++ *
++ * cpu_init sets up the per-CPU stacks.
++ */
++void cpu_init(void)
++{
++	unsigned int cpu = smp_processor_id();
++	struct stack *stk = &stacks[cpu];
++
++	if (cpu >= NR_CPUS) {
++		printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
++		BUG();
++	}
++
++	/*
++	 * Define the placement constraint for the inline asm directive below.
++	 * In Thumb-2, msr with an immediate value is not allowed.
++	 */
++#ifdef CONFIG_THUMB2_KERNEL
++#define PLC	"r"
++#else
++#define PLC	"I"
++#endif
++
++	/*
++	 * setup stacks for re-entrant exception handlers
++	 */
++	__asm__ (
++	"msr	cpsr_c, %1\n\t"
++	"add	r14, %0, %2\n\t"
++	"mov	sp, r14\n\t"
++	"msr	cpsr_c, %3\n\t"
++	"add	r14, %0, %4\n\t"
++	"mov	sp, r14\n\t"
++	"msr	cpsr_c, %5\n\t"
++	"add	r14, %0, %6\n\t"
++	"mov	sp, r14\n\t"
++	"msr	cpsr_c, %7"
++	    :
++	    : "r" (stk),
++	      PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
++	      "I" (offsetof(struct stack, irq[0])),
++	      PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
++	      "I" (offsetof(struct stack, abt[0])),
++	      PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
++	      "I" (offsetof(struct stack, und[0])),
++	      PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
++	    : "r14");
++}
++
++static struct machine_desc * __init setup_machine(unsigned int nr)
++{
++	struct machine_desc *list;
++
++	/*
++	 * locate machine in the list of supported machines.
++	 */
++	list = lookup_machine_type(nr);
++	if (!list) {
++		printk("Machine configuration botched (nr %d), unable "
++		       "to continue.\n", nr);
++		while (1);
++	}
++
++	printk("Machine: %s\n", list->name);
++
++	return list;
++}
++
++static int __init arm_add_memory(unsigned long start, unsigned long size)
++{
++	struct membank *bank = &meminfo.bank[meminfo.nr_banks];
++
++	if (meminfo.nr_banks >= NR_BANKS) {
++		printk(KERN_CRIT "NR_BANKS too low, "
++			"ignoring memory at %#lx\n", start);
++		return -EINVAL;
++	}
++
++	/*
++	 * Ensure that start/size are aligned to a page boundary.
++	 * Size is appropriately rounded down, start is rounded up.
++	 */
++	size -= start & ~PAGE_MASK;
++	bank->start = PAGE_ALIGN(start);
++	bank->size  = size & PAGE_MASK;
++	bank->node  = PHYS_TO_NID(start);
++
++	/*
++	 * Check whether this memory region has non-zero size or
++	 * invalid node number.
++	 */
++	if (bank->size == 0 || bank->node >= MAX_NUMNODES)
++		return -EINVAL;
++
++	meminfo.nr_banks++;
++	return 0;
++}
++
++/*
++ * Pick out the memory size.  We look for mem=size@start,
++ * where start and size are "size[KkMm]"
++ */
++static int __init early_mem(char *p)
++{
++	static int usermem __initdata = 0;
++	unsigned long size, start;
++	char *endp;
++
++	/*
++	 * If the user specifies memory size, we
++	 * blow away any automatically generated
++	 * size.
++	 */
++	if (usermem == 0) {
++		usermem = 1;
++		meminfo.nr_banks = 0;
++	}
++
++	start = PHYS_OFFSET;
++	size  = memparse(p, &endp);
++	if (*endp == '@')
++		start = memparse(endp + 1, NULL);
++
++	arm_add_memory(start, size);
++
++	return 0;
++}
++early_param("mem", early_mem);
++
++static void __init
++setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
++{
++#ifdef CONFIG_BLK_DEV_RAM
++	extern int rd_size, rd_image_start, rd_prompt, rd_doload;
++
++	rd_image_start = image_start;
++	rd_prompt = prompt;
++	rd_doload = doload;
++
++	if (rd_sz)
++		rd_size = rd_sz;
++#endif
++}
++
++static void __init
++request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
++{
++	struct resource *res;
++	int i;
++
++	kernel_code.start   = virt_to_phys(_text);
++	kernel_code.end     = virt_to_phys(_etext - 1);
++	kernel_data.start   = virt_to_phys(_data);
++	kernel_data.end     = virt_to_phys(_end - 1);
++
++	for (i = 0; i < mi->nr_banks; i++) {
++		if (mi->bank[i].size == 0)
++			continue;
++
++		res = alloc_bootmem_low(sizeof(*res));
++		res->name  = "System RAM";
++		res->start = mi->bank[i].start;
++		res->end   = mi->bank[i].start + mi->bank[i].size - 1;
++		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
++
++		request_resource(&iomem_resource, res);
++
++		if (kernel_code.start >= res->start &&
++		    kernel_code.end <= res->end)
++			request_resource(res, &kernel_code);
++		if (kernel_data.start >= res->start &&
++		    kernel_data.end <= res->end)
++			request_resource(res, &kernel_data);
++	}
++
++	if (mdesc->video_start) {
++		video_ram.start = mdesc->video_start;
++		video_ram.end   = mdesc->video_end;
++		request_resource(&iomem_resource, &video_ram);
++	}
++
++	/*
++	 * Some machines don't have the possibility of ever
++	 * possessing lp0, lp1 or lp2
++	 */
++	if (mdesc->reserve_lp0)
++		request_resource(&ioport_resource, &lp0);
++	if (mdesc->reserve_lp1)
++		request_resource(&ioport_resource, &lp1);
++	if (mdesc->reserve_lp2)
++		request_resource(&ioport_resource, &lp2);
++}
++
++/*
++ *  Tag parsing.
++ *
++ * This is the new way of passing data to the kernel at boot time.  Rather
++ * than passing a fixed inflexible structure to the kernel, we pass a list
++ * of variable-sized tags to the kernel.  The first tag must be a ATAG_CORE
++ * tag for the list to be recognised (to distinguish the tagged list from
++ * a param_struct).  The list is terminated with a zero-length tag (this tag
++ * is not parsed in any way).
++ */
++static int __init parse_tag_core(const struct tag *tag)
++{
++	if (tag->hdr.size > 2) {
++		if ((tag->u.core.flags & 1) == 0)
++			root_mountflags &= ~MS_RDONLY;
++		ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
++	}
++	return 0;
++}
++
++__tagtable(ATAG_CORE, parse_tag_core);
++
++static int __init parse_tag_mem32(const struct tag *tag)
++{
++	return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
++}
++
++__tagtable(ATAG_MEM, parse_tag_mem32);
++
++#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
++struct screen_info screen_info = {
++ .orig_video_lines	= 30,
++ .orig_video_cols	= 80,
++ .orig_video_mode	= 0,
++ .orig_video_ega_bx	= 0,
++ .orig_video_isVGA	= 1,
++ .orig_video_points	= 8
++};
++
++static int __init parse_tag_videotext(const struct tag *tag)
++{
++	screen_info.orig_x            = tag->u.videotext.x;
++	screen_info.orig_y            = tag->u.videotext.y;
++	screen_info.orig_video_page   = tag->u.videotext.video_page;
++	screen_info.orig_video_mode   = tag->u.videotext.video_mode;
++	screen_info.orig_video_cols   = tag->u.videotext.video_cols;
++	screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
++	screen_info.orig_video_lines  = tag->u.videotext.video_lines;
++	screen_info.orig_video_isVGA  = tag->u.videotext.video_isvga;
++	screen_info.orig_video_points = tag->u.videotext.video_points;
++	return 0;
++}
++
++__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
++#endif
++
++static int __init parse_tag_ramdisk(const struct tag *tag)
++{
++	setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
++		      (tag->u.ramdisk.flags & 2) == 0,
++		      tag->u.ramdisk.start, tag->u.ramdisk.size);
++	return 0;
++}
++
++__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
++
++static int __init parse_tag_serialnr(const struct tag *tag)
++{
++	system_serial_low = tag->u.serialnr.low;
++	system_serial_high = tag->u.serialnr.high;
++	return 0;
++}
++
++__tagtable(ATAG_SERIAL, parse_tag_serialnr);
++
++static int __init parse_tag_revision(const struct tag *tag)
++{
++	system_rev = tag->u.revision.rev;
++	return 0;
++}
++
++__tagtable(ATAG_REVISION, parse_tag_revision);
++
++#ifndef CONFIG_CMDLINE_FORCE
++static int __init parse_tag_cmdline(const struct tag *tag)
++{
++	strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
++	return 0;
++}
++
++__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
++#endif /* CONFIG_CMDLINE_FORCE */
++
++/*
++ * Scan the tag table for this tag, and call its parse function.
++ * The tag table is built by the linker from all the __tagtable
++ * declarations.
++ */
++static int __init parse_tag(const struct tag *tag)
++{
++	extern struct tagtable __tagtable_begin, __tagtable_end;
++	struct tagtable *t;
++
++	for (t = &__tagtable_begin; t < &__tagtable_end; t++)
++		if (tag->hdr.tag == t->tag) {
++			t->parse(tag);
++			break;
++		}
++
++	return t < &__tagtable_end;
++}
++
++/*
++ * Parse all tags in the list, checking both the global and architecture
++ * specific tag tables.
++ */
++static void __init parse_tags(const struct tag *t)
++{
++	for (; t->hdr.size; t = tag_next(t))
++		if (!parse_tag(t))
++			printk(KERN_WARNING
++				"Ignoring unrecognised tag 0x%08x\n",
++				t->hdr.tag);
++}
++
++/*
++ * This holds our defaults.
++ */
++static struct init_tags {
++	struct tag_header hdr1;
++	struct tag_core   core;
++	struct tag_header hdr2;
++	struct tag_mem32  mem;
++	struct tag_header hdr3;
++} init_tags __initdata = {
++	{ tag_size(tag_core), ATAG_CORE },
++	{ 1, PAGE_SIZE, 0xff },
++	{ tag_size(tag_mem32), ATAG_MEM },
++	{ MEM_SIZE, PHYS_OFFSET },
++	{ 0, ATAG_NONE }
++};
++
++static void (*init_machine)(void) __initdata;
++
++static int __init customize_machine(void)
++{
++	/* customizes platform devices, or adds new ones */
++	if (init_machine)
++		init_machine();
++	return 0;
++}
++arch_initcall(customize_machine);
++
++void __init setup_arch(char **cmdline_p)
++{
++	struct tag *tags = (struct tag *)&init_tags;
++	struct machine_desc *mdesc;
++	char *from = default_command_line;
++
++	unwind_init();
++
++	setup_processor();
++	mdesc = setup_machine(machine_arch_type);
++	machine_name = mdesc->name;
++
++	if (mdesc->soft_reboot)
++		reboot_setup("s");
++
++	if (__atags_pointer)
++		tags = phys_to_virt(__atags_pointer);
++	else if (mdesc->boot_params)
++		tags = phys_to_virt(mdesc->boot_params);
++
++	/*
++	 * If we have the old style parameters, convert them to
++	 * a tag list.
++	 */
++	if (tags->hdr.tag != ATAG_CORE)
++		convert_to_tag_list(tags);
++	if (tags->hdr.tag != ATAG_CORE)
++		tags = (struct tag *)&init_tags;
++
++	if (mdesc->fixup)
++		mdesc->fixup(mdesc, tags, &from, &meminfo);
++
++	if (tags->hdr.tag == ATAG_CORE) {
++		if (meminfo.nr_banks != 0)
++			squash_mem_tags(tags);
++		save_atags(tags);
++		parse_tags(tags);
++	}
++
++	init_mm.start_code = (unsigned long) _text;
++	init_mm.end_code   = (unsigned long) _etext;
++	init_mm.end_data   = (unsigned long) _edata;
++	init_mm.brk	   = (unsigned long) _end;
++
++	/* parse_early_param needs a boot_command_line */
++	strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
++
++	/* populate cmd_line too for later use, preserving boot_command_line */
++	strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
++	*cmdline_p = cmd_line;
++
++	parse_early_param();
++
++	paging_init(mdesc);
++	request_standard_resources(&meminfo, mdesc);
++
++#ifdef CONFIG_SMP
++	smp_init_cpus();
++#endif
++
++	cpu_init();
++	tcm_init();
++
++	/*
++	 * Set up various architecture-specific pointers
++	 */
++	init_arch_irq = mdesc->init_irq;
++	system_timer = mdesc->timer;
++	init_machine = mdesc->init_machine;
++
++#ifdef CONFIG_VT
++#if defined(CONFIG_VGA_CONSOLE)
++	conswitchp = &vga_con;
++#elif defined(CONFIG_DUMMY_CONSOLE)
++	conswitchp = &dummy_con;
++#endif
++#endif
++	early_trap_init();
++}
++
++
++static int __init topology_init(void)
++{
++	int cpu;
++
++	for_each_possible_cpu(cpu) {
++		struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu);
++		cpuinfo->cpu.hotpluggable = 1;
++		register_cpu(&cpuinfo->cpu, cpu);
++	}
++
++	return 0;
++}
++subsys_initcall(topology_init);
++
++#ifdef CONFIG_HAVE_PROC_CPU
++static int __init proc_cpu_init(void)
++{
++	struct proc_dir_entry *res;
++
++	res = proc_mkdir("cpu", NULL);
++	if (!res)
++		return -ENOMEM;
++	return 0;
++}
++fs_initcall(proc_cpu_init);
++#endif
++
++static const char *hwcap_str[] = {
++	"swp",
++	"half",
++	"thumb",
++	"26bit",
++	"fastmult",
++	"fpa",
++	"vfp",
++	"edsp",
++	"java",
++	"iwmmxt",
++	"crunch",
++	"thumbee",
++	"neon",
++	"vfpv3",
++	"vfpv3d16",
++	NULL
++};
++
++static int c_show(struct seq_file *m, void *v)
++{
++	int i;
++
++	seq_printf(m, "Processor\t: %s rev %d (%s)\n",
++		   cpu_name, read_cpuid_id() & 15, elf_platform);
++
++#if defined(CONFIG_SMP)
++	for_each_online_cpu(i) {
++		/*
++		 * glibc reads /proc/cpuinfo to determine the number of
++		 * online processors, looking for lines beginning with
++		 * "processor".  Give glibc what it expects.
++		 */
++		seq_printf(m, "processor\t: %d\n", i);
++		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
++			   per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
++			   (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
++	}
++#else /* CONFIG_SMP */
++	seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
++		   loops_per_jiffy / (500000/HZ),
++		   (loops_per_jiffy / (5000/HZ)) % 100);
++#endif
++
++	/* dump out the processor features */
++	seq_puts(m, "Features\t: ");
++
++	for (i = 0; hwcap_str[i]; i++)
++		if (elf_hwcap & (1 << i))
++			seq_printf(m, "%s ", hwcap_str[i]);
++
++	seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
++	seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
++
++	if ((read_cpuid_id() & 0x0008f000) == 0x00000000) {
++		/* pre-ARM7 */
++		seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4);
++	} else {
++		if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
++			/* ARM7 */
++			seq_printf(m, "CPU variant\t: 0x%02x\n",
++				   (read_cpuid_id() >> 16) & 127);
++		} else {
++			/* post-ARM7 */
++			seq_printf(m, "CPU variant\t: 0x%x\n",
++				   (read_cpuid_id() >> 20) & 15);
++		}
++		seq_printf(m, "CPU part\t: 0x%03x\n",
++			   (read_cpuid_id() >> 4) & 0xfff);
++	}
++	seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
++
++	seq_puts(m, "\n");
++
++	seq_printf(m, "Hardware\t: %s\n", machine_name);
++	seq_printf(m, "Revision\t: %04x\n", system_rev);
++	seq_printf(m, "Serial\t\t: %08x%08x\n",
++		   system_serial_high, system_serial_low);
++
++	return 0;
++}
++
++static void *c_start(struct seq_file *m, loff_t *pos)
++{
++	return *pos < 1 ? (void *)1 : NULL;
++}
++
++static void *c_next(struct seq_file *m, void *v, loff_t *pos)
++{
++	++*pos;
++	return NULL;
++}
++
++static void c_stop(struct seq_file *m, void *v)
++{
++}
++
++const struct seq_operations cpuinfo_op = {
++	.start	= c_start,
++	.next	= c_next,
++	.stop	= c_stop,
++	.show	= c_show
++};
+diff -rupN linux-2.6.35.11/arch/arm/kernel/traps.c linux-2.6.35.11-ts7500/arch/arm/kernel/traps.c
+--- linux-2.6.35.11/arch/arm/kernel/traps.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/traps.c	2011-03-14 11:18:24.000000000 -0400
+@@ -467,7 +467,7 @@ asmlinkage int arm_syscall(int no, struc
+ {
+ 	struct thread_info *thread = current_thread_info();
+ 	siginfo_t info;
+-
++	
+ 	if ((no >> 16) != (__ARM_NR_BASE>> 16))
+ 		return bad_syscall(no, regs);
+ 
+diff -rupN linux-2.6.35.11/arch/arm/kernel/traps.c.orig linux-2.6.35.11-ts7500/arch/arm/kernel/traps.c.orig
+--- linux-2.6.35.11/arch/arm/kernel/traps.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/traps.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,774 @@
++/*
++ *  linux/arch/arm/kernel/traps.c
++ *
++ *  Copyright (C) 1995-2009 Russell King
++ *  Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  'traps.c' handles hardware exceptions after we have saved some state in
++ *  'linux/arch/arm/lib/traps.S'.  Mostly a debugging aid, but will probably
++ *  kill the offending process.
++ */
++#include <linux/signal.h>
++#include <linux/personality.h>
++#include <linux/kallsyms.h>
++#include <linux/spinlock.h>
++#include <linux/uaccess.h>
++#include <linux/hardirq.h>
++#include <linux/kdebug.h>
++#include <linux/module.h>
++#include <linux/kexec.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++
++#include <asm/atomic.h>
++#include <asm/cacheflush.h>
++#include <asm/system.h>
++#include <asm/unistd.h>
++#include <asm/traps.h>
++#include <asm/unwind.h>
++
++#include "ptrace.h"
++#include "signal.h"
++
++static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
++
++#ifdef CONFIG_DEBUG_USER
++unsigned int user_debug;
++
++static int __init user_debug_setup(char *str)
++{
++	get_option(&str, &user_debug);
++	return 1;
++}
++__setup("user_debug=", user_debug_setup);
++#endif
++
++static void dump_mem(const char *, const char *, unsigned long, unsigned long);
++
++void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
++{
++#ifdef CONFIG_KALLSYMS
++	char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN];
++	sprint_symbol(sym1, where);
++	sprint_symbol(sym2, from);
++	printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2);
++#else
++	printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
++#endif
++
++	if (in_exception_text(where))
++		dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
++}
++
++#ifndef CONFIG_ARM_UNWIND
++/*
++ * Stack pointers should always be within the kernels view of
++ * physical memory.  If it is not there, then we can't dump
++ * out any information relating to the stack.
++ */
++static int verify_stack(unsigned long sp)
++{
++	if (sp < PAGE_OFFSET ||
++	    (sp > (unsigned long)high_memory && high_memory != NULL))
++		return -EFAULT;
++
++	return 0;
++}
++#endif
++
++/*
++ * Dump out the contents of some memory nicely...
++ */
++static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
++		     unsigned long top)
++{
++	unsigned long first;
++	mm_segment_t fs;
++	int i;
++
++	/*
++	 * We need to switch to kernel mode so that we can use __get_user
++	 * to safely read from kernel space.  Note that we now dump the
++	 * code first, just in case the backtrace kills us.
++	 */
++	fs = get_fs();
++	set_fs(KERNEL_DS);
++
++	printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top);
++
++	for (first = bottom & ~31; first < top; first += 32) {
++		unsigned long p;
++		char str[sizeof(" 12345678") * 8 + 1];
++
++		memset(str, ' ', sizeof(str));
++		str[sizeof(str) - 1] = '\0';
++
++		for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
++			if (p >= bottom && p < top) {
++				unsigned long val;
++				if (__get_user(val, (unsigned long *)p) == 0)
++					sprintf(str + i * 9, " %08lx", val);
++				else
++					sprintf(str + i * 9, " ????????");
++			}
++		}
++		printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
++	}
++
++	set_fs(fs);
++}
++
++static void dump_instr(const char *lvl, struct pt_regs *regs)
++{
++	unsigned long addr = instruction_pointer(regs);
++	const int thumb = thumb_mode(regs);
++	const int width = thumb ? 4 : 8;
++	mm_segment_t fs;
++	char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
++	int i;
++
++	/*
++	 * We need to switch to kernel mode so that we can use __get_user
++	 * to safely read from kernel space.  Note that we now dump the
++	 * code first, just in case the backtrace kills us.
++	 */
++	fs = get_fs();
++	set_fs(KERNEL_DS);
++
++	for (i = -4; i < 1; i++) {
++		unsigned int val, bad;
++
++		if (thumb)
++			bad = __get_user(val, &((u16 *)addr)[i]);
++		else
++			bad = __get_user(val, &((u32 *)addr)[i]);
++
++		if (!bad)
++			p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
++					width, val);
++		else {
++			p += sprintf(p, "bad PC value");
++			break;
++		}
++	}
++	printk("%sCode: %s\n", lvl, str);
++
++	set_fs(fs);
++}
++
++#ifdef CONFIG_ARM_UNWIND
++static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
++{
++	unwind_backtrace(regs, tsk);
++}
++#else
++static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
++{
++	unsigned int fp, mode;
++	int ok = 1;
++
++	printk("Backtrace: ");
++
++	if (!tsk)
++		tsk = current;
++
++	if (regs) {
++		fp = regs->ARM_fp;
++		mode = processor_mode(regs);
++	} else if (tsk != current) {
++		fp = thread_saved_fp(tsk);
++		mode = 0x10;
++	} else {
++		asm("mov %0, fp" : "=r" (fp) : : "cc");
++		mode = 0x10;
++	}
++
++	if (!fp) {
++		printk("no frame pointer");
++		ok = 0;
++	} else if (verify_stack(fp)) {
++		printk("invalid frame pointer 0x%08x", fp);
++		ok = 0;
++	} else if (fp < (unsigned long)end_of_stack(tsk))
++		printk("frame pointer underflow");
++	printk("\n");
++
++	if (ok)
++		c_backtrace(fp, mode);
++}
++#endif
++
++void dump_stack(void)
++{
++	dump_backtrace(NULL, NULL);
++}
++
++EXPORT_SYMBOL(dump_stack);
++
++void show_stack(struct task_struct *tsk, unsigned long *sp)
++{
++	dump_backtrace(NULL, tsk);
++	barrier();
++}
++
++#ifdef CONFIG_PREEMPT
++#define S_PREEMPT " PREEMPT"
++#else
++#define S_PREEMPT ""
++#endif
++#ifdef CONFIG_SMP
++#define S_SMP " SMP"
++#else
++#define S_SMP ""
++#endif
++
++static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
++{
++	struct task_struct *tsk = thread->task;
++	static int die_counter;
++	int ret;
++
++	printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
++	       str, err, ++die_counter);
++	sysfs_printk_last_file();
++
++	/* trap and error numbers are mostly meaningless on ARM */
++	ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
++	if (ret == NOTIFY_STOP)
++		return ret;
++
++	print_modules();
++	__show_regs(regs);
++	printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
++		TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
++
++	if (!user_mode(regs) || in_interrupt()) {
++		dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
++			 THREAD_SIZE + (unsigned long)task_stack_page(tsk));
++		dump_backtrace(regs, tsk);
++		dump_instr(KERN_EMERG, regs);
++	}
++
++	return ret;
++}
++
++DEFINE_SPINLOCK(die_lock);
++
++/*
++ * This function is protected against re-entrancy.
++ */
++void die(const char *str, struct pt_regs *regs, int err)
++{
++	struct thread_info *thread = current_thread_info();
++	int ret;
++
++	oops_enter();
++
++	spin_lock_irq(&die_lock);
++	console_verbose();
++	bust_spinlocks(1);
++	ret = __die(str, err, thread, regs);
++
++	if (regs && kexec_should_crash(thread->task))
++		crash_kexec(regs);
++
++	bust_spinlocks(0);
++	add_taint(TAINT_DIE);
++	spin_unlock_irq(&die_lock);
++	oops_exit();
++
++	if (in_interrupt())
++		panic("Fatal exception in interrupt");
++	if (panic_on_oops)
++		panic("Fatal exception");
++	if (ret != NOTIFY_STOP)
++		do_exit(SIGSEGV);
++}
++
++void arm_notify_die(const char *str, struct pt_regs *regs,
++		struct siginfo *info, unsigned long err, unsigned long trap)
++{
++	if (user_mode(regs)) {
++		current->thread.error_code = err;
++		current->thread.trap_no = trap;
++
++		force_sig_info(info->si_signo, info, current);
++	} else {
++		die(str, regs, err);
++	}
++}
++
++static LIST_HEAD(undef_hook);
++static DEFINE_SPINLOCK(undef_lock);
++
++void register_undef_hook(struct undef_hook *hook)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&undef_lock, flags);
++	list_add(&hook->node, &undef_hook);
++	spin_unlock_irqrestore(&undef_lock, flags);
++}
++
++void unregister_undef_hook(struct undef_hook *hook)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&undef_lock, flags);
++	list_del(&hook->node);
++	spin_unlock_irqrestore(&undef_lock, flags);
++}
++
++static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
++{
++	struct undef_hook *hook;
++	unsigned long flags;
++	int (*fn)(struct pt_regs *regs, unsigned int instr) = NULL;
++
++	spin_lock_irqsave(&undef_lock, flags);
++	list_for_each_entry(hook, &undef_hook, node)
++		if ((instr & hook->instr_mask) == hook->instr_val &&
++		    (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val)
++			fn = hook->fn;
++	spin_unlock_irqrestore(&undef_lock, flags);
++
++	return fn ? fn(regs, instr) : 1;
++}
++
++asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
++{
++	unsigned int correction = thumb_mode(regs) ? 2 : 4;
++	unsigned int instr;
++	siginfo_t info;
++	void __user *pc;
++
++	/*
++	 * According to the ARM ARM, PC is 2 or 4 bytes ahead,
++	 * depending whether we're in Thumb mode or not.
++	 * Correct this offset.
++	 */
++	regs->ARM_pc -= correction;
++
++	pc = (void __user *)instruction_pointer(regs);
++
++	if (processor_mode(regs) == SVC_MODE) {
++		instr = *(u32 *) pc;
++	} else if (thumb_mode(regs)) {
++		get_user(instr, (u16 __user *)pc);
++	} else {
++		get_user(instr, (u32 __user *)pc);
++	}
++
++	if (call_undef_hook(regs, instr) == 0)
++		return;
++
++#ifdef CONFIG_DEBUG_USER
++	if (user_debug & UDBG_UNDEFINED) {
++		printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
++			current->comm, task_pid_nr(current), pc);
++		dump_instr(KERN_INFO, regs);
++	}
++#endif
++
++	info.si_signo = SIGILL;
++	info.si_errno = 0;
++	info.si_code  = ILL_ILLOPC;
++	info.si_addr  = pc;
++
++	arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
++}
++
++asmlinkage void do_unexp_fiq (struct pt_regs *regs)
++{
++	printk("Hmm.  Unexpected FIQ received, but trying to continue\n");
++	printk("You may have a hardware problem...\n");
++}
++
++/*
++ * bad_mode handles the impossible case in the vectors.  If you see one of
++ * these, then it's extremely serious, and could mean you have buggy hardware.
++ * It never returns, and never tries to sync.  We hope that we can at least
++ * dump out some state information...
++ */
++asmlinkage void bad_mode(struct pt_regs *regs, int reason)
++{
++	console_verbose();
++
++	printk(KERN_CRIT "Bad mode in %s handler detected\n", handler[reason]);
++
++	die("Oops - bad mode", regs, 0);
++	local_irq_disable();
++	panic("bad mode");
++}
++
++static int bad_syscall(int n, struct pt_regs *regs)
++{
++	struct thread_info *thread = current_thread_info();
++	siginfo_t info;
++
++	if (current->personality != PER_LINUX &&
++	    current->personality != PER_LINUX_32BIT &&
++	    thread->exec_domain->handler) {
++		thread->exec_domain->handler(n, regs);
++		return regs->ARM_r0;
++	}
++
++#ifdef CONFIG_DEBUG_USER
++	if (user_debug & UDBG_SYSCALL) {
++		printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
++			task_pid_nr(current), current->comm, n);
++		dump_instr(KERN_ERR, regs);
++	}
++#endif
++
++	info.si_signo = SIGILL;
++	info.si_errno = 0;
++	info.si_code  = ILL_ILLTRP;
++	info.si_addr  = (void __user *)instruction_pointer(regs) -
++			 (thumb_mode(regs) ? 2 : 4);
++
++	arm_notify_die("Oops - bad syscall", regs, &info, n, 0);
++
++	return regs->ARM_r0;
++}
++
++static inline void
++do_cache_op(unsigned long start, unsigned long end, int flags)
++{
++	struct mm_struct *mm = current->active_mm;
++	struct vm_area_struct *vma;
++
++	if (end < start || flags)
++		return;
++
++	down_read(&mm->mmap_sem);
++	vma = find_vma(mm, start);
++	if (vma && vma->vm_start < end) {
++		if (start < vma->vm_start)
++			start = vma->vm_start;
++		if (end > vma->vm_end)
++			end = vma->vm_end;
++
++		flush_cache_user_range(vma, start, end);
++	}
++	up_read(&mm->mmap_sem);
++}
++
++/*
++ * Handle all unrecognised system calls.
++ *  0x9f0000 - 0x9fffff are some more esoteric system calls
++ */
++#define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE)
++asmlinkage int arm_syscall(int no, struct pt_regs *regs)
++{
++	struct thread_info *thread = current_thread_info();
++	siginfo_t info;
++
++	if ((no >> 16) != (__ARM_NR_BASE>> 16))
++		return bad_syscall(no, regs);
++
++	switch (no & 0xffff) {
++	case 0: /* branch through 0 */
++		info.si_signo = SIGSEGV;
++		info.si_errno = 0;
++		info.si_code  = SEGV_MAPERR;
++		info.si_addr  = NULL;
++
++		arm_notify_die("branch through zero", regs, &info, 0, 0);
++		return 0;
++
++	case NR(breakpoint): /* SWI BREAK_POINT */
++		regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
++		ptrace_break(current, regs);
++		return regs->ARM_r0;
++
++	/*
++	 * Flush a region from virtual address 'r0' to virtual address 'r1'
++	 * _exclusive_.  There is no alignment requirement on either address;
++	 * user space does not need to know the hardware cache layout.
++	 *
++	 * r2 contains flags.  It should ALWAYS be passed as ZERO until it
++	 * is defined to be something else.  For now we ignore it, but may
++	 * the fires of hell burn in your belly if you break this rule. ;)
++	 *
++	 * (at a later date, we may want to allow this call to not flush
++	 * various aspects of the cache.  Passing '0' will guarantee that
++	 * everything necessary gets flushed to maintain consistency in
++	 * the specified region).
++	 */
++	case NR(cacheflush):
++		do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2);
++		return 0;
++
++	case NR(usr26):
++		if (!(elf_hwcap & HWCAP_26BIT))
++			break;
++		regs->ARM_cpsr &= ~MODE32_BIT;
++		return regs->ARM_r0;
++
++	case NR(usr32):
++		if (!(elf_hwcap & HWCAP_26BIT))
++			break;
++		regs->ARM_cpsr |= MODE32_BIT;
++		return regs->ARM_r0;
++
++	case NR(set_tls):
++		thread->tp_value = regs->ARM_r0;
++#if defined(CONFIG_HAS_TLS_REG)
++		asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
++#elif !defined(CONFIG_TLS_REG_EMUL)
++		/*
++		 * User space must never try to access this directly.
++		 * Expect your app to break eventually if you do so.
++		 * The user helper at 0xffff0fe0 must be used instead.
++		 * (see entry-armv.S for details)
++		 */
++		*((unsigned int *)0xffff0ff0) = regs->ARM_r0;
++#endif
++		return 0;
++
++#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG
++	/*
++	 * Atomically store r1 in *r2 if *r2 is equal to r0 for user space.
++	 * Return zero in r0 if *MEM was changed or non-zero if no exchange
++	 * happened.  Also set the user C flag accordingly.
++	 * If access permissions have to be fixed up then non-zero is
++	 * returned and the operation has to be re-attempted.
++	 *
++	 * *NOTE*: This is a ghost syscall private to the kernel.  Only the
++	 * __kuser_cmpxchg code in entry-armv.S should be aware of its
++	 * existence.  Don't ever use this from user code.
++	 */
++	case NR(cmpxchg):
++	for (;;) {
++		extern void do_DataAbort(unsigned long addr, unsigned int fsr,
++					 struct pt_regs *regs);
++		unsigned long val;
++		unsigned long addr = regs->ARM_r2;
++		struct mm_struct *mm = current->mm;
++		pgd_t *pgd; pmd_t *pmd; pte_t *pte;
++		spinlock_t *ptl;
++
++		regs->ARM_cpsr &= ~PSR_C_BIT;
++		down_read(&mm->mmap_sem);
++		pgd = pgd_offset(mm, addr);
++		if (!pgd_present(*pgd))
++			goto bad_access;
++		pmd = pmd_offset(pgd, addr);
++		if (!pmd_present(*pmd))
++			goto bad_access;
++		pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
++		if (!pte_present(*pte) || !pte_dirty(*pte)) {
++			pte_unmap_unlock(pte, ptl);
++			goto bad_access;
++		}
++		val = *(unsigned long *)addr;
++		val -= regs->ARM_r0;
++		if (val == 0) {
++			*(unsigned long *)addr = regs->ARM_r1;
++			regs->ARM_cpsr |= PSR_C_BIT;
++		}
++		pte_unmap_unlock(pte, ptl);
++		up_read(&mm->mmap_sem);
++		return val;
++
++		bad_access:
++		up_read(&mm->mmap_sem);
++		/* simulate a write access fault */
++		do_DataAbort(addr, 15 + (1 << 11), regs);
++	}
++#endif
++
++	default:
++		/* Calls 9f00xx..9f07ff are defined to return -ENOSYS
++		   if not implemented, rather than raising SIGILL.  This
++		   way the calling program can gracefully determine whether
++		   a feature is supported.  */
++		if ((no & 0xffff) <= 0x7ff)
++			return -ENOSYS;
++		break;
++	}
++#ifdef CONFIG_DEBUG_USER
++	/*
++	 * experience shows that these seem to indicate that
++	 * something catastrophic has happened
++	 */
++	if (user_debug & UDBG_SYSCALL) {
++		printk("[%d] %s: arm syscall %d\n",
++		       task_pid_nr(current), current->comm, no);
++		dump_instr("", regs);
++		if (user_mode(regs)) {
++			__show_regs(regs);
++			c_backtrace(regs->ARM_fp, processor_mode(regs));
++		}
++	}
++#endif
++	info.si_signo = SIGILL;
++	info.si_errno = 0;
++	info.si_code  = ILL_ILLTRP;
++	info.si_addr  = (void __user *)instruction_pointer(regs) -
++			 (thumb_mode(regs) ? 2 : 4);
++
++	arm_notify_die("Oops - bad syscall(2)", regs, &info, no, 0);
++	return 0;
++}
++
++#ifdef CONFIG_TLS_REG_EMUL
++
++/*
++ * We might be running on an ARMv6+ processor which should have the TLS
++ * register but for some reason we can't use it, or maybe an SMP system
++ * using a pre-ARMv6 processor (there are apparently a few prototypes like
++ * that in existence) and therefore access to that register must be
++ * emulated.
++ */
++
++static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
++{
++	int reg = (instr >> 12) & 15;
++	if (reg == 15)
++		return 1;
++	regs->uregs[reg] = current_thread_info()->tp_value;
++	regs->ARM_pc += 4;
++	return 0;
++}
++
++static struct undef_hook arm_mrc_hook = {
++	.instr_mask	= 0x0fff0fff,
++	.instr_val	= 0x0e1d0f70,
++	.cpsr_mask	= PSR_T_BIT,
++	.cpsr_val	= 0,
++	.fn		= get_tp_trap,
++};
++
++static int __init arm_mrc_hook_init(void)
++{
++	register_undef_hook(&arm_mrc_hook);
++	return 0;
++}
++
++late_initcall(arm_mrc_hook_init);
++
++#endif
++
++void __bad_xchg(volatile void *ptr, int size)
++{
++	printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
++		__builtin_return_address(0), ptr, size);
++	BUG();
++}
++EXPORT_SYMBOL(__bad_xchg);
++
++/*
++ * A data abort trap was taken, but we did not handle the instruction.
++ * Try to abort the user program, or panic if it was the kernel.
++ */
++asmlinkage void
++baddataabort(int code, unsigned long instr, struct pt_regs *regs)
++{
++	unsigned long addr = instruction_pointer(regs);
++	siginfo_t info;
++
++#ifdef CONFIG_DEBUG_USER
++	if (user_debug & UDBG_BADABORT) {
++		printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
++			task_pid_nr(current), current->comm, code, instr);
++		dump_instr(KERN_ERR, regs);
++		show_pte(current->mm, addr);
++	}
++#endif
++
++	info.si_signo = SIGILL;
++	info.si_errno = 0;
++	info.si_code  = ILL_ILLOPC;
++	info.si_addr  = (void __user *)addr;
++
++	arm_notify_die("unknown data abort code", regs, &info, instr, 0);
++}
++
++void __attribute__((noreturn)) __bug(const char *file, int line)
++{
++	printk(KERN_CRIT"kernel BUG at %s:%d!\n", file, line);
++	*(int *)0 = 0;
++
++	/* Avoid "noreturn function does return" */
++	for (;;);
++}
++EXPORT_SYMBOL(__bug);
++
++void __readwrite_bug(const char *fn)
++{
++	printk("%s called, but not implemented\n", fn);
++	BUG();
++}
++EXPORT_SYMBOL(__readwrite_bug);
++
++void __pte_error(const char *file, int line, unsigned long val)
++{
++	printk("%s:%d: bad pte %08lx.\n", file, line, val);
++}
++
++void __pmd_error(const char *file, int line, unsigned long val)
++{
++	printk("%s:%d: bad pmd %08lx.\n", file, line, val);
++}
++
++void __pgd_error(const char *file, int line, unsigned long val)
++{
++	printk("%s:%d: bad pgd %08lx.\n", file, line, val);
++}
++
++asmlinkage void __div0(void)
++{
++	printk("Division by zero in kernel.\n");
++	dump_stack();
++}
++EXPORT_SYMBOL(__div0);
++
++void abort(void)
++{
++	BUG();
++
++	/* if that doesn't kill us, halt */
++	panic("Oops failed to kill thread");
++}
++EXPORT_SYMBOL(abort);
++
++void __init trap_init(void)
++{
++	return;
++}
++
++void __init early_trap_init(void)
++{
++	unsigned long vectors = CONFIG_VECTORS_BASE;
++	extern char __stubs_start[], __stubs_end[];
++	extern char __vectors_start[], __vectors_end[];
++	extern char __kuser_helper_start[], __kuser_helper_end[];
++	int kuser_sz = __kuser_helper_end - __kuser_helper_start;
++
++	/*
++	 * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
++	 * into the vector page, mapped at 0xffff0000, and ensure these
++	 * are visible to the instruction stream.
++	 */
++	memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
++	memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
++	memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
++
++	/*
++	 * Copy signal return handlers into the vector page, and
++	 * set sigreturn to be a pointer to these.
++	 */
++	memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
++	       sizeof(sigreturn_codes));
++	memcpy((void *)KERN_RESTART_CODE, syscall_restart_code,
++	       sizeof(syscall_restart_code));
++
++	flush_icache_range(vectors, vectors + PAGE_SIZE);
++	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
++}
+diff -rupN linux-2.6.35.11/arch/arm/kernel/vmlinux.lds.S linux-2.6.35.11-ts7500/arch/arm/kernel/vmlinux.lds.S
+--- linux-2.6.35.11/arch/arm/kernel/vmlinux.lds.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/kernel/vmlinux.lds.S	2011-03-14 11:18:24.000000000 -0400
+@@ -84,6 +84,12 @@ SECTIONS
+ 
+ 	.text : {			/* Real text segment		*/
+ 		_text = .;		/* Text and read-only data	*/
++#ifdef CONFIG_CPU_ISPAD_ENABLE
++			. = ALIGN(1024);
++			__ispad_begin = .;
++			*(.ispad)
++			__ispad_end = .;
++#endif      
+ 			__exception_text_start = .;
+ 			*(.exception.text)
+ 			__exception_text_end = .;
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/debug-macro.S linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/debug-macro.S
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/debug-macro.S	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,54 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//#include <linux/config.h>
++#include <linux/linkage.h>
++#include <mach/hardware.h>
++
++		.macro	addruart,rx,tmp
++		mrc	p15, 0, \rx, c1, c0
++		tst	\rx, #1				@ MMU enabled ?
++		moveq	\rx, #(SYSPA_UART0_BASE_ADDR)	@ physical base address of UART0
++		movne	\rx, #(SYSVA_UART0_BASE_ADDR & 0xFF000000) @ virtual base address of UART0
++		orrne	\rx, \rx, #(SYSVA_UART0_BASE_ADDR & 0x00FF0000)
++		orrne	\rx, \rx, #(SYSVA_UART0_BASE_ADDR & 0x0000FF00)
++		orrne	\rx, \rx, #(SYSVA_UART0_BASE_ADDR & 0x000000FF)
++		.endm
++
++		.macro	senduart,rd,rx
++		strb	\rd, [\rx, #0x00]
++		.endm
++
++		.macro	waituart,rd,rx
++		mov	\rd, #0xf000
++1001:		subs	\rd, \rd, #1
++		bne	1001b	
++		.endm
++
++		.macro	busyuart,rd,rx
++		nop
++		mov	\rd, #0xf000
++1010:		subs	\rd, \rd, #1
++		bne	1010b
++		.endm
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/dma.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/dma.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/dma.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/dma.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,27 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_DMA_H__
++#define __ASM_ARCH_DMA_H__
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/entry-macro.S linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/entry-macro.S
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/entry-macro.S	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,79 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//#include <mach/star_intc.h>
++#include <mach/star_intc.h>
++
++	.macro	disable_fiq
++	.endm
++
++	.macro	get_irqnr_preamble, base, tmp
++	.endm
++
++	.macro	arch_ret_to_user, tmp1, tmp2
++	.endm
++
++
++#ifdef CONFIG_VIC_INTERRUPT
++	.macro	get_fiqnr_and_base, irqnr, irqstat, base, tmp
++	ldr	\base, =(SYSVA_VIC_BASE_ADDR + 0x140)
++	ldr	\irqnr, [\base]
++	.endm
++
++	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
++	ldr	\base, =(SYSVA_VIC_BASE_ADDR + 0x140)
++	ldr	\irqnr, [\base]
++	.endm
++#else
++	.macro	get_fiqnr_and_base, irqnr, irqstat, base, tmp
++	ldr	\base, =(SYSVA_VIC_BASE_ADDR + 0x20)
++	ldr	\irqstat, [\base]
++	mov	\irqnr, #0
++9001:
++	tst	\irqstat, #1
++	bne	9002f
++	add	\irqnr, \irqnr, #1
++	mov	\irqstat, \irqstat, lsr #1
++	cmp	\irqnr, #32
++	bcc	9001b
++9002:
++	.endm
++
++	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
++	ldr	\base, =(SYSVA_VIC_BASE_ADDR + 0x1C)
++	ldr	\irqstat, [\base]
++	mov	\irqnr, #0
++9003:
++	tst	\irqstat, #1
++	bne	9004f
++	add	\irqnr, \irqnr, #1
++	mov	\irqstat, \irqstat, lsr #1
++	cmp	\irqnr, #32
++	bcc	9003b
++9004:
++	.endm
++#endif
++
++	.macro	irq_prio_table
++	.endm
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/hardware.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/hardware.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/hardware.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,71 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_HARDWARE_H__
++#define __ASM_ARCH_HARDWARE_H__
++
++//#include <linux/config.h>
++#include <mach/param.h>
++
++#include <mach/star_sys_memory_map.h>
++#include <mach/star_intc.h>
++#include <mach/star_timer.h>
++#include <mach/star_uart.h>
++#include <mach/star_gpio.h>
++#include <mach/star_pci_bridge.h>
++#include <mach/star_misc.h>
++#include <mach/star_powermgt.h>
++#include <mach/star_rtc.h>
++#include <mach/star_wdtimer.h>
++#include <mach/star_smc.h>
++#include <mach/star_nic.h>
++#include <mach/star_ide.h>
++
++#if 1 // on ASIC
++#define SYS_CLK			(87500000) // 87.5MHz
++#define UART_CLK		(24000000) // 24MHz
++#define AHB_CLK			(SYS_CLK)
++#define APB_CLK			(AHB_CLK >> 1)
++#define TIMER_COUNTER		(APB_CLK / HZ)
++#else // on FPGA
++#define SYS_CLK			(13000000) // 13MHz
++#define UART_CLK		(13000000) // 13Mhz
++#define AHB_CLK			(SYS_CLK)
++#define APB_CLK			(AHB_CLK)
++#define TIMER_COUNTER		(APB_CLK / HZ)
++#endif
++
++#define DEBUG_CONSOLE		(0)
++
++#define FLASH_BASE_ADDR		SYSPA_FLASH_SRAM_BANK0_BASE_ADDR
++#define FLASH_SIZE		0x800000
++
++#define PCIBIOS_MIN_IO		0x00000000
++#define PCIBIOS_MIN_MEM		0x00000000
++#if 1
++#define pcibios_assign_all_busses()	0
++#else
++#define pcibios_assign_all_busses()	1
++#endif
++
++#endif /* __ASM_ARCH_HARDWARE_H__ */
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/io.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/io.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/io.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,35 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_IO_H__
++#define __ASM_ARCH_IO_H__
++
++//#include <asm/hardware.h>
++
++#define IO_SPACE_LIMIT		0xffffffff
++
++#define __io(p)			((void __iomem *)(p))
++#define __mem_pci(a)		(a)
++#define __mem_isa(a)		(a)
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/irqs.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/irqs.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/irqs.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,36 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_IRQS_H__
++#define __ASM_ARCH_IRQS_H__
++
++//#include <mach/star_intc.h>
++#include <mach/star_intc.h>
++
++#define NR_IRQS (32)
++
++#ifdef CONFIG_VIC_INTERRUPT 
++#define irq_finish(irq) do { INTC_IRQ_VECTOR_ADDRESS_REG = 0; } while (0)
++#endif
++
++#endif /* __ASM_ARCH_IRQS_H__ */
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/memory.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/memory.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/memory.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,82 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_MEMORY_H
++#define __ASM_ARCH_MEMORY_H
++
++#if 0
++#define TASK_SIZE		(0xC0000000UL)	
++#define TASK_SIZE_26		(0x04000000UL)
++#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
++#endif
++
++#define CONFIG_SYSTEM_DRAM_BASE	0x00000000
++#if defined(CONFIG_STR8100_DRAM_64M)
++#define CONFIG_SYSTEM_DRAM_SIZE 64
++#elif defined(CONFIG_STR8100_DRAM_32M)
++#define CONFIG_SYSTEM_DRAM_SIZE 32
++#elif defined(CONFIG_STR8100_DRAM_16M)
++#define CONFIG_SYSTEM_DRAM_SIZE 16
++#endif
++#define MEM_SIZE		(CONFIG_SYSTEM_DRAM_SIZE)
++#define END_MEM			(CONFIG_SYSTEM_DRAM_BASE + CONFIG_SYSTEM_DRAM_SIZE)
++#define DMA_SIZE		0xffffffff
++#define PHYS_OFFSET		(CONFIG_SYSTEM_DRAM_BASE) // physical start address of memory
++#if 0
++#define PAGE_OFFSET 		(0xC0000000UL)
++#endif
++
++/*
++#define __virt_to_bus(x)	((x) - PAGE_OFFSET)
++#define __bus_to_virt(x)	((x) + PAGE_OFFSET)
++*/
++#if 0
++#define __virt_to_phys__is_a_macro
++#define __virt_to_phys(vpage)	((vpage) - PAGE_OFFSET)
++
++#define __phys_to_virt__is_a_macro
++#define __phys_to_virt(ppage)	((ppage) + PAGE_OFFSET)
++
++#define __virt_to_bus__is_a_macro
++#define __virt_to_bus(x)	((x) - PAGE_OFFSET)
++
++#define __bus_to_virt__is_a_macro
++#define __bus_to_virt(x)	((x) + PAGE_OFFSET)
++#endif
++
++/*
++#define __virt_to_bus(x) __virt_to_phys(x)
++#define __bus_to_virt(x) __phys_to_virt(x)
++
++#define __pfn_to_bus(x) __pfn_to_phys(x)
++#define __bus_to_pfn(x) __phys_to_pfn(x)
++*/
++
++/*
++#define __pfn_to_bus(p)         __phys_to_bus(__pfn_to_phys(p))
++#define __bus_to_pfn(b)         __phys_to_pfn(__bus_to_phys(b))
++*/
++
++
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/param.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/param.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/param.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/param.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,32 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_PARAM_H__
++#define __ASM_ARCH_PARAM_H__
++
++// For timer, there will be HZ ticks per second
++/* scott.patch
++#define HZ	100
++*/
++
++#endif /* __ARCH_ASM_PARAM_H__ */
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_demo_dma.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_demo_dma.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_demo_dma.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_demo_dma.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,189 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __DEMO_DMA_H__
++#define __DEMO_DMA_H__
++#include <linux/types.h>	/* size_t */
++#include <linux/interrupt.h>
++#include <linux/module.h>
++
++#include <mach/star_dmac.h>
++
++/*
++ * defines for each channel
++ */
++#define DMAC_CH_DISABLE                0
++#define DMAC_CH_ENABLE                 1
++
++#define DMAC_CH_DST_SEL_M0             0
++#define DMAC_CH_DST_SEL_M1             1
++
++#define DMAC_CH_SRC_SEL_M0             0
++#define DMAC_CH_SRC_SEL_M1             1
++
++#define DMAC_CH_DSTAD_CTL_INC          0
++#define DMAC_CH_DSTAD_CTL_DEC          1
++#define DMAC_CH_DSTAD_CTL_FIX          2
++
++#define DMAC_CH_SRCAD_CTL_INC          0
++#define DMAC_CH_SRCAD_CTL_DEC          1
++#define DMAC_CH_SRCAD_CTL_FIX          2
++
++#define DMAC_CH_MODE_HW_HANDSHAKE      1
++
++#define DMAC_CH_SRC_WIDTH_8_BITS       0
++#define DMAC_CH_SRC_WIDTH_16_BITS      1
++#define DMAC_CH_SRC_WIDTH_32_BITS      2
++
++#define DMAC_CH_DST_WIDTH_8_BITS       0
++#define DMAC_CH_DST_WIDTH_16_BITS      1
++#define DMAC_CH_DST_WIDTH_32_BITS      2
++
++#define DMAC_CH_ABT_TRANSFER           1
++
++#define DMAC_CH_PROT1_PRIVILEGED_MODE  1
++#define DMAC_CH_PROT1_USER_MODE        0
++
++#define DMAC_CH_PROT2_BUFFERABLE       1
++#define DMAC_CH_PROT2_NON_BUFFERABLE   0
++
++#define DMAC_CH_PROT3_CACHEABLE        1
++#define DMAC_CH_PROT3_NON_CACHEABLE    0
++
++#define DMAC_CH_PRI_LEVEL_0            0
++#define DMAC_CH_PRI_LEVEL_1            1
++#define DMAC_CH_PRI_LEVEL_2            2
++#define DMAC_CH_PRI_LEVEL_3            3
++
++#define DMAC_CH_TC_MASK_DISABLE        0
++#define DMAC_CH_TC_MASK_ENABLE         1
++
++#define DMAC_MAX_CHANNEL_NUM           (8)
++
++
++#define DMAC_CH0_ID                    (1 << 0)
++#define DMAC_CH1_ID                    (1 << 1)
++#define DMAC_CH2_ID                    (1 << 2)
++#define DMAC_CH3_ID                    (1 << 3)
++#define DMAC_CH4_ID                    (1 << 4)
++#define DMAC_CH5_ID                    (1 << 5)
++#define DMAC_CH6_ID                    (1 << 6)
++#define DMAC_CH7_ID                    (1 << 7)
++#define DMAC_CH_ID(idx)                (1 << idx) 
++
++#define DMAC_LITTLE_ENDIAN             (0)
++#define DMAC_BIG_ENDIAN                (1)
++
++/* 
++ * DMAC LLP Descriptor
++ */
++typedef struct _DMAC_LLP_CONTROL_    DMAC_LLP_CONTROL_T;
++
++struct _DMAC_LLP_CONTROL_
++{
++//#if (ENDIAN_MODE == LITTLE_ENDIAN)
++#if 1
++    unsigned int    tot_size              : 12;//b11-0
++    unsigned int    reserved_1            : 4; //b15-12    
++    unsigned int    dst_sel               : 1; //b16
++    unsigned int    src_sel               : 1; //b17    
++    unsigned int    dstad_ctl             : 2; //b19-18        
++    unsigned int    srcad_ctl             : 2; //b21-20        
++    unsigned int    dst_width             : 3; //b24-22
++    unsigned int    src_width             : 3; //b27-25
++    unsigned int    tc_status_mask        : 1; //b28
++    unsigned int    reserved_0            : 3; //b31-29
++
++#else
++
++
++    unsigned int    reserved_0            : 3; //b31-29
++    unsigned int    tc_status_mask        : 1; //b28
++    unsigned int    src_width             : 3; //b27-25
++    unsigned int    dst_width             : 3; //b24-22
++    unsigned int    srcad_ctl             : 2; //b21-20
++    unsigned int    dstad_ctl             : 2; //b19-18    
++    unsigned int    src_sel               : 1; //b17
++    unsigned int    dst_sel               : 1; //b16
++    unsigned int    reserved_1            : 4; //b15-12
++    unsigned int    tot_size              : 12;//b11-0
++
++
++#endif
++}; 
++
++
++/* 
++ * DMAC LLP Descriptor object
++ */
++typedef struct _DMAC_LLP_    DMAC_LLP_T;
++struct _DMAC_LLP_
++{
++    unsigned int    SrcAddr;
++    
++    unsigned int    DstAddr;
++    
++    DMAC_LLP_T     *LLP;
++
++    DMAC_LLP_CONTROL_T    Ctrl_TotSize;    
++};
++
++typedef struct _DMAC_HARDWARE_HANDSHAKE_OBJ_    DMAC_HARDWARE_HANDSHAKE_OBJ_T;
++struct _DMAC_HARDWARE_HANDSHAKE_OBJ_
++{
++    unsigned int    src_addr;                     //Src address
++    unsigned int    dst_addr;                     //Dst address
++    unsigned int    src_master;                   //0:AHB0, 1:AHB1
++    unsigned int    dst_master;                   //0:AHB0, 1:AHB1
++    unsigned int    dstad_ctl;                    //0:Incr, 1:Decr, 2:Fix
++    unsigned int    srcad_ctl;                    //0:Incr, 1:Decr, 2:Fix
++    unsigned int    src_width;                    //0:8bits, 1:16bits, 2:32bits
++    unsigned int    dst_width;                    //0:8bits, 1:16bits, 2:32bits
++    unsigned int    transfer_bytes;               //Byte Count to be transferred
++    unsigned int    channel_id;                   //0~7 for Channel0-7 selection
++    unsigned int    channel_num;                   //0~7
++    unsigned int    target_select;                //target ID
++    unsigned int    src_burst_size;               //number of transfer 
++    unsigned int    llp_addr;                     //LLP address
++
++    void * private_data;
++    DMAC_LLP_T* llp_head;
++}; 
++
++
++extern void Hal_Dmac_Configure_DMA_Handshake(DMAC_HARDWARE_HANDSHAKE_OBJ_T *dmac_obj);
++extern irqreturn_t str8100_dma_err_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs);
++//extern int str8100_i2s_init(int sampling_rate);
++extern int str8100_i2s_init(int sampling_rate,u32 i2s_sdata_width, u32 i2s_mode,
++			u32 i2s_tranfer_timing_ctrl, u32 i2s_sclk_mode);
++extern u32 Hal_Dmac_Get_Channel_Transfer_Unit_Number(u32 byte_size, u32 src_width);
++
++extern u32 I2s_Gpio_SSP_Initialise(void);
++extern void I2s_Gpio_SSP_Write(u16);
++extern void I2s_Gpio_SSP_Switch_To_Record_Data(void);
++extern void I2s_Gpio_SSP_Switcg_To_Playback_Data(void);
++
++
++#endif //#ifndef __DEMO_DMA_H__
++
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_dmac.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_dmac.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_dmac.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_dmac.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,409 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_DMAC_H_
++#define	_STAR_DMAC_H_
++
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	DMAC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_GDMAC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	DMAC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_GDMAC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	DMAC_INT_STATUS_REG			DMAC_MEM_MAP_VALUE(0x000)
++
++#define	DMAC_INT_TC_STATUS_REG			DMAC_MEM_MAP_VALUE(0x004)
++#define	DMAC_INT_TC_STATUS_CLR_REG		DMAC_MEM_MAP_VALUE(0x008)
++
++#define	DMAC_INT_ERR_STATUS_REG			DMAC_MEM_MAP_VALUE(0x00C)
++#define	DMAC_INT_ERR_STATUS_CLR_REG		DMAC_MEM_MAP_VALUE(0x010)
++
++#define	DMAC_TC_STATUS_REG			DMAC_MEM_MAP_VALUE(0x014)
++#define	DMAC_ERR_STATUS_REG			DMAC_MEM_MAP_VALUE(0x018)
++
++#define	DMAC_CH_ENABLE_STATUS_REG		DMAC_MEM_MAP_VALUE(0x01C)
++#define	DMAC_CH_BUSY_STATUS_REG			DMAC_MEM_MAP_VALUE(0x020)
++
++#define	DMAC_CSR_REG				DMAC_MEM_MAP_VALUE(0x024)
++#define	DMAC_SYNC_REG				DMAC_MEM_MAP_VALUE(0x028)
++
++#define	DMAC_CH0_CSR_REG			DMAC_MEM_MAP_VALUE(0x100)
++#define	DMAC_CH0_CFG_REG			DMAC_MEM_MAP_VALUE(0x104)
++#define	DMAC_CH0_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x108)
++#define	DMAC_CH0_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x10C)
++#define	DMAC_CH0_LLP_REG			DMAC_MEM_MAP_VALUE(0x110)
++#define	DMAC_CH0_SIZE_REG			DMAC_MEM_MAP_VALUE(0x114)
++
++#define	DMAC_CH1_CSR_REG			DMAC_MEM_MAP_VALUE(0x120)
++#define	DMAC_CH1_CFG_REG			DMAC_MEM_MAP_VALUE(0x124)
++#define	DMAC_CH1_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x128)
++#define	DMAC_CH1_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x12C)
++#define	DMAC_CH1_LLP_REG			DMAC_MEM_MAP_VALUE(0x130)
++#define	DMAC_CH1_SIZE_REG			DMAC_MEM_MAP_VALUE(0x134)
++
++#define	DMAC_CH2_CSR_REG			DMAC_MEM_MAP_VALUE(0x140)
++#define	DMAC_CH2_CFG_REG			DMAC_MEM_MAP_VALUE(0x144)
++#define	DMAC_CH2_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x148)
++#define	DMAC_CH2_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x14C)
++#define	DMAC_CH2_LLP_REG			DMAC_MEM_MAP_VALUE(0x150)
++#define	DMAC_CH2_SIZE_REG			DMAC_MEM_MAP_VALUE(0x154)
++
++#define	DMAC_CH3_CSR_REG			DMAC_MEM_MAP_VALUE(0x160)
++#define	DMAC_CH3_CFG_REG			DMAC_MEM_MAP_VALUE(0x164)
++#define	DMAC_CH3_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x168)
++#define	DMAC_CH3_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x16C)
++#define	DMAC_CH3_LLP_REG			DMAC_MEM_MAP_VALUE(0x170)
++#define	DMAC_CH3_SIZE_REG			DMAC_MEM_MAP_VALUE(0x174)
++
++#define	DMAC_CH4_CSR_REG			DMAC_MEM_MAP_VALUE(0x180)
++#define	DMAC_CH4_CFG_REG			DMAC_MEM_MAP_VALUE(0x184)
++#define	DMAC_CH4_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x188)
++#define	DMAC_CH4_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x18C)
++#define	DMAC_CH4_LLP_REG			DMAC_MEM_MAP_VALUE(0x190)
++#define	DMAC_CH4_SIZE_REG			DMAC_MEM_MAP_VALUE(0x194)
++
++#define	DMAC_CH5_CSR_REG			DMAC_MEM_MAP_VALUE(0x1A0)
++#define	DMAC_CH5_CFG_REG			DMAC_MEM_MAP_VALUE(0x1A4)
++#define	DMAC_CH5_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1A8)
++#define	DMAC_CH5_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1AC)
++#define	DMAC_CH5_LLP_REG			DMAC_MEM_MAP_VALUE(0x1B0)
++#define	DMAC_CH5_SIZE_REG			DMAC_MEM_MAP_VALUE(0x1B4)
++
++#define	DMAC_CH6_CSR_REG			DMAC_MEM_MAP_VALUE(0x1C0)
++#define	DMAC_CH6_CFG_REG			DMAC_MEM_MAP_VALUE(0x1C4)
++#define	DMAC_CH6_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1C8)
++#define	DMAC_CH6_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1CC)
++#define	DMAC_CH6_LLP_REG			DMAC_MEM_MAP_VALUE(0x1D0)
++#define	DMAC_CH6_SIZE_REG			DMAC_MEM_MAP_VALUE(0x1D4)
++
++#define	DMAC_CH7_CSR_REG			DMAC_MEM_MAP_VALUE(0x1E0)
++#define	DMAC_CH7_CFG_REG			DMAC_MEM_MAP_VALUE(0x1E4)
++#define	DMAC_CH7_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1E8)
++#define	DMAC_CH7_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1EC)
++#define	DMAC_CH7_LLP_REG			DMAC_MEM_MAP_VALUE(0x1F0)
++#define	DMAC_CH7_SIZE_REG			DMAC_MEM_MAP_VALUE(0x1F4)
++
++
++#define DMAC_CH0_INT_BIT_INDEX			0
++#define DMAC_CH1_INT_BIT_INDEX			1
++#define DMAC_CH2_INT_BIT_INDEX			2
++#define DMAC_CH3_INT_BIT_INDEX			3
++#define DMAC_CH4_INT_BIT_INDEX			4
++#define DMAC_CH5_INT_BIT_INDEX			5
++#define DMAC_CH6_INT_BIT_INDEX			6
++#define DMAC_CH7_INT_BIT_INDEX			7
++
++#define DMAC_CH0_INT_TC_BIT_INDEX		0
++#define DMAC_CH1_INT_TC_BIT_INDEX		1
++#define DMAC_CH2_INT_TC_BIT_INDEX		2
++#define DMAC_CH3_INT_TC_BIT_INDEX		3
++#define DMAC_CH4_INT_TC_BIT_INDEX		4
++#define DMAC_CH5_INT_TC_BIT_INDEX		5
++#define DMAC_CH6_INT_TC_BIT_INDEX		6
++#define DMAC_CH7_INT_TC_BIT_INDEX		7
++
++#define DMAC_CH0_INT_TC_CLR_BIT_INDEX		0
++#define DMAC_CH1_INT_TC_CLR_BIT_INDEX		1
++#define DMAC_CH2_INT_TC_CLR_BIT_INDEX		2
++#define DMAC_CH3_INT_TC_CLR_BIT_INDEX		3
++#define DMAC_CH4_INT_TC_CLR_BIT_INDEX		4
++#define DMAC_CH5_INT_TC_CLR_BIT_INDEX		5
++#define DMAC_CH6_INT_TC_CLR_BIT_INDEX		6
++#define DMAC_CH7_INT_TC_CLR_BIT_INDEX		7
++
++#define DMAC_CH0_INT_ERR_BIT_INDEX		0
++#define DMAC_CH1_INT_ERR_BIT_INDEX		1
++#define DMAC_CH2_INT_ERR_BIT_INDEX		2
++#define DMAC_CH3_INT_ERR_BIT_INDEX		3
++#define DMAC_CH4_INT_ERR_BIT_INDEX		4
++#define DMAC_CH5_INT_ERR_BIT_INDEX		5
++#define DMAC_CH6_INT_ERR_BIT_INDEX		6
++#define DMAC_CH7_INT_ERR_BIT_INDEX		7
++
++#define DMAC_CH0_INT_ERR_CLR_BIT_INDEX		0
++#define DMAC_CH1_INT_ERR_CLR_BIT_INDEX		1
++#define DMAC_CH2_INT_ERR_CLR_BIT_INDEX		2
++#define DMAC_CH3_INT_ERR_CLR_BIT_INDEX		3
++#define DMAC_CH4_INT_ERR_CLR_BIT_INDEX		4
++#define DMAC_CH5_INT_ERR_CLR_BIT_INDEX		5
++#define DMAC_CH6_INT_ERR_CLR_BIT_INDEX		6
++#define DMAC_CH7_INT_ERR_CLR_BIT_INDEX		7
++
++#define DMAC_CH0_TC_STATUS_BIT_INDEX		0
++#define DMAC_CH1_TC_STATUS_BIT_INDEX		1
++#define DMAC_CH2_TC_STATUS_BIT_INDEX		2
++#define DMAC_CH3_TC_STATUS_BIT_INDEX		3
++#define DMAC_CH4_TC_STATUS_BIT_INDEX		4
++#define DMAC_CH5_TC_STATUS_BIT_INDEX		5
++#define DMAC_CH6_TC_STATUS_BIT_INDEX		6
++#define DMAC_CH7_TC_STATUS_BIT_INDEX		7
++
++#define DMAC_CH0_ERR_STATUS_BIT_INDEX		0
++#define DMAC_CH1_ERR_STATUS_BIT_INDEX		1
++#define DMAC_CH2_ERR_STATUS_BIT_INDEX		2
++#define DMAC_CH3_ERR_STATUS_BIT_INDEX		3
++#define DMAC_CH4_ERR_STATUS_BIT_INDEX		4
++#define DMAC_CH5_ERR_STATUS_BIT_INDEX		5
++#define DMAC_CH6_ERR_STATUS_BIT_INDEX		6
++#define DMAC_CH7_ERR_STATUS_BIT_INDEX		7
++
++#define DMAC_CH0_ENABLE_STATUS_BIT_INDEX	0
++#define DMAC_CH1_ENABLE_STATUS_BIT_INDEX	1
++#define DMAC_CH2_ENABLE_STATUS_BIT_INDEX	2
++#define DMAC_CH3_ENABLE_STATUS_BIT_INDEX	3
++#define DMAC_CH4_ENABLE_STATUS_BIT_INDEX	4
++#define DMAC_CH5_ENABLE_STATUS_BIT_INDEX	5
++#define DMAC_CH6_ENABLE_STATUS_BIT_INDEX	6
++#define DMAC_CH7_ENABLE_STATUS_BIT_INDEX	7
++
++#define DMAC_CH0_BUSY_STATUS_BIT_INDEX		0
++#define DMAC_CH1_BUSY_STATUS_BIT_INDEX		1
++#define DMAC_CH2_BUSY_STATUS_BIT_INDEX		2
++#define DMAC_CH3_BUSY_STATUS_BIT_INDEX		3
++#define DMAC_CH4_BUSY_STATUS_BIT_INDEX		4
++#define DMAC_CH5_BUSY_STATUS_BIT_INDEX		5
++#define DMAC_CH6_BUSY_STATUS_BIT_INDEX		6
++#define DMAC_CH7_BUSY_STATUS_BIT_INDEX		7
++
++#define DMAC_ENABLE_BIT_INDEX			0
++#define DMAC_MASTER0_ENDIAN_BIT_INDEX		1
++#define DMAC_MASTER1_ENDIAN_BIT_INDEX		2
++
++#define DMAC_CH0_SYNC_ENABLE_BIT_INDEX		0
++#define DMAC_CH1_SYNC_ENABLE_BIT_INDEX		1
++#define DMAC_CH2_SYNC_ENABLE_BIT_INDEX		2
++#define DMAC_CH3_SYNC_ENABLE_BIT_INDEX		3
++#define DMAC_CH4_SYNC_ENABLE_BIT_INDEX		4
++#define DMAC_CH5_SYNC_ENABLE_BIT_INDEX		5
++#define DMAC_CH6_SYNC_ENABLE_BIT_INDEX		6
++#define DMAC_CH7_SYNC_ENABLE_BIT_INDEX		7
++
++#define DMAC_CH_INT_TC_MASK_BIT_INDEX		0
++#define DMAC_CH_INT_ERR_MASK_BIT_INDEX		1
++#define DMAC_CH_INT_ABT_MASK_BIT_INDEX		2
++#define DMAC_CH_BUSY_BIT_INDEX			8
++
++#define DMAC_CH_ENABLE_BIT_INDEX		0
++#define DMAC_CH_DST_SEL_BIT_INDEX		1
++#define DMAC_CH_SRC_SEL_BIT_INDEX		2
++#define DMAC_CH_DST_ADDR_CTL_BIT_INDEX		3
++#define DMAC_CH_SRC_ADDR_CTL_BIT_INDEX		5
++#define DMAC_CH_MODE_BIT_INDEX			7
++#define DMAC_CH_DST_WIDTH_BIT_INDEX		8
++#define DMAC_CH_SRC_WIDTH_BIT_INDEX		11
++#define DMAC_CH_ABT_BIT_INDEX			15
++#define DMAC_CH_SRC_BURST_SIZE_BIT_INDEX	16
++#define DMAC_CH_PROTECT_MODE_BIT_INDEX		19
++#define DMAC_CH_PROTECT_BUFFERABLE_BIT_INDEX	20
++#define DMAC_CH_PROTECT_CACHEABLE_BIT_INDEX	21
++#define DMAC_CH_PRIORITY_BIT_INDEX		22
++#define DMAC_CH_HHST_SEL_BIT_INDEX		25
++
++#define DMAC_CH_DST_ADDR_CTL_MASK		0x3
++#define DMAC_CH_DST_ADDR_CTL_INC		0x0
++#define DMAC_CH_DST_ADDR_CTL_DEC		0x1
++#define DMAC_CH_DST_ADDR_CTL_FIXED		0x2
++
++#define DMAC_CH_SRC_ADDR_CTL_MASK		0x3
++#define DMAC_CH_SRC_ADDR_CTL_INC		0x0
++#define DMAC_CH_SRC_ADDR_CTL_DEC		0x1
++#define DMAC_CH_SRC_ADDR_CTL_FIXED		0x2
++
++#define DMAC_CH_MODE_NORMAL			0x0
++#define DMAC_CH_MODE_HANDSHAKE			0x1
++
++#define DMAC_CH_DST_WIDTH_MASK			0x3
++#define DMAC_CH_DST_WIDTH_8BIT			0x0
++#define DMAC_CH_DST_WIDTH_16BIT			0x1
++#define DMAC_CH_DST_WIDTH_32BIT			0x2
++
++#define DMAC_CH_SRC_WIDTH_MASK			0x3
++#define DMAC_CH_SRC_WIDTH_8BIT			0x0
++#define DMAC_CH_SRC_WIDTH_16BIT			0x1
++#define DMAC_CH_SRC_WIDTH_32BIT			0x2
++
++#define DMAC_CH_SRC_BURST_SIZE_MASK		0x8
++#define DMAC_CH_SRC_BURST_SIZE_1		0x0
++#define DMAC_CH_SRC_BURST_SIZE_4		0x1
++#define DMAC_CH_SRC_BURST_SIZE_8		0x2
++#define DMAC_CH_SRC_BURST_SIZE_16		0x3
++#define DMAC_CH_SRC_BURST_SIZE_32		0x4
++#define DMAC_CH_SRC_BURST_SIZE_64		0x5
++#define DMAC_CH_SRC_BURST_SIZE_128		0x6
++#define DMAC_CH_SRC_BURST_SIZE_256		0x7
++
++#define DMAC_CH_PRIORITY_MASK			0x4
++#define DMAC_CH_PRIORITY_0			0x0	/* lowest priority */
++#define DMAC_CH_PRIORITY_1			0x1
++#define DMAC_CH_PRIORITY_2			0x2
++#define DMAC_CH_PRIORITY_3			0x3	/* highest priority */
++
++
++#define	DMAC_CH_CSR_REG(idx)			DMAC_MEM_MAP_VALUE(0x100+0x20*(idx))
++#define	DMAC_CH_CFG_REG(idx)			DMAC_MEM_MAP_VALUE(0x104+0x20*(idx))
++#define	DMAC_CH_SRC_ADDR_REG(idx)		DMAC_MEM_MAP_VALUE(0x108+0x20*(idx))
++#define	DMAC_CH_DST_ADDR_REG(idx)		DMAC_MEM_MAP_VALUE(0x10C+0x20*(idx))
++#define	DMAC_CH_LLP_REG(idx)			DMAC_MEM_MAP_VALUE(0x110+0x20*(idx))
++#define	DMAC_CH_SIZE_REG(idx)			DMAC_MEM_MAP_VALUE(0x114+0x20*(idx))
++
++
++#define	HAL_DMAC_ENABLE_CHANNEL(idx)		((DMAC_CH_CSR_REG(idx)) |= (0x1))
++
++#define	HAL_DMAC_DISABLE_CHANNEL(idx)		((DMAC_CH_CSR_REG(idx)) &= ~(0x1))
++
++#define	HAL_GET_DMAC_CHANNEL_LLP_COUNTER(ch)	((DMAC_CH_CFG_REG(ch) >> 16) & 0xF)
++
++
++/*DMAC HW Hand-shake target ID*/
++#define	DMAC_HW_HAND_SHAKE_PCM_TX0_ID		0x0
++#define	DMAC_HW_HAND_SHAKE_PCM_RX0_ID		0x1
++
++#define	DMAC_HW_HAND_SHAKE_SPI_TX_ID		0x2
++#define	DMAC_HW_HAND_SHAKE_SPI_RX_ID		0x3
++
++#define	DMAC_HW_HAND_SHAKE_I2S_TX_LEFT_ID	0x4
++#define	DMAC_HW_HAND_SHAKE_I2S_TX_RIGHT_ID	0x5
++
++#define	DMAC_HW_HAND_SHAKE_UART0_TX_ID		0x6
++#define	DMAC_HW_HAND_SHAKE_UART0_RX_ID		0x7
++
++#define	DMAC_HW_HAND_SHAKE_UART1_TX_ID		0x8
++#define	DMAC_HW_HAND_SHAKE_UART1_RX_ID		0x9
++
++#define	DMAC_HW_HAND_SHAKE_USBDEV_ID		0xA
++
++#define	DMAC_HW_HAND_SHAKE_I2S_RX_LEFT_ID	0xB
++#define	DMAC_HW_HAND_SHAKE_I2S_RX_RIGHT_ID	0xC
++
++#define	DMAC_HW_HAND_SHAKE_PCM_TX1_ID		0xD
++#define	DMAC_HW_HAND_SHAKE_PCM_RX1_ID		0xE
++
++
++#define MAX_DMA_VEC				32
++
++#define DMAC_DST_SEL_MASTER0			0
++#define DMAC_DST_SEL_MASTER1			1
++#define DMAC_SRC_SEL_MASTER0			0
++#define DMAC_SRC_SEL_MASTER1			1
++
++#define DMAC_RESPONSE_OK			0
++#define DMAC_RESPONSE_ERR			-1
++
++struct dma_xfer;
++typedef struct dma_xfer dma_xfer_t;
++typedef void (*dma_end_io_t)(dma_xfer_t *dma_xfer, int err);
++typedef struct
++{
++	u32	src_addr;	// virtual addr
++	u32	dst_addr;	// virtual addr
++	u32	size;		// bytes
++	u8	dst_sel;
++	u8	src_sel;
++	u8	dst_addr_ctl;
++	u8	src_addr_ctl;
++	u8	dst_width;
++	u8	src_width;
++} dma_vec_t;
++
++struct dma_xfer
++{
++	u8		nr_vec;
++	dma_vec_t	vec[MAX_DMA_VEC];
++	dma_end_io_t	dma_end_io;
++	void		*private;
++};
++
++/*
++ * DMAC	LLP Descriptor
++ */
++typedef struct
++{
++	u32	src_addr;			// physical addr
++	u32	dst_addr;			// physical addr
++	u32	llp;
++	u32	tot_size	: 12;
++	u32	reserved0	: 4;
++	u32	dst_sel		: 1;
++	u32	src_sel		: 1;
++	u32	dst_addr_ctl	: 2;
++	u32	src_addr_ctl	: 2;
++	u32	dst_width	: 3;
++	u32	src_width	: 3;
++	u32	tc_mask		: 1;
++	u32	reserved1	: 3;
++} __attribute__((packed)) dma_llp_descr_t;
++
++#define HAL_DMAC_ENABLE() \
++	    ((DMAC_CSR_REG) |= (1<<DMAC_ENABLE_BIT_INDEX))
++
++
++#define HAL_DMAC_DISABLE() \
++	    ((DMAC_CSR_REG) &= ~(1<<DMAC_ENABLE_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER0_BIG_ENDIAN() \
++	    ((DMAC_CSR_REG) |= (1<<DMAC_MASTER0_ENDIAN_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER0_LITTLE_ENDIAN() \
++	    ((DMAC_CSR_REG) &= ~(1<<DMAC_MASTER0_ENDIAN_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER1_BIG_ENDIAN() \
++	    ((DMAC_CSR_REG) |= (1<<DMAC_MASTER1_ENDIAN_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER1_LITTLE_ENDIAN() \
++	    ((DMAC_CSR_REG) &= ~(1<<DMAC_MASTER1_ENDIAN_BIT_INDEX))
++
++#define HAL_DMAC_READ_ERROR_ABORT_INTERRUPT_STATUS(err_abt_status) \
++	    ((err_abt_status) = (DMAC_INT_ERR_STATUS_REG))
++
++
++#define HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(err_abt_status) \
++	    ((DMAC_INT_ERR_STATUS_CLR_REG) = (err_abt_status))
++
++
++#define HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(tc_status) \
++	    ((tc_status) = (DMAC_INT_TC_STATUS_REG) & 0xFF)
++
++
++#define HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(tc_status) \
++	    ((DMAC_INT_TC_STATUS_CLR_REG) = (tc_status) & 0xFF)
++
++
++
++
++
++
++#endif	// end of #ifndef _STAR_DMAC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_gpio.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_gpio.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_gpio.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_gpio.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,327 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_GPIO_H_
++#define	_STAR_GPIO_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	GPIOA_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSPA_GPIOA_BASE_ADDR + reg_offset)))
++#define	GPIOB_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSPA_GPIOB_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	GPIOA_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSVA_GPIOA_BASE_ADDR + reg_offset)))
++#define	GPIOB_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSVA_GPIOB_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * For GPIO Set	A
++ */
++#define	GPIOA_DATA_OUTPUT_REG			GPIOA_MEM_MAP_VALUE(0x00)
++#define	GPIOA_DATA_INPUT_REG			GPIOA_MEM_MAP_VALUE(0x04)
++#define	GPIOA_DIRECTION_REG			GPIOA_MEM_MAP_VALUE(0x08)
++
++#define	GPIOA_DATA_BIT_SET_REG			GPIOA_MEM_MAP_VALUE(0x10)
++#define	GPIOA_DATA_BIT_CLEAR_REG		GPIOA_MEM_MAP_VALUE(0x14)
++
++#define	GPIOA_INTERRUPT_ENABLE_REG		GPIOA_MEM_MAP_VALUE(0x20)
++#define	GPIOA_INTERRUPT_RAW_STATUS_REG		GPIOA_MEM_MAP_VALUE(0x24)
++#define	GPIOA_INTERRUPT_MASKED_STATUS_REG	GPIOA_MEM_MAP_VALUE(0x28)
++#define	GPIOA_INTERRUPT_MASK_REG		GPIOA_MEM_MAP_VALUE(0x2C)
++#define	GPIOA_INTERRUPT_CLEAR_REG		GPIOA_MEM_MAP_VALUE(0x30)
++#define	GPIOA_INTERRUPT_TRIGGER_METHOD_REG	GPIOA_MEM_MAP_VALUE(0x34)
++#define	GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG	GPIOA_MEM_MAP_VALUE(0x38)
++#define	GPIOA_INTERRUPT_TRIGGER_TYPE_REG	GPIOA_MEM_MAP_VALUE(0x3C)
++
++#define	GPIOA_BOUNCE_ENABLE_REG			GPIOA_MEM_MAP_VALUE(0x40)
++#define	GPIOA_BOUNCE_CLOCK_PRESCALE_REG		GPIOA_MEM_MAP_VALUE(0x44)
++
++
++/*
++ * For GPIO Set	B
++ */
++#define	GPIOB_DATA_OUTPUT_REG			GPIOB_MEM_MAP_VALUE(0x00)
++#define	GPIOB_DATA_INPUT_REG			GPIOB_MEM_MAP_VALUE(0x04)
++#define	GPIOB_DIRECTION_REG			GPIOB_MEM_MAP_VALUE(0x08)
++
++#define	GPIOB_DATA_BIT_SET_REG			GPIOB_MEM_MAP_VALUE(0x10)
++#define	GPIOB_DATA_BIT_CLEAR_REG		GPIOB_MEM_MAP_VALUE(0x14)
++
++#define	GPIOB_INTERRUPT_ENABLE_REG		GPIOB_MEM_MAP_VALUE(0x20)
++#define	GPIOB_INTERRUPT_RAW_STATUS_REG		GPIOB_MEM_MAP_VALUE(0x24)
++#define	GPIOB_INTERRUPT_MASKED_STATUS_REG	GPIOB_MEM_MAP_VALUE(0x28)
++#define	GPIOB_INTERRUPT_MASK_REG		GPIOB_MEM_MAP_VALUE(0x2C)
++#define	GPIOB_INTERRUPT_CLEAR_REG		GPIOB_MEM_MAP_VALUE(0x30)
++#define	GPIOB_INTERRUPT_TRIGGER_METHOD_REG	GPIOB_MEM_MAP_VALUE(0x34)
++#define	GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG	GPIOB_MEM_MAP_VALUE(0x38)
++#define	GPIOB_INTERRUPT_TRIGGER_TYPE_REG	GPIOB_MEM_MAP_VALUE(0x3C)
++
++#define	GPIOB_BOUNCE_ENABLE_REG			GPIOB_MEM_MAP_VALUE(0x40)
++#define	GPIOB_BOUNCE_CLOCK_PRESCALE_REG		GPIOB_MEM_MAP_VALUE(0x44)
++
++
++/*
++ * define constant macros
++ */
++
++#define	MAX_GPIO_PINS		(32)
++
++#define	GPIO_0_MASK		(1 << 0)
++#define	GPIO_1_MASK		(1 << 1)
++#define	GPIO_2_MASK		(1 << 2)
++#define	GPIO_3_MASK		(1 << 3)
++#define	GPIO_4_MASK		(1 << 4)
++#define	GPIO_5_MASK		(1 << 5)
++#define	GPIO_6_MASK		(1 << 6)
++#define	GPIO_7_MASK		(1 << 7)
++#define	GPIO_8_MASK		(1 << 8)
++#define	GPIO_9_MASK		(1 << 9)
++#define	GPIO_10_MASK		(1 << 10)
++#define	GPIO_11_MASK		(1 << 11)
++#define	GPIO_12_MASK		(1 << 12)
++#define	GPIO_13_MASK		(1 << 13)
++#define	GPIO_14_MASK		(1 << 14)
++#define	GPIO_15_MASK		(1 << 15)
++#define	GPIO_16_MASK		(1 << 16)
++#define	GPIO_17_MASK		(1 << 17)
++#define	GPIO_18_MASK		(1 << 18)
++#define	GPIO_19_MASK		(1 << 19)
++#define	GPIO_20_MASK		(1 << 20)
++#define	GPIO_21_MASK		(1 << 21)
++#define	GPIO_22_MASK		(1 << 22)
++#define	GPIO_23_MASK		(1 << 23)
++#define	GPIO_24_MASK		(1 << 24)
++#define	GPIO_25_MASK		(1 << 25)
++#define	GPIO_26_MASK		(1 << 26)
++#define	GPIO_27_MASK		(1 << 27)
++#define	GPIO_28_MASK		(1 << 28)
++#define	GPIO_29_MASK		(1 << 29)
++#define	GPIO_30_MASK		(1 << 30)
++#define	GPIO_31_MASK		(1 << 31)
++
++
++/*
++ * macro declarations for GPIO Set A
++ */
++#define	HAL_GPIOA_READ_DATA_OUT_STATUS(data_out_state) \
++    ((data_out_state) =	(GPIOA_DATA_OUTPUT_REG))
++
++#define	HAL_GPIOA_READ_DATA_IN_STATUS(data_in_state) \
++    ((data_in_state) = (GPIOA_DATA_INPUT_REG))
++
++#define	HAL_GPIOA_SET_DIRECTION_OUTPUT(gpio_index) \
++    ((GPIOA_DIRECTION_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_SET_DIRECTION_INPUT(gpio_index) \
++    ((GPIOA_DIRECTION_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_SET_DATA_OUT_HIGH(gpio_index)	\
++    ((GPIOA_DATA_BIT_SET_REG) =	(gpio_index))
++
++#define	HAL_GPIOA_SET_DATA_OUT_LOW(gpio_index) \
++    ((GPIOA_DATA_BIT_CLEAR_REG)	= (gpio_index))
++
++#define	HAL_GPIOA_ENABLE_INTERRUPT(gpio_index) \
++    ((GPIOA_INTERRUPT_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_DISABLE_INTERRUPT(gpio_index)	\
++    ((GPIOA_INTERRUPT_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_READ_INTERRUPT_RAW_STATUS(raw_state) \
++    ((raw_state) = (GPIOA_INTERRUPT_RAW_STATUS_REG))
++
++#define	HAL_GPIOA_READ_INTERRUPT_MASKED_STATUS(masked_raw_state) \
++    ((masked_raw_state)	= (GPIOA_INTERRUPT_MASKED_STATUS_REG))
++
++#define	HAL_GPIOA_DISABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOA_INTERRUPT_MASK_REG)	&= ~(gpio_index))
++
++#define	HAL_GPIOA_ENABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOA_INTERRUPT_MASK_REG)	|= (gpio_index))
++
++#define	HAL_GPIOA_CLEAR_INTERRUPT(gpio_index) \
++    ((GPIOA_INTERRUPT_CLEAR_REG) = (gpio_index))
++
++#define	HAL_GPIOA_SET_INTERRUPT_EDGE_TRIGGER_MODE(gpio_index) \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_SET_INTERRUPT_LEVEL_TRIGGER_MODE(gpio_index) \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_SET_INTERRUPT_SINGLE_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_BOTH_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) |= (gpio_index));	\
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_SINGLE_RISING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_SINGLE_FALLING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_HIGH_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_LOW_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOA_ENABLE_BOUNCE(gpio_index) \
++    ((GPIOA_BOUNCE_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_DISABLE_BOUNCE(gpio_index) \
++    ((GPIOA_BOUNCE_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_READ_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((prescale_ratio) =	((GPIOA_BOUNCE_CLOCK_PRESCALE_REG) & 0x0000FFFF))
++
++#define	HAL_GPIOA_WRITE_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((GPIOA_BOUNCE_CLOCK_PRESCALE_REG) = (prescale_ratio & 0x0000FFFF))
++
++
++
++/*
++ * macro declarations for GPIO Set B
++ */
++#define	HAL_GPIOB_READ_DATA_OUT_STATUS(data_out_state) \
++    ((data_out_state) =	(GPIOB_DATA_OUTPUT_REG))
++
++#define	HAL_GPIOB_READ_DATA_IN_STATUS(data_in_state) \
++    ((data_in_state) = (GPIOB_DATA_INPUT_REG))
++
++#define	HAL_GPIOB_SET_DIRECTION_OUTPUT(gpio_index) \
++    ((GPIOB_DIRECTION_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_SET_DIRECTION_INPUT(gpio_index) \
++    ((GPIOB_DIRECTION_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_SET_DATA_OUT_HIGH(gpio_index)	\
++    ((GPIOB_DATA_BIT_SET_REG) =	(gpio_index))
++
++#define	HAL_GPIOB_SET_DATA_OUT_LOW(gpio_index) \
++    ((GPIOB_DATA_BIT_CLEAR_REG)	= (gpio_index))
++
++#define	HAL_GPIOB_ENABLE_INTERRUPT(gpio_index) \
++    ((GPIOB_INTERRUPT_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_DISABLE_INTERRUPT(gpio_index)	\
++    ((GPIOB_INTERRUPT_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_READ_INTERRUPT_RAW_STATUS(raw_state) \
++    ((raw_state) = (GPIOB_INTERRUPT_RAW_STATUS_REG))
++
++#define	HAL_GPIOB_READ_INTERRUPT_MASKED_STATUS(masked_raw_state) \
++    ((masked_raw_state)	= (GPIOB_INTERRUPT_MASKED_STATUS_REG))
++
++#define	HAL_GPIOB_DISABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOB_INTERRUPT_MASK_REG)	&= ~(gpio_index))
++
++#define	HAL_GPIOB_ENABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOB_INTERRUPT_MASK_REG)	|= (gpio_index))
++
++#define	HAL_GPIOB_CLEAR_INTERRUPT(gpio_index) \
++    ((GPIOB_INTERRUPT_CLEAR_REG) = (gpio_index))
++
++#define	HAL_GPIOB_SET_INTERRUPT_EDGE_TRIGGER_MODE(gpio_index) \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_SET_INTERRUPT_LEVEL_TRIGGER_MODE(gpio_index) \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_SET_INTERRUPT_SINGLE_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_BOTH_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) |= (gpio_index));	\
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_SINGLE_RISING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_SINGLE_FALLING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_HIGH_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_LOW_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOB_ENABLE_BOUNCE(gpio_index) \
++    ((GPIOB_BOUNCE_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_DISABLE_BOUNCE(gpio_index) \
++    ((GPIOB_BOUNCE_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_READ_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((prescale_ratio) =	((GPIOB_BOUNCE_CLOCK_PRESCALE_REG) & 0x0000FFFF))
++
++#define	HAL_GPIOB_WRITE_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((GPIOB_BOUNCE_CLOCK_PRESCALE_REG) = (prescale_ratio & 0x0000FFFF))
++
++
++#endif	// end of _STAR_GPIO_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_hsdmac.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_hsdmac.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_hsdmac.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_hsdmac.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,106 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_HSDMAC_H_
++#define	_STAR_HSDMAC_H_
++
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	HSDMAC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSPA_MISC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	HSDMAC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSVA_MISC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	HSDMAC_CONTROL_STATUS_REG		HSDMAC_MEM_MAP_VALUE(0x040)
++
++#define	HSDMAC_MASTER0_ADDR_REG			HSDMAC_MEM_MAP_VALUE(0x050)
++
++#define	HSDMAC_MASTER1_ADDR_REG			HSDMAC_MEM_MAP_VALUE(0x054)
++
++#define	HSDMAC_LLP_REG				HSDMAC_MEM_MAP_VALUE(0x058)
++
++#define	HSDMAC_TOT_SIZE_REG			HSDMAC_MEM_MAP_VALUE(0x05C)
++
++
++#define	HAL_GET_HSDMAC_LLP_COUNTER		((HSDMAC_CONTROL_STATUS_REG >> 8) & 0xF)
++
++#define	HAL_HSDMAC_ENABLE()			((HSDMAC_CONTROL_STATUS_REG) |= (0x1))
++
++#define	HAL_HSDMAC_DISABLE()			((HSDMAC_CONTROL_STATUS_REG) &= ~(0x1))
++
++
++#define HSDMAC_MASTER0_TO_MASTER1		0
++#define HSDMAC_MASTER1_TO_MASTER0		1
++
++#define HSDMAC_RESPONSE_OK			0
++#define HSDMAC_RESPONSE_ERR			-1
++
++#define MAX_HSDMA_VEC 				32
++
++#define MAX_HSDMA_XFER_SIZE			(0xFFF << 2)
++
++struct hsdma_xfer;
++typedef struct hsdma_xfer hsdma_xfer_t;
++typedef void (*hsdma_end_io_t)(hsdma_xfer_t *hsdma_xfer, int err);
++typedef struct
++{
++	u8	data_direction;
++	u32	src_addr; // virtual
++	u32	dst_addr; // virtual
++	u32	size; // bytes
++} __attribute__((packed)) hsdma_vec_t;
++
++struct hsdma_xfer
++{
++	u8			nr_vec;
++	hsdma_vec_t		vec[MAX_HSDMA_VEC];
++	hsdma_end_io_t		hsdma_end_io;
++	void			*private;
++};
++
++/*
++ * HSDMAC LLP Descriptor object
++ */
++typedef struct
++{
++	u32	src_addr; // physical
++	u32	dst_addr; // physical
++	u32	llp;
++	u32	tot_size	: 16;//b15-b0
++	u32	reserved0	: 12;//b27-b16
++	u32	tc_mask		: 1; //b28
++	u32	data_direction	: 1; //b29
++	u32	reserved1	: 2; //b31-30
++} __attribute__((packed)) hsdma_llp_descr_t;
++
++
++#endif	// end of #ifndef _STAR_HSDMAC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_i2c.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_i2c.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_i2c.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_i2c.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,69 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_I2C_H_
++#define _STAR_I2C_H_
++
++#include <mach/star_sys_memory_map.h>
++
++#define I2C_MEM_MAP_ADDR(reg_offset)          (SYSVA_I2C_BASE_ADDR + reg_offset) 
++#define I2C_MEM_MAP_VALUE(reg_offset)         (*((unsigned int volatile *)I2C_MEM_MAP_ADDR(reg_offset)))
++
++#define I2C_CONTROLLER_REG_ADDR               I2C_MEM_MAP_ADDR(0x20)
++#define I2C_TIME_OUT_REG_ADDR                 I2C_MEM_MAP_ADDR(0x24)
++#define I2C_SLAVE_ADDRESS_REG_ADDR            I2C_MEM_MAP_ADDR(0x28)
++#define I2C_WRITE_DATA_REG_ADDR               I2C_MEM_MAP_ADDR(0x2C)
++#define I2C_READ_DATA_REG_ADDR                I2C_MEM_MAP_ADDR(0x30)
++#define I2C_INTERRUPT_STATUS_REG_ADDR         I2C_MEM_MAP_ADDR(0x34)
++#define I2C_INTERRUPT_ENABLE_REG_ADDR         I2C_MEM_MAP_ADDR(0x38)
++
++#define I2C_CONTROLLER_REG                    I2C_MEM_MAP_VALUE(0x20)
++#define I2C_TIME_OUT_REG                      I2C_MEM_MAP_VALUE(0x24)
++#define I2C_SLAVE_ADDRESS_REG                 I2C_MEM_MAP_VALUE(0x28)
++#define I2C_WRITE_DATA_REG                    I2C_MEM_MAP_VALUE(0x2C)
++#define I2C_READ_DATA_REG                     I2C_MEM_MAP_VALUE(0x30)
++#define I2C_INTERRUPT_STATUS_REG              I2C_MEM_MAP_VALUE(0x34)
++#define I2C_INTERRUPT_ENABLE_REG              I2C_MEM_MAP_VALUE(0x38)
++
++#define I2C_READ_ONLY_CMD      (0)
++#define I2C_WRITE_ONLY_CMD     (1)
++#define I2C_WRITE_READ_CMD     (2)
++#define I2C_READ_WRITE_CMD     (3)
++
++#define I2C_DATA_LEN_1_BYTE    (0)
++#define I2C_DATA_LEN_2_BYTE    (1)
++#define I2C_DATA_LEN_3_BYTE    (2)
++#define I2C_DATA_LEN_4_BYTE    (3)
++
++#define I2C_BUS_ERROR_FLAG     (0x1)
++#define I2C_ACTION_DONE_FLAG   (0x2)
++
++#define HAL_I2C_ENABLE_I2C()          (I2C_CONTROLLER_REG) |= ((unsigned int)0x1 << 31); 
++#define HAL_I2C_DISABLE_I2C()         (I2C_CONTROLLER_REG) &= ~((unsigned int)0x1 << 31);
++#define HAL_I2C_ENABLE_DATA_SWAP()    (I2C_CONTROLLER_REG) |= (0x1 << 24); 
++#define HAL_I2C_DISABLE_DATA_SWAP()   (I2C_CONTROLLER_REG) &= ~(0x1 << 24); 
++#define HAL_I2C_START_TRANSFER()      (I2C_CONTROLLER_REG) |= (0x1 << 6); 
++#define HAL_I2C_STOP_TRANSFER()       (I2C_CONTROLLER_REG) &= ~(0x1 << 6); 
++
++#endif
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_i2s.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_i2s.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_i2s.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_i2s.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,176 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_I2S_H_
++#define _STAR_I2S_H_
++
++/******************************************************************************
++ * MODULE NAME:    star_i2s.h
++ * PROJECT CODE:   Orion
++ * DESCRIPTION:    
++ * MAINTAINER:     MJLIU
++ * DATE:           15 September 2005
++ *
++ * SOURCE CONTROL: 
++ *
++ * REVISION HISTORY:
++ *     15 September 2005  -  MJLIU	- Initial Version v1.0
++ *
++ *
++ * SOURCE:
++ * ISSUES:
++ * NOTES TO USERS:
++ ******************************************************************************/
++
++#include <mach/star_sys_memory_map.h>
++
++#define I2S_MEM_MAP_ADDR(reg_offset)          (SYSVA_I2S_BASE_ADDR + reg_offset) 
++#define I2S_MEM_MAP_VALUE(reg_offset)         (*((unsigned int volatile *)I2S_MEM_MAP_ADDR(reg_offset)))
++
++//#define I2S_BASE_ADDR                         (SYS_I2S_BASE_ADDR)
++
++
++/*
++ * define access macros
++ */
++#define I2S_CONFIGURATION_REG_ADDR            I2S_MEM_MAP_ADDR(0xC0)
++#define I2S_RIGHT_TRANSMIT_DATA_REG_ADDR      I2S_MEM_MAP_ADDR(0xC4)
++#define I2S_LEFT_TRANSMIT_DATA_REG_ADDR       I2S_MEM_MAP_ADDR(0xC8)
++#define I2S_RIGHT_RECEIVE_DATA_REG_ADDR       I2S_MEM_MAP_ADDR(0xCC)
++#define I2S_LEFT_RECEIVE_DATA_REG_ADDR        I2S_MEM_MAP_ADDR(0xD0)
++#define I2S_INTERRUPT_STATUS_REG_ADDR         I2S_MEM_MAP_ADDR(0xD4)
++#define I2S_INTERRUPT_ENABLE_REG_ADDR         I2S_MEM_MAP_ADDR(0xD8)
++
++#define I2S_CONFIGURATION_REG                 I2S_MEM_MAP_VALUE(0xC0)
++#define I2S_RIGHT_TRANSMIT_DATA_REG           I2S_MEM_MAP_VALUE(0xC4)
++#define I2S_LEFT_TRANSMIT_DATA_REG            I2S_MEM_MAP_VALUE(0xC8)
++#define I2S_RIGHT_RECEIVE_DATA_REG            I2S_MEM_MAP_VALUE(0xCC)
++#define I2S_LEFT_RECEIVE_DATA_REG             I2S_MEM_MAP_VALUE(0xD0)
++#define I2S_INTERRUPT_STATUS_REG              I2S_MEM_MAP_VALUE(0xD4)
++#define I2S_INTERRUPT_ENABLE_REG              I2S_MEM_MAP_VALUE(0xD8)
++
++
++/*
++ * define constants macros
++ */
++#define I2S_DATA_16_BIT             (0)
++#define I2S_DATA_32_BIT             (1)
++
++#define I2S_RXBF_R_FULL_FLAG        (0x01)
++#define I2S_TXBF_R_EMPTY_FLAG       (0x02)
++#define I2S_RXBF_L_FULL_FLAG        (0x04)
++#define I2S_TXBF_L_EMPTY_FLAG       (0x08)
++
++#define I2S_RXBF_R_OR_FLAG          (0x10)
++#define I2S_TXBF_R_UR_FLAG          (0x20)
++#define I2S_RXBF_L_OR_FLAG          (0x40)
++#define I2S_TXBF_L_UR_FLAG          (0x80)
++
++
++#define I2S_MASTER_MODE             (1)
++#define I2S_SLAVE_MODE              (0)
++
++#define I2S_I2S_MODE                (1)
++#define I2S_RJF_MODE                (2)
++#define I2S_LJF_MODE                (3)
++
++#define I2S_CLOCK_CONTINUOUS_MODE   (0)
++#define I2S_CLOCK_256S_MODE         (1)
++
++
++#define I2S_WS_RATE_32KHZ           (1)    /* 8.192 MHz */
++#define I2S_WS_RATE_44_1KHZ         (2)    /* 11.2896 MHz */
++#define I2S_WS_RATE_48KHZ           (3)    /* 12.288 MHz */
++
++
++/*
++ * define data structure
++ */
++#if 0
++typedef struct _I2S_OBJECT_    I2S_OBJECT_T;
++
++struct _I2S_OBJECT_
++{
++    u_int32          config;
++    u_int32          interrupt_config;
++
++
++    /* 
++     * For interrupt setting
++     */
++    INTC_OBJECT_T    intc_obj;
++};
++
++
++/*
++ * function declarations
++ */
++void    Hal_I2s_Initialize(I2S_OBJECT_T *);
++#endif
++
++
++/*
++ * macro declarations
++ */
++#define HAL_I2S_ENABLE_I2S() \
++{ \
++    (I2S_CONFIGURATION_REG) |= ((u32)0x1 << 31); \
++}
++
++#define HAL_I2S_DISABLE_I2S() \
++{ \
++    (I2S_CONFIGURATION_REG) &= ~((u32)0x1 << 31); \
++}
++
++#define HAL_I2S_ENABLE_DATA_SWAP() \
++{ \
++    (I2S_CONFIGURATION_REG) |= (0x1 << 24); \
++}
++
++#define HAL_I2S_DISABLE_DATA_SWAP() \
++{ \
++    (I2S_CONFIGURATION_REG) &= ~(0x1 << 24); \
++}
++
++#define HAL_I2S_DISABLE_LEFT_CHANNEL_TRANSMIT_BUFFER_UNDERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_TXBF_L_UR_FLAG); \
++}
++
++#define HAL_I2S_DISABLE_RIGHT_CHANNEL_TRANSMIT_BUFFER_UNDERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_TXBF_R_UR_FLAG); \
++}
++
++#define HAL_I2S_DISABLE_LEFT_CHANNEL_RECEIVE_BUFFER_OVERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_RXBF_L_OR_FLAG); \
++}
++
++#define HAL_I2S_DISABLE_RIGHT_CHANNEL_RECEIVE_BUFFER_OVERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_RXBF_R_OR_FLAG); \
++}
++
++
++#endif  // end of #ifndef _STAR_I2S_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_ide.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_ide.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_ide.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_ide.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,245 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_IDE_H_
++#define	_STAR_IDE_H_
++
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	IDE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_IDE_CONTROLLER_BASE_ADDR + reg_offset)))
++#define	IDE_BUS_MEM_MAP_VALUE(reg_offset)	(*((u8 volatile *)(SYSPA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#define IDE_DATA_MEM_MAP_VALUE(reg_offset)	(*((u16 volatile *)(SYSPA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	IDE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_IDE_CONTROLLER_BASE_ADDR + reg_offset)))
++#define	IDE_BUS_MEM_MAP_VALUE(reg_offset)	(*((u8 volatile *)(SYSVA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#define IDE_DATA_MEM_MAP_VALUE(reg_offset)	(*((u16 volatile *)(SYSVA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * IDE Controller Registers
++ */
++#define IDE_PIO_CONTROL_REG			IDE_MEM_MAP_VALUE(0x00)
++#define IDE_DRIVE0_PIO_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x04)
++#define IDE_DRIVE1_PIO_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x08)
++#define IDE_DRIVE0_DMA_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x0C)
++#define IDE_DRIVE1_DMA_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x10)
++#define IDE_UDMA_TIMING_CONFIG_REG		IDE_MEM_MAP_VALUE(0x14)
++#define IDE_DMA_UDMA_CONTROL_REG		IDE_MEM_MAP_VALUE(0x18)
++#define IDE_STATUS_CONTROL_REG			IDE_MEM_MAP_VALUE(0x1C)
++#define IDE_BUS_MASTER_DTP_REG			IDE_MEM_MAP_VALUE(0x20)
++#define IDE_FAST_PATH_ACCESS_WINDOW_REG		IDE_MEM_MAP_VALUE(0x24)
++#define IDE_FAST_PATH_DMA_BURST_SIZE_REG	IDE_MEM_MAP_VALUE(0x28)
++
++
++/*
++ * IDE Command Block Registers
++ */
++#define _IDE_DATA_REG				IDE_DATA_MEM_MAP_VALUE(0x20)
++#define _IDE_ERROR_REG				IDE_BUS_MEM_MAP_VALUE(0x24)
++#define _IDE_FEATURES_REG			IDE_BUS_MEM_MAP_VALUE(0x24)
++#define _IDE_SECTOR_COUNT_REG			IDE_BUS_MEM_MAP_VALUE(0x28)
++#define _IDE_LBA_LOW_REG			IDE_BUS_MEM_MAP_VALUE(0x2C)
++#define _IDE_LBA_MID_REG			IDE_BUS_MEM_MAP_VALUE(0x30)
++#define _IDE_LBA_HIGH_REG			IDE_BUS_MEM_MAP_VALUE(0x34)
++#define _IDE_DEVICE_REG				IDE_BUS_MEM_MAP_VALUE(0x38)
++#define _IDE_COMMAND_REG			IDE_BUS_MEM_MAP_VALUE(0x3C)
++#define _IDE_STATUS_REG				IDE_BUS_MEM_MAP_VALUE(0x3C)
++
++
++/*
++ * IDE Control Block Registers
++ */
++#define IDE_DEVICE_CONTROL_REG			IDE_BUS_MEM_MAP_VALUE(0x40)
++#define IDE_ALTERNATE_STATUS_REG		IDE_BUS_MEM_MAP_VALUE(0x40)
++
++
++#define IDE_CD					(0x01)
++#define IDE_IO					(0x02)
++#define IDE_REL					(0x04)
++#define IDE_OVL					(0x02)
++#define IDE_BSY					(0x80)
++#define IDE_DRQ					(0x08)
++#define IDE_SERV				(0x10)
++#define IDE_DMRD				(0x20)
++#define IDE_ERR					(0x01)
++#define IDE_SRST				(0x04)
++
++/*
++ * macro declarations for IDE Controller
++ */
++#define HAL_IDE_DRIVE0_IORDY_SAMPLE_ENABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) |= (0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE0_IORDY_SAMPLE_DISABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE1_IORDY_SAMPLE_ENABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) |= (0x1 << 1); \
++}
++
++#define HAL_IDE_DRIVE1_IORDY_SAMPLE_DISABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_IDE_DRIVE0_UDMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 0); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 2); \
++}
++
++#define HAL_IDE_DRIVE0_UDMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE1_UDMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 1); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_IDE_DRIVE1_UDMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_IDE_DRIVE0_DMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 2); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE0_DMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 2); \
++}
++
++#define HAL_IDE_DRIVE1_DMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 3); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_IDE_TO_USB_FAST_PATH_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 4); \
++}
++
++#define HAL_IDE_TO_USB_FAST_PATH_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 4); \
++}
++
++#define HAL_IDE_DRIVE1_DMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_IDE_DMA_UDMA_START() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1); \
++}
++
++#define HAL_IDE_DMA_UDMA_STOP() \
++{ \
++    (IDE_STATUS_CONTROL_REG) &= ~(0x1); \
++}
++
++#define HAL_IDE_CLEAR_PRD_INTERRUPT_STATUS() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 2); \
++}
++
++#define HAL_IDE_CLEAR_INTRQ_INTERRUPT_STATUS() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 1); \
++}
++
++#define HAL_IDE_HOST_TRANSFER_WRITE_OUT() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 3); \
++}
++
++#define HAL_IDE_HOST_TRANSFER_READ_IN() \
++{ \
++    (IDE_STATUS_CONTROL_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_IDE_MASK_PRD_INTERRUPT() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 6); \
++}
++
++#define HAL_IDE_UNMASK_PRD_INTERRUPT() \
++{ \
++    (IDE_STATUS_CONTROL_REG) &= ~(0x1 << 6); \
++}
++
++#define HAL_IDE_SET_DESCRIPTOR_TABLE_POINTER(dtp) \
++{ \
++    (IDE_BUS_MASTER_DTP_REG) = (dtp); \
++}
++
++#define HAL_IDE_SET_FAST_PATH_ACCESS_WINDOW(fp_access_window) \
++{ \
++    (IDE_FAST_PATH_ACCESS_WINDOW_REG) = (fp_access_window); \
++}
++
++/*
++ * macro declarations for IDE Device
++ */
++#define HAL_IDE_SELECT_DEVICE_0() \
++{ \
++    (_IDE_DEVICE_REG) = 0; \
++}
++
++#define HAL_IDE_SELECT_DEVICE_1() \
++{ \
++    (_IDE_DEVICE_REG) = (0x1 << 4); \
++}
++
++#define HAL_IDE_ENABLE_DEVICE_INTRQ() \
++{ \
++    (IDE_DEVICE_CONTROL_REG) = (0); \
++}
++
++#define HAL_IDE_DISABLE_DEVICE_INTRQ() \
++{ \
++    (IDE_DEVICE_CONTROL_REG) = (0x2); \
++}
++
++
++#endif  // end of #ifndef _STAR_IDE_H_
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_intc.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_intc.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_intc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_intc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,328 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_INTC_H_
++#define	_STAR_INTC_H_
++
++
++//#include <mach/star_sys_memory_map.h>
++#include <mach/star_sys_memory_map.h>
++
++#if defined(__UBOOT__)
++#define	INTC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_VIC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	INTC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_VIC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	INTC_INTERRUPT_RAW_STATUS_REG		INTC_MEM_MAP_VALUE(0x000)
++#define	INTC_EDGE_INTERRUPT_SOURCE_CLEAR_REG	INTC_MEM_MAP_VALUE(0x004)
++#define	INTC_INTERRUPT_MASK_REG			INTC_MEM_MAP_VALUE(0x008)
++#define	INTC_INTERRUPT_MASK_CLEAR_REG		INTC_MEM_MAP_VALUE(0x00C)
++#define	INTC_INTERRUPT_TRIGGER_MODE_REG		INTC_MEM_MAP_VALUE(0x010)
++#define	INTC_INTERRUPT_TRIGGER_LEVEL_REG	INTC_MEM_MAP_VALUE(0x014)
++#define	INTC_FIQ_SELECT_REG			INTC_MEM_MAP_VALUE(0x018)
++#define	INTC_IRQ_STATUS_REG			INTC_MEM_MAP_VALUE(0x01C)
++#define	INTC_FIQ_STATUS_REG			INTC_MEM_MAP_VALUE(0x020)
++#define	INTC_SOFTWARE_INTERRUPT_REG		INTC_MEM_MAP_VALUE(0x024)
++#define	INTC_SOFTWARE_INTERRUPT_CLEAR_REG	INTC_MEM_MAP_VALUE(0x028)
++#define	INTC_SOFTWARE_PRIORITY_MASK_REG		INTC_MEM_MAP_VALUE(0x02C)
++#define	INTC_POWER_MANAGEMENT_INTERRUPT_REG	INTC_MEM_MAP_VALUE(0x034)
++
++#define	INTC_VECTOR_ADDRESS_0_REG		INTC_MEM_MAP_VALUE(0x040)
++#define	INTC_VECTOR_ADDRESS_1_REG		INTC_MEM_MAP_VALUE(0x044)
++#define	INTC_VECTOR_ADDRESS_2_REG		INTC_MEM_MAP_VALUE(0x048)
++#define	INTC_VECTOR_ADDRESS_3_REG		INTC_MEM_MAP_VALUE(0x04C)
++#define	INTC_VECTOR_ADDRESS_4_REG		INTC_MEM_MAP_VALUE(0x050)
++#define	INTC_VECTOR_ADDRESS_5_REG		INTC_MEM_MAP_VALUE(0x054)
++#define	INTC_VECTOR_ADDRESS_6_REG		INTC_MEM_MAP_VALUE(0x058)
++#define	INTC_VECTOR_ADDRESS_7_REG		INTC_MEM_MAP_VALUE(0x05C)
++#define	INTC_VECTOR_ADDRESS_8_REG		INTC_MEM_MAP_VALUE(0x060)
++#define	INTC_VECTOR_ADDRESS_9_REG		INTC_MEM_MAP_VALUE(0x064)
++#define	INTC_VECTOR_ADDRESS_10_REG		INTC_MEM_MAP_VALUE(0x068)
++#define	INTC_VECTOR_ADDRESS_11_REG		INTC_MEM_MAP_VALUE(0x06C)
++#define	INTC_VECTOR_ADDRESS_12_REG		INTC_MEM_MAP_VALUE(0x070)
++#define	INTC_VECTOR_ADDRESS_13_REG		INTC_MEM_MAP_VALUE(0x074)
++#define	INTC_VECTOR_ADDRESS_14_REG		INTC_MEM_MAP_VALUE(0x078)
++#define	INTC_VECTOR_ADDRESS_15_REG		INTC_MEM_MAP_VALUE(0x07C)
++#define	INTC_VECTOR_ADDRESS_16_REG		INTC_MEM_MAP_VALUE(0x080)
++#define	INTC_VECTOR_ADDRESS_17_REG		INTC_MEM_MAP_VALUE(0x084)
++#define	INTC_VECTOR_ADDRESS_18_REG		INTC_MEM_MAP_VALUE(0x088)
++#define	INTC_VECTOR_ADDRESS_19_REG		INTC_MEM_MAP_VALUE(0x08C)
++#define	INTC_VECTOR_ADDRESS_20_REG		INTC_MEM_MAP_VALUE(0x090)
++#define	INTC_VECTOR_ADDRESS_21_REG		INTC_MEM_MAP_VALUE(0x094)
++#define	INTC_VECTOR_ADDRESS_22_REG		INTC_MEM_MAP_VALUE(0x098)
++#define	INTC_VECTOR_ADDRESS_23_REG		INTC_MEM_MAP_VALUE(0x09C)
++#define	INTC_VECTOR_ADDRESS_24_REG		INTC_MEM_MAP_VALUE(0x0A0)
++#define	INTC_VECTOR_ADDRESS_25_REG		INTC_MEM_MAP_VALUE(0x0A4)
++#define	INTC_VECTOR_ADDRESS_26_REG		INTC_MEM_MAP_VALUE(0x0A8)
++#define	INTC_VECTOR_ADDRESS_27_REG		INTC_MEM_MAP_VALUE(0x0AC)
++#define	INTC_VECTOR_ADDRESS_28_REG		INTC_MEM_MAP_VALUE(0x0B0)
++#define	INTC_VECTOR_ADDRESS_29_REG		INTC_MEM_MAP_VALUE(0x0B4)
++#define	INTC_VECTOR_ADDRESS_30_REG		INTC_MEM_MAP_VALUE(0x0B8)
++#define	INTC_VECTOR_ADDRESS_31_REG		INTC_MEM_MAP_VALUE(0x0BC)
++
++#define	INTC_INTERRUPT_PRIORITY_0_REG		INTC_MEM_MAP_VALUE(0x0C0)
++#define	INTC_INTERRUPT_PRIORITY_1_REG		INTC_MEM_MAP_VALUE(0x0C4)
++#define	INTC_INTERRUPT_PRIORITY_2_REG		INTC_MEM_MAP_VALUE(0x0C8)
++#define	INTC_INTERRUPT_PRIORITY_3_REG		INTC_MEM_MAP_VALUE(0x0CC)
++#define	INTC_INTERRUPT_PRIORITY_4_REG		INTC_MEM_MAP_VALUE(0x0D0)
++#define	INTC_INTERRUPT_PRIORITY_5_REG		INTC_MEM_MAP_VALUE(0x0D4)
++#define	INTC_INTERRUPT_PRIORITY_6_REG		INTC_MEM_MAP_VALUE(0x0D8)
++#define	INTC_INTERRUPT_PRIORITY_7_REG		INTC_MEM_MAP_VALUE(0x0DC)
++#define	INTC_INTERRUPT_PRIORITY_8_REG		INTC_MEM_MAP_VALUE(0x0E0)
++#define	INTC_INTERRUPT_PRIORITY_9_REG		INTC_MEM_MAP_VALUE(0x0E4)
++#define	INTC_INTERRUPT_PRIORITY_10_REG		INTC_MEM_MAP_VALUE(0x0E8)
++#define	INTC_INTERRUPT_PRIORITY_11_REG		INTC_MEM_MAP_VALUE(0x0EC)
++#define	INTC_INTERRUPT_PRIORITY_12_REG		INTC_MEM_MAP_VALUE(0x0F0)
++#define	INTC_INTERRUPT_PRIORITY_13_REG		INTC_MEM_MAP_VALUE(0x0F4)
++#define	INTC_INTERRUPT_PRIORITY_14_REG		INTC_MEM_MAP_VALUE(0x0F8)
++#define	INTC_INTERRUPT_PRIORITY_15_REG		INTC_MEM_MAP_VALUE(0x0FC)
++#define	INTC_INTERRUPT_PRIORITY_16_REG		INTC_MEM_MAP_VALUE(0x100)
++#define	INTC_INTERRUPT_PRIORITY_17_REG		INTC_MEM_MAP_VALUE(0x104)
++#define	INTC_INTERRUPT_PRIORITY_18_REG		INTC_MEM_MAP_VALUE(0x108)
++#define	INTC_INTERRUPT_PRIORITY_19_REG		INTC_MEM_MAP_VALUE(0x10C)
++#define	INTC_INTERRUPT_PRIORITY_20_REG		INTC_MEM_MAP_VALUE(0x110)
++#define	INTC_INTERRUPT_PRIORITY_21_REG		INTC_MEM_MAP_VALUE(0x114)
++#define	INTC_INTERRUPT_PRIORITY_22_REG		INTC_MEM_MAP_VALUE(0x118)
++#define	INTC_INTERRUPT_PRIORITY_23_REG		INTC_MEM_MAP_VALUE(0x11C)
++#define	INTC_INTERRUPT_PRIORITY_24_REG		INTC_MEM_MAP_VALUE(0x120)
++#define	INTC_INTERRUPT_PRIORITY_25_REG		INTC_MEM_MAP_VALUE(0x124)
++#define	INTC_INTERRUPT_PRIORITY_26_REG		INTC_MEM_MAP_VALUE(0x128)
++#define	INTC_INTERRUPT_PRIORITY_27_REG		INTC_MEM_MAP_VALUE(0x12C)
++#define	INTC_INTERRUPT_PRIORITY_28_REG		INTC_MEM_MAP_VALUE(0x130)
++#define	INTC_INTERRUPT_PRIORITY_29_REG		INTC_MEM_MAP_VALUE(0x134)
++#define	INTC_INTERRUPT_PRIORITY_30_REG		INTC_MEM_MAP_VALUE(0x138)
++#define	INTC_INTERRUPT_PRIORITY_31_REG		INTC_MEM_MAP_VALUE(0x13C)
++
++#define	INTC_IRQ_VECTOR_ADDRESS_REG		INTC_MEM_MAP_VALUE(0x140)
++
++#define	INTC_VECTOR_INTERRUPT_ENABLE_REG	INTC_MEM_MAP_VALUE(0x144)
++
++
++
++/*
++ * define constants macros
++ */
++#define	INTC_TIMER1_BIT_INDEX			(0)
++#define	INTC_TIMER2_BIT_INDEX			(1)
++
++#define	INTC_CLOCK_SCALE_BIT_INDEX		(2)
++
++#define	INTC_WATCHDOG_TIMER_BIT_INDEX		(3)
++
++#define	INTC_GPIO_EXTERNAL_INT_BIT_INDEX	(4)
++
++#define	INTC_PCI_INTA_BIT_INDEX			(5)
++#define	INTC_PCI_INTB_BIT_INDEX			(6)
++#define	INTC_PCI_BROKEN_BIT_INDEX		(7)
++#define	INTC_PCI_AHB2BRIDGE_BIT_INDEX		(8)
++
++#define	INTC_UART0_BIT_INDEX			(9)
++#define	INTC_UART1_BIT_INDEX			(10)
++
++#define	INTC_GDMAC_TC_BIT_INDEX			(11)
++#define	INTC_GDMAC_ERROR_BIT_INDEX		(12)
++
++#define	INTC_PCMCIA_BRIDGE_BIT_INDEX		(13)
++
++#define	INTC_RTC_BIT_INDEX			(14)
++
++#define	INTC_PCM_BIT_INDEX			(15)
++
++#define	INTC_USB20_DEVICE_BIT_INDEX		(16)
++
++#define	INTC_IDE_BIT_INDEX			(17)
++
++#define	INTC_NIC_STATUS_BIT_INDEX		(18)
++#define	INTC_NIC_TXTC_BIT_INDEX			(19)
++#define	INTC_NIC_RXRC_BIT_INDEX			(20)
++#define	INTC_NIC_TXQE_BIT_INDEX			(21)
++#define	INTC_NIC_RXQF_BIT_INDEX			(22)
++
++#define	INTC_USB11_BIT_INDEX			(23)
++#define	INTC_USB20_BIT_INDEX			(24)
++
++#define	INTC_I2S_BIT_INDEX			(25)
++#define	INTC_SPI_BIT_INDEX			(26)
++#define	INTC_I2C_BIT_INDEX			(27)
++
++#define	INTC_USB_DEVICE_VBUS_BIT_INDEX		(28)
++
++#define	INTC_EXT_INT29_BIT_INDEX		(29)
++#define	INTC_EXT_INT30_BIT_INDEX		(30)
++#define	INTC_HSDMAC_BIT_INDEX			(31)
++
++
++/*
++ * define interrupt types
++ */
++#define	INTC_IRQ_INTERRUPT			(0)
++#define	INTC_FIQ_INTERRUPT			(1)
++
++/*
++ * define interrupt trigger mode
++ */
++#define	INTC_LEVEL_TRIGGER			(0)
++#define	INTC_EDGE_TRIGGER			(1)
++
++/*
++ * define rising/falling edge for edge trigger mode
++ */
++#define	INTC_RISING_EDGE			(0)
++#define	INTC_FALLING_EDGE			(1)
++
++/*
++ * define active High/Low for level trigger mode
++ */
++#define	INTC_ACTIVE_HIGH			(0)
++#define	INTC_ACTIVE_LOW				(1)
++
++/*
++ * macro declarations
++ */
++#define	HAL_INTC_READ_INTERRUPT_RAW_STATUS(int_raw_status) \
++{ \
++    (int_raw_status) = (INTC_INTERRUPT_RAW_STATUS_REG);	\
++}
++
++
++#define	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(source_bit_index)	\
++{ \
++    (INTC_EDGE_INTERRUPT_SOURCE_CLEAR_REG) = (1	<< source_bit_index); \
++}
++
++
++#define	HAL_INTC_READ_INTERRUPT_MASK(int_mask) \
++{ \
++    (int_mask) = (INTC_INTERRUPT_MASK_REG); \
++}
++
++
++#define	HAL_INTC_WRITE_INTERRUPT_MASK(int_mask)	\
++{ \
++    (INTC_INTERRUPT_MASK_REG) =	(int_mask); \
++}
++
++
++#define	HAL_INTC_DISABLE_INTERRUPT_SOURCE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_MASK_REG) =	(1 << source_bit_index); \
++}
++
++
++#define	HAL_INTC_ENABLE_INTERRUPT_SOURCE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_MASK_CLEAR_REG) = (1 << source_bit_index); \
++}
++
++
++#define	HAL_INTC_SET_EDGE_TRIGGER_MODE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_MODE_REG) |= (1 << source_bit_index);\
++}
++
++
++#define	HAL_INTC_SET_LEVEL_TRIGGER_MODE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_MODE_REG) &= (~(1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_SET_RISING_EDGE_TRIGGER_LEVEL(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) &= (~(1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_SET_FALLING_EDGE_TRIGGER_LEVEL(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) |= (1 <<	source_bit_index); \
++}
++
++
++#define	HAL_INTC_SET_ACTIVE_HIGH_TRIGGER_LEVEL(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) &= (~(1 << source_bit_index));\
++}
++
++
++#define	HAL_INTC_SET_ACTIVE_LOW_TRIGGER_LEVEL(source_bit_index)	\
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) |= ((1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_ASSIGN_INTERRUPT_TO_IRQ(source_bit_index) \
++{ \
++    (INTC_FIQ_SELECT_REG) &= (~(1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_ASSIGN_INTERRUPT_TO_FIQ(source_bit_index) \
++{ \
++    (INTC_FIQ_SELECT_REG) |= (1	<< source_bit_index); \
++}
++
++
++#define	HAL_INTC_READ_IRQ_STATUS(int_irq_status) \
++{ \
++    (int_irq_status) = (INTC_IRQ_STATUS_REG); \
++}
++
++
++#define	HAL_INTC_READ_FIQ_STATUS(int_fiq_status) \
++{ \
++    (int_fiq_status) = (INTC_FIQ_STATUS_REG); \
++}
++
++
++#define	HAL_INTC_READ_SOFTWARE_INTERRUPT(software_interrupt) \
++{ \
++    (software_interrupt) = (INTC_SOFTWARE_INTERRUPT_REG); \
++}
++
++
++#define	HAL_INTC_ENABLE_SOFTWARE_INTERRUPT(source_bit_index) \
++{ \
++    (INTC_SOFTWARE_INTERRUPT_REG) = (1 << source_bit_index); \
++}
++
++
++#define	HAL_INTC_CLEAR_SOFTWARE_INTERRUPT(source_bit_index) \
++{ \
++    (INTC_SOFTWARE_INTERRUPT_CLEAR_REG)	= (1 <<	source_bit_index); \
++}
++
++
++#define	HAL_INTC_SELECT_INTERRUPT_SOURCE_FOR_SLEEP_WAKEUP(source_bit_index) \
++{ \
++    (INTC_POWER_MANAGEMENT_INTERRUPT_REG) = (1 << source_bit_index); \
++}
++
++#endif	// end of #ifndef _STAR_INTC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_misc.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_misc.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_misc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_misc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,402 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_MISC_H_
++#define	_STAR_MISC_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	MISC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_MISC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	MISC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_MISC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	MISC_MEMORY_REMAP_REG				MISC_MEM_MAP_VALUE(0x00)
++#define	MISC_CHIP_CONFIG_REG				MISC_MEM_MAP_VALUE(0x04)
++#define	MISC_DEBUG_PROBE_DATA_REG			MISC_MEM_MAP_VALUE(0x08)
++#define	MISC_DEBUG_PROBE_SELECTION_REG			MISC_MEM_MAP_VALUE(0x0C)
++#define	MISC_PCI_CONTROL_BROKEN_MASK_REG		MISC_MEM_MAP_VALUE(0x10)
++#define	MISC_PCI_BROKEN_STATUS_REG			MISC_MEM_MAP_VALUE(0x14)
++#define	MISC_PCI_DEVICE_VENDOR_ID_REG			MISC_MEM_MAP_VALUE(0x18)
++#define	MISC_USB_HOST_PHY_CONTROL_TEST_REG		MISC_MEM_MAP_VALUE(0x1C)
++#define	MISC_GPIOA_PIN_ENABLE_REG			MISC_MEM_MAP_VALUE(0x20)
++#define	MISC_GPIOB_PIN_ENABLE_REG			MISC_MEM_MAP_VALUE(0x24)
++#define	MISC_GPIOA_RESISTOR_CONFIG_REG			MISC_MEM_MAP_VALUE(0x28)
++#define	MISC_GPIOA_DRIVE_STRENGTH_CONFIG_REG		MISC_MEM_MAP_VALUE(0x2C)
++#define	MISC_FAST_ETHERNET_PHY_CONFIG_REG		MISC_MEM_MAP_VALUE(0x30)
++#define	MISC_SOFTWARE_TEST_1_REG			MISC_MEM_MAP_VALUE(0x38)
++#define	MISC_SOFTWARE_TEST_2_REG			MISC_MEM_MAP_VALUE(0x3C)
++
++#define	MISC_E_FUSE_0_REG				MISC_MEM_MAP_VALUE(0x60)
++#define	MISC_E_FUSE_1_REG				MISC_MEM_MAP_VALUE(0x64)
++
++
++/*
++ * define constants macros
++ */
++#define	MISC_PARALLEL_FLASH_BOOT		(0)
++#define	MISC_SPI_SERIAL_FLASH_BOOT		(1)
++
++#define	MISC_LITTLE_ENDIAN			(0)
++#define	MISC_BIG_ENDIAN				(1)
++
++#define	MISC_FARADAY_ICE			(0)
++#define	MISC_ARM_ICE				(1)
++
++#define	MISC_EXT_INT29_PINS			((0x1 << 0))
++#define	MISC_EXT_INT30_PINS			((0x1 << 1))
++#define	MISC_EXT_INT31_PINS			((0x1 << 2))
++#define	MISC_I2C_PINS				((0x1 << 13) | (0x1 << 14))
++#define	MISC_I2S_PINS				((0x1 << 15) | (0x1 << 16) | (0x1 << 17))
++#define	MISC_PCM_PINS				((0x1 << 18) | (0x1 << 19) | (0x1 << 20) | (0x1 << 21))
++#define	MISC_LED0_PINS				((0x1 << 22))
++#define	MISC_LED1_PINS				((0x1 << 23))
++#define	MISC_LED2_PINS				((0x1 << 24))
++#define	MISC_LED012_PINS			((0x1 << 22) | (0x1 << 23) | (0x1 << 24))
++#define	MISC_WDTIMER_RESET_PINS			((0x1 << 25))
++#define	MISC_SPI_PINS				((0x1 << 26) | (0x1 << 27) | (0x1 << 28) | (0x1 << 29) | (0x1 << 30) | (0x1 << 31))
++#define	MISC_MDC_MDIO_PINS			((0x1 << 0) | (0x1 << 1))
++#define	MISC_NIC_COL_PINS			((0x1 << 2))
++#define	MISC_IDE_PINS				((0xFF << 3))
++#define	MISC_SRAM_BANK1_PINS			((0x1 << 11) | (0x1 << 14))
++#define	MISC_SRAM_BANK2_PINS			((0x1 << 12) | (0x1 << 15))
++#define	MISC_SRAM_BANK3_PINS			((0x1 << 13) | (0x1 << 16))
++#define	MISC_PCMCIA_PINS			((0x1 << 17) | (0x1 << 18) | (0x1 << 19) | (0x1 << 20))
++#define	MISC_UART1_PINS				((0x1 << 21) | (0x1 << 22))
++#define	MISC_PCI_PINS				(((u32)0x1FF << 23))
++
++#define	MISC_UART0_ACT0_Pin			(0x1 << 2)
++#define	MISC_UART1_ACT1_Pin			(0x1 << 3)
++
++#define	MISC_GPIOA_PIN_0			(0)
++#define	MISC_GPIOA_PIN_1			(1)
++#define	MISC_GPIOA_PIN_2			(2)
++#define	MISC_GPIOA_PIN_3			(3)
++#define	MISC_GPIOA_PIN_4			(4)
++#define	MISC_GPIOA_PIN_5			(5)
++#define	MISC_GPIOA_PIN_6			(6)
++#define	MISC_GPIOA_PIN_7			(7)
++#define	MISC_GPIOA_PIN_8			(8)
++#define	MISC_GPIOA_PIN_9			(9)
++#define	MISC_GPIOA_PIN_10			(10)
++
++#define	MISC_GPIOA_75K_RESISTOR_PULL_DOWN	(1)
++#define	MISC_GPIOA_75K_RESISTOR_PULL_UP		(2)
++#define	MISC_GPIOA_75K_RESISTOR_PULL_KEEPER	(3)
++
++#define	MISC_GPIOA_DRIVE_STRENGTH_4MA		(0)
++#define	MISC_GPIOA_DRIVE_STRENGTH_8MA		(1)
++
++
++/*
++ * macro declarations
++ */
++#define	HAL_MISC_ENABLE_SPI_SERIAL_FLASH_BANK_ACCESS() \
++{ \
++    (MISC_CHIP_CONFIG_REG) |= (0x1 << 4); \
++}
++
++#define	HAL_MISC_DISABLE_SPI_SERIAL_FLASH_BANK_ACCESS()	\
++{ \
++    (MISC_CHIP_CONFIG_REG) &= ~(0x1 << 4); \
++}
++
++
++/*
++ * Macro defines for GPIOA and GPIOB Pin Enable	Register
++ */
++#define	HAL_MISC_ENABLE_EXT_INT29_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_EXT_INT29_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_EXT_INT29_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_EXT_INT29_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_EXT_INT30_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_EXT_INT30_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_EXT_INT30_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_EXT_INT30_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_I2C_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_I2C_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_I2C_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_I2C_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_I2S_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_I2S_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_I2S_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_I2S_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_PCM_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_PCM_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_PCM_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_PCM_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED0_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED0_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED0_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED0_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED1_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED1_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED1_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED1_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED2_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED2_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED2_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED2_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED012_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED012_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED012_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED012_PINS);	\
++}
++
++#define	HAL_MISC_ENABLE_WDTIMER_RESET_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_WDTIMER_RESET_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_WDTIMER_RESET_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_WDTIMER_RESET_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SPI_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_SPI_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SPI_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_SPI_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_UART0_ACT0_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_UART0_ACT0_Pin); \
++}
++
++#define	HAL_MISC_DISABLE_UART0_ACT0_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_UART0_ACT0_Pin); \
++}
++
++#define	HAL_MISC_ENABLE_UART1_ACT1_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_UART1_ACT1_Pin); \
++}
++
++#define	HAL_MISC_DISABLE_UART1_ACT1_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_UART1_ACT1_Pin); \
++}
++
++#define	HAL_MISC_ENABLE_MDC_MDIO_PINS()	\
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_MDC_MDIO_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_MDC_MDIO_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_MDC_MDIO_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_NIC_COL_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_NIC_COL_PINS);	\
++}
++
++#define	HAL_MISC_DISABLE_NIC_COL_PINS()	\
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_NIC_COL_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_IDE_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_IDE_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_IDE_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_IDE_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SRAM_BANK1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_SRAM_BANK1_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SRAM_BANK1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_SRAM_BANK1_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SRAM_BANK2_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_SRAM_BANK2_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SRAM_BANK2_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_SRAM_BANK2_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SRAM_BANK3_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_SRAM_BANK3_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SRAM_BANK3_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_SRAM_BANK3_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_PCMCIA_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_PCMCIA_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_PCMCIA_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_PCMCIA_PINS);	\
++}
++
++#define	HAL_MISC_ENABLE_UART1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_UART1_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_UART1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_UART1_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_PCI_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_PCI_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_PCI_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_PCI_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_ALL_SHARED_GPIO_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	= (0x0); \
++    (MISC_GPIOB_PIN_ENABLE_REG)	= (0x0); \
++}
++
++#define	HAL_MISC_DISABLE_ALL_SHARED_GPIO_PINS()	\
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	= (0xFFFFFFFF);	\
++    (MISC_GPIOB_PIN_ENABLE_REG)	= (0xFFFFFFFF);	\
++}
++
++#define	HAL_MISC_CONFIGURE_GPIOA_RESISTOR(pin_index, value) \
++{ \
++    (MISC_GPIOA_RESISTOR_CONFIG_REG) &=	~(0x3 << (2 * pin_index)); \
++    (MISC_GPIOA_RESISTOR_CONFIG_REG) |=	((value	& 0x3) << (2 * pin_index)); \
++}
++
++#define	HAL_MISC_CONFIGURE_GPIOA_DRIVE_STRENGTH(pin_index, value) \
++{ \
++    (MISC_GPIOA_DRIVE_STRENGTH_CONFIG_REG) &= ~(0x1 << pin_index); \
++    (MISC_GPIOA_DRIVE_STRENGTH_CONFIG_REG) |= (value <<	pin_index); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE0() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x0); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE1() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x1); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE2() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x2); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE3() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x3); \
++}
++
++
++#endif	// end of #ifndef _STAR_MISC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_nic.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_nic.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_nic.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_nic.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,346 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_NIC_H_
++#define	_STAR_NIC_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	NIC_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSPA_NIC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	NIC_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSVA_NIC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	NIC_PHY_CONTROL_REG0			NIC_MEM_MAP_VALUE(0x000)
++#define	NIC_PHY_CONTROL_REG1			NIC_MEM_MAP_VALUE(0x004)
++
++#define	NIC_MAC_CONTROL_REG			NIC_MEM_MAP_VALUE(0x008)
++#define	NIC_FLOW_CONTROL_CONFIG_REG		NIC_MEM_MAP_VALUE(0x00C)
++
++#define	NIC_ARL_CONFIG_REG			NIC_MEM_MAP_VALUE(0x010)
++
++#define	NIC_MY_MAC_HIGH_BYTE_REG		NIC_MEM_MAP_VALUE(0x014)
++#define	NIC_MY_MAC_LOW_BYTE_REG			NIC_MEM_MAP_VALUE(0x018)
++
++#define	NIC_HASH_TABLE_CONTROL_REG		NIC_MEM_MAP_VALUE(0x01C)
++
++#define	NIC_MY_VLANID_CONTROL_REG		NIC_MEM_MAP_VALUE(0x020)
++
++#define	NIC_MY_VLANID_0_1			NIC_MEM_MAP_VALUE(0x024)
++#define	NIC_MY_VLANID_2_3			NIC_MEM_MAP_VALUE(0x028)
++
++#define	NIC_DMA_CONFIG_REG			NIC_MEM_MAP_VALUE(0x030)
++#define	NIC_TX_DMA_CONTROL_REG			NIC_MEM_MAP_VALUE(0x034)
++#define	NIC_RX_DMA_CONTROL_REG			NIC_MEM_MAP_VALUE(0x038)
++#define	NIC_TX_DESC_PTR_REG			NIC_MEM_MAP_VALUE(0x03C)
++#define	NIC_RX_DESC_PTR_REG			NIC_MEM_MAP_VALUE(0x040)
++
++#define	NIC_TX_DESC_BASE_ADDR_REG		NIC_MEM_MAP_VALUE(0x044)
++#define	NIC_RX_DESC_BASE_ADDR_REG		NIC_MEM_MAP_VALUE(0x048)
++#define	NIC_DELAYED_INT_CONFIG_REG		NIC_MEM_MAP_VALUE(0x04C)
++
++#define	NIC_INT_STATUS_REG			NIC_MEM_MAP_VALUE(0x050)
++#define	NIC_INT_MASK_REG			NIC_MEM_MAP_VALUE(0x054)
++
++#define	NIC_TEST_0_REG				NIC_MEM_MAP_VALUE(0x058)
++#define	NIC_TEST_1_REG				NIC_MEM_MAP_VALUE(0x05C)
++
++#define	NIC_MIB_RX_OK_PKT_CNTR			NIC_MEM_MAP_VALUE(0x100)
++#define	NIC_MIB_RX_OK_BYTE_CNTR			NIC_MEM_MAP_VALUE(0x104)
++#define	NIC_MIB_RX_RUNT_BYTE_CNTR		NIC_MEM_MAP_VALUE(0x108)
++#define	NIC_MIB_RX_OSIZE_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x10C)
++
++#define	NIC_MIB_RX_NO_BUF_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x110)
++
++#define	NIC_MIB_RX_CRC_ERR_PKT_CNTR		NIC_MEM_MAP_VALUE(0x114)
++
++#define	NIC_MIB_RX_ARL_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x118)
++
++#define	NIC_MIB_MYVLANID_MISMATCH_DROP_PKT_CNTR	NIC_MEM_MAP_VALUE(0x11C)
++
++#define	NIC_MIB_RX_CHKSUM_ERR_PKT_CNTR		NIC_MEM_MAP_VALUE(0x120)
++
++#define	NIC_MIB_RX_PAUSE_FRAME_PKT_CNTR		NIC_MEM_MAP_VALUE(0x124)
++
++#define	NIC_MIB_TX_OK_PKT_CNTR			NIC_MEM_MAP_VALUE(0x128)
++#define	NIC_MIB_TX_OK_BYTE_CNTR			NIC_MEM_MAP_VALUE(0x12C)
++
++#define	NIC_MIB_TX_COLLISION_CNTR		NIC_MEM_MAP_VALUE(0x130)
++#define	NIC_MIB_TX_PAUSE_FRAME_CNTR		NIC_MEM_MAP_VALUE(0x130)
++
++#define	NIC_MIB_TX_FIFO_UNDERRUN_RETX_CNTR	NIC_MEM_MAP_VALUE(0x134)
++
++
++
++
++/*
++ * define constants macros
++ */
++
++#define	NIC_PHY_ADDRESS		1 //the phy addr const	value
++#define	NIC_PHY_ID		0x0243	//the phy id
++
++#define	GW_NIC_MAX_TFD_NUM	(32)
++#define	GW_NIC_MAX_RFD_NUM	(32)
++#define	MAX_BUFFERS		(64)
++
++
++
++#define	MMU_OFF			(0)
++#define	MMU_ON			(1)
++#define	OS_NULL			(0)
++
++
++#define	NET_BUFFER_PACKET_SIZE		(512)
++#define	NET_BUFFER_SHIFT_BIT_NUM	(9)	// 2*n9=512
++
++#define	MAX_PACKET_LEN		(1536)
++
++#define	INTERNAL_LOOPBACK_MODE	(1)
++#define	SOFTWARE_REPEATER_MODE	(2)
++
++#define	TXTC_INT_BIT		(0x08000000)
++#define	TX_INSV_BIT		(0x04000000)
++
++#define	LS_BIT			(0x10000000)
++#define	FS_BIT			(0x20000000)
++#define	EOR_BIT			(0x40000000)
++#define	FS_LS_BIT		(0x30000000)
++#define	C_BIT			(0x80000000)
++#define	FS_LS_C_BIT		(0xB0000000)
++#define	FS_LS_INT_BIT		(0x38000000)
++
++
++
++// HASH	TABLE CONTROL REGISTER
++#define	NIC_HASH_TABLE_BIST_DONE_BIT	(0x1 <<	17)
++#define	NIC_HASH_TABLE_BIST_OK_BIT	(0x1 <<	16)
++#define	NIC_HASH_COMMAND_START_BIT	(0x1 <<	14)
++#define	NIC_HASH_COMMAND_BIT		(0x1 <<	13)
++#define	NIC_HASH_BIT_DATA		(0x1 <<	12)
++#define	NIC_HASH_BIT_ADDRESS_BIT	(0x1ff)
++
++
++#define	NIC_REG_CNT			((0x48 << 2) + 1)
++
++/*
++ * macro access
++ */
++
++#define	GW_NIC_TX_TFD_NEXT(work_tfd_ptr) \
++    work_tfd_ptr = NIC_TX_TFD_Ring.head	+ (((u32)(work_tfd_ptr - NIC_TX_TFD_Ring.head) + 1) % GW_NIC_MAX_TFD_NUM)
++
++
++#define	GW_NIC_TX_TFD_PREVIOUS(work_tfd_ptr) \
++    work_tfd_ptr = NIC_TX_TFD_Ring.head	+ ((GW_NIC_MAX_TFD_NUM + (u32)(work_tfd_ptr - NIC_TX_TFD_Ring.head) - 1) % GW_NIC_MAX_TFD_NUM)
++
++
++#define	GW_NIC_RX_RFD_NEXT(work_rfd_ptr) \
++    work_rfd_ptr = NIC_RX_RFD_Ring.head	+ (((u32)(work_rfd_ptr - NIC_RX_RFD_Ring.head) + 1) % GW_NIC_MAX_RFD_NUM)
++
++
++#define	GW_NIC_RX_RFD_PREVIOUS(work_rfd_ptr) \
++    work_rfd_ptr = NIC_RX_RFD_Ring.head	+ ((GW_NIC_MAX_RFD_NUM + (u32)(work_rfd_ptr - NIC_RX_RFD_Ring.head) - 1) % GW_NIC_MAX_RFD_NUM)
++
++
++/*
++ * PHY register	defines
++ */
++#define	PHY_MII_CONTROL_REG_ADDR		0x00
++#define	PHY_MII_STATUS_REG_ADDR			0x01
++#define	PHY_ID1_REG_ADDR			0x02
++#define	PHY_ID2_REG_ADDR			0x03
++#define	PHY_AN_ADVERTISEMENT_REG_ADDR		0x04
++#define	PHY_AN_REAMOTE_CAP_REG_ADDR		0x05
++
++
++#define	PHY_RESERVED1_REG_ADDR			0x10
++#define	PHY_RESERVED2_REG_ADDR			0x11
++#define	PHY_CH_STATUS_OUTPUT_REG_ADDR		0x12
++#define	PHY_RESERVED3_REG_ADDR			0x13
++#define	PHY_RESERVED4_REG_ADDR			0x14
++
++
++#define	PHY_SPEC_CONTROL_REG_ADDR		0x16
++#define	PHY_INTC_CONTROL_STATUS_REG_ADDR	0x17
++
++/*
++ * NIC registers access	macros defines
++ */
++
++//0x004
++#define	HAL_NIC_WRITE_PHY_CONTROL1(config_value) \
++    ((NIC_PHY_CONTROL_REG1) = (config_value))
++
++#define	HAL_NIC_READ_PHY_CONTROL1(config_value)	\
++    ((config_value) = (NIC_PHY_CONTROL_REG1))
++
++//0x008
++#define	HAL_NIC_WRITE_MAC_CONFIGURATION(config_value) \
++    ((NIC_MAC_CONTROL_REG) = (config_value))
++
++#define	HAL_NIC_READ_MAC_CONFIGURATION(config_value) \
++    ((config_value) = (NIC_MAC_CONTROL_REG))
++
++//0x00C
++#define	HAL_NIC_WRITE_FLOW_CONTROL_CONFIG(fc_cfg) \
++    ((NIC_FLOW_CONTROL_CONFIG_REG) = (fc_cfg))
++
++#define	HAL_NIC_READ_FLOW_CONTROL_CONFIG(fc_cfg) \
++    ((fc_cfg) =	(NIC_FLOW_CONTROL_CONFIG_REG))
++
++//0x010
++#define	HAL_NIC_WRITE_ARL_CONFIGURATION(cfg) \
++    ((NIC_ARL_CONFIG_REG) = (cfg))
++
++#define	HAL_NIC_READ_ARL_CONFIGURATION(cfg) \
++    ((cfg) = (NIC_ARL_CONFIG_REG))
++
++//0x014,
++#define	HAL_NIC_WRITE_MY_MAC_HIGH_BYTE(cfg) \
++    ((NIC_MY_MAC_HIGH_BYTE_REG)	= (cfg & 0x0000FFFF ) )
++
++#define	HAL_NIC_READ_MY_MAC_HIGH_BYTE(cfg) \
++    ((cfg) = (NIC_MY_MAC_HIGH_BYTE_REG & 0x0000FFFF ))
++
++//0x018
++#define	HAL_NIC_WRITE_MY_MAC_LOW_BYTE(cfg) \
++    ((NIC_MY_MAC_LOW_BYTE_REG) = (cfg))
++
++#define	HAL_NIC_READ_MY_MAC_LOW_BYTE(cfg) \
++    ((cfg) = (NIC_MY_MAC_LOW_BYTE_REG))
++
++//0x03C
++#define	HAL_NIC_READ_INTERRUPT_STATUS(int_status) \
++    ((int_status) = (NIC_INT_STATUS_REG))
++
++#define	HAL_NIC_CLEAR_ALL_INTERRUPT_STATUS_SOURCES()\
++    ((NIC_INT_STATUS_REG) = (0xFFFFFFFF))
++
++#define	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCES(source) \
++    ((NIC_INT_STATUS_REG) |= (source))
++
++#define	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_STATUS_REG) |= (1	<< (source_bit_index)))
++
++//0x040
++#define	HAL_NIC_DISABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++    ((NIC_INT_MASK_REG)	= (0xFFFFFFFF))
++
++#define	HAL_NIC_ENABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++    ((NIC_INT_MASK_REG)	= (0x00000000))
++
++#define	HAL_NIC_DISABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_MASK_REG)	|= (1 << (source_bit_index)))
++
++#define	HAL_NIC_ENABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_MASK_REG)	&= ~(1 << (source_bit_index)))
++
++//0x44
++#define	HAL_NIC_WRITE_TEST0_REG(cfg) \
++    ((NIC_TEST_0_REG) =	(cfg))
++
++#define	HAL_NIC_READ_TEST0_REG(cfg) \
++    ((cfg) = (NIC_TEST_0_REG))
++
++//0x48
++#define	HAL_NIC_WRITE_TEST1_REG(cfg) \
++    ((NIC_TEST_1_REG) =	(cfg))
++
++#define	HAL_NIC_READ_TEST1_REG(cfg) \
++    ((cfg) = (NIC_TEST_1_REG))
++
++
++
++/*
++ * NIC's DMA macros defines
++ */
++#define	HAL_NIC_TX_DMA_START() \
++    ((NIC_TX_DMA_CONTROL_REG) =	(1))
++
++
++#define	HAL_NIC_TX_DMA_STOP() \
++    ((NIC_TX_DMA_CONTROL_REG) =	(0))
++
++
++#define	HAL_NIC_READ_TX_DMA_STATE(state) \
++    ((state) = (NIC_TX_DMA_CONTROL_REG))
++
++
++#define	HAL_NIC_RX_DMA_START() \
++    ((NIC_RX_DMA_CONTROL_REG) =	(1))
++
++
++#define	HAL_NIC_RX_DMA_STOP() \
++    ((NIC_RX_DMA_CONTROL_REG) =	(0))
++
++
++#define	HAL_NIC_WRITE_TXSD(tssd_value) \
++    ((NIC_TX_DESC_PTR_REG) = (tssd_value))
++
++
++#define	HAL_NIC_READ_TXSD(tssd_value) \
++    ((tssd_value) = (NIC_TX_DESC_PTR_REG))
++
++
++#define	HAL_NIC_WRITE_RXSD(fssd_value) \
++    ((NIC_RX_DESC_PTR_REG) = (fssd_value))
++
++
++#define	HAL_NIC_READ_RXSD(fssd_value) \
++    ((fssd_value) = (NIC_RX_DESC_PTR_REG))
++
++
++#define	HAL_NIC_WRITE_TX_BASE(ts_base_value) \
++    ((NIC_TX_DESC_BASE_ADDR_REG) = (ts_base_value))
++
++
++#define	HAL_NIC_READ_TX_BASE(ts_base_value) \
++    ((ts_base_value) = (NIC_TX_DESC_BASE_ADDR_REG))
++
++
++#define	HAL_NIC_WRITE_RX_BASE(fs_base_value) \
++    ((NIC_RX_DESC_BASE_ADDR_REG) = (fs_base_value))
++
++
++#define	HAL_NIC_READ_RX_BASE(fs_base_value) \
++    ((fs_base_value) = (NIC_RX_DESC_BASE_ADDR_REG))
++
++
++#define	HAL_NIC_WRITE_DELAYED_INTERRUPT_CONFIG(delayed_interrupt_config) \
++    ((NIC_DELAYED_INT_CONFIG_REG) = (delayed_interrupt_config))
++
++
++#define	HAL_NIC_READ_DELAYED_INTERRUPT_CONFIG(delayed_interrupt_config)	\
++    ((delayed_interrupt_config)	= (NIC_DELAYED_INT_CONFIG_REG))
++
++#endif	// end of #ifndef _STAR_NIC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pci_bridge.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pci_bridge.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pci_bridge.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pci_bridge.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,132 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_PCI_DRIDGE_H_
++#define	_STAR_PCI_DRIDGE_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#define	PCI_IO_SPACE_BASE_ADDR			(SYSPA_PCI_IO_SPACE_BASE_ADDR)
++#define PCI_IO_SPACE_SIZE			0x08000000 /* 64MB */
++#define PCI_IO_SPACE_START			PCI_IO_SPACE_BASE_ADDR
++#define PCI_IO_SPACE_END			(PCI_IO_SPACE_BASE_ADDR + PCI_IO_SPACE_SIZE - 1)
++#define	PCI_MEMORY_SPACE_BASE_ADDR		(SYSPA_PCI_MEMORY_SPACE_BASE_ADDR)
++#define PCI_MEMORY_SPACE_SIZE			0x10000000 /* 256MB */
++#define PCI_NPREFETCH_MEMORY_SPACE_START	PCI_MEMORY_SPACE_BASE_ADDR
++#define PCI_NPREFETCH_MEMORY_SPACE_SIZE		0x00800000 /* 8MB */
++#define PCI_NPREFETCH_MEMORY_SPACE_END		(PCI_NPREFETCH_MEMORY_SPACE_START + PCI_NPREFETCH_MEMORY_SPACE_SIZE - 1)
++#define PCI_PREFETCH_MEMORY_SPACE_START		(PCI_NPREFETCH_MEMORY_SPACE_START + PCI_NPREFETCH_MEMORY_SPACE_SIZE)
++#define PCI_PREFETCH_MEMORY_SPACE_SIZE		0x00800000 /* 8MB */
++#define PCI_PREFETCH_MEMORY_SPACE_END		(PCI_PREFETCH_MEMORY_SPACE_START + PCI_PREFETCH_MEMORY_SPACE_SIZE - 1)
++
++
++#if defined(__UBOOT__)
++#define	PCIB_MEM_MAP_VALUE(base, reg_offset)	(*((u32 volatile *)(SYSPA_PCI_##base##_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	PCIB_MEM_MAP_VALUE(base, reg_offset)	(*((u32 volatile *)(SYSVA_PCI_##base##_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	PCI_BRIDGE_CONFIG_DATA			PCIB_MEM_MAP_VALUE(CONFIG_DATA_BASE, 0x2C)
++#define	PCI_BRIDGE_CONFIG_ADDR			PCIB_MEM_MAP_VALUE(CONFIG_ADDR_BASE, 0x28)
++
++#define PCI_BRIDGE_CONFIG_DATA_REG_OFFSET	0x2C
++#define PCI_BRIDGE_CONFIG_ADDR_REG_OFFSET	0x28
++
++/*
++ * define constants macros
++ */
++#define	PCIB_BUS_CLOCK_33M			1
++
++#define	PCIB_BUS_CLOCK_66M			2
++
++#define	PCIB_DEVICE_ID				0x8131
++
++#define	PCIB_VENDOR_ID				0xEEEE
++
++#define	PCIB_CLASS_CODE				0xFF0000
++
++#define	PCIB_REVISION_ID			0x00
++
++#define	PCIB_BAR0_MEMORY_SPACE_BASE		0x20000000
++
++#define	PCIB_BAR1_IO_SPACE_BASE			0x20000000
++
++
++#define	PCI_MEMORY_SPACE_BASE			0xB0000000
++
++#define	PCI_IO_SPACE_BASE			0xA8000000
++
++
++#define	PCI_MAX_BUS_NUM				0x01
++#define	PCI_MAX_DEVICE_NUM			0x14
++#define	PCI_MAX_FUNCTION_NUM			0x01
++#define	PCI_MAX_REG_NUM				0x3C
++
++
++#define	PCI_MAX_DEVICE_TYPE_NUM			0x13
++#define	PCI_MAX_BAR_NUM				0x06
++
++
++#define	PCI_CSH_VENDOR_ID_REG_ADDR		0x00
++#define	PCI_CSH_DEVICE_ID_REG_ADDR		0x02
++#define	PCI_CSH_COMMAND_REG_ADDR		0x04
++#define	PCI_CSH_STATUS_REG_ADDR			0x06
++#define	PCI_CSH_REVISION_CLASS_REG_ADDR		0x08
++#define	PCI_CSH_CACHE_LINE_SIZE_REG_ADDR	0x0C
++#define	PCI_CSH_LATENCY_TIMER_REG_ADDR		0x0D
++#define	PCI_CSH_HEADER_TYPE_REG_ADDR		0x0E
++#define	PCI_CSH_BIST_REG_ADDR			0x0F
++#define	PCI_CSH_BAR_REG_ADDR			0x10
++
++
++#define	PCI_IO_SPACE_SIZE_1M			0x00
++#define	PCI_IO_SPACE_SIZE_2M			0x01
++#define	PCI_IO_SPACE_SIZE_4M			0x02
++#define	PCI_IO_SPACE_SIZE_8M			0x03
++#define	PCI_IO_SPACE_SIZE_16M			0x04
++#define	PCI_IO_SPACE_SIZE_32M			0x05
++#define	PCI_IO_SPACE_SIZE_64M			0x06
++#define	PCI_IO_SPACE_SIZE_128M			0x07
++#define	PCI_IO_SPACE_SIZE_256M			0x08
++#define	PCI_IO_SPACE_SIZE_512M			0x09
++#define	PCI_IO_SPACE_SIZE_1G			0x0A
++#define	PCI_IO_SPACE_SIZE_2G			0x0B
++
++
++#define	PCI_MEMORY_SPACE_TYPE			0
++#define	PCI_IO_SPACE_TYPE			1
++
++#define	PCI_BROKEN_FLAG				1
++#define	PCI_AHB2PCIB_FLAG			2
++
++
++#endif	// end of #ifndef _STAR_PCI_DRIDGE_H_
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pcmcia_bridge.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pcmcia_bridge.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pcmcia_bridge.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pcmcia_bridge.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,231 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_PCMCIA_DRIDGE_H_
++#define	_STAR_PCMCIA_DRIDGE_H_
++
++/******************************************************************************
++ * MODULE NAME:	   star_pcmcia_bridge.h
++ * PROJECT CODE:   Equuleus
++ * DESCRIPTION:
++ * MAINTAINER:	   Eric	Yang
++ * DATE:	   15 September	2005
++ *
++ * SOURCE CONTROL:
++ *
++ * LICENSE:
++ *     This source code	is copyright (c) 2005 Star Semi	Inc.
++ *     All rights reserved.
++ *
++ * REVISION HISTORY:
++ *     15 September 2005  -  Eric Yang	- Initial Version v1.0
++ *
++ *
++ * SOURCE:
++ * ISSUES:
++ * NOTES TO USERS:
++ ******************************************************************************/
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	PCMCIA_BRIDGE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_PCMCIA_CONTROL_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	PCMCIA_BRIDGE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_PCMCIA_CONTROL_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	PCMCIA_CONFIGURATION_REG			PCMCIA_BRIDGE_MEM_MAP_VALUE(0x20)
++#define	PCMCIA_MEMORY_ACCESS_TIMING_PARAM_REG		PCMCIA_BRIDGE_MEM_MAP_VALUE(0x24)
++#define	PCMCIA_IO_ACCESS_TIMING_PARAM_REG		PCMCIA_BRIDGE_MEM_MAP_VALUE(0x28)
++
++
++#define	PCMCIA_ATTRIBUTE_MEMORY_SPACE_BASE_ADDR		(SYSPA_PCMCIA_ATTRIBUTE_MEMORY_BASE_ADDR)
++#define	PCMCIA_COMMOM_MEMORY_SPACE_BASE_ADDR		(SYSPA_PCMCIA_COMMON_MEMORY_BASE_ADDR)
++#define	PCMCIA_IO_SPACE_BASE_ADDR			(SYSPA_PCMCIA_IO_SPACE_BASE_ADDR)
++
++
++
++/*
++ * define constants macros
++ */
++#define	PCMCIA_DATA_BUS_WIDTH_8		(0)
++
++#define	PCMCIA_DATA_BUS_WIDTH_16	(1)
++
++
++/*
++ * Flags for PCMCIA_STATUS
++ */
++#define	FLAG_STATUS_BVD1		0x01
++#define	FLAG_STATUS_STSCHG		0x01
++#define	FLAG_STATUS_BVD2		0x02
++#define	FLAG_STATUS_SPKR		0x02
++#define	FLAG_STATUS_DETECT		0xf3	  /* bit 2=0,3=0 ,0x0c bit 2=1,3=1 */
++#define	FLAG_STATUS_WRPROT		0x10
++#define	FLAG_STATUS_READY		0x20
++#define	FLAG_STATUS_INPACK		0x40
++
++
++/*
++ * Flags for PCMCIA_CSC
++ */
++#define	FLAG_CSC_BVD1			0x01
++#define	FLAG_CSC_BVD2			0x02
++#define	FLAG_CSC_READY			0x04
++#define	FLAG_CSC_INPACK			0x08
++#define	FLAG_CSC_STSCHG			0x10
++#define	FLAG_CSC_CARDINT		0x20
++#define	FLAG_CSC_DETECT			0x40
++#define	FLAG_CSC_SWCDC			0x80
++
++
++/*
++ * Flags for PCMCIA_POWER
++ */
++#define	FLAG_POWER_OFF			0x00	  /* Turn off the socket */
++#define	FLAG_POWER_3V			0x01	  /* 1:Vcc = 3.3v 0:Vcc	= 5.0v */
++#define	FLAG_POWER_SWH			0x02	  /* Direct 5V/3V switch enable	*/
++#define	FLAG_POWER_CTL			0x10	  /* Socket power control */
++#define	FLAG_POWER_AUTO			0x20	  /* Auto power	switch enable */
++#define	FLAG_POWER_OUTENA		0x40	  /* Output enable */
++
++
++/*
++ * Flags for PCMCIA_GBLCTL
++ */
++#define	FLAG_GBLCTL_PWRDOWN		0x01
++#define	FLAG_GBLCTL_WBACK		0x02
++#define	FLAG_GBLCTL_16BITS		0x04
++#define	FLAG_GBLCTL_IOCARD		0x08
++#define	FLAG_GBLCTL_SWCDINT		0x10
++#define	FLAG_GBLCTL_RESET		0x20
++
++
++/*
++ * Flags for PCMCIA_INTCFG
++ */
++#define	FLAG_INTCFG_BDEAD		0x01
++#define	FLAG_INTCFG_BWARN		0x02
++#define	FLAG_INTCFG_READY		0x04
++#define	FLAG_INTCFG_INPACK		0x08
++#define	FLAG_INTCFG_LEVEL		0x10
++#define	FLAG_INTCFG_FEDGE		0x20
++#define	FLAG_INTCFG_REDGE		0x30
++#define	FLAG_INTCFG_DETECT		0x40
++#define	FLAG_INTCFG_STSCHG		0x80
++
++
++/*
++ * Definitions for Card	Status flags for GetStatus
++ */
++#define	STATUS_BATDEAD			0x0001
++#define	STATUS_BATWARN			0x0002
++#define	STATUS_DETECT			0x0004
++#define	STATUS_WRPROT			0x0008
++#define	STATUS_READY			0x0010
++#define	STATUS_INPACK			0x0020
++#define	STATUS_STSCHG			0x0040    /* just for	CSC */
++#define	SOFTWARE_STATUS_DETECT		0x0040    /* just for	CSC */
++
++
++/*
++ * Set Socket configuration flags
++ */
++#define	SS_PWR_AUTO			0x0001
++#define	SS_PWR_SWH			0x0002
++#define	SS_PWR_SEL			0x0004
++#define	SS_POWER_ON			0x0008
++#define	SS_OUTPUT_ENA			0x0010
++#define	SS_IOCARD			0x0020
++#define	SS_RESET			0x0040
++#define	SS_WBACK			0x0080
++#define	SS_16BITS			0x0100
++#define	SS_PWR_DOWN_MODE		0x0200
++#define	SS_SWCDINT			0x0400
++
++
++/*
++ * Set Interrupt Configuration flags
++ */
++#define	INTR_BATDEAD			0x0001
++#define	INTR_BATWARN			0x0002
++#define	INTR_READY			0x0004
++#define	INTR_INPACK			0x0008
++#define	INTR_CARDINT			0x0010
++#define	INTR_DETECT			0x0020
++#define	INTR_STSCHG			0x0040
++
++
++/*
++ * tuple code
++ */
++#define	CISTPL_NULL			0x00
++#define	CISTPL_DEVICE			0x01
++#define	CISTPL_NO_LINK			0x14
++#define	CISTPL_VERS_1			0x15
++#define	CISTPL_CONFIG			0x1a
++#define	CISTPL_CFTABLE_ENTRY		0x1b
++#define	CISTPL_MANFID			0x20
++#define	CISTPL_END			0xff
++
++
++/*
++ * Return codes
++ */
++#define	CS_SUCCESS			0x00
++#define	CS_UNSUPPORTED_FUNCTION		0x15
++#define	CS_NO_MORE_ITEMS		0x1f
++#define	CS_BAD_TUPLE			0x40
++
++
++/*
++ * Attributes for tuple	calls
++ */
++#define	TUPLE_RETURN_LINK		0x01
++#define	TUPLE_RETURN_COMMON		0x02
++
++#define	RETURN_FIRST_TUPLE		0xff
++
++
++/*
++ * macro declarations
++ */
++#define	HAL_PCMCIA_ENABLE_PCMCIA_CONTROLLER() \
++{ \
++    (PCMCIA_CONFIGURATION_REG) |= (0x1 << 1); \
++}
++
++#define	HAL_PCMCIA_DISABLE_PCMCIA_CONTROLLER() \
++{ \
++    (PCMCIA_CONFIGURATION_REG) &= ~(0x1	<< 1); \
++}
++
++
++#endif	// end of #ifndef _STAR_PCMCIA_DRIDGE_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pcm.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pcm.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_pcm.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_pcm.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,277 @@
++/******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_PCM_H_
++#define _STAR_PCM_H_
++
++/******************************************************************************
++ * MODULE NAME:    star_pcm.h
++ * PROJECT CODE:   Orion
++ * DESCRIPTION:    
++ * MAINTAINER:     MJLIU
++ * DATE:           15 September 2005
++ *
++ * SOURCE CONTROL: 
++ *
++ * LICENSE:
++ *     This source code is copyright (c) 2005 Star Semi Inc.
++ *     All rights reserved.
++ *
++ * REVISION HISTORY:
++ *     15 September 2005  -  MJLIU	- Initial Version v1.0
++ *
++ *
++ * SOURCE:
++ * ISSUES:
++ * NOTES TO USERS:
++ ******************************************************************************/
++
++#include <mach/star_sys_memory_map.h>
++
++#define PCM_BASE_ADDR                         (SYSVA_PCM_BASE_ADDR)
++#define PCM_MEM_MAP_ADDR(reg_offset)          (PCM_BASE_ADDR + reg_offset)
++#define PCM_MEM_MAP_VALUE(reg_offset)         (*((u32 volatile *)PCM_MEM_MAP_ADDR(reg_offset)))
++
++
++/*
++ * define access macros
++ */
++#define PCM_CONFIGURATION_0_REG               PCM_MEM_MAP_VALUE(0x80)
++#define PCM_CONFIGURATION_1_REG               PCM_MEM_MAP_VALUE(0x84)
++
++#define PCM_CHANNEL_0_CONFIG_REG              PCM_MEM_MAP_VALUE(0x88)
++#define PCM_CHANNEL_1_CONFIG_REG              PCM_MEM_MAP_VALUE(0x8C)
++#define PCM_CHANNEL_2_CONFIG_REG              PCM_MEM_MAP_VALUE(0x90)
++#define PCM_CHANNEL_3_CONFIG_REG              PCM_MEM_MAP_VALUE(0x94)
++
++#define PCM_TX_DATA_31_0_REG                  PCM_MEM_MAP_VALUE(0x98)
++#define PCM_TX_DATA_63_32_REG                 PCM_MEM_MAP_VALUE(0x9C)
++
++#define PCM_RX_DATA_31_0_REG                  PCM_MEM_MAP_VALUE(0xA0)
++#define PCM_RX_DATA_63_32_REG                 PCM_MEM_MAP_VALUE(0xA4)
++
++#define PCM_INTERRUPT_STATUS_REG              PCM_MEM_MAP_VALUE(0xA8)
++#define PCM_INTERRUPT_ENABLE_REG              PCM_MEM_MAP_VALUE(0xAC)
++
++
++
++/*
++ * define constants macros
++ */
++#define CH0_BIT_INDEX                         (0x1)
++#define CH1_BIT_INDEX                         (0x2)
++#define CH2_BIT_INDEX                         (0x4)
++#define CH3_BIT_INDEX                         (0x8)
++
++#define PCM_RXBUF_FULL_FG                     (0x1)
++#define PCM_TXBUF_EMPTY_FG                    (0x2)
++#define PCM_RXBUF_OVERRUN_FG                  (0x4)
++#define PCM_TXBUF_UNDERRUN_FG                 (0x8)
++
++#define PCM_ENABLE_FG                         (0x1 << 23)
++
++#define PCM_IDL_MODE                          (0)
++#define PCM_GCI_MODE                          (1)
++
++#define PCM_DATA_BIT_8                        (0)
++#define PCM_DATA_BIT_16                       (1)
++
++
++/*
++ * Set Commands Variables
++ */
++#define        Software_Reset                               (0x02)
++#define        Hardware_Reset                               (0x04)
++#define        Write_Transmit_Time_Slot                     (0x40)
++#define        Read_Transmit_Time_Slot                      (0x41)
++#define        Write_Receive_Time_Slot                      (0x42)
++#define        Read_Receive_Time_Slot                       (0x43)
++#define        Write_Tx_Rx_CLK_Slot_Tx_CLK_Edge             (0x44)
++#define        Read_Tx_Rx_CLK_Slot_Tx_CLK_Edge              (0x45)
++#define        Write_Device_Configure_Reg                   (0x46)
++#define        Read_Device_Configure_Reg                    (0x47)
++#define        Write_Channel_Enable_Operating_Mode_Reg      (0x4A)
++#define        Read_Channel_Enable_Operating_Mode_Reg       (0x4B)
++#define        Read_Signal_Reg                              (0x4D)
++#define        Input_Data_Reg                               (0x52)
++#define        Output_Data_Reg                              (0x53)
++#define        Input_Direction_Reg                          (0x54)
++#define        Output_Direction_Reg                         (0x55)
++#define        Write_System_State                           (0x56)
++#define        Read_System_State                            (0x57)
++#define        Write_Operating_Functon                      (0x60)
++#define        Read_Operating_Functon                       (0x61)
++#define        Write_System_State_Config                    (0x68)
++#define        Read_System_State_Config                     (0x69)
++#define        Write_Interrupt_Mask_Reg                     (0x6C)
++#define        Read_Interrupt_Mask_Reg                      (0x6D)
++#define        Write_Operating_Condition                    (0x70)
++#define        Write_Loop_Supervision_Parameter             (0xC2)
++#define        Write_DC_Feed_Parameter                      (0xC6)
++#define        Write_Signal_A_B_Parameter                   (0xD2)
++#define        Write_Switching_Reg_Parameter                (0xE4)
++#define        Write_Switching_Reg_Control                  (0xE6)
++
++
++/*
++ * define data structure
++ */
++typedef struct _PCM_CHANNEL_OBJECT_    PCM_CHANNEL_OBJECT_T;
++
++struct _PCM_CHANNEL_OBJECT_
++{
++    u16          channel_0_tx_data;
++    u16          channel_0_rx_data;
++    u32          channel_0_data_width;     /* 0 : 8-bit, 1 : 16-bit */
++
++    u16          channel_1_tx_data;
++    u16          channel_1_rx_data;
++    u32          channel_1_data_width;
++
++    u16          channel_2_tx_data;
++    u16          channel_2_rx_data;
++    u32          channel_2_data_width;
++
++    u16          channel_3_tx_data;
++    u16          channel_3_rx_data;
++    u32          channel_3_data_width;
++    
++    u32          channel_enable_config;    /* bit[0] = 0 : channel 0 disabled
++                                                     [0] = 1 : channel 0 enabled
++                                                  bit[1] = 0 : channel 1 disabled
++                                                     [1] = 1 : channel 1 enabled
++                                                  bit[2] = 0 : channel 2 disabled
++                                                     [2] = 1 : channel 2 enabled
++                                                  bit[3] = 0 : channel 3 disabled
++                                                     [3] = 1 : channel 3 enabled */
++};
++
++
++typedef struct _PCM_OBJECT_    PCM_OBJECT_T;
++
++struct _PCM_OBJECT_
++{
++    u32          config_0;
++    u32          config_1; 
++    
++    u32          channel_0_config;
++    u32          channel_1_config;
++    u32          channel_2_config;
++    u32          channel_3_config;
++    
++    u32          interrupt_config;
++    
++    /* 
++     * For interrupt setting
++     */
++//    INTC_OBJECT_T    intc_obj;
++};
++
++
++
++/*
++ * function declarations
++ */
++void       Hal_Pcm_Initialize(PCM_OBJECT_T *);
++
++                                                                           
++/*
++ * macro declarations
++ */
++#define HAL_PCM_ENABLE_PCM() \
++{ \
++    (PCM_CONFIGURATION_0_REG) |= ((u32)0x1 << 31); \
++}
++
++#define HAL_PCM_DISABLE_PCM() \
++{ \
++    (PCM_CONFIGURATION_0_REG) &= ~((u32)0x1 << 31); \
++}
++
++#define HAL_PCM_ENABLE_DATA_SWAP() \
++{ \
++    (PCM_CONFIGURATION_0_REG) |= (0x1 << 24); \
++}
++
++#define HAL_PCM_DISABLE_DATA_SWAP() \
++{ \
++    (PCM_CONFIGURATION_0_REG) &= ~(0x1 << 24); \
++}
++
++#define HAL_PCM_WRITE_TX_DATA_0(tx_data_0) \
++{ \
++    (PCM_TX_DATA_31_0_REG) = tx_data_0; \
++}
++
++#define HAL_PCM_WRITE_TX_DATA_1(tx_data_1) \
++{ \
++    (PCM_TX_DATA_63_32_REG) = tx_data_1; \
++}
++
++#define HAL_PCM_READ_RX_DATA_0(rx_data_0) \
++{ \
++    (rx_data_0) = PCM_RX_DATA_31_0_REG; \
++}
++
++#define HAL_PCM_READ_RX_DATA_1(rx_data_1) \
++{ \
++    (rx_data_1) = PCM_RX_DATA_63_32_REG; \
++}
++
++#define HAL_PCM_READ_INTERRUPT_STATUS(status) \
++{ \
++    (status) = PCM_INTERRUPT_STATUS_REG; \
++}
++
++#define HAL_PCM_CLEAR_INTERRUPT_STATUS(status) \
++{ \
++    (PCM_INTERRUPT_STATUS_REG) = (status & 0xC0); \
++}
++
++#define HAL_PCM_DISABLE_RECEIVE_BUFFER_FULL_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_PCM_DISABLE_TRANSMIT_BUFFER_EMPTY_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_PCM_DISABLE_RECEIVE_BUFFER_OVERRUN_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 2); \
++}
++
++#define HAL_PCM_DISABLE_TRANSMIT_BUFFER_UNDERRUN_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_PCM_DISABLE_ALL_INTERRUPT_SOURCES() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) = 0; \
++}
++
++#endif  // end of #ifndef _STAR_PCM_H_
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_powermgt.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_powermgt.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_powermgt.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_powermgt.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,616 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_POWERMGT_H_
++#define	_STAR_POWERMGT_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	PWRMGT_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSPA_POWER_MANAGEMENT_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	PWRMGT_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSVA_POWER_MANAGEMENT_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	PWRMGT_CLOCK_GATE_CONTROL0_REG			PWRMGT_MEM_MAP_VALUE(0x00)
++#define	PWRMGT_CLOCK_GATE_CONTROL1_REG			PWRMGT_MEM_MAP_VALUE(0x04)
++#define	PWRMGT_SOFTWARE_RESET_CONTROL_REG		PWRMGT_MEM_MAP_VALUE(0x08)
++#define	PWRMGT_SYSTEM_CLOCK_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x0C)
++#define	PWRMGT_PLL_POWER_DOWN_CONTROL_REG		PWRMGT_MEM_MAP_VALUE(0x10)
++#define	PWRMGT_CPU_INITIALIZATION_REG			PWRMGT_MEM_MAP_VALUE(0x14)
++#define	PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG		PWRMGT_MEM_MAP_VALUE(0x1C)
++#define	PWRMGT_USB_DEVICE_POWERMGT_REG			PWRMGT_MEM_MAP_VALUE(0x20)
++#define	PWRMGT_REGULATOR_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x24)
++#define	PWRMGT_RTC_XTAL_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x28)
++#define	PWRMGT_PLL250_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x2C)
++
++
++/*
++ * define constants macros
++ */
++#define	PWRMGT_PCMCIA_SOFTWARE_RESET_BIT_INDEX			(1)
++#define	PWRMGT_IDE_SOFTWARE_RESET_BIT_INDEX			(2)
++#define	PWRMGT_VIC_SOFTWARE_RESET_BIT_INDEX			(3)
++#define	PWRMGT_DMA_SOFTWARE_RESET_BIT_INDEX			(4)
++#define	PWRMGT_NIC_SOFTWARE_RESET_BIT_INDEX			(5)
++#define	PWRMGT_USB_HOST_SOFTWARE_RESET_BIT_INDEX		(6)
++#define	PWRMGT_PCI_BRIDGE_SOFTWARE_RESET_BIT_INDEX		(7)
++#define	PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX			(8)
++#define	PWRMGT_UART0_SOFTWARE_RESET_BIT_INDEX			(9)
++#define	PWRMGT_UART1_SOFTWARE_RESET_BIT_INDEX			(10)
++#define	PWRMGT_TIMER_SOFTWARE_RESET_BIT_INDEX			(11)
++#define	PWRMGT_WDTIMER_SOFTWARE_RESET_BIT_INDEX			(12)
++#define	PWRMGT_GPIO_SOFTWARE_RESET_BIT_INDEX			(13)
++#define	PWRMGT_USB_DEVICE_SOFTWARE_RESET_BIT_INDEX		(14)
++#define	PWRMGT_FAST_ETHERNET_PHY_SOFTWARE_RESET_BIT_INDEX	(15)
++#define	PWRMGT_HSDMA_SOFTWARE_RESET_BIT_INDEX			(16)
++
++
++#define	PWRMGT_PLL_FREQUENCY_175MHZ			(0 << 0)
++#define	PWRMGT_PLL_FREQUENCY_200MHZ			(1 << 0)
++#define	PWRMGT_PLL_FREQUENCY_225MHZ			(2 << 0)
++#define	PWRMGT_PLL_FREQUENCY_250MHZ			(3 << 0)
++
++#define	PWRMGT_CPUCLK_DIVIDER_BY_1			(0 << 2)
++#define	PWRMGT_CPUCLK_DIVIDER_BY_2			(1 << 2)
++#define	PWRMGT_CPUCLK_DIVIDER_BY_3			(2 << 2)
++#define	PWRMGT_CPUCLK_DIVIDER_BY_4			(3 << 2)
++
++#define	PWRMGT_HCLK_DIVIDER_BY_1			(0 << 4)
++#define	PWRMGT_HCLK_DIVIDER_BY_2			(1 << 4)
++#define	PWRMGT_HCLK_DIVIDER_BY_3			(2 << 4)
++#define	PWRMGT_HCLK_DIVIDER_BY_4			(3 << 4)
++
++#define	PWRMGT_HCLK_SOURCE_FCLK				(0 << 6)
++#define	PWRMGT_HCLK_SOURCE_125MHZ			(1 << 6)
++
++#define	PWRMGT_PCLK_DIVIDER_BY_1			(0 << 8)
++#define	PWRMGT_PCLK_DIVIDER_BY_2			(1 << 8)
++#define	PWRMGT_PCLK_DIVIDER_BY_3			(2 << 8)
++#define	PWRMGT_PCLK_DIVIDER_BY_4			(3 << 8)
++
++#define	PWRMGT_PCICLK_DIVIDER_BY_1			(0 << 10)
++#define	PWRMGT_PCICLK_DIVIDER_BY_2			(1 << 10)
++#define	PWRMGT_PCICLK_DIVIDER_BY_3			(2 << 10)
++#define	PWRMGT_PCICLK_DIVIDER_BY_4			(3 << 10)
++
++
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_1		(1)
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_2		(2)
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_3		(3)
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_4		(4)
++
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_1		(1)
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_2		(2)
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_3		(3)
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_4		(4)
++
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_1			(1)
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_2			(2)
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_3			(3)
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_4			(4)
++
++/*
++ * Macro defines for Clock Gate	Control
++ */
++#define	HAL_PWRMGT_DISABLE_DRAMC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_NIC_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 0); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x0F << 20); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 5); \
++}
++
++#define	HAL_PWRMGT_DISABLE_NIC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x0F <<	20); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_PCI_BRIDGE_33M_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 1); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	10); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 10); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 28) | (0x1 << 30); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 7); \
++}
++
++#define	HAL_PWRMGT_ENABLE_PCI_BRIDGE_66M_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 1); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	10); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x0 << 10); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 28) | (0x1 << 30); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 7); \
++}
++
++#define	HAL_PWRMGT_DISABLE_PCI_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	28) | (0x1 << 30)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_USB_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0xF << 1); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 24); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 28); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 6) | (0x1 << 14); \
++}
++
++#define	HAL_PWRMGT_DISABLE_USB_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1 << 24); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 28); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_DMA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 16); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 4); \
++}
++
++#define	HAL_PWRMGT_DISABLE_DMA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1 << 16); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_IDE_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 8) | (0x1	<< 9); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 2); \
++}
++
++#define	HAL_PWRMGT_DISABLE_IDE_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	8) | (0x1 << 9)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_UART0_CLOCK()	\
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~((0x1	<< 1) |	(0x1 <<	2) | (0x1 << 5)); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 12); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 9); \
++}
++
++#define	HAL_PWRMGT_DISABLE_UART0_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 12); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_UART1_CLOCK()	\
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~((0x1	<< 1) |	(0x1 <<	2) | (0x1 << 5)); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 13); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 10); \
++}
++
++#define	HAL_PWRMGT_DISABLE_UART1_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 13); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_PCMCIA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 4) | (0x1	<< 5); \
++}
++
++#define	HAL_PWRMGT_DISABLE_PCMCIA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	4) | (0x1 << 5)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_GPIO_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 25); \
++}
++
++#define	HAL_PWRMGT_DISABLE_GPIO_CLOCK()	\
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 25); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_WDTIMER_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 21) | (0x1 << 22); \
++}
++
++#define	HAL_PWRMGT_DISABLE_WDTIMER_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	21) | (0x1 << 22)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_RTC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 23); \
++}
++
++#define	HAL_PWRMGT_DISABLE_RTC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 23); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_TIMER_CLOCK()	\
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 17) | (0x1 << 18)	| (0x1 << 19); \
++}
++
++#define	HAL_PWRMGT_DISABLE_TIMER_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	17) | (0x1 << 18) | (0x1 << 19)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_I2C_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 1); \
++}
++
++#define	HAL_PWRMGT_DISABLE_I2C_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 1); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_I2S_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~((0x1	<< 5) |	(0x1 <<	6)); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 1) | (0x1	<< 10);	\
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 8); \
++}
++
++#define	HAL_PWRMGT_DISABLE_I2S_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	1) | (0x1 << 10)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_PCM_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 5); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 1) | (0x1	<< 6); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 8); \
++}
++
++#define	HAL_PWRMGT_DISABLE_PCM_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	1) | (0x1 << 6)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_SPI_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 0) | (0x1	<< 1); \
++}
++
++#define	HAL_PWRMGT_DISABLE_SPI_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	0) | (0x1 << 1)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_VIC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 12); \
++}
++
++#define	HAL_PWRMGT_DISABLE_VIC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1 << 12); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_SMC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 4) | (0x1	<< 5); \
++}
++
++#define	HAL_PWRMGT_DISABLE_SMC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	4) | (0x1 << 5)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_HSDMA_CLOCK()	\
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 29); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 16); \
++}
++
++#define	HAL_PWRMGT_DISABLE_HSDMA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 29); \
++}
++
++
++
++/*
++ * Macro defines for Reset Control
++ */
++#define	HAL_PWRMGT_GLOBAL_SOFTWARE_RESET() \
++{ \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1);	\
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1); \
++}
++
++
++/*
++ * Macro defines for System Clock Control
++ */
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_175MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++}
++
++
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_200MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= 0x1; \
++}
++
++
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_225MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= 0x2; \
++}
++
++
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_250MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= 0x3; \
++}
++
++
++#define	HAL_PWRMGT_CONFIG_PLLCLK_TO_CPUCLK_RATIO(ratio)	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	2); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (((ratio	- 1) & 0x3) << 2); \
++}
++
++
++#define	HAL_PWRMGT_CONFIG_CPUCLK_TO_HCLK_RATIO(ratio) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	4); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (((ratio	- 1) & 0x3) << 4); \
++}
++
++
++#define	HAL_PWRMGT_HCLK_SOURCE_FCLK() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x1 <<	6); \
++}
++
++
++#define	HAL_PWRMGT_HCLK_SOURCE_125MHZ()	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 6); \
++}
++
++
++#define	HAL_PWRMGT_GIGA_NIC_CLOCK_SOURCE_HCLK()	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x1 <<	7); \
++}
++
++
++#define	HAL_PWRMGT_GIGA_NIC_CLOCK_SOURCE_62_5MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 7); \
++}
++
++
++#define	HAL_PWRMGT_CONFIG_HCLK_TO_PCLK_RATIO(ratio) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	8); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (((ratio	- 1) & 0x3) << 8); \
++}
++
++
++#define	HAL_PWRMGT_I2S_CLOCK_SOURCE_8192000HZ()	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	12); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x0 << 12); \
++}
++
++
++#define	HAL_PWRMGT_I2S_CLOCK_SOURCE_11289600HZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	12); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 12); \
++}
++
++
++#define	HAL_PWRMGT_I2S_CLOCK_SOURCE_12288000HZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	12); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x2 << 12); \
++}
++
++
++#define	HAL_PWRMGT_CONFIGURE_MDC_CLOCK_DIVIDER(divided_value) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	14); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= ((divided_value & 0x3) << 14); \
++}
++
++
++#define	HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(pin_source_select, divided_value) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3F << 16); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= ((pin_source_select & 0xF) << 16); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= ((divided_value & 0x3) << 20); \
++}
++
++
++/*
++ * Macro defines for PLL Power Down Control
++ */
++#define	HAL_PWRMGT_POWER_DOWN_SYSTEM_XTAL_PAD()	\
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 7)
++
++#define	HAL_PWRMGT_POWER_ON_SYSTEM_XTAL_PAD() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 7)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X5() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 0)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X5() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 0)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X8() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 1)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X8() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 1)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X3() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 2)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X3() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 2)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_USBH_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 3)
++
++#define	HAL_PWRMGT_POWER_ON_USBH_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 3)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_USBD_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 4)
++
++#define	HAL_PWRMGT_POWER_ON_USBD_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 4)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X2250() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 5)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X2250()	\
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 5)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X7() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 6)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X7() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 6)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_ALL_PLL()	\
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG =	0x7F;
++
++#define	HAL_PWRMGT_POWER_ON_ALL_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG =	0;
++
++
++/*
++ * Macro defines for Pad Drive Strength	Control
++ */
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_PCMCIA_CARDBUS_MODE() \
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x3 << 0); \
++}
++
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_PCI_MODE()	\
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x3 << 0); \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG |= (0x1 << 0); \
++}
++
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_MII_MODE()	\
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG |= (0x1 << 2); \
++}
++
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_RGMII_MODE() \
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x1 << 2); \
++}
++
++#define	HAL_PWRMGT_ENABLE_MII_PAD_SIGNAL_NOT_BOUNDED() \
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG |= (0x1 << 3); \
++}
++
++#define	HAL_PWRMGT_DISABLE_MII_PAD_SIGNAL_NOT_BOUNDED()	\
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x1 << 3); \
++}
++
++
++/*
++ * Macro defines for USB Device	Power Management
++ */
++#define	HAL_PWRMGT_REMOTE_WAKEUP_USB_HOST() \
++{ \
++    PWRMGT_USB_DEVICE_POWERMGT_REG |= (0x1 << 4); \
++}
++
++#define	HAL_PWRMGT_USB_DEVICE_PHY_CLOCK_SOURCE_EXTERNAL_12MHZ()	\
++{ \
++    PWRMGT_USB_DEVICE_POWERMGT_REG &= ~(0x1 << 5); \
++}
++
++#define	HAL_PWRMGT_USB_DEVICE_PHY_CLOCK_SOURCE_INTERNAL_12MHZ()	\
++{ \
++    PWRMGT_USB_DEVICE_POWERMGT_REG |= (0x1 << 5); \
++}
++
++
++/*
++ * Macro defines for Regulator Control
++ */
++
++
++#endif	// end of #ifndef _STAR_POWERMGT_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_rtc.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_rtc.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_rtc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_rtc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,87 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_RTC_H_
++#define	_STAR_RTC_H_
++
++#include <mach/star_sys_memory_map.h>
++
++#define	RTC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_RTC_BASE_ADDR + reg_offset)))
++
++#define	RTC_SECOND_REG				RTC_MEM_MAP_VALUE(0x00)
++#define	RTC_MINUTE_REG				RTC_MEM_MAP_VALUE(0x04)
++#define	RTC_HOUR_REG				RTC_MEM_MAP_VALUE(0x08)
++#define	RTC_DAY_REG				RTC_MEM_MAP_VALUE(0x0C)
++#define	RTC_SECOND_ALARM_REG			RTC_MEM_MAP_VALUE(0x10)
++#define	RTC_MINUTE_ALARM_REG			RTC_MEM_MAP_VALUE(0x14)
++#define	RTC_HOUR_ALARM_REG			RTC_MEM_MAP_VALUE(0x18)
++#define	RTC_RECORD_REG				RTC_MEM_MAP_VALUE(0x1C)
++#define	RTC_CONTROL_REG				RTC_MEM_MAP_VALUE(0x20)
++#define	RTC_INTERRUPT_STATUS_REG		RTC_MEM_MAP_VALUE(0x34)
++
++#define	RTC_ENABLE_BIT				(1 << 0)
++#define	RTC_AUTO_SECOND_ALARM_ENABLE_BIT	(1 << 1)
++#define	RTC_AUTO_MINUTE_ALARM_ENABLE_BIT	(1 << 2)
++#define	RTC_AUTO_HOUR_ALARM_ENABLE_BIT		(1 << 3)
++#define	RTC_AUTO_DAY_ALARM_ENABLE_BIT		(1 << 4)
++#define	RTC_MATCH_ALARM_ENABLE_BIT		(1 << 5)
++#define	RTC_BATTERY_LOW_VOLTAGE_ENABLE_BIT	(1 << 6)
++
++#define RTC_AUTO_SECOND_ALARM_INTR_BIT      (1 << 0)
++#define RTC_AUTO_MINUTE_ALARM_INTR_BIT      (1 << 1)
++#define RTC_AUTO_HOUR_ALARM_INTR_BIT        (1 << 2)
++#define RTC_AUTO_DAY_ALARM_INTR_BIT         (1 << 3)
++#define RTC_MATCH_ALARM_INTR_BIT            (1 << 4)
++#define RTC_BATTERY_LOW_VOLTAGE_INTR_BIT    (1 << 5)
++
++#define	HAL_RTC_READ_SECOND(second)         ((second) = (RTC_SECOND_REG) & 0x3F);
++#define	HAL_RTC_READ_MINUTE(minute)         ((minute) = (RTC_MINUTE_REG) & 0x3F);
++#define	HAL_RTC_READ_HOUR(hour)	            ((hour) = (RTC_HOUR_REG) & 0x1F);
++#define	HAL_RTC_READ_DAY(day)               ((day) = (RTC_DAY_REG) & 0xFFFF);
++#define	HAL_RTC_ENABLE()                    ((RTC_CONTROL_REG) |= (RTC_ENABLE_BIT));
++#define	HAL_RTC_DISABLE()                   ((RTC_CONTROL_REG) &= ~(RTC_ENABLE_BIT));
++#define	HAL_RTC_AUTO_SECOND_ALARM_ENABLE()  ((RTC_CONTROL_REG) |= (RTC_AUTO_SECOND_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_SECOND_ALARM_DISABLE() ((RTC_CONTROL_REG) &= ~(RTC_AUTO_SECOND_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_MINUTE_ALARM_ENABLE()  ((RTC_CONTROL_REG) |= (RTC_AUTO_MINUTE_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_MINUTE_ALARM_DISABLE() ((RTC_CONTROL_REG) &= ~(RTC_AUTO_MINUTE_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_HOUR_ALARM_ENABLE()    ((RTC_CONTROL_REG) |= (RTC_AUTO_HOUR_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_HOUR_ALARM_DISABLE()   ((RTC_CONTROL_REG) &= ~(RTC_AUTO_HOUR_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_DAY_ALARM_ENABLE()	    ((RTC_CONTROL_REG) |= (RTC_AUTO_DAY_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_DAY_ALARM_DISABLE()    ((RTC_CONTROL_REG) &= ~(RTC_AUTO_DAY_ALARM_ENABLE_BIT));
++#define	HAL_RTC_MATCH_ALARM_ENABLE()        ((RTC_CONTROL_REG) |= (RTC_MATCH_ALARM_ENABLE_BIT));
++#define	HAL_RTC_MATCH_ALARM_DISABLE()       ((RTC_CONTROL_REG) &= ~(RTC_MATCH_ALARM_ENABLE_BIT));
++#define	HAL_RTC_BATTERY_LOW_VOLTAGE_INTERRUPT_ENABLE()   ((RTC_CONTROL_REG) |= (RTC_BATTERY_LOW_VOLTAGE_ENABLE_BIT));
++#define	HAL_RTC_BATTERY_LOW_VOLTAGE_INTERRUPT_DISABLE()	 ((RTC_CONTROL_REG) &= ~(RTC_BATTERY_LOW_VOLTAGE_ENABLE_BIT));
++#define	HAL_RTC_WRITE_RECORD(record)        ((RTC_RECORD_REG) =	(record));
++#define	HAL_RTC_READ_RECORD(record)         ((record) =	(RTC_RECORD_REG)); 
++#define	HAL_RTC_WRITE_MATCHED_ALARM_SECOND(second)  ((RTC_SECOND_ALARM_REG) = (second &	0x3F));
++#define	HAL_RTC_READ_MATCHED_ALARM_SECOND(second)   ((second) =	(RTC_SECOND_ALARM_REG) & 0x3F);
++#define	HAL_RTC_WRITE_MATCHED_ALARM_MINUTE(minute)  ((RTC_MINUTE_ALARM_REG) = (minute &	0x3F));
++#define	HAL_RTC_READ_MATCHED_ALARM_MINUTE(minute)   ((minute) =	(RTC_MINUTE_ALARM_REG) & 0x3F);
++#define	HAL_RTC_WRITE_MATCHED_ALARM_HOUR(hour)      ((RTC_HOUR_ALARM_REG) = (hour & 0x1F));
++#define	HAL_RTC_READ_MATCHED_ALARM_HOUR(hour)       ((hour) = (RTC_HOUR_ALARM_REG) & 0x1F);
++#define	HAL_RTC_READ_INTERRUPT_STATUS(status)       ((status) =	(RTC_INTERRUPT_STATUS_REG) & 0x3F);
++#define	HAL_RTC_WRITE_INTERRUPT_STATUS(status)      ((RTC_INTERRUPT_STATUS_REG)	= (status) & 0x3F);
++
++#endif
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_smc.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_smc.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_smc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_smc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,57 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_SMC_H_
++#define	_STAR_SMC_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	SMC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSPA_SMC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	SMC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSVA_SMC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++
++/*
++ * Static Memory Controller Registers
++ */
++#define	SMC_MEM_BANK0_CONFIG_REG	SMC_MEM_MAP_VALUE(0x00)
++#define	SMC_MEM_BANK0_TIMING_REG	SMC_MEM_MAP_VALUE(0x04)
++#define	SMC_MEM_BANK1_CONFIG_REG	SMC_MEM_MAP_VALUE(0x08)
++#define	SMC_MEM_BANK1_TIMING_REG	SMC_MEM_MAP_VALUE(0x0C)
++#define	SMC_MEM_BANK2_CONFIG_REG	SMC_MEM_MAP_VALUE(0x10)
++#define	SMC_MEM_BANK2_TIMING_REG	SMC_MEM_MAP_VALUE(0x14)
++#define	SMC_MEM_BANK3_CONFIG_REG	SMC_MEM_MAP_VALUE(0x18)
++#define	SMC_MEM_BANK3_TIMING_REG	SMC_MEM_MAP_VALUE(0x1C)
++
++/*
++ * macros declarations
++ */
++
++#endif	// end of #ifndef _STAR_SMC_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_spi.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_spi.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_spi.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_spi.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,169 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_SPI_H_
++#define _STAR_SPI_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define SPI_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_SPI_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define SPI_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_SPI_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define SPI_CONFIGURATION_REG			SPI_MEM_MAP_VALUE(0x40)
++#define SPI_SERVICE_STATUS_REG			SPI_MEM_MAP_VALUE(0x44)
++#define SPI_BIT_RATE_CONTROL_REG		SPI_MEM_MAP_VALUE(0x48)
++#define SPI_TRANSMIT_CONTROL_REG		SPI_MEM_MAP_VALUE(0x4C)
++#define SPI_TRANSMIT_BUFFER_REG			SPI_MEM_MAP_VALUE(0x50)
++#define SPI_RECEIVE_CONTROL_REG			SPI_MEM_MAP_VALUE(0x54)
++#define SPI_RECEIVE_BUFFER_REG			SPI_MEM_MAP_VALUE(0x58)
++#define SPI_FIFO_TRANSMIT_CONFIG_REG		SPI_MEM_MAP_VALUE(0x5C)
++#define SPI_FIFO_TRANSMIT_CONTROL_REG		SPI_MEM_MAP_VALUE(0x60)
++#define SPI_FIFO_RECEIVE_CONFIG_REG		SPI_MEM_MAP_VALUE(0x64)
++#define SPI_INTERRUPT_STATUS_REG		SPI_MEM_MAP_VALUE(0x68)
++#define SPI_INTERRUPT_ENABLE_REG		SPI_MEM_MAP_VALUE(0x6C)
++
++
++/*
++ * define constants macros
++ */
++#define SPI_TX_RX_FIFO_DEPTH			(8)
++
++#define SPI_CH0					(0)
++#define SPI_CH1					(1)
++#define SPI_CH2					(2)
++#define SPI_CH3					(3)
++
++
++#define SPI_RXFIFO_OT_FG			(0x01)
++#define SPI_TXFIFO_UT_FG			(0x02)
++#define SPI_RXBUF_FULL_FG			(0x04)
++#define SPI_TXBUF_EMPTY_FG			(0x08)
++
++#define SPI_RXFIFO_OR_FG			(0x10)
++#define SPI_TXFIFO_UR_FG			(0x20)
++#define SPI_RXBUF_OR_FG				(0x40)
++#define SPI_TXBUF_UR_FG				(0x80)
++
++/*
++ * define Character Length Control
++ */
++#define SPI_LEN_BIT_8				(0)
++#define SPI_LEN_BIT_16				(1)
++#define SPI_LEN_BIT_24				(2)
++#define SPI_LEN_BIT_32				(3)
++
++
++/*
++ * macro declarations
++ */
++#define HAL_SPI_ENABLE_SPI() \
++{ \
++    (SPI_CONFIGURATION_REG) |= ((u_int32)0x1 << 31); \
++}
++
++#define HAL_SPI_DISABLE_SPI() \
++{ \
++    (SPI_CONFIGURATION_REG) &= ~((u_int32)0x1 << 31); \
++}
++
++#define HAL_SPI_ENABLE_DATA_SWAP() \
++{ \
++    (SPI_CONFIGURATION_REG) |= (0x1 << 24); \
++}
++
++#define HAL_SPI_DISABLE_DATA_SWAP() \
++{ \
++    (SPI_CONFIGURATION_REG) &= ~(0x1 << 24); \
++}
++
++#define HAL_SPI_TRANSMIT_DATA(tx_data) \
++{ \
++    (SPI_TRANSMIT_BUFFER_REG) = tx_data; \
++}
++
++#define HAL_SPI_RECEIVE_DATA(rx_data) \
++{ \
++    (rx_data) = SPI_RECEIVE_BUFFER_REG; \
++}
++
++#define HAL_SPI_GET_TRANSMIT_FIFO_WORDS_NUMBER(tx_fifo_words_num) \
++{ \
++    (tx_fifo_words_num) = SPI_FIFO_TRANSMIT_CONFIG_REG & 0xF; \
++}
++
++#define HAL_SPI_GET_RECEIVE_FIFO_WORDS_NUMBER(rx_fifo_words_num) \
++{ \
++    (rx_fifo_words_num) = SPI_FIFO_RECEIVE_CONFIG_REG & 0xF; \
++}
++
++#define HAL_SPI_DISABLE_ALL_INTERRUPT_SOURCES() \
++{ \
++    (SPI_INTERRUPT_ENABLE_REG) = 0; \
++}
++
++#define HAL_SPI_DISABLE_TX_FIFO_THRESHOLD_INTERRUPT() \
++{ \
++    (SPI_INTERRUPT_ENABLE_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_SPI_DISABLE_RX_FIFO_THRESHOLD_INTERRUPT() \
++{ \
++    (SPI_INTERRUPT_ENABLE_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_SPI_READ_INTERRUPT_STATUS(status) \
++{ \
++    (status) = SPI_INTERRUPT_STATUS_REG; \
++}
++
++#define HAL_SPI_CLEAR_INTERRUPT_STATUS(status) \
++{ \
++    (SPI_INTERRUPT_STATUS_REG) = (status & 0xF0); \
++}
++
++#define HAL_SPI_SET_FIFO_TRANSMIT_DELAY(delay) \
++{ \
++    (SPI_FIFO_TRANSMIT_CONTROL_REG) = (delay & 0x1F); \
++}
++
++#define STR8100_SPI_SERIAL_MODE_GENERAL              0x0
++#define STR8100_SPI_SERIAL_MODE_MICROPROCESSOR       0x1
++ 
++struct str8100_spi_dev_attr
++{ 
++	int spi_serial_mode;
++};
++
++#endif // end of #ifndef _STAR_SPI_H_
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_sys_memory_map.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_sys_memory_map.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_sys_memory_map.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_sys_memory_map.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,109 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_SYS_MEMORY_MAP_H_
++#define	_STAR_SYS_MEMORY_MAP_H_
++
++
++#if 0
++#define __UBOOT__
++#else
++#define __LINUX__
++#endif
++
++
++/*
++ * sytem memory	mapping	after reset
++ */
++#define SYSPA_FLASH_SRAM_BANK0_BASE_ADDR	0x10000000
++#define SYSPA_FLASH_SRAM_BANK1_BASE_ADDR	0x11000000
++#define SYSPA_FLASH_SRAM_BANK2_BASE_ADDR	0x12000000
++#define SYSPA_FLASH_SRAM_BANK3_BASE_ADDR	0x13000000
++#define	SYSPA_PCMCIA_ATTRIBUTE_MEMORY_BASE_ADDR	0x14000000
++#define	SYSPA_PCMCIA_COMMON_MEMORY_BASE_ADDR	0x15000000
++#define	SYSPA_PCMCIA_IO_SPACE_BASE_ADDR		0x16000000
++#define	SYSPA_IDE_DEVICE_BASE_ADDR		0x18000000
++#define	SYSPA_SDRAM_MEMORY_BASE_ADDR		0x20000000
++#define	SYSPA_GDMAC_BASE_ADDR			0x60000000
++#define	SYSPA_NIC_BASE_ADDR			0x70000000
++#define	SYSPA_SPI_BASE_ADDR			0x71000000
++#define	SYSPA_PCM_BASE_ADDR			0x71000000
++#define	SYSPA_I2C_BASE_ADDR			0x71000000
++#define	SYSPA_I2S_BASE_ADDR			0x71000000
++#define	SYSPA_DDRC_SDRC_BASE_ADDR		0x72000000
++#define	SYSPA_SMC_BASE_ADDR			0x73000000
++#define	SYSPA_PCMCIA_CONTROL_BASE_ADDR		0x73000000
++#define	SYSPA_IDE_CONTROLLER_BASE_ADDR		0x74000000
++#define	SYSPA_MISC_BASE_ADDR			0x76000000
++#define	SYSPA_POWER_MANAGEMENT_BASE_ADDR	0x77000000
++#define	SYSPA_UART0_BASE_ADDR			0x78000000
++#define	SYSPA_UART1_BASE_ADDR			0x78800000
++#define	SYSPA_TIMER_BASE_ADDR			0x79000000
++#define	SYSPA_WATCHDOG_TIMER_BASE_ADDR		0x7A000000
++#define	SYSPA_RTC_BASE_ADDR			0x7B000000
++#define	SYSPA_GPIOA_BASE_ADDR			0x7C000000
++#define	SYSPA_GPIOB_BASE_ADDR			0x7C800000
++#define	SYSPA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR	0xA0000000
++#define	SYSPA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR	0xA4000000
++#define	SYSPA_PCI_IO_SPACE_BASE_ADDR		0xA8000000
++#define	SYSPA_PCI_MEMORY_SPACE_BASE_ADDR	0xB0000000
++#define	SYSPA_USB11_CONFIG_BASE_ADDR		0xC0000000
++#define	SYSPA_USB11_OPERATION_BASE_ADDR		0xC4000000
++#define	SYSPA_USB20_CONFIG_BASE_ADDR		0xC8000000
++#define	SYSPA_USB20_OPERATION_BASE_ADDR		0xCC000000
++#define	SYSPA_USB20_DEVICE_BASE_ADDR		0xD0000000
++#define	SYSPA_VIC_BASE_ADDR			0xFFFFF000
++
++#if defined(__LINUX__)
++#define	SYSVA_FLASH_BASE_ADDR				0xFF000000
++#define SYSVA_IDE_DEVICE_BASE_ADDR		0xFFF00000
++#define SYSVA_GDMAC_BASE_ADDR			0xFFF01000
++#define SYSVA_NIC_BASE_ADDR			0xFFF02000
++#define SYSVA_SPI_BASE_ADDR			0xFFF03000
++#define SYSVA_PCM_BASE_ADDR			0xFFF04000
++#define SYSVA_I2C_BASE_ADDR			0xFFF05000
++#define SYSVA_I2S_BASE_ADDR			0xFFF06000
++#define SYSVA_DDRC_SDRC_BASE_ADDR		0xFFF07000
++#define SYSVA_SMC_BASE_ADDR			0xFFF08000
++#define SYSVA_PCMCIA_CONTROL_BASE_ADDR		0xFFF09000
++#define SYSVA_IDE_CONTROLLER_BASE_ADDR		0xFFF0A000
++#define SYSVA_MISC_BASE_ADDR			0xFFF0B000
++#define SYSVA_POWER_MANAGEMENT_BASE_ADDR	0xFFF0C000
++#define SYSVA_UART0_BASE_ADDR			0xFFF0D000
++#define SYSVA_UART1_BASE_ADDR			0xFFF0E000
++#define SYSVA_TIMER_BASE_ADDR			0xFFF0F000
++#define SYSVA_WATCHDOG_TIMER_BASE_ADDR		0xFFF10000
++#define SYSVA_RTC_BASE_ADDR			0xFFF11000
++#define SYSVA_GPIOA_BASE_ADDR			0xFFF12000
++#define SYSVA_GPIOB_BASE_ADDR			0xFFF13000
++#define SYSVA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR	0xFFF14000
++#define SYSVA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR	0xFFF15000
++#define SYSVA_USB11_CONFIG_BASE_ADDR		0xFFF16000
++#define SYSVA_USB11_OPERATION_BASE_ADDR		0xFFF17000
++#define SYSVA_USB20_CONFIG_BASE_ADDR		0xFFF18000
++#define SYSVA_USB20_OPERATION_BASE_ADDR		0xFFF19000
++#define SYSVA_USB20_DEVICE_BASE_ADDR		0xFFF1A000
++#define SYSVA_VIC_BASE_ADDR			0xFFF1B000
++#endif //__LINUX__
++
++#endif // end of #ifndef _STAR_SYS_MEMORY_MAP_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_timer.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_timer.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_timer.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_timer.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,312 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_TIMER_H_
++#define	_STAR_TIMER_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	TIMER_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_TIMER_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	TIMER_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_TIMER_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	TIMER1_COUNTER_REG			TIMER_MEM_MAP_VALUE(0x00)
++#define	TIMER1_AUTO_RELOAD_VALUE_REG		TIMER_MEM_MAP_VALUE(0x04)
++#define	TIMER1_MATCH_VALUE1_REG			TIMER_MEM_MAP_VALUE(0x08)
++#define	TIMER1_MATCH_VALUE2_REG			TIMER_MEM_MAP_VALUE(0x0C)
++
++#define	TIMER2_COUNTER_REG			TIMER_MEM_MAP_VALUE(0x10)
++#define	TIMER2_AUTO_RELOAD_VALUE_REG		TIMER_MEM_MAP_VALUE(0x14)
++#define	TIMER2_MATCH_VALUE1_REG			TIMER_MEM_MAP_VALUE(0x18)
++#define	TIMER2_MATCH_VALUE2_REG			TIMER_MEM_MAP_VALUE(0x1C)
++
++#define	TIMER1_TIMER2_CONTROL_REG		TIMER_MEM_MAP_VALUE(0x30)
++#define	TIMER1_TIMER2_INTERRUPT_STATUS_REG	TIMER_MEM_MAP_VALUE(0x34)
++#define	TIMER1_TIMER2_INTERRUPT_MASK_REG	TIMER_MEM_MAP_VALUE(0x38)
++
++#define	TIMER3_COUNTER_LOW_REG			TIMER_MEM_MAP_VALUE(0x40)
++#define	TIMER3_CONTROL_REG			TIMER_MEM_MAP_VALUE(0x44)
++
++
++/*
++ * define constants macros
++ */
++#define	TIMER1_ENABLE_BIT_INDEX			0
++#define	TIMER1_CLOCK_SOURCE_BIT_INDEX		1
++#define	TIMER1_OVERFLOW_ENABLE_BIT_INDEX	2
++
++#define	TIMER2_ENABLE_BIT_INDEX			3
++#define	TIMER2_CLOCK_SOURCE_BIT_INDEX		4
++#define	TIMER2_OVERFLOW_ENABLE_BIT_INDEX	5
++
++#define	TIMER1_UP_DOWN_COUNT_BIT_INDEX		9
++#define	TIMER2_UP_DOWN_COUNT_BIT_INDEX		10
++
++#define	TIMER1_MATCH1_INTERRUPT_BIT_INDEX	0
++#define	TIMER1_MATCH2_INTERRUPT_BIT_INDEX	1
++#define	TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX	2
++
++#define	TIMER2_MATCH1_INTERRUPT_BIT_INDEX	3
++#define	TIMER2_MATCH2_INTERRUPT_BIT_INDEX	4
++#define	TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX	5
++
++#define TIMER3_ENABLE_BIT_INDEX			17
++#define TIMER3_RESET_BIT_INDEX			16
++
++#define	TIMER_CLOCK_SOURCE_PCLK			0
++#define	TIMER_CLOCK_SOURCE_EXT_CLK		1
++
++
++#define	TIMER_OVERFLOW_MODE_DISABLE		0
++#define	TIMER_OVERFLOW_MODE_ENABLE		1
++
++
++#define	TIMER_COUNTER_MODE_UP			0
++#define	TIMER_COUNTER_MODE_DOWN			1
++
++
++#define	MATCH1_MASK_ENABLE			(1 << 0)
++
++#define	MATCH2_MASK_ENABLE			(1 << 1)
++
++#define	OVERFLOW_MASK_ENABLE			(1 << 2)
++
++
++/*
++ * macro declarations
++ */
++#define	HAL_TIMER_ENABLE_TIMER1() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER1_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER1() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER1_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER2() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER2_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER2() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER2_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER1_OVERFLOW_MODE()	\
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER1_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER1_OVERFLOW_MODE() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER1_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER2_OVERFLOW_MODE()	\
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER2_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER2_OVERFLOW_MODE() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER2_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER1_DOWNCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER1_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER1_UPCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER1_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER2_DOWNCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER2_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER2_UPCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER2_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_READ_INTERRUPT_STATUS(interrupt_status) \
++{ \
++    ((interrupt_status)	= (TIMER1_TIMER2_INTERRUPT_STATUS_REG)); \
++}
++
++
++#define	HAL_TIMER_WRITE_INTERRUPT_STATUS(interrupt_status) \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_STATUS_REG) = (interrupt_status)); \
++}
++
++
++#define	HAL_TIMER_READ_INTERRUPT_MASK(interrupt_mask) \
++{ \
++    ((interrupt_mask) =	(TIMER1_TIMER2_INTERRUPT_MASK_REG)); \
++}
++
++
++#define	HAL_TIMER_WRITE_INTERRUPT_MASK(interrupt_mask) \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	= (interrupt_mask)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_TIMER2_ALL_INTERRUPTS() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	= (0x3F));\
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER1_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER1_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER1_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER1_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER1_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER1_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER1_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER2_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER2_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER2_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER2_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER2_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER2_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER2_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER2_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER2_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER2_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER3() \
++{ \
++    ((TIMER3_CONTROL_REG) = 0); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER3() \
++{ \
++    ((TIMER3_CONTROL_REG) = (1 << TIMER3_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_RESET_TIMER3() \
++{ \
++    ((TIMER3_CONTROL_REG) = (1 << TIMER3_RESET_BIT_INDEX)); \
++}
++
++#ifndef __ASSEMBLY__
++static inline unsigned long long HAL_TIMER_GET_TIMER3_COUNTER(void)
++{
++	unsigned long h;
++	unsigned long l;
++
++	h = TIMER3_CONTROL_REG & 0xFFFF;
++	l = TIMER3_COUNTER_LOW_REG;
++
++	return ((((unsigned long long)h) << 32) | l);
++}
++#endif
++
++#endif	// end of #ifndef _STAR_TIMER_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_uart.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_uart.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_uart.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_uart.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,350 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_UART_H_
++#define	_STAR_UART_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#define	UART_MEM_MAP_VALUE_PHY(reg_offset)	(*((u32	volatile *)(SYSPA_UART0_BASE_ADDR + reg_offset)))
++#define	UART_MEM_MAP_VALUE_VIR(reg_offset)	(*((u32	volatile *)(SYSVA_UART0_BASE_ADDR + reg_offset)))
++
++
++#define	UART1_OFFSET		0x800000  //SYS_UART1_BASE_ADDR	= 0x78800000 = (UART1_OFFSET+ SYS_UART0_BASE_ADDR)
++
++#define	__UART_RBR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	__UART_THR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	__UART_DLL(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++
++#define	__UART_IER(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++#define	__UART_DLM(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++
++#define	__UART_IIR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	__UART_FCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	__UART_PSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++
++#define	__UART_LCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x0C)
++#define	__UART_MCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x10) //UART(n) Control Reg
++#define	__UART_LSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x14)
++#define	__UART_SPR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x1C)
++
++#if defined(__UBOOT__)
++#define	_UART_RBR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	_UART_THR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	_UART_DLL(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++
++#define	_UART_IER(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++#define	_UART_DLM(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++
++#define	_UART_IIR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	_UART_FCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	_UART_PSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++
++#define	_UART_LCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x0C)
++#define	_UART_MCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x10) //UART(n) Control Reg
++#define	_UART_LSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x14)
++#define	_UART_SPR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x1C)
++#elif defined(__LINUX__)
++#define	_UART_RBR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x00)
++#define	_UART_THR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x00)
++#define	_UART_DLL(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x00)
++
++#define	_UART_IER(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x04)
++#define	_UART_DLM(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x04)
++
++#define	_UART_IIR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x08)
++#define	_UART_FCR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x08)
++#define	_UART_PSR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x08)
++
++#define	_UART_LCR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x0C)
++#define	_UART_MCR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x10) //UART(n) Control Reg
++#define	_UART_LSR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x14)
++#define	_UART_SPR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x1C)
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define constants macros
++ */
++#define	UART_INPUT_CLOCK		(13000000)
++
++
++#define	UART_FIFO_DEPTH			16
++
++
++#define	RX_DATA_READY_INT		(1 << 0)
++#define	THR_EMPTY_INT			(1 << 1)
++#define	RX_LINE_STATUS_INT		(1 << 2)
++#define	MODEM_STATUS_INT		(1 << 3)
++
++
++#define	NO_INT_PENDING_MASK		(0x1)
++#define	RX_LINE_STATUS_INT_MASK		(0x6)
++#define	RX_DATA_READY_INT_MASK		(0x4)
++#define	RX_DATA_TIMEOUT_INT_MASK	(0xC)
++#define	THR_EMPTY_INT_MASK		(0x2)
++#define	MODEM_STATUS_CHANGE_MASK	(0x0)
++
++
++/* FCR Register	*/
++#define	FIFO_ENABLE			(1 << 0)
++#define	RX_FIFO_RESET			(1 << 1)
++#define	TX_FIFO_RESET			(1 << 2)
++#define	DMA_MODE			(1 << 3)
++
++
++#define	RX_FIFO_TRIGGER_LEVEL_1		(0 << 6)
++#define	RX_FIFO_TRIGGER_LEVEL_4		(1 << 6)
++#define	RX_FIFO_TRIGGER_LEVEL_8		(2 << 6)
++#define	RX_FIFO_TRIGGER_LEVEL_14	(3 << 6)
++
++
++#define	TX_FIFO_TRIGGER_LEVEL_1		(0 << 4)
++#define	TX_FIFO_TRIGGER_LEVEL_3		(1 << 4)
++#define	TX_FIFO_TRIGGER_LEVEL_9		(2 << 4)
++#define	TX_FIFO_TRIGGER_LEVEL_13	(3 << 4)
++
++
++
++/* LCR Register	*/
++#define	WORD_LENGTH_5			(0 << 0)
++#define	WORD_LENGTH_6			(1 << 0)
++#define	WORD_LENGTH_7			(2 << 0)
++#define	WORD_LENGTH_8			(3 << 0)
++
++#define	STOP_BIT_1			(0 << 2)
++#define	STOP_BIT_1_5			(1 << 2)
++#define	STOP_BIT_2			(1 << 2)
++
++#define	PARITY_CHECK_NONE		(0 << 3)
++#define	PARITY_CHECK_EVEN		(3 << 3)
++#define	PARITY_CHECK_ODD		(1 << 3)
++#define	PARITY_CHECK_STICK_ONE		(5 << 3)
++#define	PARITY_CHECK_STICK_ZERO		(7 << 3)
++
++#define	SET_BREAK			(1 << 6)
++
++#define	DLAB_ENABLE			(1 << 7)
++
++/* MCR Register	*/
++//#define UART_MCR_DTR			0x1		/* Data	Terminal Ready */
++//#define UART_MCR_RTS			0x2		/* Request to Send */
++//#define UART_MCR_OUT1			0x4		/* output1 */
++//#define UART_MCR_OUT2			0x8		/* output2 or global interrupt enable */
++#define	UART_MCR_LPBK			0x10		/* loopback mode */
++
++
++/* LSR Register	*/
++#define	_DATA_READY			(1 << 0)
++#define	OVERRUN_ERROR			(1 << 1)
++#define	PARITY_ERROR			(1 << 2)
++#define	FRAMING_ERROR			(1 << 3)
++#define	BREAK_INTERRUPT			(1 << 4)
++#define	THR_EMPTY			(1 << 5)
++#define	TRANSMITTER_EMPTY		(1 << 6)
++#define	FIFO_DATA_ERROR			(1 << 7)
++
++#define	TEST_PARITY_ERROR		(1 << 0)
++#define	TEST_FRAMING_ERROR		(1 << 1)
++#define	TEST_BAUD_GEN			(1 << 2)
++#define	TEST_LOOPBACK_ENABLE		(1 << 3)
++
++
++#define	WORD_FIVE_BITS			5
++#define	WORD_SIX_BITS			6
++#define	WORD_SEVEN_BITS			7
++#define	WORD_EIGHT_BITS			8
++
++#define	NONE_PARITY			1
++#define	EVEN_PARITY			2
++#define	ODD_PARITY			3
++#define	ONE_PARITY			4
++#define	ZERO_PARITY			5
++
++#define	ONE_STOP_BIT			1
++#define	ONE_HALF_STOP_BIT		2
++#define	TWO_STOP_BIT			3
++
++#define	TX_RX_FIFO_DISABLE		0
++#define	TX_RX_FIFO_ENABLE		1
++
++
++/*
++ * macros declarations
++ */
++
++#define	HAL_UART_READ_DATA(idx,data) \
++{ \
++    ((data) = (_UART_RBR(idx)) & 0xFF);	\
++}
++
++
++#define	HAL_UART_WRITE_DATA(idx,data) \
++{ \
++    ((_UART_THR(idx)) =	(data) & 0xFF);	\
++}
++
++
++#define	HAL_UART_ENABLE_INTERRUPT_TYPE(idx,interrupt_type) \
++{ \
++    ((_UART_IER(idx)) |= (interrupt_type & 0xF)); \
++}
++
++
++#define	HAL_UART_DISABLE_INTERRUPT_TYPE(idx,interrupt_type) \
++{ \
++    ((_UART_IER(idx)) &= ~(interrupt_type & 0xF)); \
++}
++
++
++#define	HAL_UART_READ_INTERRUPT_IDENTIFICATION(idx,uart_IIR) \
++{ \
++    ((uart_IIR)	= (_UART_IIR(idx))); \
++}
++
++
++#define	HAL_UART_CHECK_NO_INT_PENDING(idx,uart_IIR) \
++{ \
++    (((uart_IIR) & 0xF)	== (NO_INT_PENDING_MASK)); \
++}
++
++
++#define	HAL_UART_CHECK_RX_LINE_STATUS_INT(idx,uart_IIR)	\
++    (((uart_IIR) & 0xF)	== (RX_LINE_STATUS_INT_MASK))
++
++
++#define	HAL_UART_CHECK_RX_DATA_READY_INT(idx,uart_IIR) \
++    (((uart_IIR) & 0xF)	== (RX_DATA_READY_INT_MASK))
++
++
++#define	HAL_UART_CHECK_RX_DATA_TIMEOUT_INT(idx,uart_IIR) \
++    (((uart_IIR) & 0xF)	== (RX_DATA_TIMEOUT_INT_MASK))
++
++
++#define	HAL_UART_CHECK_THR_EMPTY_INT(idx,uart_IIR) \
++    (((uart_IIR) & 0xF)	== (THR_EMPTY_INT_MASK))
++
++
++#define	HAL_UART_FIFO_ENABLE(idx) \
++{ \
++    ((_UART_FCR(idx)) |= (FIFO_ENABLE)); \
++}
++
++
++#define	HAL_UART_FIFO_DISABLE(idx) \
++{ \
++    ((_UART_FCR(idx)) &= ~(FIFO_ENABLE)); \
++}
++
++
++#define	HAL_UART_RESET_RX_FIFO(idx) \
++{ \
++   ((_UART_FCR(idx)) |=	(RX_FIFO_RESET)); \
++}
++
++
++#define	HAL_UART_RESET_TX_FIFO(idx) \
++{ \
++    ((_UART_FCR(idx)) |= (TX_FIFO_RESET)); \
++}
++
++
++#define	HAL_UART_DLAB_ENABLE(idx) \
++{ \
++    ((_UART_LCR(idx)) |= (DLAB_ENABLE)); \
++}
++
++
++#define	HAL_UART_DLAB_DISABLE(idx) \
++{ \
++    ((_UART_LCR(idx)) &= ~(DLAB_ENABLE)); \
++}
++
++
++#define	HAL_UART_ENABLE_LOOPBACK_MODE(idx) \
++{ \
++    ((_UART_MCR(idx)) |= (UART_MCR_LPBK)); \
++}
++
++
++#define	HAL_UART_DISABLE_LOOPBACK_MODE(idx) \
++{ \
++    ((_UART_MCR(idx)) &= ~(UART_MCR_LPBK)); \
++}
++
++
++#define	HAL_UART_READ_LINE_STATUS(idx,uart_LSR)	\
++{ \
++    ((uart_LSR)	= (_UART_LSR(idx))); \
++}
++
++
++#define	HAL_UART_WRITE_DLL(idx,dll_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    _UART_DLL(idx) = (u32)dll_value; \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_WRITE_DLM(idx,dlm_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    _UART_DLM(idx) = (u32)dlm_value; \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_WRITE_PSR(idx,psr_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    _UART_PSR(idx) = (u32)(psr_value & 0x3); \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_READ_PSR(idx,psr_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    (psr_value)	= (u32)((_UART_PSR(idx)) & 0x3); \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_CHECK_RX_DATA_READY(idx) \
++    (((_UART_LSR(idx)) & _DATA_READY) == (_DATA_READY))
++
++
++#define	HAL_UART_CHECK_TX_FIFO_EMPTY(idx) \
++    (((_UART_LSR(idx)) & THR_EMPTY) == (THR_EMPTY))
++
++
++#define	HAL_UART_CHECK_TRANSMITTER_EMPTY(idx) \
++    (((_UART_LSR(idx)) & TRANSMITTER_EMPTY) == (TRANSMITTER_EMPTY))
++
++
++#endif	// end of #ifndef _STAR_UART_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_wdtimer.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_wdtimer.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/star_wdtimer.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/star_wdtimer.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,170 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_WATCHDOG_TIMER_H_
++#define	_STAR_WATCHDOG_TIMER_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	WDTIMER_MEM_MAP_VALUE(reg_offset)	(*((u32	volatile *)(SYSPA_WATCHDOG_TIMER_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	WDTIMER_MEM_MAP_VALUE(reg_offset)	(*((u32	volatile *)(SYSVA_WATCHDOG_TIMER_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	WDTIMER_COUNTER_REG			WDTIMER_MEM_MAP_VALUE(0x00)
++#define	WDTIMER_AUTO_RELOAD_REG			WDTIMER_MEM_MAP_VALUE(0x04)
++#define	WDTIMER_COUNTER_RESTART_REG		WDTIMER_MEM_MAP_VALUE(0x08)
++#define	WDTIMER_CONTROL_REG			WDTIMER_MEM_MAP_VALUE(0x0C)
++#define	WDTIMER_STATUS_REG			WDTIMER_MEM_MAP_VALUE(0x10)
++#define	WDTIMER_CLEAR_REG			WDTIMER_MEM_MAP_VALUE(0x14)
++#define	WDTIMER_INTERRUPT_LENGTH_REG		WDTIMER_MEM_MAP_VALUE(0x18)
++
++
++/*
++ * define constants macros
++ */
++#define	WDTIMER_ENABLE_BIT			(1 << 0)
++#define	WDTIMER_SYSTEM_RESET_ENABLE_BIT		(1 << 1)
++#define	WDTIMER_SYSTEM_INTERRUPT_ENABLE_BIT	(1 << 2)
++#define	WDTIMER_EXTERNAL_SIGNAL_ENABLE_BIT	(1 << 3)
++#define	WDTIMER_EXTERNAL_CLOCK_ENABLE_BIT	(1 << 4)
++
++
++#define	WDTIMER_MAGIC_RESTART_VALUE		(0x5AB9)
++
++
++/*
++ * macros declarations
++ */
++#define	HAL_WDTIMER_READ_COUNTER(counter) \
++{ \
++    ((counter) = (WDTIMER_COUNTER_REG)); \
++}
++
++
++#define	HAL_WDTIMER_WRITE_AUTO_RELOAD_COUNTER(counter) \
++{ \
++    ((WDTIMER_AUTO_RELOAD_REG) = (counter)); \
++}
++
++
++#define	HAL_WDTIMER_READ_AUTO_RELOAD_COUNTER(counter) \
++{ \
++    ((counter) = (WDTIMER_AUTO_RELOAD_REG)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_RESTART_RELOAD() \
++{ \
++    ((WDTIMER_COUNTER_RESTART_REG) = (WDTIMER_MAGIC_RESTART_VALUE)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_SYSTEM_RESET() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_SYSTEM_RESET_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE_SYSTEM_RESET() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_SYSTEM_RESET_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_SYSTEM_INTERRUPT() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_SYSTEM_INTERRUPT_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE_SYSTEM_INTERRUPT() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_SYSTEM_INTERRUPT_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_EXTERNAL_SIGNAL() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_EXTERNAL_SIGNAL_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE_EXTERNAL_SIGNAL() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_EXTERNAL_SIGNAL_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_CLOCK_SOURCE_PCLK()	\
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_EXTERNAL_CLOCK_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_CLOCK_SOURCE_EXTCLK() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_EXTERNAL_CLOCK_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_READ_STATUS(status)	\
++{ \
++    ((status) =	(WDTIMER_STATUS_REG) & 0x00000001); \
++}
++
++
++#define	HAL_WDTIMER_CLEAR_STATUS() \
++{ \
++    ((WDTIMER_CLEAR_REG) = (1)); \
++}
++
++
++#define	HAL_WDTIMER_WRITE_INTERRUPT_LENGTH(length) \
++{ \
++    ((WDTIMER_INTERRUPT_LENGTH_REG) = (length) & 0x000000FF); \
++}
++
++
++#endif	// end of #ifndef _STAR_WATCHDOG_TIMER_H_
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/system.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/system.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/system.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,50 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_SYSTEM_H__
++#define __ASM_ARCH_SYSTEM_H__
++
++#include <mach/star_powermgt.h>
++#include <mach/star_timer.h>
++
++static inline void arch_idle(void)
++{
++	volatile u32 dst= (*((u32 volatile *)(SYSVA_FLASH_BASE_ADDR + 0x20000)));
++
++// local_irq_enable();
++
++	cpu_do_idle();
++}
++
++static inline void arch_reset(char mode, const char *cmd)
++{
++	HAL_PWRMGT_GLOBAL_SOFTWARE_RESET();
++}
++
++extern u64 volatile str8100_counter_tick;
++static inline u64 str8100_read_counter(void)
++{
++        return (str8100_counter_tick + TIMER2_COUNTER_REG);
++}
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/timex.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/timex.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/timex.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,33 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_TIMEX_H__
++#define __ASM_ARCH_TIMEX_H__
++
++#if 1 // on ASIC
++#define CLOCK_TICK_RATE		(43750000)
++#else // on FPGA
++#define CLOCK_TICK_RATE		(13000000)
++#endif
++
++#endif /* __ASM_ARCH_TIMEX_H__ */
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/uncompress.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/uncompress.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/uncompress.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,87 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_UNCOMPRESS_H__
++#define __ASM_ARCH_UNCOMPRESS_H__
++
++#include <mach/star_uart.h>
++
++#define flush(x)	
++
++
++static void putstr(const char *s)
++{
++	while (*s) {
++		volatile unsigned int status = 0;
++
++		do {
++			status = __UART_LSR(0);
++		} while (!((status & THR_EMPTY) == THR_EMPTY));
++
++		__UART_THR(0) = *s;
++
++		if (*s == '\n') {
++			do {
++				status = __UART_LSR(0);
++			} while (!((status & THR_EMPTY) == THR_EMPTY));
++			__UART_THR(0) = '\r';
++		}
++		s++;
++	}
++}
++
++static const char * const digits="0123456789ABCDEF";
++static void ser_puts_hex8(unsigned char hex)
++{ 
++   char buf[3];
++   buf[0] = digits[(hex >> 4) & 0xF];
++   buf[1] = digits[hex & 0xF];
++      
++   buf[2] = '\0';
++   putstr(buf);
++}
++void ser_puts_hex32(unsigned long hex)
++{
++   char buf[9];
++   int i;
++   
++   for(i=7; i >= 0; i--)
++   {
++      buf[7-i] = digits[(hex >> (i * 4)) & 0xF];
++   }
++   
++   buf[8] = '\0';
++  putstr(buf);
++}
++
++/*
++static void putc(int c)
++{
++ star_putstr(&c);
++}
++
++*/
++#define arch_decomp_setup()
++#define arch_decomp_wdog()
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/include/mach/vmalloc.h linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/vmalloc.h
+--- linux-2.6.35.11/arch/arm/mach-str8100/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/include/mach/vmalloc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,31 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __ASM_ARCH_VMALLOC_H__
++#define __ASM_ARCH_VMALLOC_H__
++
++//#include <linux/config.h>
++
++#define VMALLOC_END	(PAGE_OFFSET + 0x10000000)
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/Kconfig linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Kconfig
+--- linux-2.6.35.11/arch/arm/mach-str8100/Kconfig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,143 @@
++if ARCH_STR8100
++
++menu "STR8100 Options"
++
++config CONSOLE_BAUD_RATE
++	int "Console Baud Rate"
++	default 38400
++	help
++	  set the console baudrate
++
++config VIC_INTERRUPT
++	bool "Enable Vector Interrupt Controller"
++	default y
++	help
++	  enable the vector interrupt controller
++
++choice
++	prompt "DRAM SIZE"
++	default STR8100_DRAM_16M
++
++config STR8100_DRAM_16M
++	bool "16MBytes"
++
++config STR8100_DRAM_32M
++	bool "32MBytes"
++
++config STR8100_DRAM_64M
++	bool "64MBytes"
++
++endchoice
++
++if PCI
++choice
++	prompt "PCI Frequency"
++	default STR8100_PCI33M
++
++config STR8100_PCI33M
++	bool "PCI_33Mhz"
++
++config STR8100_PCI66M
++	bool "PCI_66Mhz"
++
++endchoice
++endif
++
++config STR8100_DMA
++	bool "Enable DMA Controller"
++	default n
++	help
++	  enable the DMA controller
++
++config STR8100_HSDMA
++	bool "Enable HSDMA Controller"
++	default n
++	help
++	  enable the HSDMA controller
++
++config STR8100_INFO
++	bool "STR8100 Infomation at /proc/str8100/info"
++
++config STR8100_USBD_REBOOT_INTHANDLER
++	tristate "USB Mass Storage Device"
++
++config STR8100_I2S
++	bool "Enable I2S sound"
++	default n
++	help
++	  enable the I2S sound with /proc/str8100/i2s
++
++config STR8100_I2S_DEMO
++	tristate "Enable I2S sound demo driver"
++	default n
++	help
++	  enable the I2S sound demo driver with /proc/str8100/i2s
++
++config STR8100_I2S_WM8772_DEMO
++	tristate "Enable I2S sound demo driver with WM8772"
++	default n
++	help
++	  enable the I2S sound demo driver with wm8772
++
++config LE88221_CONTROL
++	bool "Legerity LE88221 Control Support"
++	depends on SPI
++
++config STR8100_PCM_LEGERITY_2PHONE_DEMO
++	tristate "2 phone PCM sound demo driver for Legerity"
++	select LE88221_CONTROL
++	default n
++
++config STR8100_RTC
++	bool "STR8100 Real Time Clock Support"
++
++config STR8100_GPIO
++	bool "STR8100 GPIO Support"
++	
++config STR8100_GPIO_INTERRUPT
++	bool "Interrupt Library Support"
++	depends on STR8100_GPIO	
++
++config STR8100_GPIO_GENERIC_INTERFACE
++	bool "Generic GPIO Interface Support"
++	depends on STR8100_GPIO	
++	select GENERIC_GPIO
++
++comment "Flash MAP"
++config STR8100_FLASH_PART
++	bool "STR8100 flash partition setting"
++
++if STR8100_FLASH_PART
++	config ARMBOOT_OFFSET
++	hex "ARMBOOT OFFSET"
++	default 0x0
++	help
++	  The armboot start offset in flash layout
++
++	config KERNEL_OFFSET
++	hex "KERNEL OFFSET"
++	default 0x40000
++	help
++	  The kernel start offset in flash layout
++
++	config ROOTFS_OFFSET
++	hex "ROOTFS OFFSET"
++	default 0x140000
++	help
++	  The rootfs start offset in flash layout
++
++	config CFG_OFFSET
++	hex "CFG OFFSET"
++	default 0x7f0000
++	help
++	  The cfg start offset in flash layout
++endif
++
++
++comment "Third Party Support"
++
++config STR8100_EWC_SUPPORT
++	bool "EWC(802.11N) Support"
++endmenu
++
++endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/le88221_control.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/le88221_control.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/le88221_control.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/le88221_control.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,1037 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/interrupt.h>
++#include <linux/spi/spi.h>
++#include <linux/delay.h>
++#include <asm/semaphore.h>
++#include <mach/star_spi.h>
++
++static struct spi_device *le88221_spidev;
++static struct semaphore le88221_lock;
++
++/******************************************************************************
++* Busy Tone
++* Frequency: 480Hz + 620Hz
++* Temporal Pattern: 0.5s on/ 0.5s off
++* Event Reported After: 2 cycles of precise, 3 cycles of nonprecise
++*******************************************************************************/
++void le88221_busy_tone(struct spi_device *spi)
++{
++	u8 rx_data;
++	u8 write_data;
++	int retval;
++
++	//enable channel 1 and channel 2
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator 
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator C and D    
++	// 05 1F 1C C5 06 9D 1C C5
++	//FreqC= 1311(0x051f) * 0.3662 = 480.0882 Hz
++	//AmpC = 7365(0x1cc5) * 
++	//FreqD= 1693(0x069d) * 0.3662 = 619.9766 Hz
++	//AmpCD= 7365(0x1cc5) *
++	write_data = 0xD4;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x05;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xC5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x06;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x9D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xC5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Cadence Timer
++	// 00 64 00 64 (100ms On/ 100ms Off)
++	write_data = 0xE0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x64;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x64;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator
++	//Eanble Signal generator cadencing, Signal generator C,D
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x8C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System State
++	//Activate codec, Active Low battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x23;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++}
++
++/******************************************************************************
++* Dial Tone
++* Frequency: 350Hz + 440Hz
++* Temporal Pattern: Steady tone
++* Event Reported After: Approximately 0.75 seconds
++*******************************************************************************/
++void spi_le88221_dial_tone(struct spi_device *spi)
++{
++	u8 rx_data;
++	u8 write_data;
++	int retval;
++
++	//enable channel 1 and channel 2
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator 
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator C and D    
++	// 03 BC 1C C5 04 B2 1C C5
++	write_data = 0xD4;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xBC;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xC5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x04;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xB2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xC5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Cadence Timer
++	// 00 00 00 00
++	write_data = 0xE0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator
++	//Eanble Signal generator cadencing, Signal generator C,D
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x8C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System State
++	//Activate codec, Active Low battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x23;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++}
++
++void le88221_balanced_ring(struct spi_device *spi)
++{
++	u8 rx_data;
++	u8 write_data;
++	int retval;
++ 
++	//enable channel 1 and channel 2
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Write Signal Generator A,B and Bias Param
++	// 00 00 00 00 37 42 5B 00 00 00 00
++	//0x00:Ramp has a positive slope, SG A,B out continuous, sinusoidal waves
++	//Bias : 0 (0x0000) V
++	//FreqA: 55(0x0037) * 0.3662 = 20.141 Hz 
++	//AmpA : 16987(0x425B)
++	//FreqB: 0(0x0000) * 0.3662 = 0 Hz
++	//AmpB : 0(0x0000)
++	write_data = 0xD2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x37;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x5B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System State
++	//Activate codec, Active Mid Battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x2B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Loop Supervision Param
++	// 1B 84 B3 05
++	write_data = 0xC2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x84;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xB3;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x05;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System state        
++	//Deactivate codec, Balanced ringing
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x07;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++}
++
++void le88221_unbalanced_ring(struct spi_device *spi)
++{
++	u8 rx_data;
++	u8 write_data;
++	int retval;
++
++	//enable channel 1 and channel 2
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator 
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Cadence Timer
++	//01 90 03 20 (400ms on/800ms off)
++	write_data = 0xE0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x90;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x20;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Signal generator 
++	// Enable tone generator specified by EGA...
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x80;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Write Signal Generator A,B and Bias Param
++	// 00 00 00 00 37 21 2D 00 00 00 00
++	//0x00:Ramp has a positive slope, SG A,B out continuous, sinusoidal waves
++	//Bias : 0(0x0000) V
++	//FreqA: 55(0x0037) * 0.3662 = 20.141 Hz 
++	//AmpA : 8493(0x212D)
++	//FreqB: 0(0x0000) * 0.3662 = 0 Hz
++	//AmpB : 0(0x0000)
++	write_data = 0xD2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x37;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x21;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x2D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System State
++	//Activate codec, Active Mid Battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x2B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set Loop Supervision Param
++	// 1B 84 33 05
++	write_data = 0xC2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x1B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x84;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x33;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x05;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++
++	//Set System state        
++	//Deactivate codec, Balanced ringing
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0x0A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++}
++
++u32 le88221_hook_off(struct spi_device *spi)
++{
++	u8 rx_data;
++	u8 rx_data21, rx_data22;
++	u8 write_data;
++	int retval;
++
++	/* if Hook1/2 off hook status at the same time */ 	        	    
++	/*
++	 * Check Hook1/2 On or Off (Read Signaling Register)
++	 * Hook Switch, 0:On hook , 1:Off hook
++	 */
++	write_data = 0x4F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data21, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &rx_data22, 1);
++
++	return ((rx_data21 & 0x01) && (rx_data22 & 0x01));
++}
++
++static int le88221_init_hw(struct spi_device *spi)
++{
++#if 0
++	int retval;
++	u8 write_data;
++	u8 read_data;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	if (retval < 0) {
++
++	}
++#endif
++
++#if 0
++	u8 tx_buf[] = { 0x00, 0x00, 0x00, 0x00 };
++	u8 rx_buf[] = { 0x00, 0x00, 0x00, 0x00 };
++	struct spi_transfer t[2];
++	struct spi_message m;
++
++	spi_message_init(&m);
++	memset(t, 0, (sizeof t));
++
++	t[0].tx_buf = tx_buf;
++	t[0].len = sizeof(tx_buf);
++	spi_message_add_tail(&t[0], &m);
++
++	t[1].rx_buf = rx_buf;
++	t[1].len = sizeof(rx_buf);
++	spi_message_add_tail(&t[1], &m);
++
++	down(&le88221_lock);
++	spi_sync(flash->spi, &m);
++	up(&le88221_lock);
++
++#endif
++
++	int retval;
++	u8 write_data;
++	u8 read_data;
++
++	// Hardware Reset
++	write_data = 0x04;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// 1ms delay
++	udelay(1000);
++
++	// I/O direction
++	write_data = 0x54;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x02;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x55;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	// Write Device Register(Define PCLK freq,ie 2.048MHz)
++	write_data = 0x46;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x02;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	write_data = 0x47;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Read Revision Code Number (RCN)
++	write_data = 0x73;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	printk("Revision:0x%02x\n", read_data);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	printk("Product:0x%02x\n", read_data);
++
++	/* 
++	 * Write SRP register for Flyback power supply(VBL reference) 
++	 * Note there should be voltages on VBH, VBL, VREF after the following codes are invoked.
++	 */
++	write_data = 0xE4;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x05;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x80;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0xE5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++    
++	// Write SRC register
++	write_data = 0xE6;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x07;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0xE7;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);   
++#endif
++    
++    	// wait 100ms delay until switing regulator is stable
++	mdelay(100);
++
++	// System State Register
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#ifdef Print_Reg
++	write_data = 0x57;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif    
++
++	// I/O Data Register
++	write_data = 0x52;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x53;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif        
++
++	/*
++	 * For channel 1,2 operation
++	 */
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x03;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x4B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	// Operating Functions
++	write_data = 0x60;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x61;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	// Operating Conditions
++	write_data = 0x70;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x71;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	// Loop Supervision Parameters  19 88 A4 00 */
++	write_data = 0xC2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x19;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x88;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA4;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// DC Feed Parameters  2C 08
++	write_data = 0xC6;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x08;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Signal Generator A and B Parameters  00 04 25 00 37 3E C3 00 00 00 00
++	write_data = 0xD2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x04;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x25;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x37;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3E;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xC3;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x44;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x68;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x35;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Digital Impedance Scaling Network
++	write_data = 0xCA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xEA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0xCB;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++    
++	// Z-Filter (FIR Only) Coefficients BA EB 2A 2C B5 25 AA 24 2C 3D
++	write_data = 0x98;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xBA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xEB;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xB5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x25;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xAA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x24;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Z-Filter (IIR Only) Coefficients  AA BA 27 9F 01
++	write_data = 0x9A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xAA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xBA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x27;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x9F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// R-Filter Coefficients  2D 01 2B B0 5A 33 24 5C 35 A4 5A 3D 33 B6
++	write_data = 0x8A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xB0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x5A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x33;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x24;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x5C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x35;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA4;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x5A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x33;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xB6;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// X-Filter Coefficients 3A 10 3D 3D B2 A7 6B A5 2A CE 2A 8F
++	write_data = 0x88;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x10;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x3D;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xB2;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA7;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x6B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xCE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x8F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// GR (Receive Gain A8 71
++	write_data = 0x82;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA8;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x71;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// GX (Transmit Gain) A9 F0
++	write_data = 0x80;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA9;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xF0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Voice Path Gains
++	write_data = 0x50;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef PRINT_REG
++	write_data = 0x51;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	// B1-Filter (FIR Only) Coefficients  2A 42 22 4B 1C A3 A8 FF 8F AA F5 9F BA F0
++	write_data = 0x86;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x22;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x4B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x1C;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA3;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xA8;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x8F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xAA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xF5;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x9F;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xBA;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xF0;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// B2-Filter (IIR Only) Coefficients 2E 01
++	write_data = 0x96;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x2E;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++ 	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);   
++
++	//le88221_busy_tone(spi);
++	//le88221_dial_tone(spi);
++	//le88221_balanced_ring(spi);
++	le88221_unbalanced_ring(spi);
++
++#if 1
++	while (!le88221_hook_off(spi))
++		; // do nothing
++#endif
++
++#ifdef OPEN_CH1_2
++	SPI_DEBUG("=== Configure channel 1...\n");
++	/*
++	 * For channel 1 operation, Active mode
++	 */
++	//Set Channel Enable and Operating Mode
++	//Channel 1 enabled, Channel 2 disabled
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set Signal generator
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set Operating Conditions
++	//0x00 : all disabled
++	write_data = 0x70;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set System state
++	//Activate codec, Active Low Battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x23;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	/*
++	 * If you want loopback test , you can TX_Time_Slot 00, TX_Time_Slot 02
++	 */
++	//Set Transmit time slot
++	write_data = 0x40;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++#ifdef LEGERITY_LOOPBACK_TEST
++	//Set Receive time slot
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x02;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#else
++	//Set Receive time slot
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif                                        
++
++	//Read Register Status
++	write_data = 0x4B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read Register Status(0x4B): channel 1 %s, channel 2 %s\n",(rx_data&0x01)?"enabled":"disabled",(rx_data&0x02)?"enabled":"disabled");
++
++	//Read System State Register
++	write_data = 0x57;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read System State Register(0x57): REX=%d, METR=%d, Codec %s, POLNR=%d, SS=0x%x\n",(rx_data&(1<<7)),(rx_data&(1<<6)),(rx_data&(1<<5))?"enabled":"disabled",(rx_data&(1<<4)),(rx_data&0xF));
++    
++	//Read Transmit time slot
++	write_data = 0x41;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Read Receive time slot
++	write_data = 0x43;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	SPI_DEBUG("=== Configure channel 2...\n");
++	/* 
++	 * For channel 2 operation, Active mode 
++	 */
++	//Set Channel Enable and Operating Mode
++	//Channel 1 disabled, Channel 2 enabled
++	write_data = 0x4A;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x02;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set Signal generator
++	//0x00: all disabled
++	write_data = 0xDE;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set Operating Conditions
++	//0x00 : all disabled
++	write_data = 0x70;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	//Set System state
++	//Activate codec, Active Low Battery
++	write_data = 0x56;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x23;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	/*
++	 * If you want loopback test , you can TX_Time_Slot 00, TX_Time_Slot 02 
++	 */
++#ifdef LEGERITY_LOOPBACK_TEST
++	// Transmit time slot
++	write_data = 0x40;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x02;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Receive time slot
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x00;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#else
++	// Transmit time slot
++	write_data = 0x40;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++
++	// Receive time slot
++	write_data = 0x42;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0x01;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++#endif
++
++	//Read Register Status
++	write_data = 0x4B;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read Register Status(0x4B): channel 1 %s, channel 2 %s\n",(rx_data&0x01)?"enabled":"disabled",(rx_data&0x02)?"enabled":"disabled");
++
++	//Read System State Register
++	write_data = 0x57;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read System State Register(0x57): REX=%d, METR=%d, Codec %s, POLNR=%d, SS=0x%x\n",(rx_data&(1<<7)),(rx_data&(1<<6)),(rx_data&(1<<5))?"enabled":"disabled",(rx_data&(1<<4)),(rx_data&0xF));
++
++	//Read Transmit time slot
++	write_data = 0x41;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read Transmit time slot(0x41): Transmit time slot = 0x%02x\n",rx_data&0x7f);
++
++	//Read Receive time slot
++	write_data = 0x43;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	write_data = 0xFF;
++	retval = spi_write_read_sync(spi, &write_data, 1, &read_data, 1);
++	SPI_DEBUG("Read Receive time slot(0x43): Receive time slot = 0x%02x\n",rx_data&0x7f);
++#endif      
++
++	return 0;
++}
++
++void Pcm_Initial_Legerity_Le88221(void)
++{
++	le88221_init_hw(le88221_spidev);
++}
++
++static int __devinit le88221_probe(struct spi_device *spi)
++{
++	le88221_spidev = spi;
++	init_MUTEX(&le88221_lock);
++	return 0;
++}
++
++static int __devexit le88221_remove(struct spi_device *spi)
++{
++	printk("le88221_remove() enter\n");
++	return 0;
++}
++
++static struct spi_driver le88221_driver = {
++	.driver = {
++		.name	= "le88221",
++		.bus	= &spi_bus_type,
++		.owner	= THIS_MODULE,
++	},
++	.probe	= le88221_probe,
++	.remove	= __devexit_p(le88221_remove),
++};
++
++static int le88221_init(void)
++{
++	return spi_register_driver(&le88221_driver);
++}
++
++static void le88221_exit(void)
++{
++	spi_unregister_driver(&le88221_driver);
++}
++
++module_init(le88221_init);
++module_exit(le88221_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Star Semi");
++MODULE_DESCRIPTION("Legerity Le88221 driver");
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/Makefile linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Makefile
+--- linux-2.6.35.11/arch/arm/mach-str8100/Makefile	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,26 @@
++#
++# Makefile for the linux kernel.
++#
++
++# Object file lists.
++
++str8100_demo_pcm_legerity_2phone-objs := str8100_demo_pcm_legerity_config_2phone.o
++str8100_demo_i2s-objs := str8100_demo_i2s_config.o
++str8100_demo_i2s_wm8772-objs := str8100_demo_i2s_wm8772_config.o
++
++obj-y			:= str8100_debug.o str8100_setup.o str8100_timer.o str8100_intc.o str8100_misc.o str8100_counter.o str8100_pm.o str8100_demo_dma.o
++obj-m			:=
++obj-n			:=
++obj-			:=
++
++obj-$(CONFIG_PCI) += str8100_pci.o
++obj-$(CONFIG_STR8100_DMA) += str8100_dma.o
++obj-$(CONFIG_STR8100_HSDMA) += str8100_hsdma.o
++obj-$(CONFIG_STR8100_I2S) += str8100_i2s.o
++obj-$(CONFIG_STR8100_I2S_DEMO) += str8100_demo_i2s.o
++obj-$(CONFIG_STR8100_I2S_WM8772_DEMO) += str8100_demo_i2s_wm8772.o
++obj-$(CONFIG_LE88221_CONTROL) += le88221_control.o
++obj-$(CONFIG_STR8100_PCM_LEGERITY_2PHONE_DEMO) += str8100_demo_pcm_legerity_2phone.o
++obj-$(CONFIG_STR8100_RTC)	+= str8100_rtc.o
++obj-$(CONFIG_STR8100_GPIO)	+= str8100_gpio.o
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/Makefile.boot linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Makefile.boot
+--- linux-2.6.35.11/arch/arm/mach-str8100/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/Makefile.boot	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,11 @@
++# Note: the following conditions must always be true:
++#   ZRELADDR == virt_to_phys(TEXTADDR)
++#   PARAMS_PHYS must be within 4MB of ZRELADDR
++#   INITRD_PHYS must be in RAM
++
++   zreladdr-y	:= 0x00008000
++params_phys-y	:= 0x00000100
++initrd_phys-y	:= 0x00C00000
++# scott.test
++kernel_phys-y	:= 0x00600000
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_counter.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_counter.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_counter.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_counter.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,215 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/init.h>
++#include <linux/timex.h>
++#include <linux/proc_fs.h>
++#include <linux/module.h>
++
++#include <mach/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/time.h>
++
++u64 volatile str8100_counter_tick;
++EXPORT_SYMBOL(str8100_counter_tick);
++
++static struct proc_dir_entry *str8100_counter_proc_entry;
++
++#if 0
++// this is defined in include/asm/arch-str8100/system.h
++u64 str8100_read_counter(void)
++{
++	return (str8100_counter_tick + TIMER2_COUNTER_REG);
++}
++EXPORT_SYMBOL(str8100_read_counter);
++#endif
++
++static int match1=0;
++static int match2=0;
++static void str8100_setup_counter(void)
++{
++	unsigned long control_value;
++	unsigned long mask_value;    
++	unsigned long val;    
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++	mask_value = TIMER1_TIMER2_INTERRUPT_MASK_REG;
++
++	TIMER2_COUNTER_REG		= 0;
++	TIMER2_AUTO_RELOAD_VALUE_REG	= 0;
++	TIMER2_MATCH_VALUE1_REG		= match1;
++	TIMER2_MATCH_VALUE2_REG		= match2;
++
++	// Clock Source: PCLK
++	control_value &= ~(1 << TIMER2_CLOCK_SOURCE_BIT_INDEX);
++
++	// UP Count Mode
++	control_value &= ~(1 << TIMER2_UP_DOWN_COUNT_BIT_INDEX);
++
++	// un-mask match1, match2, and overflow interrupt sources
++	mask_value &= ~(0x7 << 3);
++
++	// mask match1, match2 interrupt sources
++	//mask_value |= (0x3 << 3);
++	val=0;
++	if(!match1) val|=0x1;
++	if(!match2) val|=0x2;
++	mask_value |= (val<< 3);
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++	TIMER1_TIMER2_INTERRUPT_MASK_REG = mask_value;
++}
++
++static void str8100_counter_enable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++
++	// enable overflow mode
++	control_value |= (1 << TIMER2_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value |= (1 << TIMER2_ENABLE_BIT_INDEX);
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++}
++
++static void str8100_counter_disable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++
++	// enable overflow mode
++	control_value &= ~(1 << TIMER2_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value &= ~(1 << TIMER2_ENABLE_BIT_INDEX);
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++}
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t
++str8100_counter_interrupt(int irq, void *dev_id /*, struct pt_regs *regs*/)
++{
++#ifndef CONFIG_VIC_INTERRUPT
++	// clear counter interrrupt status
++	TIMER1_TIMER2_INTERRUPT_STATUS_REG &= ~(1 << TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX);
++#endif
++	str8100_counter_tick += (1ULL << 32);
++	if(match1){
++		TIMER2_MATCH_VALUE1_REG=TIMER2_COUNTER_REG+match1;
++		TIMER1_TIMER2_INTERRUPT_MASK_REG |= (0x1<<3);
++	}
++	if(match2){
++		TIMER2_MATCH_VALUE2_REG=TIMER2_COUNTER_REG+match2;
++		TIMER1_TIMER2_INTERRUPT_MASK_REG |= (0x2<<3);
++	}
++	return IRQ_HANDLED;
++}
++
++static struct irqaction str8100_counter_irq = {
++	.name		= "STR8100 Counter Tick",
++	/* scott.patch */
++	.flags		= IRQF_DISABLED | IRQF_TIMER,
++	.handler	= str8100_counter_interrupt,
++};
++
++static int str8100_counter_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
++{
++	return sprintf(page, "str8100_counter_tick: %llu\n", str8100_counter_tick + TIMER2_COUNTER_REG);
++}
++
++
++static int
++str8100_counter_write_proc(struct file *file, const char __user *buffer,
++	unsigned long count, void *data)
++{
++	char *str;
++	char *cmd;
++
++	if (count > 0) {
++		str = (char *)buffer,
++		cmd = strsep(&str, "\t \n");
++		if (!cmd) goto err_out;
++		if (strcmp(cmd, "match1") == 0) {
++			u32 addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 10);
++			match1=addr;
++
++		} else if (strcmp(cmd, "match2") == 0) {
++			u32 addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 10);
++			match2=addr;
++
++
++		} else {
++			goto err_out;
++		}
++	}
++	if(match1){
++		TIMER2_MATCH_VALUE1_REG=TIMER2_COUNTER_REG+match1;
++		TIMER1_TIMER2_INTERRUPT_MASK_REG |= (0x1<<3);
++	}
++	if(match2){
++		TIMER2_MATCH_VALUE2_REG=TIMER2_COUNTER_REG+match2;
++		TIMER1_TIMER2_INTERRUPT_MASK_REG |= (0x2<<3);
++	}
++
++	return count;
++
++err_out:
++	return -EFAULT;
++}
++/*
++ * Set up timer interrupt, and return the current time in seconds.
++ */
++int __init str8100_counter_setup(void)
++{
++     
++	str8100_setup_counter();
++	setup_irq(INTC_TIMER2_BIT_INDEX, &str8100_counter_irq);
++	str8100_counter_enable();
++	str8100_counter_proc_entry = create_proc_entry("str8100/counter", S_IFREG | S_IRUGO, NULL);
++	if (str8100_counter_proc_entry) {
++		str8100_counter_proc_entry->read_proc = str8100_counter_read_proc;
++		str8100_counter_proc_entry->write_proc = str8100_counter_write_proc;
++	}
++
++	return 0;
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_debug.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_debug.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_debug.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_debug.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,47 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/types.h>
++#include <mach/hardware.h>
++
++void debug_puts(const char *s)
++{
++	while (*s) {
++		volatile unsigned int status = 0;
++		do {
++			status = _UART_LSR(0);
++		} while (!((status & THR_EMPTY) == THR_EMPTY));
++
++		_UART_THR(0) = *s;
++
++		if (*s == '\n') {
++			do {
++				status = _UART_LSR(0);
++			} while (!((status & THR_EMPTY) == THR_EMPTY));
++
++			_UART_THR(0) = '\r';
++		}
++		s++;
++	}
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_dma.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_dma.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_dma.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_dma.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,576 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//Options 
++//#define DEBUG_PRINT	
++//=================================================================================
++
++#include <linux/kernel.h>	/* printk() */
++#include <linux/delay.h>
++#include <mach/star_demo_dma.h>
++#include <mach/star_i2s.h>
++#include <mach/star_powermgt.h>
++#include <mach/star_misc.h>
++#include <mach/star_gpio.h>
++
++#ifdef DEBUG_PRINT
++#undef DEBUG_PRINT
++//#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++#define DEBUG_PRINT printk
++#else
++#define DEBUG_PRINT(arg...) 
++#endif
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_Dmac_Get_Channel_Transfer_Unit_Number
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++u32 Hal_Dmac_Get_Channel_Transfer_Unit_Number(u32 byte_size, u32 src_width)
++{
++    u32    transfer_unit_num;
++    
++    
++    if (src_width == DMAC_CH_SRC_WIDTH_8_BITS)  // 8-bit
++    {
++        transfer_unit_num = byte_size;
++    }
++    else if (src_width == DMAC_CH_SRC_WIDTH_16_BITS)  // 16-bit
++    {
++        if (byte_size % 2)
++        {
++            transfer_unit_num = (byte_size >> 1) + 1;
++        }
++        else
++        {
++            transfer_unit_num = (byte_size >> 1);
++        }
++    }
++    else if (src_width == DMAC_CH_SRC_WIDTH_32_BITS)  // 32-bit
++    {
++        if (byte_size % 4)
++        {
++            transfer_unit_num = (byte_size >> 2) + 1;
++        }
++        else
++        {
++            transfer_unit_num = (byte_size >> 2);
++        }
++    }
++    else
++    {
++        transfer_unit_num = 0;
++    }
++    
++    return transfer_unit_num;
++}
++EXPORT_SYMBOL(Hal_Dmac_Get_Channel_Transfer_Unit_Number);
++
++
++void Hal_Dmac_Configure_DMA_Handshake(DMAC_HARDWARE_HANDSHAKE_OBJ_T *dmac_obj)
++{
++    u32    channel_control, ch;
++
++    /*
++     * Configure DMA controller for UART's hardware DMA handshake mode
++     */    
++
++	/*
++	 * Stop mplayer will also stop PCM if disable GDMA Controller.
++	 * Changed to disable corresponding channels only.
++	 */
++	//HAL_DMAC_DISABLE();
++	for (ch = 0; ch < DMAC_MAX_CHANNEL_NUM; ch++)
++	{
++		if (dmac_obj->channel_id & DMAC_CH_ID(ch))
++			HAL_DMAC_DISABLE_CHANNEL(ch);
++	}
++	
++//#if (ENDIAN_MODE == BIG_ENDIAN)
++#if 0
++    /*Set Master0 and Master 1 endianness as Big Endian*/
++    HAL_DMAC_SET_MASTER0_BIG_ENDIAN();
++    HAL_DMAC_SET_MASTER1_BIG_ENDIAN();
++#else
++    /*Set Master0 and Master 1 endianness as Little Endian*/
++    HAL_DMAC_SET_MASTER0_LITTLE_ENDIAN();
++    HAL_DMAC_SET_MASTER1_LITTLE_ENDIAN();
++#endif
++
++    //Clear TC interrupt status    
++    HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(0xFF);        // 8 channels
++
++    //Clear Errot/Abort interrupt status    
++    HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(0x00FF00FF);    // 8 channels
++
++    /*
++     * Configure DMA's channel control
++     */   
++    channel_control = ((DMAC_CH_TC_MASK_DISABLE << 31) | \
++                       ((dmac_obj->target_select&0xf) << 25) | \
++                       (DMAC_CH_PRI_LEVEL_3 << 22) | \
++                       (DMAC_CH_PROT3_NON_CACHEABLE << 21) | \
++                       (DMAC_CH_PROT2_NON_BUFFERABLE << 20) | \
++                       (DMAC_CH_PROT1_PRIVILEGED_MODE << 19) | \
++                       ((dmac_obj->src_burst_size&0x7) << 16) | \
++                       ((dmac_obj->src_width&0x7) << 11) | \
++                       ((dmac_obj->dst_width&0x7) << 8) | \
++                       (DMAC_CH_MODE_HW_HANDSHAKE << 7) | \
++                       ((dmac_obj->srcad_ctl&0x3) << 5) | \
++                       ((dmac_obj->dstad_ctl&0x3) << 3) | \
++                       (dmac_obj->src_master << 2) | \
++                       (dmac_obj->dst_master << 1) | \
++                       (DMAC_CH_DISABLE));
++
++#if 0
++    // for testing only
++    if (dmac_obj->llp_addr != 0)
++    {
++        /*
++         * For LLP hardware handshaking with at least one descriptors, disable TC interrupt 
++         * of the first descriptor.
++         */
++        channel_control |= (DMAC_CH_TC_MASK_ENABLE << 31);
++    }
++#endif
++    for (ch = 0; ch < DMAC_MAX_CHANNEL_NUM; ch++)
++    {
++        if (dmac_obj->channel_id & DMAC_CH_ID(ch))
++        {  
++            /*
++             * Configure channel's CSR register
++             */
++            DMAC_CH_CSR_REG(ch) = channel_control & 0xFFFFFFFE; //Disable CH(n) DMA
++                
++            /*
++             * Configure channel's CFG register: disable channel abort interrupt,
++             * enable channel error and terminal count interrupts.
++             */
++            DMAC_CH_CFG_REG(ch) |= (0x07);
++            DMAC_CH_CFG_REG(ch) &= ~((0x3));
++        }                               	
++    }
++
++    for (ch = 0; ch < DMAC_MAX_CHANNEL_NUM; ch++)
++    {
++        if (dmac_obj->channel_id & DMAC_CH_ID(ch))
++        {  
++            //Set Src address register
++            DMAC_CH_SRC_ADDR_REG(ch)= dmac_obj->src_addr;
++
++            //Set Dst address register
++            DMAC_CH_DST_ADDR_REG(ch)= dmac_obj->dst_addr;    
++
++            //Set Transfer Number
++            if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_8_BITS)
++            {
++                DMAC_CH_SIZE_REG(ch) = (dmac_obj->transfer_bytes & 0x0FFF);
++                DEBUG_PRINT("%s: 8-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_16_BITS)
++            {                                  
++                DMAC_CH_SIZE_REG(ch) = ((dmac_obj->transfer_bytes >> 1) + (dmac_obj->transfer_bytes % 2)) & 0x0FFF;
++                DEBUG_PRINT("%s: 16-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_32_BITS)
++            {
++                DMAC_CH_SIZE_REG(ch) = ((dmac_obj->transfer_bytes >> 2) + ((dmac_obj->transfer_bytes % 4) ? 1 : 0)) & 0x0FFF;
++                DEBUG_PRINT("%s: 32-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else
++            {
++            	DEBUG_PRINT("%s: dead\n",__FUNCTION__);
++                while (1);
++            }
++
++            //Enable Channel DMA transfer 
++            HAL_DMAC_ENABLE_CHANNEL(ch);
++             
++            //Set Channel's Sync logic
++            DMAC_SYNC_REG |= (1 << ch);
++
++            /*
++             * Configure channel LLP if LLP is enabled
++             */
++            DMAC_CH_LLP_REG(ch) = (dmac_obj->llp_addr == 0) ? 0 : (dmac_obj->llp_addr & 0xFFFFFFFC);
++        }
++    }
++}
++EXPORT_SYMBOL(Hal_Dmac_Configure_DMA_Handshake);
++
++irqreturn_t str8100_dma_err_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 dma_error_status,dma_ch;
++printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++
++	HAL_DMAC_READ_ERROR_ABORT_INTERRUPT_STATUS(dma_error_status);
++	for (dma_ch = 0; dma_ch < DMAC_MAX_CHANNEL_NUM; dma_ch++)
++	{
++		if (dma_error_status & DMAC_CH_ID(dma_ch))
++		{
++			printk("%s: this_irq=%d, DMA channel error on ch %d\n",__FUNCTION__,this_irq,dma_ch);
++			HAL_DMAC_DISABLE_CHANNEL(dma_ch);
++			HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(DMAC_CH_ID(dma_ch));
++		}
++	}	
++	
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++	return IRQ_HANDLED;
++}
++EXPORT_SYMBOL(str8100_dma_err_irq_handler);
++
++static const u32 rate_map[3][4]={	{48000,    0,    0,    0},
++					{44100,22050,11025, 5512},
++					{32000,16000, 8000,    0}};
++    /*
++     * Configure I2S related parameters
++     */
++/*//#define i2s_sdata_width	I2S_DATA_16_BIT
++#define i2s_sdata_width		I2S_DATA_32_BIT
++#define i2s_mode	 	I2S_SLAVE_MODE
++//#define i2s_mode		I2S_MASTER_MODE
++#define i2s_tranfer_timing_ctrl	I2S_I2S_MODE
++//#define i2s_tranfer_timing_ctrl	I2S_RJF_MODE
++//#define i2s_tranfer_timing_ctrl	I2S_LJF_MODE
++#define i2s_sclk_mode		I2S_CLOCK_CONTINUOUS_MODE
++//#define i2s_sclk_mode		I2S_CLOCK_256S_MODE
++*/
++
++//int str8100_i2s_init(sampling_rate,I2S_DATA_32_BIT, I2S_MASTER_MODE, I2S_I2S_MODE, I2S_CLOCK_256S_MODE);
++//int str8100_i2s_init(sampling_rate,I2S_DATA_32_BIT, I2S_SLAVE_MODE, I2S_I2S_MODE, I2S_CLOCK_CONTINUOUS_MODE);
++
++int str8100_i2s_init(int sampling_rate,u32 i2s_sdata_width, u32 i2s_mode,
++			u32 i2s_tranfer_timing_ctrl, u32 i2s_sclk_mode){
++	u32 tmp;
++	u32 i/*clock*/ ,j,i2s_src_clk_div;
++	DEBUG_PRINT("%s: sampling_rate=%d\n",__FUNCTION__,sampling_rate);
++	
++	for(i=0;i<3;i++)
++		for(j=0;j<4;j++)
++			if(rate_map[i][j]==sampling_rate) goto rate_match;
++
++rate_match:
++	if(i==3&&j==4) {
++		printk("%s: unsupported sampling rate (%d)\n",__FUNCTION__,sampling_rate);
++		return -1;
++	}else{
++		DEBUG_PRINT("%s: clock=%d,src_clk_div=%d\n",__FUNCTION__,i,j);
++	}
++	
++	i2s_src_clk_div=j;
++
++	/*
++	 * Select I2S clock source; here we use 48K sampling rate for the target file.
++	 */
++	 
++//	switch(sampling_rate){
++	switch(i/*clock*/){
++	case 0/*48000*/: 
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_12288000HZ(); 
++		break; 
++	case 1/*44100*/:
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_11289600HZ(); 
++		break;
++	case 2/*32000*/: 
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_8192000HZ(); 
++		break; 
++	}
++
++	HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(11,0);
++	
++	// Enable I2S pins
++	HAL_MISC_ENABLE_I2S_PINS();
++	
++	// Enable I2S clock
++	HAL_PWRMGT_ENABLE_I2S_CLOCK(); 
++
++	//Hal_Pwrmgt_Software_Reset(PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX);
++
++
++    /*
++     * Configure I2S to be Master & Transmitter
++     * Note the I2S's WS Clock is derived from Clock & Power Management Functional
++     * Block!!
++     */
++	I2S_CONFIGURATION_REG = 
++                        (i2s_sdata_width << 0) |
++                        (i2s_src_clk_div << 4) |
++                        (0x1 << 12) |   /* Use I2SSD as data output pin and GPIOA[3] as data input pin for full-duplex mode */
++                        (0x0 << 15) |   /* Disable clock phase invert */
++                        (0x0 << 24) |   /* Disable I2S data swap */
++                        ((i2s_sclk_mode & 0x1) << 25) |
++                        ((i2s_tranfer_timing_ctrl & 0x3) << 26) |
++                        (0x0 << 29) |   /* Enable I2S Transmitter */
++			(i2s_mode << 30) |
++			(0x0 << 31);	/* Disable I2S */
++
++	//Enable none while initializing
++	I2S_INTERRUPT_ENABLE_REG = 0x0;
++//	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG | I2S_TXBF_R_EMPTY_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++
++    // Clear spurious interrupt sources
++    I2S_INTERRUPT_STATUS_REG = 0xF0;
++
++    tmp = I2S_LEFT_RECEIVE_DATA_REG;
++    tmp = I2S_RIGHT_RECEIVE_DATA_REG;
++
++    // Disable I2S
++    HAL_I2S_DISABLE_I2S();
++
++	return 0;
++}
++EXPORT_SYMBOL(str8100_i2s_init);
++
++
++
++/*
++ * Define which GPIO Pins will serve as Winbond's W571C161's SSP (Serial Setup
++ * Potr) Pins which consist of SSPEN, SSPCLK, and SSPTR.
++ * Note these three pins are uni-directional output pins:
++ * SSPEN  : mapping to COM1 pin
++ * SSPCLK : mapping to COM2 pin
++ * SSPTR  : mapping to COM3 pin
++ */
++//#define SSPEN_GPIO_INDEX        (3)   /* use GPIOA #3 as WM8772's COM1 */
++#define SSPEN_GPIO_INDEX        (0)   /* use GPIOA #3 as WM8772's COM1 */
++
++#define SSPCLK_GPIO_INDEX       (1)   /* use GPIOA #4 as WM8772's COM2 */
++
++#define SSPTR_GPIO_INDEX        (2)   /* use GPIOA #5 as WM8772's COM3 */
++
++#define SWITCH_GPIO_INDEX       (7)   /* use GPIOA #6 as WM8772's Transfer or Receiver */
++
++/*
++ * Macro-defines to "output" SSPEN, SSPCLK and SSPTR
++ */
++#define SSPEN_HIGH()            HAL_GPIOA_SET_DATA_OUT_HIGH(0x1 << SSPEN_GPIO_INDEX)
++
++#define SSPEN_LOW()             HAL_GPIOA_SET_DATA_OUT_LOW(0x1 << SSPEN_GPIO_INDEX)
++
++
++#define SSPCLK_HIGH()           HAL_GPIOA_SET_DATA_OUT_HIGH(0x1 << SSPCLK_GPIO_INDEX)
++
++#define SSPCLK_LOW()            HAL_GPIOA_SET_DATA_OUT_LOW(0x1 << SSPCLK_GPIO_INDEX)
++
++
++#define SSPTR_HIGH()            HAL_GPIOA_SET_DATA_OUT_HIGH(0x1 << SSPTR_GPIO_INDEX)
++
++#define SSPTR_LOW()             HAL_GPIOA_SET_DATA_OUT_LOW(0x1 << SSPTR_GPIO_INDEX)
++
++
++/*
++ * SWITCH TX/RX For ASIC VER.
++ */
++#define SSPSW_HIGH()            HAL_GPIOA_SET_DATA_OUT_HIGH(0x1 << SWITCH_GPIO_INDEX)
++
++#define SSPSW_LOW()             HAL_GPIOA_SET_DATA_OUT_LOW(0x1 << SWITCH_GPIO_INDEX)
++
++/*
++ * Macro-defines to configure the "directions" of SSPEN, SSPCLK and SSPTR
++ */
++#define SSPEN_DIR_OUT()         HAL_GPIOA_SET_DIRECTION_OUTPUT(0x1 << SSPEN_GPIO_INDEX)
++
++#define SSPCLK_DIR_OUT()        HAL_GPIOA_SET_DIRECTION_OUTPUT(0x1 << SSPCLK_GPIO_INDEX)
++
++#define SSPTR_DIR_OUT()         HAL_GPIOA_SET_DIRECTION_OUTPUT(0x1 << SSPTR_GPIO_INDEX)
++
++//For ASIC
++#define SSPSW_DIR_OUT()         HAL_GPIOA_SET_DIRECTION_OUTPUT(0x1 << SWITCH_GPIO_INDEX)
++
++
++#define TIME_FACTOR               (20)
++
++/*
++ * Function prototype declaration
++ */
++u32            I2s_Gpio_SSP_Initialise(void);
++
++void           I2s_Gpio_SSP_Write(u16);
++
++void           I2s_Gpio_SSP_Switch_To_Record_Data(void);
++
++void           I2s_Gpio_SSP_Switcg_To_Playback_Data(void);
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2s_Gpio_SSP_Initialise
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++u32 I2s_Gpio_SSP_Initialise(void)
++{
++ 
++    // Enable GPIO clock
++    HAL_PWRMGT_ENABLE_GPIO_CLOCK();
++
++    // Perform GPIO software reset
++//    Hal_Pwrmgt_Software_Reset(PWRMGT_GPIO_SOFTWARE_RESET_BIT_INDEX);
++
++
++    /*
++     * 1. Determine/Check which three GPIO pins will serve as SSPEN, SSPCLK and 
++     *    SSPTR pins
++     * 2. At initialization :
++     *    SSPEN  : Output Direction, High state
++     *    SSPCLK : Output Direction, Low state
++     *    SSPTR  : Output Direction, Low state
++     */
++    SSPEN_DIR_OUT();
++    
++    SSPCLK_DIR_OUT();
++    
++    SSPTR_DIR_OUT();
++
++
++    /*
++     * Set SSPEN to be HIGH and SSPCLK/SSPTR be be LOW to "Free" SSP Bus
++     */
++     
++    SSPEN_HIGH();
++
++#if 1
++    SSPCLK_LOW();
++
++    SSPTR_LOW();
++#else
++    SSPCLK_HIGH();
++
++    SSPTR_HIGH();
++#endif
++
++    return 0;  // for success indication
++}
++EXPORT_SYMBOL(I2s_Gpio_SSP_Initialise);
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2s_Gpio_SSP_Write
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++void I2s_Gpio_SSP_Write(u16 reg_data)
++{
++    unsigned long   cpsr_flags;
++    u32 volatile    ii;
++
++
++	local_irq_save(cpsr_flags);
++    
++    SSPEN_HIGH();
++
++    SSPCLK_LOW();
++
++    SSPTR_LOW();
++
++    ndelay(2 * TIME_FACTOR);
++
++    SSPEN_LOW();
++
++    // Output D15 ~ D0 of reg_data
++    for (ii = 0; ii < 16; ii++)
++    {
++        SSPCLK_LOW();
++    
++        ndelay(3 * TIME_FACTOR);//setup time
++        
++        if (reg_data & 0x8000)
++        {
++            SSPTR_HIGH();
++        }
++        else
++        {
++            SSPTR_LOW();
++        }
++        
++        ndelay(5 * TIME_FACTOR);
++        
++        SSPCLK_HIGH();
++        
++        ndelay(5 * TIME_FACTOR);//hold time
++
++        SSPCLK_LOW();
++        
++        ndelay(3 * TIME_FACTOR);
++
++        // Shift left by one bit to get the next data bit
++        reg_data <<= 1;
++    }
++    
++    SSPEN_HIGH();
++
++    SSPCLK_LOW();
++
++    ndelay(1 * TIME_FACTOR);
++
++    // for testing only
++#if 0
++    SSPCLK_HIGH();
++
++//    SSPTR_HIGH();
++#endif
++
++
++    // Delay some time
++//    for (ii = 0; ii < 0x100000; ii++);    
++
++	local_irq_restore(cpsr_flags);
++}
++EXPORT_SYMBOL(I2s_Gpio_SSP_Write);
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2s_Gpio_SSP_Switch_To_Record_Data
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++void I2s_Gpio_SSP_Switch_To_Record_Data(void)
++{
++    SSPSW_DIR_OUT();
++    
++    SSPSW_HIGH();
++}
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2s_Gpio_SSP_Switcg_To_Playback_Data
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++void I2s_Gpio_SSP_Switcg_To_Playback_Data(void)
++{
++    SSPSW_DIR_OUT();
++    
++    SSPSW_LOW();
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_i2s_config.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_i2s_config.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_i2s_config.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_i2s_config.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,471 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++
++#include <linux/kernel.h>	/* printk() */
++#include <linux/errno.h>	/* error codes */
++#include <linux/types.h>	/* size_t */
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++#include <linux/pci.h>
++
++#include <asm/system.h>		/* cli(), *_flags */
++#include <asm/uaccess.h>	/* copy_*_user */
++
++#include <mach/star_powermgt.h>
++#include <mach/star_misc.h>
++#include <mach/star_i2s.h>
++#include <mach/star_demo_dma.h>
++
++MODULE_AUTHOR("Mac Lin");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++#define CONFIG_I2S_USE_DMA
++//Debug = left only
++#define DEBUG	
++
++static struct proc_dir_entry *star_i2s_proc_entry=NULL;
++static u32 sampling_rate=44100;
++static u32 sample_size=16;
++
++module_param(sampling_rate, int, 0);
++MODULE_PARM_DESC(gpio, "sampling_rate");
++
++module_param(sample_size, int, 0);
++MODULE_PARM_DESC(gpio, "sample_size");
++
++#define DMA_TRANSFER_MAX_BYTE    (0xfff<<(sample_size>>4)) 
++#define BUFSIZE (0xfff<<4) //twice the 32-bit DMA transfer byte size
++
++static u8* lbuffer;
++static u8* lbuffer_p;
++static u32 llen=0;
++static u32 lpos=0;
++static u32 i2s_err_lur=0;
++
++static u32 debug=0;
++#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++
++//=================================================================================
++//
++#ifdef CONFIG_I2S_USE_DMA
++
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8759_dma_handshake_left_tx;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8759_dma_handshake_right_tx;
++
++static u32                          i2s_wm8759_dma_right_tx_channel = 1;
++
++
++
++
++
++void I2s_WM8759_Configure_DMA_Hardware_Handshake(void)
++{
++    /*
++     * Configure DMA's channel setting for I2S's Left Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    i2s_wm8759_dma_handshake_left_tx.channel_num = 0;
++    i2s_wm8759_dma_handshake_left_tx.channel_id = DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num);
++    i2s_wm8759_dma_handshake_left_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_LEFT_ID;
++    i2s_wm8759_dma_handshake_left_tx.src_addr = (u32)lbuffer_p;
++    i2s_wm8759_dma_handshake_left_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    i2s_wm8759_dma_handshake_left_tx.dst_master = DMAC_CH_DST_SEL_M0;
++    i2s_wm8759_dma_handshake_left_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    i2s_wm8759_dma_handshake_left_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++    
++	switch(sample_size){
++	case 16:
++		i2s_wm8759_dma_handshake_left_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xCA);
++		i2s_wm8759_dma_handshake_left_tx.src_width = DMAC_CH_SRC_WIDTH_16_BITS;
++		i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_16_BITS;
++		break;
++	case 32:
++		i2s_wm8759_dma_handshake_left_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xC8);
++		i2s_wm8759_dma_handshake_left_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++		i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++		break;
++	}
++
++//    i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_16_BITS;
++
++    /*
++     * Note here the total number of bytes for each DMA transfer is specified!!
++     */
++//    i2s_wm8759_dma_handshake_left_tx.transfer_bytes = DMA_TRANSFER_MAX_BYTE;
++    i2s_wm8759_dma_handshake_left_tx.transfer_bytes = (llen<DMA_TRANSFER_MAX_BYTE)?llen:DMA_TRANSFER_MAX_BYTE;
++
++    i2s_wm8759_dma_handshake_left_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8759_dma_handshake_left_tx);
++
++#ifndef DEBUG 
++    /*
++     * Configure DMA's channel setting for I2S's Right Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    i2s_wm8759_dma_handshake_right_tx.channel_id = DMAC_CH_ID(i2s_wm8759_dma_right_tx_channel);
++    
++    i2s_wm8759_dma_handshake_right_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_RIGHT_ID;
++
++    i2s_wm8759_dma_handshake_right_tx.src_addr = (u32)rbuffer_p;
++
++    i2s_wm8759_dma_handshake_right_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xC4);
++
++    i2s_wm8759_dma_handshake_right_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    
++    i2s_wm8759_dma_handshake_right_tx.dst_master = DMAC_CH_DST_SEL_M0;
++
++    i2s_wm8759_dma_handshake_right_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    
++    i2s_wm8759_dma_handshake_right_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++
++    i2s_wm8759_dma_handshake_right_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    
++    i2s_wm8759_dma_handshake_right_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    /*
++     * Note here the total number of bytes for each DMA transfer is specified!!
++     */
++    i2s_wm8759_dma_handshake_right_tx.transfer_bytes = DMA_TRANSFER_MAX_BYTE;
++
++    i2s_wm8759_dma_handshake_right_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8759_dma_handshake_right_tx);
++#endif
++    return;
++}
++#endif //CONFIG_I2S_USE_DMA
++
++
++//=================================================================================
++//
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++#ifdef CONFIG_I2S_USE_DMA
++static irqreturn_t str8100_dma_tc_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 dma_tc_status,tot_size;
++	u32 len;
++//printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++
++    HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(dma_tc_status);
++
++    /*
++     * For DMA's Tx for I2S Left Channel
++     */
++	if (dma_tc_status & DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num))
++	{                      
++		HAL_DMAC_DISABLE_CHANNEL(i2s_wm8759_dma_handshake_left_tx.channel_num);
++		HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num));
++		lpos+=i2s_wm8759_dma_handshake_left_tx.transfer_bytes;
++		if(lpos<llen){
++			/*
++			 * Re-initialize DMA's channel for Left_Tx
++			 */
++			DMAC_CH_SRC_ADDR_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = (u32)lbuffer_p+lpos;
++			DMAC_CH_DST_ADDR_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = (SYSPA_I2S_BASE_ADDR + 0xC8);        
++			
++			/*
++			 * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++			 * number of source transfer width!
++			 */        
++			len=(llen - lpos);
++			i2s_wm8759_dma_handshake_left_tx.transfer_bytes= (len<DMA_TRANSFER_MAX_BYTE)?len:DMA_TRANSFER_MAX_BYTE;
++
++			if (i2s_wm8759_dma_handshake_left_tx.src_width == DMAC_CH_SRC_WIDTH_16_BITS)
++			{
++			    tot_size = (i2s_wm8759_dma_handshake_left_tx.transfer_bytes >> 1) + ((i2s_wm8759_dma_handshake_left_tx.transfer_bytes % 2) ? 1 : 0);
++			}
++			else if (i2s_wm8759_dma_handshake_left_tx.src_width == DMAC_CH_SRC_WIDTH_32_BITS)
++			{
++			    tot_size = (i2s_wm8759_dma_handshake_left_tx.transfer_bytes >> 2) + ((i2s_wm8759_dma_handshake_left_tx.transfer_bytes % 4) ? 1 : 0);
++			}
++			else
++			{
++			    tot_size = i2s_wm8759_dma_handshake_left_tx.transfer_bytes;
++			}
++			
++			DMAC_CH_SIZE_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = tot_size & 0x0FFF;
++			HAL_DMAC_ENABLE_CHANNEL(i2s_wm8759_dma_handshake_left_tx.channel_num);
++//printk("%s: 32-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,i2s_wm8759_dma_handshake_left_tx.transfer_bytes,i2s_wm8759_dma_handshake_left_tx.channel_num,DMAC_CH_SIZE_REG(i2s_wm8759_dma_handshake_left_tx.channel_num));
++
++	}else{
++		llen=lpos=0;
++	}
++	}
++
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++#endif //CONFIG_I2S_USE_DMA
++
++static irqreturn_t str8100_i2s_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 interrupt_status;
++	DEBUG_PRINT("%s: this_irq=%d, I2S_INTERRUPT_STATUS_REG=0x%.8x,llen=%d,lpos=%d\n",__FUNCTION__,this_irq,I2S_INTERRUPT_STATUS_REG,llen,lpos);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++	interrupt_status = I2S_INTERRUPT_STATUS_REG;   
++if((llen<lpos)||llen==0)     HAL_I2S_DISABLE_I2S();
++
++#ifndef CONFIG_I2S_USE_DMA
++		I2S_RIGHT_TRANSMIT_DATA_REG=0;
++
++	if ((lpos<=llen) && (interrupt_status & I2S_TXBF_L_EMPTY_FLAG)){
++		switch(sample_size){
++			case 16:
++				I2S_LEFT_TRANSMIT_DATA_REG=(*((u16*)(&lbuffer[lpos])))<<16;lpos+=2;
++				break;
++			case 32:
++				I2S_LEFT_TRANSMIT_DATA_REG=*((u32*)(&lbuffer[lpos]));lpos+=4;
++				break;
++		}
++		
++		if(lpos>llen){
++			// Disable Left Channel's Transmit Buffer Interrupt Sources
++			I2S_INTERRUPT_ENABLE_REG &= ~(I2S_TXBF_L_EMPTY_FLAG | I2S_TXBF_L_UR_FLAG);
++			lpos=llen=0;
++		}
++	}
++#endif //!CONFIG_I2S_USE_DMA
++
++
++	if (llen>=lpos && (interrupt_status & I2S_TXBF_L_UR_FLAG)){
++		// Clear I2S interrupt status
++		i2s_err_lur++;
++		if(i2s_err_lur>10)
++			I2S_INTERRUPT_ENABLE_REG &= ~(I2S_TXBF_L_UR_FLAG);
++//			HAL_I2S_DISABLE_I2S();
++		
++		printk("%s: Left Channel Tx Underrun!,llen=%d, lpos=%d, interrupt_status=%.8x,i2s_err_lur=%d\n",__FUNCTION__,llen,lpos,interrupt_status,i2s_err_lur);
++	}
++	I2S_INTERRUPT_STATUS_REG &= 0xf0;
++
++	
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++
++
++//=================================================================================
++static int proc_read_i2s(char *buf, char **start, off_t offset,
++                   int count, int *eof, void *data)
++{
++	int len=0;
++	DEBUG_PRINT("%s:\n",__FUNCTION__);
++	len += sprintf(buf,	"sampling_rate=%d\n"
++				"sample_size=%d\n"
++			,sampling_rate,sample_size); 
++	*eof = 1;
++	return len;
++}
++
++static proc_write_i2s(struct file *file, const char *buffer, unsigned long count, void *data){
++	int len=0;
++	DEBUG_PRINT("%s: sample size %d, sampling rate %d, count=%d\n",__FUNCTION__,sample_size,sampling_rate,count);
++	
++	//is buffer free?
++	if(lpos!=llen){
++		printk("%s: buffer not free\n");
++		return -EBUSY;
++	}
++	if(sampling_rate!=32000&&sampling_rate!=44100&&sampling_rate!=48000){
++		printk("%s: invalid sampling rate(%d)\n",sampling_rate);
++		return -EFAULT;
++	}
++	if(sample_size!=16&&sample_size!=32){
++		printk("%s: invalid sample size(%d)\n",sample_size);
++		return -EFAULT;
++	}
++
++	//copy the raw data to local buffer	
++	if(count>BUFSIZE) len=BUFSIZE;
++	else len=count;
++	
++	if(copy_from_user(lbuffer,buffer,len)){
++		return -EFAULT;	
++	}
++	llen=len;
++	lpos=0;
++	i2s_err_lur=0;
++	
++	str8100_i2s_init(sampling_rate,I2S_DATA_32_BIT, I2S_MASTER_MODE, I2S_I2S_MODE, I2S_CLOCK_256S_MODE);
++
++#ifdef CONFIG_I2S_USE_DMA
++    /*
++     * Configure DMA for hardware handshake for I2S
++     * Note the DMA is NOT enabled after invoking the following function, but the specified
++     * DMA channels are enabled!!
++     */
++    i2s_wm8759_dma_right_tx_channel = 1;   
++
++    I2s_WM8759_Configure_DMA_Hardware_Handshake();  
++
++#endif //CONFIG_I2S_USE_DMA
++	//fill the tx left/right registers
++
++		switch(sample_size){
++			case 16:
++				I2S_LEFT_TRANSMIT_DATA_REG=(*((u16*)(&lbuffer[lpos])))<<16;lpos+=2;
++				break;
++			case 32:
++				I2S_LEFT_TRANSMIT_DATA_REG=*((u32*)(&lbuffer[lpos]));lpos+=4;
++				break;
++		}
++
++	I2S_RIGHT_TRANSMIT_DATA_REG=0;
++
++#ifdef CONFIG_I2S_USE_DMA
++	/*
++	 * Enable I2S's interrupt sources
++	 * Note for DMA hardware handshake, we only need to enable Left/Right Channel's 
++	 * Transmit Buffer Underrun.
++	 */
++#ifdef DEBUG	
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_L_UR_FLAG);
++#else
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG);
++#endif
++#else //CONFIG_I2S_USE_DMA
++#ifdef DEBUG	
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_L_UR_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++#else
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG | I2S_TXBF_R_EMPTY_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++#endif
++#endif //CONFIG_I2S_USE_DMA
++
++	// Enable CPU interrupt
++	local_irq_enable();
++	
++#ifdef CONFIG_I2S_USE_DMA
++	/*
++	 * Note DMA must be enabled first before I2S is enabled
++	 */
++	HAL_DMAC_ENABLE();
++#endif //CONFIG_I2S_USE_DMA
++	HAL_I2S_ENABLE_I2S();
++
++
++	while (1){
++		local_irq_disable();
++		if (lpos>llen||llen==0){
++			// Disable I2S
++			HAL_I2S_DISABLE_I2S();
++			break;
++		}
++		local_irq_enable();
++	}
++	DEBUG_PRINT("%s: exit. i2s_err_lur=%d\n",__FUNCTION__,i2s_err_lur);
++
++	local_irq_enable();
++
++	return len;
++
++debug:
++	HAL_I2S_DISABLE_I2S();
++	return count;
++}
++
++static void __exit i2s_exit_module(void){
++	printk("%s:\n",__FUNCTION__);
++	remove_proc_entry("str8100/i2s", NULL);
++	free_irq(INTC_I2S_BIT_INDEX, NULL);
++#ifdef CONFIG_I2S_USE_DMA
++	free_irq(INTC_GDMAC_TC_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_ERROR_BIT_INDEX, NULL);
++#endif //CONFIG_I2S_USE_DMA
++	if(lbuffer) {
++		pci_free_consistent(NULL, BUFSIZE, lbuffer, lbuffer_p);
++		lbuffer=lbuffer_p=NULL;
++	}
++}
++
++static int __init i2s_init_module(void)
++{
++	
++	u32 ret;
++	
++	printk("%s:\n",__FUNCTION__);
++#ifdef CONFIG_I2S_USE_DMA
++	printk("%s: DMA Enabled...\n",__FUNCTION__);
++#endif //CONFIG_I2S_USE_DMA
++
++	star_i2s_proc_entry = create_proc_entry("str8100/i2s", S_IFREG | S_IRUGO, NULL);
++	if(!star_i2s_proc_entry){
++		return -EBUSY;
++	}
++	star_i2s_proc_entry->read_proc=proc_read_i2s;
++	star_i2s_proc_entry->write_proc=proc_write_i2s;
++	
++	lbuffer = pci_alloc_consistent(NULL, BUFSIZE, &lbuffer_p);
++	if(!lbuffer){
++		printk("%s: alloc lbuffer failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++
++	str8100_set_interrupt_trigger (INTC_I2S_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_LOW);
++	if ((ret=request_irq(INTC_I2S_BIT_INDEX, str8100_i2s_irq_handler, 0, "i2s", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_I2S_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++
++#ifdef CONFIG_I2S_USE_DMA
++	str8100_set_interrupt_trigger (INTC_GDMAC_TC_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_TC_BIT_INDEX, str8100_dma_tc_irq_handler, 0, "dma tc", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_TC_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++	str8100_set_interrupt_trigger (INTC_GDMAC_ERROR_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_ERROR_BIT_INDEX, str8100_dma_err_irq_handler, 0, "dma error", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_ERROR_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++#endif //CONFIG_I2S_USE_DMA
++
++	return 0;
++exit1:
++	i2s_exit_module();
++	return -EBUSY;
++}
++
++module_init(i2s_init_module);
++module_exit(i2s_exit_module);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_i2s_wm8772_config.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_i2s_wm8772_config.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_i2s_wm8772_config.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_i2s_wm8772_config.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,924 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//Options
++#define DEBUG
++#define I2S_FULL_DUPLEX
++#define I2S_WM8772_DMAC_LLP_TEST
++#define I2S_WM8772_DMAC_LLP_NUM      3
++#define I2S_WM8772_BUFFER_SIZE       (48 * 1 * 2 * 100)
++#define I2S_TIMING 	I2S_I2S_MODE
++//#define I2S_TIMING 	I2S_RJF_MODE
++//#define I2S_TIMING 	I2S_LJF_MODE
++#define DATA_WIDTH 	I2S_DATA_32_BIT
++//#define DATA_WIDTH 	I2S_DATA_16_BIT
++#define I2S_MODE 	I2S_MASTER_MODE
++//#define I2S_MODE 	I2S_SLAVE_MODE
++#define I2S_SCLK_MODE	I2S_CLOCK_256S_MODE
++//#define I2S_SCLK_MODE	I2S_CLOCK_CONTINUOUS_MODE
++//*******************
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++
++#include <linux/kernel.h>	/* printk() */
++#include <linux/errno.h>	/* error codes */
++#include <linux/types.h>	/* size_t */
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++#include <linux/pci.h>
++
++#include <asm/system.h>		/* cli(), *_flags */
++#include <asm/uaccess.h>	/* copy_*_user */
++
++#include <mach/star_powermgt.h>
++#include <mach/star_misc.h>
++#include <mach/star_i2s.h>
++#include <mach/star_demo_dma.h>
++
++MODULE_AUTHOR("Mac Lin");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++//Debug = left only
++
++static u32 sampling_rate=44100;
++
++module_param(sampling_rate, int, 0);
++MODULE_PARM_DESC(gpio, "sampling_rate");
++
++//#define DMA_TRANSFER_MAX_BYTE    (0xfff<<(sample_size>>4)) 
++//#define BUFSIZE (0xfff<<4) //twice the 32-bit DMA transfer byte size
++
++static u8* buffer=NULL;
++static u8* buffer_p=NULL;
++static DMAC_LLP_T* desc=NULL;
++static DMAC_LLP_T* desc_p=NULL;
++
++static u8* lbuffer=NULL;
++static u8* lbuffer_p=NULL;
++static DMAC_LLP_T* lb_txd=NULL;
++static DMAC_LLP_T* lb_txd_p=NULL;
++static DMAC_LLP_T* lb_rxd=NULL;
++static DMAC_LLP_T* lb_rxd_p=NULL;
++
++static u8* rbuffer=NULL;
++static u8* rbuffer_p=NULL;
++static DMAC_LLP_T* rb_txd=NULL;
++static DMAC_LLP_T* rb_txd_p=NULL;
++static DMAC_LLP_T* rb_rxd=NULL;
++static DMAC_LLP_T* rb_rxd_p=NULL;
++
++static DMAC_LLP_T* i2s_left_tx_channel_dma_llp_desc=NULL;
++static DMAC_LLP_T* i2s_left_rx_channel_dma_llp_desc=NULL;
++static DMAC_LLP_T* i2s_right_tx_channel_dma_llp_desc=NULL;
++static DMAC_LLP_T* i2s_right_rx_channel_dma_llp_desc=NULL;
++
++static u8* i2s_left_channel_llp_buf[I2S_WM8772_DMAC_LLP_NUM];
++static u8* i2s_right_channel_llp_buf[I2S_WM8772_DMAC_LLP_NUM];
++
++
++static u32 i2s_err_lur=0;
++
++static u32 debug=0;
++#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++
++static u32 i2s_wm8772_dma_left_tx_channel 	= 0;
++static u32 i2s_wm8772_dma_right_tx_channel 	= 1;
++static u32 i2s_wm8772_dma_left_rx_channel 	= 2;
++static u32 i2s_wm8772_dma_right_rx_channel 	= 3;
++
++
++#if (I2S_WM8772_DMAC_LLP_NUM >= 3)
++#define I2S_WM8772_DMAC_LLP_RING_TEST
++#endif
++#define BUFSIZE (I2S_WM8772_DMAC_LLP_NUM*I2S_WM8772_BUFFER_SIZE*4)
++
++#define I2S_BASE_ADDR SYSPA_I2S_BASE_ADDR
++#define i2s_dmac_llp_num I2S_WM8772_DMAC_LLP_NUM
++//=================================================================================
++//
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2s_Configure_WM8772
++ * PURPOSE:
++ *
++ ******************************************************************************/
++void I2s_Configure_WM8772(u32 interface_format, u32 word_length, u32 data_interface_mode)
++{
++    u16    reg_data;
++
++
++    /*
++     * The current configuration of W571C161 DAC are:
++     * 1. MODE : External hardware setting control mode
++     * 2. COM1 = 1, COM2 = 0 : 16-bit I2S
++     * 3. COM3 = 0 : De-emphasis filter off
++     * 4. I2S Level 2 (Slave Mode) : How to configure it
++     */
++
++    /*
++     * Configure register R31 for reset
++     */
++#if 1
++    reg_data = (0x1F << 9) |  /* Register address value : 0x1F */
++               (0x1FF);
++#else
++    reg_data = (0xF << 9) |  /* Register address value : 0xF */
++               (0x1FF);
++#endif
++
++    I2s_Gpio_SSP_Write(reg_data);
++    
++    /*
++     * Configure register R2
++     */ 
++    reg_data = (0x2 << 9) |  /* Register address value : 0x2 */
++#if 1
++//               (0x5 << 5) |  /* Right Channel Output Mixer Status : right channel data */
++               (0x9 << 5) |  /* Right Channel Output Mixer Status : right channel data */
++                             /* Left Channel Output Mixer Status : left channel data */
++#else
++               (0x2 << 7) |  /* Right Channel Output Mixer Status : right channel data */
++               (0x1 << 5) |  /* Left Channel Output Mixer Status : left channel data */
++#endif
++               (0x0 << 4) |  /* IZM : disable */
++               (0x0 << 3) |  /* ATC : right channels use right attenuations */
++               (0x0 << 2) |  /* PDWNALL : disable */
++               (0x0 << 1) |  /* DEEMPALL : normal */
++               (0x0 << 0);   /* Soft Mute Select : normal */
++
++    I2s_Gpio_SSP_Write(reg_data);
++ 
++    /*
++     * Configure register R12
++     */
++    reg_data = (0xC << 9) |  /* Register address value : 0xC */
++               (0x1 << 6) |  /* Disable the MUTE decoded circuit used by DZFM */
++//               (0x0 << 6) |  /* Enable the MUTE decoded circuit used by DZFM */
++               (0x0 << 2) |  /* Normal operation */
++               (0x0 << 1) |  /* Normal operation */
++               (0x0 << 0);   /* Normal operation */
++
++    I2s_Gpio_SSP_Write(reg_data);
++
++    
++    /*
++     * Configure register R9
++     */
++    reg_data = (0x9 << 9) |  /* Register address value : 0x9 */
++               (0x0 << 8) |  /* Channel 3L/R De-emphasis Status : No de-emphasis */
++               (0x0 << 7) |  /* Channel 2L/R De-emphasis Status : No de-emphasis */
++               (0x0 << 6) |  /* Channel 1L/R De-emphasis Status : No de-emphasis */
++               (0x1 << 5) |  /* Channel 3L/R Play Status : Mute */
++               (0x1 << 4) |  /* Channel 2L/R Play Status : Mute */
++               (0x0 << 3) |  /* Channel 1L/R Play Status : play */
++               (0x3 << 1) |  /* DZFM[1:0] : Channel 3 */
++               (0x1 << 0);   /* ZCD : disabled */
++
++    I2s_Gpio_SSP_Write(reg_data);
++
++
++    /*
++     * Configure register R3 for audio data interface format
++     */
++    reg_data = (0x3 << 9) |  /* Register address value : 0x3 */
++               (0x0 << 6) |  /* Phase : normal */
++               (0x0 << 4) |  /* Input Word Length : 16-bit(0x0 << 4) ; 32-bit(0x3 <<4) */
++#if 0
++               (0x1 << 3) |  /* BCK Polarity : invert : for DSP mode only ????? */
++#else
++               (0x0 << 3) |  /* BCK Polarity : normal */
++#endif
++
++#if 0
++               (0x1 << 2) |  /* LRC Polarity : invert */
++#else
++               (0x0 << 2) |  /* LRC Polarity : normal */
++#endif          
++               (0x0 << 0);   /* Interface Format : right justified mode */
++
++    if (interface_format == I2S_RJF_MODE)
++    {
++        reg_data |= 0;
++    }
++    else if (interface_format == I2S_LJF_MODE)
++    {
++        reg_data |= 1;
++    }
++    else if (interface_format == I2S_I2S_MODE)
++    {
++        reg_data |= 2;
++    }
++    else
++    {
++        printk("\nI2S: Incorrect selected interface mode: DSP mode!\n");
++        
++        reg_data |= 3;
++    }
++
++    /*
++     *  16-bit data for I2S_RJF_MODE
++     */ 
++    if (interface_format == I2S_RJF_MODE)
++    {
++        // 16-bit data
++        reg_data |= (0 << 4);
++    }
++    else
++    {
++        if (word_length == I2S_DATA_16_BIT)
++        {
++            reg_data |= (0 << 4);
++        }
++        else if (word_length == I2S_DATA_32_BIT)
++        {
++            reg_data |= (3 << 4);
++        }
++    }
++
++    I2s_Gpio_SSP_Write(reg_data);
++
++    
++    /*
++     * Configure register R10
++     */
++    reg_data = (0xA << 9) |  /* Register address value : 0xA */
++               (0x2 << 6) |  /* Frequency Ratio = MCLK/LRC : 256 */
++               //(0x3 << 6) |  /* Frequency Ratio = MCLK/LRC : 384 */
++               //(0x0 << 6) |  /* Frequency Ratio = MCLK/LRC : 128 */
++               (0x0 << 5) |  /* Data Interface Mode : Level 2 (Slave mode) */
++               (0x0 << 4) |  /* All Channel Power Down : play */
++               (0x1 << 3) |  /* Channel 3 L/R Play Status : power down */
++               (0x1 << 2) |  /* Channel 2 L/R Play Status : power down */
++               (0x0 << 1) |  /* Channel 1 L/R Play Status : play */
++#if 0
++               (0x1 << 0);   /* ADC deactive */
++#else
++               (0x0 << 0);   /* ADC active */
++#endif
++
++    if (data_interface_mode == I2S_SLAVE_MODE)
++    {
++        /*
++         * Equuleus's I2S is in Slave mode, so WM8772 will be in Master mode
++         */
++        reg_data |= (0x1 << 5);
++    }
++
++    I2s_Gpio_SSP_Write(reg_data);
++
++
++    /*
++     * Configure register R11?????
++     */
++    reg_data = (0xB << 9) |  /* Register address value : 0xB */
++               (0x0 << 8);   /* 128x oversampling */
++               
++    I2s_Gpio_SSP_Write(reg_data);
++
++
++    /*
++     * Configure register R12
++     */
++    reg_data = (0xC << 9) |  /* Register address value : 0xC */
++               (0x0 << 3);   /* Highpass filter enabled */
++               
++    I2s_Gpio_SSP_Write(reg_data);
++    
++    return;
++}
++
++//=================================================================================
++//
++
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8772_dma_right_tx;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8772_dma_right_rx;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8772_dma_left_tx;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8772_dma_left_rx;
++
++void I2s_Configure_WM8772_DMA_Hardware_Handshake(void)
++{
++	u32 ii,tot_size;
++    /*
++     * Initialize DMAC's LLP descriptors
++     */
++	i2s_left_tx_channel_dma_llp_desc=lb_txd;
++	i2s_left_rx_channel_dma_llp_desc=lb_rxd;
++	i2s_right_tx_channel_dma_llp_desc=rb_txd;
++	i2s_right_rx_channel_dma_llp_desc=rb_rxd;
++	
++    for (ii = 0; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++    {
++        memset ((void *)&i2s_left_tx_channel_dma_llp_desc[ii], 0x0, sizeof (i2s_left_tx_channel_dma_llp_desc[ii]));
++        memset ((void *)&i2s_left_rx_channel_dma_llp_desc[ii], 0x0, sizeof (i2s_left_rx_channel_dma_llp_desc[ii]));
++        
++        memset ((void *)&i2s_right_tx_channel_dma_llp_desc[ii], 0x0, sizeof (i2s_right_tx_channel_dma_llp_desc[ii]));
++        memset ((void *)&i2s_right_rx_channel_dma_llp_desc[ii], 0x0, sizeof (i2s_right_rx_channel_dma_llp_desc[ii]));
++    }
++
++//1. *****************************************************************************
++    /*
++     * Configure DMA's channel setting for I2S's Left Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    for (ii = 0; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++    {
++        i2s_left_tx_channel_dma_llp_desc[ii].SrcAddr = i2s_left_channel_llp_buf[ii];
++        
++        i2s_left_tx_channel_dma_llp_desc[ii].DstAddr = (I2S_BASE_ADDR + 0xC8);
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_left_tx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&lb_txd_p[ii+1] : (DMAC_LLP_T *)&lb_txd_p[1];
++#else
++        i2s_left_tx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&lb_txd_p[ii+1] : (DMAC_LLP_T *)(0);
++#endif
++
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++        
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tot_size = tot_size;  /* TOT_SIZE */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_sel = DMAC_CH_DST_SEL_M0;  /* DST_SEL */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_sel = DMAC_CH_SRC_SEL_M1;  /* SRC_SEL */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;  /* DSTAD_CTL */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;  /* SRCAD_CTL */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_width = DMAC_CH_DST_WIDTH_32_BITS;  /* DST_WIDTH */
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_width = DMAC_CH_SRC_WIDTH_32_BITS;  /* SRC_WIDTH */       
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = (DMAC_CH_TC_MASK_ENABLE);  /* TC_MASK */
++#else
++        i2s_left_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = ((ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_CH_TC_MASK_ENABLE) : (DMAC_CH_TC_MASK_DISABLE));  /* TC_MASK */
++#endif
++    }
++
++    i2s_wm8772_dma_left_tx.channel_id = DMAC_CH_ID(i2s_wm8772_dma_left_tx_channel);
++    i2s_wm8772_dma_left_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_LEFT_ID;
++
++    i2s_wm8772_dma_left_tx.src_addr = i2s_left_tx_channel_dma_llp_desc[0].SrcAddr;
++    i2s_wm8772_dma_left_tx.dst_addr = i2s_left_tx_channel_dma_llp_desc[0].DstAddr;
++
++    i2s_wm8772_dma_left_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    i2s_wm8772_dma_left_tx.dst_master = DMAC_CH_DST_SEL_M0;
++
++    i2s_wm8772_dma_left_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    i2s_wm8772_dma_left_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++
++    i2s_wm8772_dma_left_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    i2s_wm8772_dma_left_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++
++    // Note here the total number of bytes is specified!!
++    i2s_wm8772_dma_left_tx.transfer_bytes = I2S_WM8772_BUFFER_SIZE * 4;
++
++    i2s_wm8772_dma_left_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    i2s_wm8772_dma_left_tx.llp_addr = (i2s_dmac_llp_num == 1) ? 0 : (u32)i2s_left_tx_channel_dma_llp_desc[0].LLP;
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8772_dma_left_tx);
++//2. *****************************************************************************
++    /*
++     * Configure DMA's channel setting for I2S's Right Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    for (ii = 0; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++    {
++        i2s_right_tx_channel_dma_llp_desc[ii].SrcAddr = i2s_right_channel_llp_buf[ii];
++        
++        i2s_right_tx_channel_dma_llp_desc[ii].DstAddr = (I2S_BASE_ADDR + 0xC4);
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_right_tx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&rb_txd_p[ii+1] : (DMAC_LLP_T *)&rb_txd_p[1];
++#else
++        i2s_right_tx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&rb_txd_p[ii + 1] : (DMAC_LLP_T *)(0);
++#endif
++
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tot_size = tot_size;  /* TOT_SIZE */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_sel = DMAC_CH_DST_SEL_M0;  /* DST_SEL */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_sel = DMAC_CH_SRC_SEL_M1;  /* SRC_SEL */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;  /* DSTAD_CTL */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;  /* SRCAD_CTL */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_width = DMAC_CH_DST_WIDTH_32_BITS;  /* DST_WIDTH */
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_width = DMAC_CH_SRC_WIDTH_32_BITS;  /* SRC_WIDTH */
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = (DMAC_CH_TC_MASK_ENABLE);  /* TC_MASK */
++#else
++        i2s_right_tx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = ((ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_CH_TC_MASK_ENABLE) : (DMAC_CH_TC_MASK_DISABLE));  /* TC_MASK */
++#endif
++    }
++
++
++    i2s_wm8772_dma_right_tx.channel_id = DMAC_CH_ID(i2s_wm8772_dma_right_tx_channel);
++    i2s_wm8772_dma_right_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_RIGHT_ID;
++
++    i2s_wm8772_dma_right_tx.src_addr = i2s_right_tx_channel_dma_llp_desc[0].SrcAddr;
++    i2s_wm8772_dma_right_tx.dst_addr = i2s_right_tx_channel_dma_llp_desc[0].DstAddr;
++
++    i2s_wm8772_dma_right_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    i2s_wm8772_dma_right_tx.dst_master = DMAC_CH_DST_SEL_M0;
++
++    i2s_wm8772_dma_right_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    i2s_wm8772_dma_right_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++
++    i2s_wm8772_dma_right_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    i2s_wm8772_dma_right_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    i2s_wm8772_dma_right_tx.transfer_bytes = I2S_WM8772_BUFFER_SIZE * 4;
++
++    i2s_wm8772_dma_right_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;
++
++    i2s_wm8772_dma_right_tx.llp_addr = (i2s_dmac_llp_num == 1) ? 0 : (u32)i2s_right_tx_channel_dma_llp_desc[0].LLP;
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8772_dma_right_tx);
++
++
++//3. *****************************************************************************
++    /*
++     * Configure DMA's channel setting for I2S's Left Channel Rx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    for (ii = 0; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++    {
++        i2s_left_rx_channel_dma_llp_desc[ii].SrcAddr = (I2S_BASE_ADDR + 0xD0);
++        
++        i2s_left_rx_channel_dma_llp_desc[ii].DstAddr = i2s_left_channel_llp_buf[ii];
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_left_rx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&lb_rxd_p[ii + 1] : (DMAC_LLP_T *)&lb_rxd_p[1];
++#else
++        i2s_left_rx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&lb_rxd_p[ii + 1] : (DMAC_LLP_T *)(0);
++#endif
++
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tot_size = tot_size;  /* TOT_SIZE */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_sel = DMAC_CH_DST_SEL_M1;  /* DST_SEL */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_sel = DMAC_CH_SRC_SEL_M0;  /* SRC_SEL */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;  /* DSTAD_CTL */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;  /* SRCAD_CTL */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_width = DMAC_CH_DST_WIDTH_32_BITS;  /* DST_WIDTH */
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_width = DMAC_CH_SRC_WIDTH_32_BITS;  /* SRC_WIDTH */
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = (DMAC_CH_TC_MASK_ENABLE);  /* TC_MASK */
++#else
++        i2s_left_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = ((ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_CH_TC_MASK_ENABLE) : (DMAC_CH_TC_MASK_DISABLE));  /* TC_MASK */
++#endif
++    }
++
++    i2s_wm8772_dma_left_rx.channel_id = DMAC_CH_ID(i2s_wm8772_dma_left_rx_channel);
++    i2s_wm8772_dma_left_rx.target_select = DMAC_HW_HAND_SHAKE_I2S_RX_LEFT_ID;
++
++    i2s_wm8772_dma_left_rx.src_addr = i2s_left_rx_channel_dma_llp_desc[0].SrcAddr;
++    i2s_wm8772_dma_left_rx.dst_addr = i2s_left_rx_channel_dma_llp_desc[0].DstAddr;
++
++    i2s_wm8772_dma_left_rx.src_master = DMAC_CH_SRC_SEL_M0;
++    i2s_wm8772_dma_left_rx.dst_master = DMAC_CH_DST_SEL_M1;
++
++    i2s_wm8772_dma_left_rx.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;
++    i2s_wm8772_dma_left_rx.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;
++
++    i2s_wm8772_dma_left_rx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    i2s_wm8772_dma_left_rx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    i2s_wm8772_dma_left_rx.transfer_bytes = I2S_WM8772_BUFFER_SIZE * 4;
++
++    i2s_wm8772_dma_left_rx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    i2s_wm8772_dma_left_rx.llp_addr = (i2s_dmac_llp_num == 1) ? 0 : (u32)i2s_left_rx_channel_dma_llp_desc[0].LLP;
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8772_dma_left_rx);
++
++//4. *****************************************************************************
++    /*
++     * Configure DMA's channel setting for I2S's Right Channel Rx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    for (ii = 0; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++    {
++        i2s_right_rx_channel_dma_llp_desc[ii].SrcAddr = (I2S_BASE_ADDR + 0xCC);
++        
++        i2s_right_rx_channel_dma_llp_desc[ii].DstAddr = i2s_right_channel_llp_buf[ii];
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_right_rx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&rb_rxd_p[ii + 1] : (DMAC_LLP_T *)&rb_rxd_p[1];
++#else
++        i2s_right_rx_channel_dma_llp_desc[ii].LLP = (ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_LLP_T *)&rb_rxd_p[ii + 1] : (DMAC_LLP_T *)(0);
++#endif
++
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tot_size = tot_size;  /* TOT_SIZE */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_sel = DMAC_CH_DST_SEL_M1;  /* DST_SEL */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_sel = DMAC_CH_SRC_SEL_M0;  /* SRC_SEL */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;  /* DSTAD_CTL */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;  /* SRCAD_CTL */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.dst_width = DMAC_CH_DST_WIDTH_32_BITS;  /* DST_WIDTH */
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.src_width = DMAC_CH_SRC_WIDTH_32_BITS;  /* SRC_WIDTH */
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = (DMAC_CH_TC_MASK_ENABLE);  /* TC_MASK */
++#else
++        i2s_right_rx_channel_dma_llp_desc[ii].Ctrl_TotSize.tc_status_mask = ((ii != (I2S_WM8772_DMAC_LLP_NUM - 1)) ? (DMAC_CH_TC_MASK_ENABLE) : (DMAC_CH_TC_MASK_DISABLE));  /* TC_MASK */
++#endif
++    }
++
++    i2s_wm8772_dma_right_rx.channel_id = DMAC_CH_ID(i2s_wm8772_dma_right_rx_channel);
++    i2s_wm8772_dma_right_rx.target_select = DMAC_HW_HAND_SHAKE_I2S_RX_RIGHT_ID;
++
++    i2s_wm8772_dma_right_rx.src_addr = i2s_right_rx_channel_dma_llp_desc[0].SrcAddr;
++    i2s_wm8772_dma_right_rx.dst_addr = i2s_right_rx_channel_dma_llp_desc[0].DstAddr;
++
++    i2s_wm8772_dma_right_rx.src_master = DMAC_CH_SRC_SEL_M0;
++    i2s_wm8772_dma_right_rx.dst_master = DMAC_CH_DST_SEL_M1;
++
++    i2s_wm8772_dma_right_rx.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;
++    i2s_wm8772_dma_right_rx.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;
++
++    i2s_wm8772_dma_right_rx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    i2s_wm8772_dma_right_rx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    i2s_wm8772_dma_right_rx.transfer_bytes = I2S_WM8772_BUFFER_SIZE * 4;
++
++    i2s_wm8772_dma_right_rx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;
++
++    i2s_wm8772_dma_right_rx.llp_addr = (i2s_dmac_llp_num == 1) ? 0 : (u32)i2s_right_rx_channel_dma_llp_desc[0].LLP;
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8772_dma_right_rx);
++//*****************************************************************************
++    return;
++}
++
++
++//=================================================================================
++//
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++static irqreturn_t str8100_dma_tc_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 dma_tc_status,tot_size;
++	u32 len;
++//printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++
++    HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(dma_tc_status);
++printk("%s: this_irq=%d, dma_tc_status=%.8x\n",__FUNCTION__,this_irq,dma_tc_status);
++
++#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
++	u32 i;
++    /*
++     * For LLP ring test, the TC interrupt shoule not happen!!
++     */
++	for(i=0;i<8;i++)
++	if (dma_tc_status & DMAC_CH_ID(i)){                      
++		HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i));
++		printk("%s: channel %d: Error!! there should be no tc irq happened!!\n",__FUNCTION__,i);
++	}
++
++#else
++    /*
++     * For this case, it's recommended to set I2S_WM8772_DMAC_LLP_NUM = 1
++     */
++    /*
++     * For DMA's Tx for I2S Left Channel
++     */
++    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_left_tx_channel))
++    {                      
++        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_left_tx_channel);
++        
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_left_tx_channel));
++
++        /*
++         * Re-initialize DMA's channel for Left_Tx
++         */
++        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_left_tx_channel) = i2s_left_tx_channel_dma_llp_desc[0].SrcAddr;
++
++        DMAC_CH_DST_ADDR(i2s_wm8772_dma_left_tx_channel) = i2s_left_tx_channel_dma_llp_desc[0].DstAddr;
++
++        /*
++         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++         * number of source transfer width!
++         */        
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        DMAC_CH_SIZE(i2s_wm8772_dma_left_tx_channel) = tot_size & 0x0FFF;
++
++        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_left_tx_channel);
++    }
++
++
++    /*
++     * For DMA's Tx for I2S Right Channel
++     */
++    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_right_tx_channel))
++    {                      
++        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_right_tx_channel);
++        
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_right_tx_channel));
++
++        /*
++         * Re-initialize DMA's channel for Right_Tx
++         */
++        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_right_tx_channel) = i2s_right_tx_channel_dma_llp_desc[0].SrcAddr;
++
++        DMAC_CH_DST_ADDR(i2s_wm8772_dma_right_tx_channel) = i2s_right_tx_channel_dma_llp_desc[0].DstAddr;
++
++        /*
++         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++         * number of source transfer width!
++         */        
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        DMAC_CH_SIZE(i2s_wm8772_dma_right_tx_channel) = tot_size & 0x0FFF;
++
++        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_right_tx_channel);
++    }
++
++
++    /*
++     * For DMA's Rx for I2S Left Channel
++     */
++    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_left_rx_channel))
++    {                      
++        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_left_rx_channel);
++        
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_left_rx_channel));
++
++        /*
++         * Re-initialize DMA's channel for Left_Rx
++         */
++        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_left_rx_channel) = i2s_left_rx_channel_dma_llp_desc[0].SrcAddr;
++
++        DMAC_CH_DST_ADDR(i2s_wm8772_dma_left_rx_channel) = i2s_left_rx_channel_dma_llp_desc[0].DstAddr;
++
++        /*
++         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++         * number of source transfer width!
++         */        
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        DMAC_CH_SIZE(i2s_wm8772_dma_left_rx_channel) = tot_size & 0x0FFF;
++
++        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_left_rx_channel);
++    }
++
++
++    /*
++     * For DMA's Rx for I2S Right Channel
++     */
++    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_right_rx_channel))
++    {                      
++        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_right_rx_channel);
++        
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_right_rx_channel));
++
++        /*
++         * Re-initialize DMA's channel for Right_Rx
++         */
++        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_right_rx_channel) = i2s_right_rx_channel_dma_llp_desc[0].SrcAddr;
++
++        DMAC_CH_DST_ADDR(i2s_wm8772_dma_right_rx_channel) = i2s_right_rx_channel_dma_llp_desc[0].DstAddr;
++
++        /*
++         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++         * number of source transfer width!
++         */        
++        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);
++
++        DMAC_CH_SIZE(i2s_wm8772_dma_right_rx_channel) = tot_size & 0x0FFF;
++
++        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_right_rx_channel);
++    }
++#endif
++
++
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++
++static irqreturn_t str8100_i2s_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 interrupt_status;
++	DEBUG_PRINT("%s: this_irq=%d, I2S_INTERRUPT_STATUS_REG=0x%.8x\n",__FUNCTION__,this_irq,I2S_INTERRUPT_STATUS_REG);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++	interrupt_status = I2S_INTERRUPT_STATUS_REG;   
++
++		I2S_RIGHT_TRANSMIT_DATA_REG=0;
++
++
++	if ((interrupt_status & (I2S_RXBF_R_FULL_FLAG | I2S_RXBF_L_FULL_FLAG | I2S_TXBF_R_EMPTY_FLAG | I2S_TXBF_L_EMPTY_FLAG))){
++		printk("%s: Error! wrong i2s empty/full flag\n",__FUNCTION__);
++	
++	}
++
++	if ((interrupt_status & (I2S_RXBF_R_OR_FLAG | I2S_RXBF_L_OR_FLAG |I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG))){
++		// Clear I2S interrupt status
++		i2s_err_lur++;
++		if(i2s_err_lur>10)
++			I2S_INTERRUPT_ENABLE_REG &= ~(I2S_TXBF_L_UR_FLAG);
++//			HAL_I2S_DISABLE_I2S();
++		
++		printk("%s: Left Channel Tx Underrun!, interrupt_status=%.8x,i2s_err_lur=%d\n",__FUNCTION__,interrupt_status,i2s_err_lur);
++	}
++	I2S_INTERRUPT_STATUS_REG &= 0xf0;
++
++	
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++
++
++//=================================================================================
++
++static void i2s_exit_module(void){
++	printk("%s:\n",__FUNCTION__);
++	remove_proc_entry("str8100/i2s", NULL);
++	free_irq(INTC_I2S_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_TC_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_ERROR_BIT_INDEX, NULL);
++	if(buffer) {
++		pci_free_consistent(NULL, BUFSIZE*2, buffer, buffer_p);
++		buffer=buffer_p=NULL;
++		lbuffer=lbuffer_p=rbuffer=rbuffer_p=NULL;
++	}
++	if(desc) {
++		pci_free_consistent(NULL, I2S_WM8772_DMAC_LLP_NUM*sizeof(DMAC_LLP_T)*4 , desc, desc_p);
++		desc=desc_p=NULL;
++		lb_txd=lb_txd_p=lb_rxd=lb_rxd_p=NULL;
++		rb_txd=rb_txd_p=rb_rxd=rb_rxd_p=NULL;
++	}
++}
++
++static int __init i2s_init_module(void)
++{
++	
++	u32 ret;
++	u32 ii;
++	
++	printk("%s:\n",__FUNCTION__);
++
++	buffer = pci_alloc_consistent(NULL, BUFSIZE*2, &buffer_p);
++	if(!buffer){
++		printk("%s: alloc buffer failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	lbuffer=buffer;
++	lbuffer_p=buffer_p;
++	rbuffer=lbuffer+BUFSIZE;
++	rbuffer_p=lbuffer_p+BUFSIZE;
++	
++	desc = pci_alloc_consistent(NULL, I2S_WM8772_DMAC_LLP_NUM*sizeof(DMAC_LLP_T)*4 , &desc_p);
++	if(!desc){
++		printk("%s: alloc buffer for desc failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	lb_txd=desc;
++	lb_txd_p=desc_p;
++	lb_rxd=desc+I2S_WM8772_DMAC_LLP_NUM;
++	lb_rxd_p=desc_p+I2S_WM8772_DMAC_LLP_NUM;
++
++	rb_txd=desc+I2S_WM8772_DMAC_LLP_NUM*2;
++	rb_txd_p=desc_p+I2S_WM8772_DMAC_LLP_NUM*2;
++	rb_rxd=desc+I2S_WM8772_DMAC_LLP_NUM*3;
++	rb_rxd_p=desc_p+I2S_WM8772_DMAC_LLP_NUM*3;
++	
++
++	str8100_set_interrupt_trigger (INTC_I2S_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_LOW);
++	if ((ret=request_irq(INTC_I2S_BIT_INDEX, str8100_i2s_irq_handler, 0, "i2s", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_I2S_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++
++	str8100_set_interrupt_trigger (INTC_GDMAC_TC_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_TC_BIT_INDEX, str8100_dma_tc_irq_handler, 0, "dma tc", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_TC_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++	str8100_set_interrupt_trigger (INTC_GDMAC_ERROR_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_ERROR_BIT_INDEX, str8100_dma_err_irq_handler, 0, "dma error", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_ERROR_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++
++	/*
++	 * Initialize GPIO pins for COM1/COM2/COM3
++	 */
++	I2s_Gpio_SSP_Initialise();
++
++	str8100_i2s_init(sampling_rate,DATA_WIDTH, I2S_MODE, I2S_TIMING, I2S_SCLK_MODE);
++
++	/*
++	 * Configure Wolfson's WM8772 ADC/DAC
++	 */
++	I2s_Configure_WM8772(I2S_TIMING, DATA_WIDTH, I2S_MODE); 
++#ifdef I2S_FULL_DUPLEX
++	/*
++	* To support I2S full duplex mode, GPIOA[3] will be used as I2S_DR pin.
++	* It means GPIOA[3] should be as input pin.
++	*/
++	MISC_GPIOA_PIN_ENABLE_REG &= ~(0x1 << 3);
++    
++	GPIOA_DIRECTION_REG &= ~(0x1 << 3);
++#endif
++
++	I2S_RIGHT_TRANSMIT_DATA_REG=0;
++	I2S_LEFT_TRANSMIT_DATA_REG=0;
++	ii=I2S_RIGHT_RECEIVE_DATA_REG;
++	ii=I2S_LEFT_RECEIVE_DATA_REG;
++
++	/*
++	 * Initialize DMAC related configuration
++	 */    
++
++	i2s_left_channel_llp_buf[0] = lbuffer_p;
++	i2s_right_channel_llp_buf[0] = rbuffer_p;
++	memset ((void *)&lbuffer[0], 0x0, I2S_WM8772_BUFFER_SIZE * 4);
++	memset ((void *)&rbuffer[0], 0x0, I2S_WM8772_BUFFER_SIZE * 4);
++	for (ii = 1; ii < I2S_WM8772_DMAC_LLP_NUM; ii++)
++	{
++		i2s_left_channel_llp_buf[ii] = i2s_left_channel_llp_buf[ii - 1] + (I2S_WM8772_BUFFER_SIZE * 4);
++		i2s_right_channel_llp_buf[ii] = i2s_right_channel_llp_buf[ii - 1] + (I2S_WM8772_BUFFER_SIZE * 4);
++		memset ((void *)&lbuffer[ii*I2S_WM8772_BUFFER_SIZE*4], 0x0, I2S_WM8772_BUFFER_SIZE * 4);
++		memset ((void *)&rbuffer[ii*I2S_WM8772_BUFFER_SIZE*4], 0x0, I2S_WM8772_BUFFER_SIZE * 4);
++	}
++
++	i2s_wm8772_dma_left_tx_channel = 0;
++    
++	i2s_wm8772_dma_right_tx_channel = 1;
++    
++	i2s_wm8772_dma_left_rx_channel = 2;
++    
++	i2s_wm8772_dma_right_rx_channel = 3;
++
++
++	I2s_Configure_WM8772_DMA_Hardware_Handshake();
++
++
++	/*
++	 * Enable I2S's interrupt sources
++	 * Note for DMA hardware handshake, we only need to enable Left/Right Channel's 
++	 * Transmit Buffer Underrun.
++	 */
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_RXBF_R_OR_FLAG | I2S_RXBF_L_OR_FLAG | I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG);
++
++	// Enable CPU interrupt
++	local_irq_enable();
++	
++	/*
++	 * Note DMA must be enabled first before I2S is enabled
++	 */
++	HAL_DMAC_ENABLE();
++	HAL_I2S_ENABLE_I2S();
++	printk("%s: exit successfully\n",__FUNCTION__);
++	return 0;
++
++exit1:
++	HAL_I2S_DISABLE_I2S();
++	i2s_exit_module();
++	printk("%s: exit errornous\n",__FUNCTION__);
++	return -EBUSY;
++}
++
++module_init(i2s_init_module);
++module_exit(i2s_exit_module);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_pcm_legerity_config_2phone.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_pcm_legerity_config_2phone.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_demo_pcm_legerity_config_2phone.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_demo_pcm_legerity_config_2phone.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,921 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//Options 
++//#define DEBUG_PRINT	
++//=================================================================================
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++
++#include <linux/kernel.h>	/* printk() */
++#include <linux/errno.h>	/* error codes */
++#include <linux/types.h>	/* size_t */
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++#include <linux/pci.h>
++#include <linux/wait.h>		//wait queue
++
++#include <asm/system.h>		/* cli(), *_flags */
++#include <asm/uaccess.h>	/* copy_*_user */
++
++#include <mach/star_spi.h>
++#include <mach/star_pcm.h>
++#include <mach/star_dmac.h>
++#include <mach/star_demo_dma.h>
++
++#include <sound/pcm.h>
++#include <mach/star_i2s.h>
++
++#define u_int32 u32
++#define u_int16 u16
++#define u_int8 u8
++
++extern void Pcm_Initial_Legerity_Le88221(void);
++
++#define Sys_Interrupt_Disable_Save_Flags(_p) local_irq_save(*(_p))
++//#define Sys_Interrupt_Disable_Save_Flags local_irq_save
++#define Sys_Interrupt_Restore_Flags local_irq_restore
++
++#define Hal_Timer_Timer3_Delay(_p) mdelay(_p/1000)
++//int debug = 0;
++#ifdef DEBUG_PRINT
++#undef DEBUG_PRINT
++//#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++#define DEBUG_PRINT printk
++#else
++//#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++#define DEBUG_PRINT(arg...) printk(KERN_DEBUG arg);
++#endif
++
++
++
++/*
++ * public variable declarations
++ */
++PCM_OBJECT_T                          pcm_object;
++PCM_CHANNEL_OBJECT_T                  pcm_channel_object;
++
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T  pcm_tx_data0_dma_legerity;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T  pcm_rx_data0_dma_legerity;
++//static DMAC_HARDWARE_HANDSHAKE_OBJ_T  pcm_tx_data1_dma_legerity;
++//static DMAC_HARDWARE_HANDSHAKE_OBJ_T  pcm_rx_data1_dma_legerity;
++
++static u_int32                        pcm_tx_data0_dma_channel_num = 2;
++//static u_int32                        pcm_tx_data1_dma_channel_num = 3;
++static u_int32                        pcm_rx_data0_dma_channel_num = 4;
++//static u_int32                        pcm_rx_data1_dma_channel_num = 5;
++
++//#define           BUFFER_SIZE    (1 * 256)
++//#define           BUFFER_SIZE    (1 * 128)
++//#define           BUFFER_SIZE    (1 * PCM_LOG_PERIOD_SEC * 8000)
++#define           BUFFER_SIZE    0xfff
++
++u_int32    *buffer0;
++u_int32    *buffer1;
++u_int32    *buffer2;
++u_int32    *buffer3;
++
++u_int32    *buffer_p0;
++u_int32    *buffer_p1;
++u_int32    *buffer_p2;
++u_int32    *buffer_p3;
++
++u_int32    *pcm_rx0_buffer_le88221;
++u_int32    *pcm_tx0_buffer_le88221;
++u_int32    *pcm_rx1_buffer_le88221;
++u_int32    *pcm_tx1_buffer_le88221;
++
++u_int32    *pcm_rx0_buffer_le88221_p;
++u_int32    *pcm_tx0_buffer_le88221_p;
++u_int32    *pcm_rx1_buffer_le88221_p;
++u_int32    *pcm_tx1_buffer_le88221_p;
++
++
++#define HAL_DMAC_WRITE_CHANNEL0_DESTINATION_ADDRESS(_p) DMAC_CH_DST_ADDR_REG(2) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL1_DESTINATION_ADDRESS(_p) DMAC_CH_DST_ADDR_REG(3) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL2_DESTINATION_ADDRESS(_p) DMAC_CH_DST_ADDR_REG(4) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL3_DESTINATION_ADDRESS(_p) DMAC_CH_DST_ADDR_REG(5) = (_p)
++
++#define HAL_DMAC_WRITE_CHANNEL0_SOURCE_ADDRESS(_p) DMAC_CH_SRC_ADDR_REG(2) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL1_SOURCE_ADDRESS(_p) DMAC_CH_SRC_ADDR_REG(3) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL2_SOURCE_ADDRESS(_p) DMAC_CH_SRC_ADDR_REG(4) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL3_SOURCE_ADDRESS(_p) DMAC_CH_SRC_ADDR_REG(5) = (_p)
++
++#define HAL_DMAC_WRITE_CHANNEL0_TRANSFER_SIZE(_p) DMAC_CH_SIZE_REG(2) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL1_TRANSFER_SIZE(_p) DMAC_CH_SIZE_REG(3) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL2_TRANSFER_SIZE(_p) DMAC_CH_SIZE_REG(4) = (_p)
++#define HAL_DMAC_WRITE_CHANNEL3_TRANSFER_SIZE(_p) DMAC_CH_SIZE_REG(5) = (_p)
++		
++#define HAL_DMAC_ENABLE_CHANNEL0(_p) HAL_DMAC_ENABLE_CHANNEL(2)
++#define HAL_DMAC_ENABLE_CHANNEL1(_p) HAL_DMAC_ENABLE_CHANNEL(3)
++#define HAL_DMAC_ENABLE_CHANNEL2(_p) HAL_DMAC_ENABLE_CHANNEL(4)
++#define HAL_DMAC_ENABLE_CHANNEL3(_p) HAL_DMAC_ENABLE_CHANNEL(5)
++        
++u_int32 rxbuf_full=0;
++u_int32 txbuf_empty=0;
++u_int32 rxbuf_overrun=0;
++u_int32 txbuf_underrun=0;
++
++u_int32 pcm_dma_ch0_tc_count = 0;
++u_int32 pcm_dma_ch2_tc_count = 0;
++u_int32 pcm_dma_ch1_tc_count = 0;
++u_int32 pcm_dma_ch3_tc_count = 0;
++
++/*
++ * For Legerity's Le88221
++ */
++#define        CH0_TX_Le88221_DELAY       (0)
++#define        CH0_RX_Le88221_DELAY       (0)
++
++#define        CH1_TX_Le88221_DELAY       (8)
++#define        CH1_RX_Le88221_DELAY       (8)
++
++#define        CH2_TX_Le88221_DELAY       (32)
++#define        CH2_RX_Le88221_DELAY       (32)
++
++#define        CH3_TX_Le88221_DELAY       (48)
++#define        CH3_RX_Le88221_DELAY       (48)
++
++
++
++
++static struct proc_dir_entry *star_pcm_proc_entry=NULL;
++static u8* txbuffer;
++//static u8* txbuffer_p;
++static u32 txlen=0;
++static u32 txpos=0;
++
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_Pcm_Initialize
++ * PURPOSE:
++ *
++ ******************************************************************************/
++void Hal_Pcm_Initialize(PCM_OBJECT_T *pPcm_Object)
++{
++    //u_int32 volatile    tx_data0 = 0;
++    u_int32 volatile    rx_data0 = 0;
++
++
++    // Enable PCM pins
++    HAL_MISC_ENABLE_PCM_PINS();
++
++    // Enable PCM clock
++    HAL_PWRMGT_ENABLE_PCM_CLOCK(); 
++
++/*    if (p2s_reset_flag == 0)
++    {
++        Hal_Pwrmgt_Software_Reset(PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX);
++        
++        p2s_reset_flag = 1;
++    }
++*/
++
++    /*
++     * Note PCM is NOT enabled after this function is invoked!!
++     */
++    PCM_CONFIGURATION_0_REG = pPcm_Object->config_0;
++    PCM_CONFIGURATION_1_REG = pPcm_Object->config_1;
++    PCM_CHANNEL_0_CONFIG_REG = pPcm_Object->channel_0_config;
++    PCM_CHANNEL_1_CONFIG_REG = pPcm_Object->channel_1_config;
++    PCM_CHANNEL_2_CONFIG_REG = pPcm_Object->channel_2_config;
++    PCM_CHANNEL_3_CONFIG_REG = pPcm_Object->channel_3_config;
++    PCM_INTERRUPT_ENABLE_REG = pPcm_Object->interrupt_config;
++
++/*
++    if (pPcm_Object->interrupt_config)
++    {
++        Hal_Intc_Register_Interrupt(&pPcm_Object->intc_obj);	
++    }
++*/
++    rx_data0 = PCM_RX_DATA_63_32_REG;
++    rx_data0 = PCM_RX_DATA_31_0_REG;
++
++    // Clear spurious interrupt sources
++    PCM_INTERRUPT_STATUS_REG = PCM_RXBUF_OVERRUN_FG | PCM_TXBUF_UNDERRUN_FG;
++
++    // Disable PCM
++    HAL_PCM_DISABLE_PCM();
++}
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_Pcm_Is_Transmit_Buffer_Empty
++ * PURPOSE:
++ *
++ ******************************************************************************/
++u_int32 Hal_Pcm_Is_Transmit_Buffer_Empty(void)
++{
++    /*
++     * Return value :
++     *    1 : PCM Tx Transmit Buffer Empty
++     *    0 : PCM Tx Transmit Buffer Not Empty
++     */    
++    return ((PCM_INTERRUPT_STATUS_REG & PCM_TXBUF_EMPTY_FG) ? 1 : 0);
++}
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_Pcm_Is_Receive_Buffer_Full
++ * PURPOSE:
++ *
++ ******************************************************************************/
++u_int32 Hal_Pcm_Is_Receive_Buffer_Full(void)
++{
++    /*
++     * Return value :
++     *    1 : PCM Rx Receive Buffer Full
++     *    0 : PCM Rx Receive Buffer Not Full
++     */    
++    return ((PCM_INTERRUPT_STATUS_REG & PCM_RXBUF_FULL_FG) ? 1 : 0);
++}
++
++/******************************************************************************
++ *
++ * FUNCTION:  Pcm_Configure_DMA_Hardware_Handshake_For_Legerity
++ * PURPOSE:
++ *
++ ******************************************************************************/
++void Pcm_Configure_DMA_Hardware_Handshake_For_Legerity(void)
++{
++
++	DEBUG_PRINT(" %s : ==>\n" ,__FUNCTION__);
++#if 1
++    /*
++     * Configure DMA's channel setting for PCM Transmit Data[31:0] Register
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++
++    pcm_tx_data0_dma_legerity.channel_id = DMAC_CH_ID(pcm_tx_data0_dma_channel_num);//0    
++    pcm_tx_data0_dma_legerity.target_select = DMAC_HW_HAND_SHAKE_PCM_TX0_ID;//0
++
++    pcm_tx_data0_dma_legerity.src_addr = (u_int32)pcm_tx0_buffer_le88221_p;//SCR        
++    pcm_tx_data0_dma_legerity.dst_addr = (SYSPA_PCM_BASE_ADDR + 0x98);//DST
++
++    pcm_tx_data0_dma_legerity.src_master = DMAC_CH_SRC_SEL_M1;//1
++    pcm_tx_data0_dma_legerity.dst_master = DMAC_CH_DST_SEL_M0;//0
++
++    pcm_tx_data0_dma_legerity.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;//0
++    pcm_tx_data0_dma_legerity.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;//2
++
++    pcm_tx_data0_dma_legerity.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    pcm_tx_data0_dma_legerity.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    pcm_tx_data0_dma_legerity.transfer_bytes = BUFFER_SIZE * 4;
++
++    pcm_tx_data0_dma_legerity.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;//0   
++
++    // Note this DMA's channel will be enabled when the following function is invoked!!
++    Hal_Dmac_Configure_DMA_Handshake(&pcm_tx_data0_dma_legerity);
++
++
++    /*
++     * Configure DMA's channel setting for PCM Receive Data[31:0] Register
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    pcm_rx_data0_dma_legerity.channel_id = DMAC_CH_ID(pcm_rx_data0_dma_channel_num);//2    
++    pcm_rx_data0_dma_legerity.target_select = DMAC_HW_HAND_SHAKE_PCM_RX0_ID;//1
++
++    pcm_rx_data0_dma_legerity.src_addr = (SYSPA_PCM_BASE_ADDR + 0xA0);//SCR
++    pcm_rx_data0_dma_legerity.dst_addr = (u_int32)pcm_rx0_buffer_le88221_p;//DST        
++
++    pcm_rx_data0_dma_legerity.src_master = DMAC_CH_SRC_SEL_M0;//0
++    pcm_rx_data0_dma_legerity.dst_master = DMAC_CH_DST_SEL_M1;//1
++
++    pcm_rx_data0_dma_legerity.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;//2
++    pcm_rx_data0_dma_legerity.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;//0
++
++    pcm_rx_data0_dma_legerity.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    pcm_rx_data0_dma_legerity.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    pcm_rx_data0_dma_legerity.transfer_bytes = BUFFER_SIZE * 4;
++
++    pcm_rx_data0_dma_legerity.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;
++
++    // Note this DMA's channel will be enabled when the following function is invoked!!
++    Hal_Dmac_Configure_DMA_Handshake(&pcm_rx_data0_dma_legerity);
++#endif
++
++
++#if 0
++    /*
++     * Configure DMA's channel setting for PCM Transmit Data[31:0] Register
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */    
++    pcm_tx_data1_dma_legerity.channel_id = DMAC_CH_ID(pcm_tx_data1_dma_channel_num);//1
++    pcm_tx_data1_dma_legerity.target_select = DMAC_HW_HAND_SHAKE_PCM_TX1_ID;
++
++    pcm_tx_data1_dma_legerity.src_addr = (u_int32)pcm_tx1_buffer_le88221_p;
++    pcm_tx_data1_dma_legerity.dst_addr = (SYSPA_PCM_BASE_ADDR + 0x9C);    
++
++    pcm_tx_data1_dma_legerity.src_master = DMAC_CH_SRC_SEL_M1;
++    pcm_tx_data1_dma_legerity.dst_master = DMAC_CH_DST_SEL_M0;
++
++    pcm_tx_data1_dma_legerity.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    pcm_tx_data1_dma_legerity.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++
++    pcm_tx_data1_dma_legerity.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    pcm_tx_data1_dma_legerity.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    pcm_tx_data1_dma_legerity.transfer_bytes = BUFFER_SIZE * 4;
++
++    pcm_tx_data1_dma_legerity.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;
++
++    Hal_Dmac_Configure_DMA_Handshake(&pcm_tx_data1_dma_legerity);
++
++
++
++    /*
++     * Configure DMA's channel setting for PCM Receive Data[31:0] Register
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */    
++    pcm_rx_data1_dma_legerity.channel_id = DMAC_CH_ID(pcm_rx_data1_dma_channel_num);//3
++    pcm_rx_data1_dma_legerity.target_select = DMAC_HW_HAND_SHAKE_PCM_RX1_ID;
++    pcm_rx_data1_dma_legerity.src_addr = (SYSPA_PCM_BASE_ADDR + 0xA4);    
++    pcm_rx_data1_dma_legerity.dst_addr = (u_int32)pcm_rx1_buffer_le88221_p;    
++
++    pcm_rx_data1_dma_legerity.src_master = DMAC_CH_SRC_SEL_M0;
++    pcm_rx_data1_dma_legerity.dst_master = DMAC_CH_DST_SEL_M1;
++
++    pcm_rx_data1_dma_legerity.srcad_ctl = DMAC_CH_SRCAD_CTL_FIX;
++    pcm_rx_data1_dma_legerity.dstad_ctl = DMAC_CH_DSTAD_CTL_INC;
++
++    pcm_rx_data1_dma_legerity.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    pcm_rx_data1_dma_legerity.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    // Note here the total number of bytes is specified!!
++    pcm_rx_data1_dma_legerity.transfer_bytes = BUFFER_SIZE * 4;
++
++    pcm_rx_data1_dma_legerity.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;
++
++    Hal_Dmac_Configure_DMA_Handshake(&pcm_rx_data1_dma_legerity);    
++#endif            
++  
++    return;
++}
++
++#if 0
++static irqreturn_t str8100_pcm_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++    u_int32 volatile    interrupt_status;    
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++#if 1
++    PCM_INTERRUPT_STATUS_REG&=0xc0;
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++#endif
++	DEBUG_PRINT("%s: this_irq=%d, PCM_INTERRUPT_STATUS_REG=0x%.8x\n",__FUNCTION__,this_irq,PCM_INTERRUPT_STATUS_REG);
++
++    // Get PCM interrupt status
++    HAL_PCM_READ_INTERRUPT_STATUS(interrupt_status);   
++    if (interrupt_status & PCM_RXBUF_FULL_FG){
++    	rxbuf_full++;
++		DEBUG_PRINT("%s: rx buf full\n",__FUNCTION__);
++    }
++
++    if (interrupt_status & PCM_TXBUF_EMPTY_FG){
++    	txbuf_empty++;
++        DEBUG_PRINT("%s: tx buf empty\n",__FUNCTION__);
++    }
++    if (interrupt_status & PCM_RXBUF_OVERRUN_FG){
++        // Clear PCM interrupt status
++        HAL_PCM_CLEAR_INTERRUPT_STATUS(PCM_RXBUF_OVERRUN_FG);
++    
++        rxbuf_overrun++;
++        DEBUG_PRINT("%s: rx buf overrun\n",__FUNCTION__);
++    }
++
++    if (interrupt_status & PCM_TXBUF_UNDERRUN_FG){
++        // Clear PCM interrupt status
++        HAL_PCM_CLEAR_INTERRUPT_STATUS(PCM_TXBUF_UNDERRUN_FG);
++
++        txbuf_underrun++;
++        DEBUG_PRINT("%s: tx buf underrun\n",__FUNCTION__);
++    }
++    PCM_INTERRUPT_STATUS_REG&=0xc0;
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++#endif
++
++#ifdef CONFIG_SND_STAR_I2S_WM8759
++#define I2S_CHANNEL_NUM 2
++extern DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8759_dma_handshake_tx[I2S_CHANNEL_NUM];
++struct snd_star_i2s_wm8759_pcm_priv {
++	struct snd_star_i2s_wm8759_priv *card_priv;
++	spinlock_t lock;
++	struct timer_list timer;
++	unsigned int buffer_size_in_bytes;
++        unsigned int period_size_in_bytes;
++	unsigned int pcm_bps;		/* bytes per second */
++	unsigned int pcm_jiffie;	/* bytes per one jiffie */
++
++	unsigned int pcm_irq_pos[I2S_CHANNEL_NUM];	/* IRQ position */
++	unsigned int pcm_buf_pos[I2S_CHANNEL_NUM];	/* position in buffer */
++
++	u32 period_count_in_buffer; 	//(buffer_size/period_size)
++	u32 desc_count;		//period_count_in_buffer*channels
++
++	u32 desc_size_in_bytes;	//desc_count*sizeof(DMAC_LLP_T);
++	DMAC_LLP_T* desc;	//vir addr of desc buffer allocated
++	DMAC_LLP_T* desc_p;	//phy addr of desc buffer allocated
++
++	struct snd_pcm_substream *substream;
++};
++#endif
++
++static DECLARE_WAIT_QUEUE_HEAD(wg);
++static int swap_flag=0;
++static int call_swap_buffer(void)
++{
++	//current->pid, current->comm);
++	//printk(KERN_INFO "swap_flag=%d ...\n",swap_flag);
++
++	//wake up swap buffer
++	swap_flag=1;
++	wake_up_interruptible(&wg);
++	return 0;
++
++}
++
++
++static int swap_buffer_thread(void *data) 
++{
++	int i;
++	u_int32    *swap_buffer,*swap_buffer_p;
++	for(;;){
++		//printk(KERN_INFO "swap buffer start \n");
++		if(pcm_rx0_buffer_le88221==buffer0){
++			//printk("rx change to buffer1 \n");
++			swap_buffer=buffer2;
++			swap_buffer_p=buffer_p2;
++		}else if(pcm_rx0_buffer_le88221==buffer1){
++			//printk("rx change to buffer2 \n");
++			swap_buffer=buffer0;
++			swap_buffer_p=buffer_p0;
++
++		}else{
++			//printk("rx change to buffer0 \n");
++			swap_buffer=buffer1;
++			swap_buffer_p=buffer_p1;
++		}
++		for(i=0;i<BUFFER_SIZE;i++)
++			swap_buffer[i] = \
++			((swap_buffer[i] >> 8) & 0x000000FF) | \
++			((swap_buffer[i] << 8) & 0x0000FF00);
++
++		//printk("swap buffer end \n");
++		if(signal_pending(current))	
++			break;
++		wait_event_interruptible(wg, swap_flag !=0);
++		swap_flag=0;
++	}	
++	
++	return 1;
++}
++
++//static irqreturn_t str8100_dma_tc_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t str8100_dma_tc_irq_handler(int this_irq, void *dev_id)
++{
++    u_int32 volatile    dma_tc_status;
++	u32 i;
++
++	DEBUG_PRINT("%s: this_irq=%d,tc_status=0x%.8x\n",__FUNCTION__,this_irq,((DMAC_INT_TC_STATUS_REG) & 0xFF) );
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(dma_tc_status);
++    HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_GDMAC_TC_BIT_INDEX);
++    HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(dma_tc_status);
++
++#ifdef CONFIG_SND_STAR_I2S_WM8759
++	if (dma_tc_status & DMAC_CH_ID(0) || dma_tc_status & DMAC_CH_ID(1))		// WM8759
++	{
++		for(i=0;i<I2S_CHANNEL_NUM;i++)
++		{
++			struct snd_pcm_substream *substream=(struct snd_pcm_substream *)i2s_wm8759_dma_handshake_tx[i].private_data;
++			struct snd_pcm_runtime *runtime = substream->runtime;
++			struct snd_star_i2s_wm8759_pcm_priv *dpcm = (struct snd_star_i2s_wm8759_pcm_priv *)runtime->private_data;
++			HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8759_dma_handshake_tx[i].channel_num));
++			dma_tc_status &= ~(DMAC_CH_ID(i2s_wm8759_dma_handshake_tx[i].channel_num));
++
++			//currently assume period size (in frames) is the DMA totsize
++			dpcm->pcm_irq_pos[i] += dpcm->period_size_in_bytes/runtime->channels;
++			dpcm->pcm_buf_pos[i] += dpcm->period_size_in_bytes/runtime->channels;
++			dpcm->pcm_buf_pos[i] %= dpcm->buffer_size_in_bytes/runtime->channels;
++
++			if (dpcm->pcm_irq_pos[i] >= (dpcm->period_size_in_bytes/runtime->channels)) {
++				dpcm->pcm_irq_pos[i] %= (dpcm->period_size_in_bytes/runtime->channels);
++				snd_pcm_period_elapsed(dpcm->substream);
++			}
++		}
++	}
++#endif
++
++    //DMA Rx reg 0
++    if (dma_tc_status & DMAC_CH_ID(pcm_rx_data0_dma_channel_num))
++    {
++        HAL_DMAC_DISABLE_CHANNEL(pcm_rx_data0_dma_channel_num);
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(pcm_rx_data0_dma_channel_num));
++        dma_tc_status &= ~(DMAC_CH_ID(pcm_rx_data0_dma_channel_num));
++
++        //make pcm ch0 to ch1, and vice versa
++		if(pcm_rx0_buffer_le88221==buffer0){
++			//printk("rx change to buffer1 \n");
++			pcm_rx0_buffer_le88221=buffer1;
++			pcm_rx0_buffer_le88221_p=buffer_p1;
++			
++		}
++        else if(pcm_rx0_buffer_le88221==buffer1){
++			//printk("rx change to buffer2 \n");
++			pcm_rx0_buffer_le88221=buffer2;
++			pcm_rx0_buffer_le88221_p=buffer_p2;
++
++		}else{
++			//printk("rx change to buffer0 \n");
++			pcm_rx0_buffer_le88221=buffer0;
++			pcm_rx0_buffer_le88221_p=buffer_p0;
++		}
++        
++        // Re-initialize DMA's channel for Rx
++        HAL_DMAC_WRITE_CHANNEL2_DESTINATION_ADDRESS((u_int32)pcm_rx0_buffer_le88221_p);
++        HAL_DMAC_WRITE_CHANNEL2_SOURCE_ADDRESS(SYSPA_PCM_BASE_ADDR + 0xA0);
++        HAL_DMAC_WRITE_CHANNEL2_TRANSFER_SIZE(BUFFER_SIZE);
++        HAL_DMAC_ENABLE_CHANNEL2();
++		call_swap_buffer();                        
++    }       
++
++    //DMA Tx reg 0
++    if (dma_tc_status & DMAC_CH_ID(pcm_tx_data0_dma_channel_num))
++    {
++        HAL_DMAC_DISABLE_CHANNEL(pcm_tx_data0_dma_channel_num);
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(pcm_tx_data0_dma_channel_num));
++        dma_tc_status &= ~(DMAC_CH_ID(pcm_tx_data0_dma_channel_num));
++
++		//swap buffer
++        if(pcm_tx0_buffer_le88221==buffer2) {
++			//printk("tx change to buffer0 \n");
++			pcm_tx0_buffer_le88221=buffer0;
++			pcm_tx0_buffer_le88221_p=buffer_p0;
++		}
++		else if(pcm_tx0_buffer_le88221==buffer1){
++			//printk("tx change to buffer2 \n");
++			pcm_tx0_buffer_le88221=buffer2;
++			pcm_tx0_buffer_le88221_p=buffer_p2;
++		}
++		else{
++			//printk("tx change to buffer1 \n");
++			pcm_tx0_buffer_le88221=buffer1;
++			pcm_tx0_buffer_le88221_p=buffer_p1;
++			}
++  
++        // Re-initialize DMA's channel for Tx
++        HAL_DMAC_WRITE_CHANNEL0_SOURCE_ADDRESS((u_int32)pcm_tx0_buffer_le88221_p);
++        HAL_DMAC_WRITE_CHANNEL0_DESTINATION_ADDRESS(SYSPA_PCM_BASE_ADDR + 0x98);
++        HAL_DMAC_WRITE_CHANNEL0_TRANSFER_SIZE(BUFFER_SIZE);
++        HAL_DMAC_ENABLE_CHANNEL0();
++    }       
++
++    /*
++     * If there is any bit set, it means something wrong!!
++     */
++    if (dma_tc_status)
++    {
++        // Something wrong because spurious interrupt happens!!
++        printk("Something wrong because spurious interrupt happens(%.8x)!!\n",dma_tc_status);
++    }
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++void pcm_init(void){
++	u32 flags;
++	//u32 tmp;
++	local_irq_save(flags);
++    /*
++     * Check CLK_OUT_SEL_Pin for 8.192 MHz
++     */
++	DEBUG_PRINT("%s:\n",__FUNCTION__);
++//    HAL_MISC_DISABLE_SPI_SERIAL_FLASH_BANK_ACCESS();
++    HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(10, 0);
++
++    /*
++     * For IDL Case:
++     *     UDCLK    : 4.096 MHz
++     *     PCMCLK   : 2.048 MHz = 4.096/(1 + 1)
++     *     FSYNCCLK : 8 KHz = 2048000/(255 + 1)
++     */
++    pcm_object.config_0 = ((/*clock_rate_ctrl*/1 & 0x7) << 0) |    /* Configure master clock rate */
++                          (0 << 12) |                   /* Disable loopback mode */
++                          (1 << 13) |                   /* Enable master mode */
++                          (0 << 14) |                   /* Select IDL mode */
++                          /*(1 << 24) | */                  /* Enable PCM data swap */
++                          (0 << 24) |                   /* Disable PCM data swap */
++                          (0 << 31);                    /* Disable PCM */
++
++    /*
++     * Note FSYNC_WIDE will be ignored when the PCM is configured as Slave or as Master
++     * with GCI mode
++     */    
++    pcm_object.config_1 = ((0 & 0x1) << 15);    /* Select FSYNC mode , 0 : short FSYNC, 1 : long FSYNC */
++
++
++    /*
++     * Configure the settings of PCM's channel
++     */
++    pcm_object.channel_0_config = ((CH0_TX_Le88221_DELAY & 0x7F) << 0) |
++                                  ((CH0_RX_Le88221_DELAY & 0x7F) << 8) |
++                                  ((PCM_DATA_BIT_8 & 0x1) << 22) |
++                                  (1 << 23);    /* Enable this channel */
++                                  
++    pcm_object.channel_1_config = ((CH1_TX_Le88221_DELAY & 0x7F) << 0) |
++                                  ((CH1_RX_Le88221_DELAY & 0x7F) << 8) |
++                                  ((PCM_DATA_BIT_8 & 0x1) << 22) |
++                                  (1 << 23);    /* Enable this channel */
++
++    pcm_object.channel_2_config = ((CH2_TX_Le88221_DELAY & 0x7F) << 0) |
++                                  ((CH2_RX_Le88221_DELAY & 0x7F) << 8) |
++                                  ((0 & 0x1) << 22) |
++                                  (0 << 23);    /* Disable this channel */
++
++    pcm_object.channel_3_config = ((CH3_TX_Le88221_DELAY & 0x7F) << 0) |
++                                  ((CH3_RX_Le88221_DELAY & 0x7F) << 8) |
++                                  ((0 & 0x1) << 22) |
++                                  (0 << 23);    /* Disable this channel */
++
++
++    // Enable PCM's interrupt sources
++//    pcm_object.interrupt_config = 0;
++    pcm_object.interrupt_config = PCM_RXBUF_OVERRUN_FG | PCM_TXBUF_UNDERRUN_FG;
++//    pcm_object.interrupt_config |=PCM_RXBUF_FULL_FG|PCM_TXBUF_EMPTY_FG;
++
++
++   
++    // Initialize PCM's setting
++    Hal_Pcm_Initialize(&pcm_object);
++    
++    
++    // Disable PCM interrupt since GDMA hardware handshake interrupt will be used.
++    //HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_PCM_BIT_INDEX);
++
++    // Initialize GDMA hardware handshake for PCM
++    Pcm_Configure_DMA_Hardware_Handshake_For_Legerity();
++
++
++    /*
++     * PCM will start to transmit and receive data once PCM is enabled. To avoid
++     * PCM Transmit Buffer underrun, we have to put one transmit data into PCM
++     * Transmit Buffer before PCM is enabled!!
++     * Note PCM channel 0 is used.
++     */
++/*
++	PCM_TX_DATA_31_0_REG=0;
++	PCM_TX_DATA_63_32_REG=0;
++
++	tmp=PCM_RX_DATA_31_0_REG;
++	tmp=PCM_RX_DATA_63_32_REG;
++*/
++    HAL_PCM_CLEAR_INTERRUPT_STATUS((PCM_RXBUF_OVERRUN_FG | PCM_TXBUF_UNDERRUN_FG));//(0x4 | 0x8)=0xC
++
++/*{
++	u32 dma_ch;
++	for (dma_ch = 0; dma_ch < DMAC_MAX_CHANNEL_NUM; dma_ch++)
++	{
++			HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(DMAC_CH_ID(dma_ch));
++        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(dma_ch));
++	}	
++}
++*/
++    HAL_DMAC_ENABLE();    
++    HAL_PCM_ENABLE_PCM();
++
++    /*
++     * Configure Legerity's Le88221 MPI Interface
++     */
++    Pcm_Initial_Legerity_Le88221();
++	local_irq_restore(flags);
++
++    
++	DEBUG_PRINT("%s: end =>\n",__FUNCTION__);
++
++}
++
++//=================================================================================
++static int proc_read_pcm(char *buf, char **start, off_t offset,
++                   int count, int *eof, void *data)
++{
++	int len=0;
++	DEBUG_PRINT("%s:\n",__FUNCTION__);
++	len += sprintf(buf,	"test\n"
++				"test\n"); 
++	*eof = 1;
++	return len;
++}
++
++static int proc_write_pcm(struct file *file, const char *buffer, unsigned long count, void *data){
++	int len=0;
++	DEBUG_PRINT("%s: count=%ld\n",__FUNCTION__,count);
++	pcm_init();
++
++	return count;
++	//is buffer free?
++	if(txpos!=txlen){
++		printk("%s: buffer not free\n",__FUNCTION__);
++		return -EBUSY;
++	}
++
++	//copy the raw data to local buffer	
++	if(count>BUFFER_SIZE) len=BUFFER_SIZE;
++	else len=count;
++	
++	if(copy_from_user(txbuffer,buffer,len)){
++		return -EFAULT;	
++	}
++	txlen=len;
++	txpos=0;
++
++	//Initialization	
++
++	// Enable CPU interrupt
++	local_irq_enable();
++	
++	/*
++	 * Note DMA must be enabled first before PCM is enabled
++	 */
++	HAL_DMAC_ENABLE();
++
++
++	while (1){
++		local_irq_disable();
++		if (txpos>txlen||txlen==0){
++			// Disable PCM
++			
++			break;
++		}
++		local_irq_enable();
++	}
++	DEBUG_PRINT("%s: exit. \n",__FUNCTION__);
++
++	local_irq_enable();
++
++	return len;
++
++//debug:
++	
++//	return count;
++}
++
++static void __exit pcm_exit_module(void){
++	printk("%s:\n",__FUNCTION__);
++	remove_proc_entry("str8100/pcm", NULL);
++	free_irq(INTC_PCM_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_TC_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_ERROR_BIT_INDEX, NULL);
++/*	if(txbuffer) {
++		pci_free_consistent(NULL, BUFFER_SIZE*4, txbuffer, txbuffer_p);
++		txbuffer=txbuffer_p=NULL;
++	}
++*/
++#if 1
++	if(buffer0) {
++		pci_free_consistent(NULL, BUFFER_SIZE*4, buffer0, *buffer_p0);
++		buffer0=buffer_p0=NULL;
++	}
++
++	if(buffer1) {
++		pci_free_consistent(NULL, BUFFER_SIZE*4, buffer1, *buffer_p1);
++		buffer1=buffer_p1=NULL;
++	}
++	if(buffer2) {
++		pci_free_consistent(NULL, BUFFER_SIZE*4, buffer2, *buffer_p2);
++		buffer2=buffer_p2=NULL;
++	}
++
++	if(buffer3) {
++		pci_free_consistent(NULL, BUFFER_SIZE*4, buffer3, *buffer_p3);
++		buffer3=buffer_p3=NULL;
++	}
++#else
++	printk("%s:buffers not freed yet!!!\n",__FUNCTION__);
++#endif	
++}
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++static int __init pcm_init_module(void)
++{
++	
++	u32 ret;
++	
++	printk("%s:\n",__FUNCTION__);
++
++	star_pcm_proc_entry = create_proc_entry("str8100/pcm", S_IFREG | S_IRUGO, NULL);
++	if(!star_pcm_proc_entry){
++		return -EBUSY;
++	}
++	star_pcm_proc_entry->read_proc=proc_read_pcm;
++	star_pcm_proc_entry->write_proc=proc_write_pcm;
++	
++/*
++	txbuffer = pci_alloc_consistent(NULL, BUFFER_SIZE, &txbuffer_p);
++	if(!txbuffer){
++		printk("%s: alloc txbuffer failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++*/
++	buffer0 = pci_alloc_consistent(NULL, BUFFER_SIZE*4, &buffer_p0);
++	if(!buffer0){
++		printk("%s: alloc buffer0 failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	buffer1 = pci_alloc_consistent(NULL, BUFFER_SIZE*4, &buffer_p1);
++	if(!buffer1){
++		printk("%s: alloc buffer1 failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	buffer2 = pci_alloc_consistent(NULL, BUFFER_SIZE*4, &buffer_p2);
++	if(!buffer2){
++		printk("%s: alloc buffer2 failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	buffer3 = pci_alloc_consistent(NULL, BUFFER_SIZE*4, &buffer_p3);
++	if(!buffer3){
++		printk("%s: alloc buffer3 failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++	DEBUG_PRINT("%s: buffers allocated... \n",__FUNCTION__);
++
++	pcm_rx0_buffer_le88221=buffer0;
++	pcm_tx0_buffer_le88221=buffer1;
++	//pcm_rx1_buffer_le88221=buffer2;
++	//pcm_tx1_buffer_le88221=buffer3;
++	
++	pcm_rx0_buffer_le88221_p=buffer_p0;
++	pcm_tx0_buffer_le88221_p=buffer_p1;
++	//pcm_rx1_buffer_le88221_p=buffer_p2;
++	//pcm_tx1_buffer_le88221_p=buffer_p3;
++/*
++	str8100_set_interrupt_trigger (INTC_PCM_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_LOW);
++	if((ret=request_irq(INTC_PCM_BIT_INDEX, str8100_pcm_irq_handler, 0, "pcm", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_PCM_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++*/
++	str8100_set_interrupt_trigger (INTC_GDMAC_TC_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_TC_BIT_INDEX, str8100_dma_tc_irq_handler, 0, "dma tc", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_TC_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++	str8100_set_interrupt_trigger (INTC_GDMAC_ERROR_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_ERROR_BIT_INDEX, str8100_dma_err_irq_handler, 0, "dma error", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_ERROR_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++	kernel_thread(swap_buffer_thread, NULL, CLONE_KERNEL);
++
++	//pcm_init();
++
++	return 0;
++exit1:
++	//pcm_exit_module();
++	return -EBUSY;
++}
++
++module_init(pcm_init_module);
++module_exit(pcm_exit_module);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_dma.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_dma.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_dma.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_dma.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,878 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/pci.h>
++#include <asm/io.h>
++#include <asm/delay.h>
++#include <mach/star_intc.h>
++#include <mach/star_dmac.h>
++
++//#define DMA_DEBUG
++//#define STR8100_DMA_TEST
++
++#define DMA_CHANNEL_MAX_ID		6 // channel 0 ~ 6
++
++#define DMA_XFER_MAX_Q_LEN		32
++#define DMA_BUSY_MAX_Q_LEN		7
++
++#define ADDR_16BIT_ALIGN_MASK		0x1
++#define ADDR_32BIT_ALIGN_MASK		0x3
++
++#define DMA_LEN_SHIFT_8BIT_WIDTH	0
++#define DMA_LEN_SHIFT_16BIT_WIDTH	1
++#define DMA_LEN_SHIFT_32BIT_WIDTH	2
++#define DMA_MAX_LEN_8BIT_WIDTH		0xfff
++#define DMA_MAX_LEN_16BIT_WIDTH		(0xfff << 1)
++#define DMA_MAX_LEN_32BIT_WIDTH		(0xfff << 2)
++
++#define DMA_COPY_BUSY_WAIT_CHANNEL	7
++#define DMA_COPY_BUSY_WAIT_LOOP		1000
++
++static u32 dma_burst_size = DMAC_CH_SRC_BURST_SIZE_32;
++
++#define DEFAULT_CH_PRIORITY		DMAC_CH_PRIORITY_3
++#define DEFAULT_CH_BURST_SIZE		DMAC_CH_SRC_BURST_SIZE_128
++#define DEFAULT_CH_SRC_WIDTH		DMAC_CH_SRC_WIDTH_8BIT
++#define DEFAULT_CH_DST_WIDTH		DMAC_CH_SRC_WIDTH_8BIT
++#define DEFAULT_CH_MODE			DMAC_CH_MODE_NORMAL
++#define DEFAULT_CH_SRC_ADDR_CTL		DMAC_CH_SRC_ADDR_CTL_INC
++#define DEFAULT_CH_DST_ADDR_CTL		DMAC_CH_DST_ADDR_CTL_INC
++#define DEFAULT_CH_DST_SEL		DMAC_DST_SEL_MASTER0
++#define DEFAULT_CH_SRC_SEL		DMAC_SRC_SEL_MASTER0
++
++#define DEFAULT_DMA_CH_CTL \
++	((0xf				<< DMAC_CH_HHST_SEL_BIT_INDEX) | \
++	 (DEFAULT_CH_PRIORITY		<< DMAC_CH_PRIORITY_BIT_INDEX) | \
++	 (DEFAULT_CH_BURST_SIZE		<< DMAC_CH_SRC_BURST_SIZE_BIT_INDEX) | \
++	 (DEFAULT_CH_SRC_WIDTH		<< DMAC_CH_SRC_WIDTH_BIT_INDEX) | \
++	 (DEFAULT_CH_DST_WIDTH		<< DMAC_CH_DST_WIDTH_BIT_INDEX) | \
++	 (DEFAULT_CH_MODE		<< DMAC_CH_MODE_BIT_INDEX) | \
++	 (DEFAULT_CH_SRC_ADDR_CTL	<< DMAC_CH_SRC_ADDR_CTL_BIT_INDEX) | \
++	 (DEFAULT_CH_DST_ADDR_CTL	<< DMAC_CH_DST_ADDR_CTL_BIT_INDEX) | \
++	 (DEFAULT_CH_DST_SEL		<< DMAC_CH_DST_SEL_BIT_INDEX) | \
++	 (DEFAULT_CH_SRC_SEL		<< DMAC_CH_SRC_SEL_BIT_INDEX))
++
++#define DMA_CH_CTL_8BIT_WIDTH \
++	((0xf				<< DMAC_CH_HHST_SEL_BIT_INDEX) | \
++	 (DMAC_CH_PRIORITY_3		<< DMAC_CH_PRIORITY_BIT_INDEX) | \
++	 (dma_burst_size		<< DMAC_CH_SRC_BURST_SIZE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_WIDTH_8BIT	<< DMAC_CH_SRC_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_DST_WIDTH_8BIT	<< DMAC_CH_DST_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_MODE_NORMAL		<< DMAC_CH_MODE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_ADDR_CTL_INC	<< DMAC_CH_SRC_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_CH_DST_ADDR_CTL_INC	<< DMAC_CH_DST_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_DST_SEL_MASTER0		<< DMAC_CH_DST_SEL_BIT_INDEX) | \
++	 (DMAC_SRC_SEL_MASTER1		<< DMAC_CH_SRC_SEL_BIT_INDEX))
++
++#define DMA_CH_CTL_16BIT_WIDTH \
++	((0xf				<< DMAC_CH_HHST_SEL_BIT_INDEX) | \
++	 (DMAC_CH_PRIORITY_3		<< DMAC_CH_PRIORITY_BIT_INDEX) | \
++	 (dma_burst_size		<< DMAC_CH_SRC_BURST_SIZE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_WIDTH_16BIT	<< DMAC_CH_SRC_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_DST_WIDTH_16BIT	<< DMAC_CH_DST_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_MODE_NORMAL		<< DMAC_CH_MODE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_ADDR_CTL_INC	<< DMAC_CH_SRC_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_CH_DST_ADDR_CTL_INC	<< DMAC_CH_DST_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_DST_SEL_MASTER0		<< DMAC_CH_DST_SEL_BIT_INDEX) | \
++	 (DMAC_SRC_SEL_MASTER1		<< DMAC_CH_SRC_SEL_BIT_INDEX))
++
++
++#define DMA_CH_CTL_32BIT_WIDTH \
++	((0xf				<< DMAC_CH_HHST_SEL_BIT_INDEX) | \
++	 (DMAC_CH_PRIORITY_3		<< DMAC_CH_PRIORITY_BIT_INDEX) | \
++	 (dma_burst_size		<< DMAC_CH_SRC_BURST_SIZE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_WIDTH_32BIT	<< DMAC_CH_SRC_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_DST_WIDTH_32BIT	<< DMAC_CH_DST_WIDTH_BIT_INDEX) | \
++	 (DMAC_CH_MODE_NORMAL		<< DMAC_CH_MODE_BIT_INDEX) | \
++	 (DMAC_CH_SRC_ADDR_CTL_INC	<< DMAC_CH_SRC_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_CH_DST_ADDR_CTL_INC	<< DMAC_CH_DST_ADDR_CTL_BIT_INDEX) | \
++	 (DMAC_DST_SEL_MASTER0		<< DMAC_CH_DST_SEL_BIT_INDEX) | \
++	 (DMAC_SRC_SEL_MASTER1		<< DMAC_CH_SRC_SEL_BIT_INDEX))
++
++typedef struct
++{
++	struct list_head	lh;
++	dma_xfer_t		*xfer;
++	dma_llp_descr_t		*llp_descr;
++	u32			llp_descr_dma;
++	int			done_status;
++} dma_job_t;
++
++
++static u8 dma_dev;
++static spinlock_t dma_lock;
++static u8 dma_busy;
++static u8 dma_busy_q_len;
++static unsigned int dma_xfer_q_len;
++static unsigned int dma_done_q_len;
++static struct list_head dma_xfer_q;
++static struct list_head dma_done_q;
++static dma_job_t *dma_running_job[DMA_CHANNEL_MAX_ID + 1];
++
++static void *dma_mem_pool;
++static u32 dma_mem_pool_dma;
++
++static dma_job_t dma_job_pool[DMA_XFER_MAX_Q_LEN];
++static struct list_head dma_job_q;
++static spinlock_t dma_job_q_lock;
++
++static void dma_process_xfer_job(void *data);
++static void dma_process_done_job(void *data);
++
++// Eileen , for linux kernel 2.6.24 , 20080424
++//old : static DECLARE_WORK(dma_xfer_task, dma_process_xfer_job, (void *)&dma_xfer_q);
++//old : static DECLARE_WORK(dma_done_task, dma_process_done_job, (void *)&dma_done_q);
++static DECLARE_WORK(dma_xfer_task, dma_process_xfer_job);
++static DECLARE_WORK(dma_done_task, dma_process_done_job);
++
++static int dma_job_q_init(void)
++{
++	int i;
++
++	dma_mem_pool = (void *)pci_alloc_consistent(NULL,
++		(DMA_XFER_MAX_Q_LEN * MAX_DMA_VEC * sizeof(dma_llp_descr_t)),
++	       	&dma_mem_pool_dma);
++
++	if (dma_mem_pool == NULL) {
++		return -1;
++	}
++
++	INIT_LIST_HEAD(&dma_job_q);
++	for (i = 0; i < DMA_XFER_MAX_Q_LEN; i++) {
++		INIT_LIST_HEAD(&dma_job_pool[i].lh);
++		dma_job_pool[i].llp_descr = (dma_llp_descr_t *)(dma_mem_pool + (i * (MAX_DMA_VEC * sizeof(dma_llp_descr_t))));
++		dma_job_pool[i].llp_descr_dma = dma_mem_pool_dma + (i * (MAX_DMA_VEC * sizeof(dma_llp_descr_t)));
++		list_add_tail(&dma_job_pool[i].lh, &dma_job_q);
++	}
++
++	return 0;
++}
++
++static dma_job_t *dma_job_alloc(void)
++{
++	dma_job_t *job;
++	unsigned long flags;
++
++	spin_lock_irqsave(&dma_job_q_lock, flags);
++	if (list_empty(&dma_job_q)) {
++		job = NULL;
++	} else {
++		job = list_entry(dma_job_q.next, dma_job_t, lh);
++		list_del_init(&job->lh);
++	}
++	spin_unlock_irqrestore(&dma_job_q_lock, flags);
++
++	return job;
++}
++
++static void dma_job_free(dma_job_t *job)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&dma_job_q_lock, flags);
++	list_add(&job->lh, &dma_job_q);
++	spin_unlock_irqrestore(&dma_job_q_lock, flags);
++}
++
++#ifdef DMA_DEBUG
++void dma_dump_reg(void)
++{
++	printk("DMAC_BASE_ADDR+0x000: 0x%08x\n", DMAC_INT_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x004: 0x%08x\n", DMAC_INT_TC_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x008: 0x%08x\n", DMAC_INT_TC_STATUS_CLR_REG);
++	printk("DMAC_BASE_ADDR+0x00C: 0x%08x\n", DMAC_INT_ERR_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x010: 0x%08x\n", DMAC_INT_ERR_STATUS_CLR_REG);
++	printk("DMAC_BASE_ADDR+0x014: 0x%08x\n", DMAC_TC_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x018: 0x%08x\n", DMAC_ERR_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x01C: 0x%08x\n", DMAC_CH_ENABLE_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x020: 0x%08x\n", DMAC_CH_BUSY_STATUS_REG);
++	printk("DMAC_BASE_ADDR+0x024: 0x%08x\n", DMAC_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x028: 0x%08x\n", DMAC_SYNC_REG);
++	printk("DMAC_BASE_ADDR+0x100: 0x%08x\n", DMAC_CH0_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x104: 0x%08x\n", DMAC_CH0_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x108: 0x%08x\n", DMAC_CH0_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x10C: 0x%08x\n", DMAC_CH0_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x110: 0x%08x\n", DMAC_CH0_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x114: 0x%08x\n", DMAC_CH0_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x120: 0x%08x\n", DMAC_CH1_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x124: 0x%08x\n", DMAC_CH1_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x128: 0x%08x\n", DMAC_CH1_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x12C: 0x%08x\n", DMAC_CH1_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x130: 0x%08x\n", DMAC_CH1_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x134: 0x%08x\n", DMAC_CH1_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x140: 0x%08x\n", DMAC_CH2_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x144: 0x%08x\n", DMAC_CH2_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x148: 0x%08x\n", DMAC_CH2_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x14C: 0x%08x\n", DMAC_CH2_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x150: 0x%08x\n", DMAC_CH2_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x154: 0x%08x\n", DMAC_CH2_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x160: 0x%08x\n", DMAC_CH3_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x164: 0x%08x\n", DMAC_CH3_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x168: 0x%08x\n", DMAC_CH3_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x16C: 0x%08x\n", DMAC_CH3_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x170: 0x%08x\n", DMAC_CH3_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x174: 0x%08x\n", DMAC_CH3_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x180: 0x%08x\n", DMAC_CH4_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x184: 0x%08x\n", DMAC_CH4_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x188: 0x%08x\n", DMAC_CH4_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x18C: 0x%08x\n", DMAC_CH4_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x190: 0x%08x\n", DMAC_CH4_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x194: 0x%08x\n", DMAC_CH4_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x1A0: 0x%08x\n", DMAC_CH5_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x1A4: 0x%08x\n", DMAC_CH5_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x1A8: 0x%08x\n", DMAC_CH5_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1AC: 0x%08x\n", DMAC_CH5_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1B0: 0x%08x\n", DMAC_CH5_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x1B4: 0x%08x\n", DMAC_CH5_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x1C0: 0x%08x\n", DMAC_CH6_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x1C4: 0x%08x\n", DMAC_CH6_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x1C8: 0x%08x\n", DMAC_CH6_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1CC: 0x%08x\n", DMAC_CH6_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1D0: 0x%08x\n", DMAC_CH6_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x1D4: 0x%08x\n", DMAC_CH6_SIZE_REG);
++	printk("DMAC_BASE_ADDR+0x1E0: 0x%08x\n", DMAC_CH7_CSR_REG);
++	printk("DMAC_BASE_ADDR+0x1E4: 0x%08x\n", DMAC_CH7_CFG_REG);
++	printk("DMAC_BASE_ADDR+0x1E8: 0x%08x\n", DMAC_CH7_SRC_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1EC: 0x%08x\n", DMAC_CH7_DST_ADDR_REG);
++	printk("DMAC_BASE_ADDR+0x1F0: 0x%08x\n", DMAC_CH7_LLP_REG);
++	printk("DMAC_BASE_ADDR+0x1F4: 0x%08x\n", DMAC_CH7_SIZE_REG);
++}
++#endif
++
++static inline void dma_copy_busy_wait(void *dst, const void *src, size_t len, unsigned long dma_len_shift)
++{
++	int err = 0;
++	int i;
++
++	len = (len >> dma_len_shift);
++
++	while ((DMAC_CH_BUSY_STATUS_REG & 0xFF) & (1 << DMA_COPY_BUSY_WAIT_CHANNEL)) {
++		udelay(1);
++	}
++
++	DMAC_CH_SRC_ADDR_REG(DMA_COPY_BUSY_WAIT_CHANNEL)	= (u32)virt_to_phys((void *)src);
++	DMAC_CH_DST_ADDR_REG(DMA_COPY_BUSY_WAIT_CHANNEL)	= (u32)virt_to_phys((void *)dst);
++	DMAC_CH_SIZE_REG(DMA_COPY_BUSY_WAIT_CHANNEL)		= (u32)len;
++
++#ifdef DMA_DEBUG
++	dma_dump_reg();
++#endif
++
++	// enable the channel
++	DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) |= 0x1;
++
++	for (i = 0; i < DMA_COPY_BUSY_WAIT_LOOP; i++) {
++		if (DMAC_TC_STATUS_REG & (1 << DMA_COPY_BUSY_WAIT_CHANNEL)) {
++			break;
++		}
++		if (DMAC_ERR_STATUS_REG & (1 << DMA_COPY_BUSY_WAIT_CHANNEL)) {
++			err = 1;
++			break;
++		}
++		udelay(1);
++	}
++
++	// disable the channel
++	DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) &= ~0x1;
++
++	if (err || (i == DMA_COPY_BUSY_WAIT_LOOP)) {
++		if (err) {
++			// clear the ERROR status
++			DMAC_INT_ERR_STATUS_CLR_REG |= (1 << DMA_COPY_BUSY_WAIT_CHANNEL);
++		}
++		memcpy(dst, src, (len << dma_len_shift));
++	} else {
++		// clear the TC status
++		DMAC_INT_TC_STATUS_CLR_REG |= (1 << DMA_COPY_BUSY_WAIT_CHANNEL);
++	}
++}
++
++void dma_memcpy_busy_wait(void *dst, const void *src, size_t len)
++{
++	void *pdst = dst;
++	const void *psrc = src;
++	unsigned long dma_len_shift;
++	unsigned long dma_max_len;
++	unsigned long flags;
++
++#ifdef DMA_DEBUG
++	printk("dst: 0x%08x\n", (u32)dst);
++	printk("src: 0x%08x\n", (u32)src);
++	printk("len: 0x%08x\n", (u32)len);
++	printk("pdst: 0x%08x\n", (u32)pdst);
++	printk("psrc: 0x%08x\n", (u32)psrc);
++#endif
++
++	local_irq_save(flags);
++	
++	// Eileen , for linux kernel 2.6.24 , 20080424
++	// old : consistent_sync((void *)src, len, PCI_DMA_TODEVICE);
++	// old : consistent_sync((void *)dst, len, PCI_DMA_FROMDEVICE);
++	dma_cache_maint((void *)src, len, PCI_DMA_TODEVICE);
++	dma_cache_maint((void *)dst, len, PCI_DMA_FROMDEVICE);
++
++	if ((((u32)psrc & ADDR_32BIT_ALIGN_MASK) == 0) &&
++		(((u32)pdst & ADDR_32BIT_ALIGN_MASK) == 0) &&
++		((len & 3) == 0)) {
++		dma_len_shift = DMA_LEN_SHIFT_32BIT_WIDTH;
++		dma_max_len = DMA_MAX_LEN_32BIT_WIDTH;
++		DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) = DMA_CH_CTL_32BIT_WIDTH;
++	} else if ((((u32)psrc & ADDR_16BIT_ALIGN_MASK) == 0) &&
++		(((u32)pdst & ADDR_16BIT_ALIGN_MASK) == 0) &&
++		((len & 1) == 0)) {
++		dma_len_shift = DMA_LEN_SHIFT_16BIT_WIDTH;
++		dma_max_len = DMA_MAX_LEN_16BIT_WIDTH;
++		DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) = DMA_CH_CTL_16BIT_WIDTH;
++	} else {
++		dma_len_shift = DMA_LEN_SHIFT_8BIT_WIDTH;
++		dma_max_len = DMA_MAX_LEN_8BIT_WIDTH;
++		DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) = DMA_CH_CTL_8BIT_WIDTH;
++	}
++
++	while (len) {
++		if (len > dma_max_len) {
++			dma_copy_busy_wait(pdst, psrc, dma_max_len, dma_len_shift);
++			pdst += dma_max_len;
++			psrc += dma_max_len;
++			len -= dma_max_len;
++		} else {
++			dma_copy_busy_wait(pdst, psrc, len, dma_len_shift);
++			len = 0;
++		}
++	}
++
++	local_irq_restore(flags);
++}
++EXPORT_SYMBOL(dma_memcpy_busy_wait);
++
++void dma_copy(dma_xfer_t *dma_xfer)
++{
++	dma_job_t *dma_job;
++	u32 size_shift = 0;
++	unsigned long flags;
++	int i;
++
++	if (dma_xfer_q_len > DMA_XFER_MAX_Q_LEN) {
++		dma_xfer->dma_end_io(dma_xfer, DMAC_RESPONSE_ERR);
++		return;
++	}
++
++	dma_job = dma_job_alloc();
++	if (dma_job == NULL) {
++		dma_xfer->dma_end_io(dma_xfer, DMAC_RESPONSE_ERR);
++		return;
++	}
++
++	memset(dma_job->llp_descr, 0, (dma_xfer->nr_vec * sizeof(dma_llp_descr_t)));
++	for (i = 0; i < dma_xfer->nr_vec; i++) {
++		// Eileen , for linux kernel 2.6.24 , 20080424
++		//old : consistent_sync((void *)dma_xfer->vec[i].src_addr, dma_xfer->vec[i].size, PCI_DMA_TODEVICE);
++		//old : consistent_sync((void *)dma_xfer->vec[i].dst_addr, dma_xfer->vec[i].size, PCI_DMA_FROMDEVICE);
++		dma_cache_maint((void *)dma_xfer->vec[i].src_addr, dma_xfer->vec[i].size, PCI_DMA_TODEVICE);
++		dma_cache_maint((void *)dma_xfer->vec[i].dst_addr, dma_xfer->vec[i].size, PCI_DMA_FROMDEVICE);
++		dma_job->llp_descr[i].src_addr = (u32)virt_to_phys((void *)dma_xfer->vec[i].src_addr);
++		dma_job->llp_descr[i].dst_addr = (u32)virt_to_phys((void *)dma_xfer->vec[i].dst_addr);
++		dma_job->llp_descr[i].dst_sel = dma_xfer->vec[i].dst_sel;
++		dma_job->llp_descr[i].src_sel = dma_xfer->vec[i].src_sel;
++		dma_job->llp_descr[i].dst_addr_ctl = dma_xfer->vec[i].dst_sel;
++		dma_job->llp_descr[i].src_addr_ctl = dma_xfer->vec[i].src_sel;
++		dma_job->llp_descr[i].dst_width = dma_xfer->vec[i].dst_width;
++		dma_job->llp_descr[i].src_width = dma_xfer->vec[i].src_width;
++		if (dma_xfer->vec[i].src_width == DMAC_CH_DST_WIDTH_32BIT) {
++			size_shift = 2;
++		} else if (dma_xfer->vec[i].src_width == DMAC_CH_DST_WIDTH_16BIT) {
++			size_shift = 1;
++		} else {
++			size_shift = 0;
++		}
++		dma_job->llp_descr[i].tot_size = (dma_xfer->vec[i].size >> size_shift) & 0xFFF;
++		if (i == (dma_xfer->nr_vec - 1)) {
++			dma_job->llp_descr[i].llp = 0;
++			dma_job->llp_descr[i].tc_mask = 0;
++		} else {
++			dma_job->llp_descr[i].llp = (u32)(dma_job->llp_descr_dma + ((i + 1) * sizeof(dma_llp_descr_t)));
++			dma_job->llp_descr[i].tc_mask = 1;
++		}
++#ifdef DMA_DEBUG
++		printk("in src_addr:  0x%08x\n", dma_xfer->vec[i].src_addr);
++		printk("in dst_addr:  0x%08x\n", dma_xfer->vec[i].dst_addr);
++		printk("src_addr:     0x%08x\n", dma_job->llp_descr[i].src_addr);
++		printk("dst_addr:     0x%08x\n", dma_job->llp_descr[i].dst_addr);
++		printk("llp:          0x%08x\n", dma_job->llp_descr[i].llp);
++		printk("tot_size:     0x%08x\n", dma_job->llp_descr[i].tot_size);
++		printk("dst_sel:      0x%08x\n", dma_job->llp_descr[i].dst_sel);
++		printk("src_sel:      0x%08x\n", dma_job->llp_descr[i].src_sel);
++		printk("dst_addr_ctl: 0x%08x\n", dma_job->llp_descr[i].dst_addr_ctl);
++		printk("src_addr_ctl: 0x%08x\n", dma_job->llp_descr[i].src_addr_ctl);
++		printk("dst_width:    0x%08x\n", dma_job->llp_descr[i].dst_width);
++		printk("src_width:    0x%08x\n", dma_job->llp_descr[i].src_width);
++		printk("tc_mask:      0x%08x\n", dma_job->llp_descr[i].tc_mask);
++#endif
++	}
++
++	dma_job->xfer = dma_xfer;
++	dma_job->done_status = 0;
++
++	spin_lock_irqsave(&dma_lock, flags);
++	list_add_tail(&dma_job->lh, &dma_xfer_q);
++	dma_xfer_q_len++;
++	spin_unlock_irqrestore(&dma_lock, flags);
++
++	if (!dma_busy) {
++		schedule_work(&dma_xfer_task);
++	}
++}
++EXPORT_SYMBOL(dma_copy);
++
++static void dma_process_xfer_job(void *data)
++{
++	struct list_head *l, *t;
++	dma_job_t *dma_job;
++	unsigned long csr_reg;
++	int i;
++	unsigned long flags;
++
++	if (dma_busy) {
++		return;
++	}
++
++	spin_lock_irqsave(&dma_lock, flags);
++	list_for_each_safe(l, t, &dma_xfer_q) {
++		dma_job = list_entry(l, dma_job_t, lh);
++		for (i = 0; i <= 6; i++) {
++			if (dma_running_job[i] != NULL) {
++				continue;
++			}
++			printk("Insert dma xfer to channel(%d)\n", i);
++			list_del_init(&dma_job->lh);
++			dma_running_job[i] = dma_job;
++			dma_xfer_q_len--;
++			dma_busy_q_len++;
++			csr_reg = DMAC_CH_CSR_REG(i);
++			if (dma_job->llp_descr[0].tc_mask) {
++				csr_reg |= (1 << 31);
++			} else {
++				csr_reg &= ~(1 << 31);
++			}
++			csr_reg &= ~(DMAC_CH_SRC_WIDTH_MASK << DMAC_CH_SRC_WIDTH_BIT_INDEX);
++			csr_reg &= ~(DMAC_CH_DST_WIDTH_MASK << DMAC_CH_DST_WIDTH_BIT_INDEX);
++			csr_reg &= ~(DMAC_CH_SRC_ADDR_CTL_MASK << DMAC_CH_SRC_ADDR_CTL_BIT_INDEX);
++			csr_reg &= ~(DMAC_CH_DST_ADDR_CTL_MASK << DMAC_CH_DST_ADDR_CTL_BIT_INDEX);
++			csr_reg |=
++				((dma_job->llp_descr[0].src_width << DMAC_CH_SRC_WIDTH_BIT_INDEX) |
++				 (dma_job->llp_descr[0].dst_width << DMAC_CH_DST_WIDTH_BIT_INDEX) |
++				 (dma_job->llp_descr[0].src_addr_ctl << DMAC_CH_SRC_ADDR_CTL_BIT_INDEX) |
++				 (dma_job->llp_descr[0].dst_addr_ctl << DMAC_CH_DST_ADDR_CTL_BIT_INDEX) |
++				 (dma_job->llp_descr[0].src_sel << DMAC_CH_SRC_SEL_BIT_INDEX) |
++				 (dma_job->llp_descr[0].dst_sel << DMAC_CH_DST_SEL_BIT_INDEX));
++			DMAC_CH_CSR_REG(i) = csr_reg;
++
++#if 0
++			if (dma_job->llp_descr[0].tc_mask) {
++				DMAC_CH_CFG_REG(i) |= 0x1;
++			} else {
++				DMAC_CH_CFG_REG(i) &= ~0x1;
++			}
++#endif
++
++			DMAC_CH_SRC_ADDR_REG(i) = dma_job->llp_descr[0].src_addr;
++			DMAC_CH_DST_ADDR_REG(i) = dma_job->llp_descr[0].dst_addr;
++			DMAC_CH_LLP_REG(i) = dma_job->llp_descr[0].llp;
++			DMAC_CH_SIZE_REG(i) = dma_job->llp_descr[0].tot_size;
++			HAL_DMAC_ENABLE_CHANNEL(i);
++			break;
++#ifdef DMA_DEBUG
++			//dma_dump_reg();
++#endif
++		}
++		if (dma_busy_q_len == DMA_BUSY_MAX_Q_LEN) {
++			dma_busy = 1;
++			break;
++		}
++	}
++	spin_unlock_irqrestore(&dma_lock, flags);
++}
++
++static void dma_process_done_job(void *data)
++{
++	dma_job_t *dma_job;
++	struct list_head *l, *t;
++	unsigned long flags;
++
++	spin_lock_irqsave(&dma_lock, flags);
++	list_for_each_safe(l, t, &dma_done_q) {
++		dma_job = list_entry(l, dma_job_t, lh);
++		list_del_init(&dma_job->lh);
++		dma_done_q_len--;
++		spin_unlock_irqrestore(&dma_lock, flags);
++		dma_job->xfer->dma_end_io(dma_job->xfer, dma_job->done_status);
++		dma_job_free(dma_job);
++		spin_lock_irqsave(&dma_lock, flags);
++	}
++	spin_unlock_irqrestore(&dma_lock, flags);
++}
++// Eileen , for linux kernel 2.6.24 , 20080424
++//old : irqreturn_t dma_tc_isr(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t dma_tc_isr(int irq, void *dev_id)
++{
++	dma_job_t *dma_job;
++	u32 tc_status;
++	int i;
++
++	tc_status = DMAC_INT_TC_STATUS_REG;
++
++	for (i = 0; i <= 6; i++) {
++		if (tc_status & (1 << i)) {
++			HAL_DMAC_DISABLE_CHANNEL(i);
++			dma_job = dma_running_job[i];
++			if (dma_job) {
++				dma_running_job[i] = NULL;
++				dma_job->done_status = DMAC_RESPONSE_OK;
++				list_add_tail(&dma_job->lh, &dma_done_q);
++				dma_done_q_len++;
++				dma_busy_q_len--;
++				if (dma_busy) {
++					dma_busy = 0;
++				}
++				schedule_work(&dma_done_task);
++				if (dma_xfer_q_len) {
++					schedule_work(&dma_xfer_task);
++				}
++			}
++			DMAC_INT_TC_STATUS_CLR_REG |= (1 << i);
++			break;
++		}
++	}
++
++	return IRQ_HANDLED;
++}
++
++// Eileen ,for linux kernel 2.6.24 , 20080424
++//irqreturn_t dma_err_isr(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t dma_err_isr(int irq, void *dev_id)
++{
++	dma_job_t *dma_job;
++	u32 err_status;
++	int i;
++
++	err_status = DMAC_INT_ERR_STATUS_REG;
++
++	for (i = 0; i <= 6; i++) {
++		if (err_status & (1 << i)) {
++			HAL_DMAC_DISABLE_CHANNEL(i);
++			dma_job = dma_running_job[i];
++			if (dma_job) {
++				dma_running_job[i] = NULL;
++				dma_job->done_status = DMAC_RESPONSE_ERR;
++				list_add_tail(&dma_job->lh, &dma_done_q);
++				dma_done_q_len++;
++				dma_busy_q_len--;
++				if (dma_busy) {
++					dma_busy = 0;
++				}
++				schedule_work(&dma_done_task);
++				if (dma_xfer_q_len) {
++					schedule_work(&dma_xfer_task);
++				}
++			}
++			DMAC_INT_ERR_STATUS_CLR_REG |= (1 << i);
++			break;
++		}
++	}
++
++	return IRQ_HANDLED;
++}
++
++void dma_channel_init(void)
++{
++	int i;
++
++	// disable the channel
++	DMAC_CH_CSR_REG(DMA_COPY_BUSY_WAIT_CHANNEL) &= ~0x1;
++	DMAC_CH_CFG_REG(DMA_COPY_BUSY_WAIT_CHANNEL) = 0x7;
++
++	for (i = 0; i <= 6; i++) {
++		HAL_DMAC_DISABLE_CHANNEL(i);
++		DMAC_CH_CSR_REG(i) = DEFAULT_DMA_CH_CTL;
++		DMAC_CH_CFG_REG(i) &= ~0x3;
++	}
++
++	return;
++}
++
++static int dma_init(void)
++{
++	int retval;
++
++	HAL_PWRMGT_ENABLE_DMA_CLOCK();
++
++	// Master0 & Master1 in Little Endian Mode, DMA Controller Enable
++	DMAC_CSR_REG = 0x1;
++
++	if (dma_job_q_init() != 0) {
++		return -EFAULT;
++	}
++
++	dma_channel_init();
++
++#ifdef DMA_DEBUG
++	dma_dump_reg();
++#endif
++
++	spin_lock_init(&dma_lock);
++	INIT_LIST_HEAD(&dma_xfer_q);
++	INIT_LIST_HEAD(&dma_done_q);
++	
++	// Eileen , for linux kernel 2.6.24 , 20080424
++	//retval = request_irq(INTC_GDMAC_TC_BIT_INDEX, &dma_tc_isr, SA_INTERRUPT, "STAR DMA TC ISR", &dma_dev);
++	retval = request_irq(INTC_GDMAC_TC_BIT_INDEX, &dma_tc_isr, IRQF_DISABLED, "STAR DMA TC ISR", &dma_dev);
++	if (retval) {
++		printk("%s: unable to get IRQ %d (irqval=%d).\n", "STAR DMA", INTC_GDMAC_TC_BIT_INDEX, retval);
++		return retval;
++	}
++	// Eileen , for linux kernel 2.6.24 , 20080424
++	// old : retval = request_irq(INTC_GDMAC_ERROR_BIT_INDEX, &dma_err_isr, SA_INTERRUPT, "STAR DMA ERR ISR", &dma_dev);
++	retval = request_irq(INTC_GDMAC_ERROR_BIT_INDEX, &dma_err_isr, IRQF_DISABLED, "STAR DMA ERR ISR", &dma_dev);
++	if (retval) {
++		printk("%s: unable to get IRQ %d (irqval=%d).\n", "STAR DMA", INTC_GDMAC_ERROR_BIT_INDEX, retval);
++		free_irq(INTC_GDMAC_TC_BIT_INDEX, &dma_dev);
++		return retval;
++	}
++
++	return 0;
++}
++
++// Eileen , for linux kernel 2.6.24 , 20080425
++#ifdef STR8100_DMA_TEST
++	static int str8100_dmacopy_busywait_test(void);
++	static int str8100_dmacopy_llp_test(void);
++#endif
++
++
++static int __init str8100_dma_init(void)
++{
++	int retval;
++
++	printk("STR8100 DMA driver init\n");
++	retval = dma_init();
++#ifdef STR8100_DMA_TEST
++	if (retval == 0) {
++	       	// Eileen , for linux kernel 2.6.24 , 20080425
++		//move : static int str8100_dmacopy_busywait_test(void);
++		//move : static int str8100_dmacopy_llp_test(void);
++		(void)str8100_dmacopy_busywait_test();
++		(void)str8100_dmacopy_llp_test();
++	}
++#endif
++	return retval;
++}
++
++static void __exit str8100_dma_exit(void)
++{
++	return;
++}
++
++module_init(str8100_dma_init);
++module_exit(str8100_dma_exit);
++
++#ifdef STR8100_DMA_TEST
++#define MEMSIZE_K	64
++#define MEMSIZE		(MEMSIZE_K*1024)
++
++static int str8100_dmacopy_busywait_test(void)
++{
++	u8 *src;
++	u8 *dst;
++	int i;
++	int sjiffies;
++	int err_cnt = 0;
++
++	src = kmalloc(MEMSIZE, GFP_KERNEL);
++	if (!src) goto out;
++	dst = kmalloc(MEMSIZE, GFP_KERNEL);
++	if (!dst) {
++		kfree(src);
++		goto out;
++	}
++
++	memset(src, 0xA9, MEMSIZE);
++	memset(dst, 0, MEMSIZE);
++
++	printk("STR8100 DMA Busy Wait Testing...\n");
++
++	sjiffies = jiffies;
++	for (i = 0; i < 1024; i++) {
++		dma_memcpy_busy_wait(dst, src, MEMSIZE);
++	}
++
++	printk("STR8100 DMA Busy Wait Testing end\n");
++	if (memcmp(src, dst, MEMSIZE) == 0) {
++		printk("STR8100 DMA Busy Wait Testing success\n");
++		printk("STR8100 DMA Busy Wait Testing speed: %dMB/s\n", (u32)((MEMSIZE_K) * HZ/(jiffies - sjiffies)));
++	} else {
++		printk("STR8100 DMA Busy Wait Testing failed\n");
++		for (i = 0; i < MEMSIZE; i++) {
++			if (src[i] != dst[i]) {
++				err_cnt++;
++			}
++		}
++		printk("err_cnt: %d\n", err_cnt);
++	}
++
++	kfree(src);
++	kfree(dst);
++
++out:
++	return 0;
++}
++
++#define NUM_DMA_XFER		32
++#define NUM_DMA_VEC		32
++#define NUM_BYTES_PER_VEC	1024
++
++static dma_xfer_t dma_xfer_test[NUM_DMA_XFER];
++static u32 dma_xfer_finished;
++
++static u8 *src_vec[NUM_DMA_XFER];
++static u8 *dst_vec[NUM_DMA_XFER];
++
++extern void dma_copy(dma_xfer_t *dma_xfer);
++extern void dma_dump_reg(void);
++
++static void dma_copy_end(dma_xfer_t *dma_xfer, int err)
++{
++	int i;
++	int idx;
++
++	idx = (int)dma_xfer->private;
++	dma_xfer_finished++;
++
++	if (err) {
++		printk("STR8100 DMA Testing failed!!\n");
++	} else {
++		for (i = 0; i < NUM_DMA_VEC; i++) {
++			if (memcmp((src_vec[idx] + i * NUM_BYTES_PER_VEC), (dst_vec[idx] + i * NUM_BYTES_PER_VEC), NUM_BYTES_PER_VEC) == 0) {
++				printk("STR8100 DMA Testing success on xfer idx:%d started at offset: %04d:\n", idx, i * NUM_BYTES_PER_VEC);
++			} else {
++				int j;
++				u8 *psrc;
++				u8 *pdst;
++
++				psrc = src_vec[idx] + i * NUM_BYTES_PER_VEC;
++				pdst = dst_vec[idx] + i * NUM_BYTES_PER_VEC;
++
++				printk("STR8100 DMA Testing error started at offset: %04d\n", i * NUM_BYTES_PER_VEC);
++
++				for (j = 0; j < NUM_BYTES_PER_VEC; j++) {
++					if ((j % 16) == 0) {
++						printk("\n %08x: ", (u32)(psrc + j));
++					}
++					if (((j % 16) != 0) && ((j % 4) == 0)) {
++						printk(" ");
++					}
++					printk("%02x", psrc[j]);
++				}
++				printk("\n");
++	
++				for (j = 0; j < NUM_BYTES_PER_VEC; j++) {
++					if ((j % 16) == 0) {
++						printk("\n %08x: ", (u32)(pdst + j));
++					}
++					if (((j % 16) != 0) && ((j % 4) == 0)) {
++						printk(" ");
++					}
++					printk("%02x", pdst[j]);
++				}
++				printk("\n");
++			}
++		}
++	}
++
++	if (dma_xfer_finished == NUM_DMA_XFER) {
++		for (i = 0; i < NUM_DMA_XFER; i++) {
++			kfree(src_vec[i]);
++			kfree(dst_vec[i]);
++		}
++	}
++}
++
++static int str8100_dmacopy_llp_test(void)
++{
++	int i, j;
++
++	for (i = 0; i < NUM_DMA_XFER; i++) {
++		src_vec[i] = kmalloc(MEMSIZE, GFP_KERNEL);
++		if (!src_vec[i]) goto err_out;
++		dst_vec[i] = kmalloc(MEMSIZE, GFP_KERNEL);
++		if (!dst_vec[i]) goto err_out;
++		memset(src_vec[i], 0xA9, MEMSIZE);
++		memset(dst_vec[i], 0x00, MEMSIZE);
++		printk("dmacopy_llp src_vec[%d]: 0x%08x\n", i, (u32)src_vec[i]);
++		printk("dmacopy_llp dst_vec[%d]: 0x%08x\n", i, (u32)dst_vec[i]);
++	}
++
++	for (i = 0; i < NUM_DMA_XFER; i++) {
++		dma_xfer_test[i].nr_vec = NUM_DMA_VEC;
++		dma_xfer_test[i].dma_end_io = dma_copy_end;
++		dma_xfer_test[i].private = (void *)i;
++		for (j = 0; j < NUM_DMA_VEC; j++) {
++			dma_xfer_test[i].vec[j].src_addr = (u32)(src_vec[i] + (j * NUM_BYTES_PER_VEC));
++			dma_xfer_test[i].vec[j].dst_addr = (u32)(dst_vec[i] + (j * NUM_BYTES_PER_VEC));
++			dma_xfer_test[i].vec[j].size = NUM_BYTES_PER_VEC;
++			dma_xfer_test[i].vec[j].dst_sel = 0;
++			dma_xfer_test[i].vec[j].src_sel = 0;
++			dma_xfer_test[i].vec[j].dst_addr_ctl = 0;
++			dma_xfer_test[i].vec[j].src_addr_ctl = 0;
++			dma_xfer_test[i].vec[j].dst_width = DMAC_CH_DST_WIDTH_8BIT;
++			dma_xfer_test[i].vec[j].src_width = DMAC_CH_SRC_WIDTH_8BIT;
++		}
++	}
++
++	printk("STR8100 DMA Testing ...\n");
++
++	for (i = 0; i < NUM_DMA_XFER; i++) {
++		dma_copy(&dma_xfer_test[i]);
++	}
++
++	return 0;
++
++err_out:
++	for (i = 0; i < NUM_DMA_XFER; i++) {
++		if (src_vec[i])
++			kfree(src_vec[i]);
++		if (dst_vec[i])
++			kfree(dst_vec[i]);
++	}
++	return 0;
++}
++
++#endif // STR8100_DMA_TEST
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_gpio.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_gpio.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_gpio.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_gpio.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,855 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/miscdevice.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <mach/hardware.h>
++#include <asm/mach-types.h>
++
++#include <mach/star_powermgt.h>
++#include <mach/star_intc.h>
++#include <mach/star_misc.h>
++#include <mach/star_gpio.h>
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++
++#define MAX_GPIOA_LINE		32
++#define MAX_GPIOB_LINE		32
++#define PIN_INPUT 0
++#define PIN_OUTPUT 1
++
++#define PIN_TRIG_EDGE 0
++#define PIN_TRIG_LEVEL 1
++
++#define PIN_TRIG_SINGLE 0
++#define PIN_TRIG_BOTH 1
++
++#define PIN_TRIG_RISING 0
++#define PIN_TRIG_FALLING 1
++
++#define PIN_TRIG_HIGH 0
++#define PIN_TRIG_LOW 1
++void (*gpio_a_isr[MAX_GPIOA_LINE])(int i);
++void (*gpio_b_isr[MAX_GPIOB_LINE])(int i);
++
++#endif
++
++#if 0
++int __init_or_module gpio_direction_input(unsigned int);
++int __init_or_module gpio_direction_output(unsigned int, unsigned int);
++void gpio_set_value(unsigned int, unsigned int);
++int gpio_get_value(unsigned int);
++void str8100_gpio_a_set_edgeintr(void (*funcptr)(int), int, int, int);
++void str8100_gpio_b_set_edgeintr(void (*funcptr)(int),int,int, int);
++void str8100_gpio_a_set_levelintr(void (*funcptr)(int),int, int);
++void str8100_gpio_b_set_levelintr(void (*funcptr)(int),int, int);
++#endif
++
++/* 
++ * str8100_gpio_a_in - read Data Input Register(RO) of GPIO A
++ * @data: the target to store content of register
++ */
++int str8100_gpio_a_datain(volatile __u32 *data)
++{
++	HAL_GPIOA_READ_DATA_IN_STATUS(*data);
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_in - read Data Input Register(RO) of GPIO B
++ * @data: the target to store content of register
++ */
++int str8100_gpio_b_datain(volatile __u32 *data)
++{
++	HAL_GPIOB_READ_DATA_IN_STATUS(*data);
++	return 0;
++}
++
++/* str8100_gpio_a_out - write Data Output Register(RW) of GPIO A
++ * @data:
++ */
++int str8100_gpio_a_dataout(__u32 data)
++{
++	GPIOA_DATA_OUTPUT_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_out - write Data Output Register(RW) of GPIO B
++ * @data:
++ */
++int str8100_gpio_b_out(__u32 data)
++{
++	GPIOB_DATA_OUTPUT_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_a_read_direction - read Direction Register(RW) GPIO A
++ * @data:
++ */
++int str8100_gpio_a_read_direction(volatile __u32 *data)
++{
++	*data = GPIOA_DIRECTION_REG;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_read_direction - read Direction Register(RW) of GPIO B
++ * @data:
++ */
++int str8100_gpio_b_read_direction(volatile __u32 *data)
++{
++	*data = GPIOB_DIRECTION_REG;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_a_write_direction - write Direction Register(RW) of GPIO A
++ * @data:
++ */
++int str8100_gpio_a_write_direction(__u32 data)
++{
++	GPIOA_DIRECTION_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_write_direction - write Direction Register(RW) of GPIO B
++ * @data:
++ */
++int str8100_gpio_b_write_direction(__u32 data)
++{
++	GPIOB_DIRECTION_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_a_dataset - write Data Bit Set Register (W) of GPIO A
++ * @data:
++ *
++ * When write to this register and if some bits of GpioDataSet are 1,
++ * the corresponding bits in GpioDataOut register will be set to 1, 
++ * and the others will not be changed.
++ */
++int str8100_gpio_a_dataset(__u32 data)
++{
++	GPIOA_DATA_BIT_SET_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_dataset - write Data Bit Set Register (W) of GPIO B
++ * @data:
++ */
++int str8100_gpio_b_dataset(__u32 data)
++{
++	GPIOB_DATA_BIT_SET_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_a_dataclear - write Data Bit Clear Register (W) of GPIO A
++ * @data:
++ *
++ * When write to this register and if some bits of GpioDataClear are 1,
++ * the corresponding bits in GpioDataOut register will be cleard, 
++ * and the others will not be changed.
++ */
++int str8100_gpio_a_dataclear(__u32 data)
++{
++	GPIOA_DATA_BIT_CLEAR_REG = data;
++	return 0;
++}
++
++/* 
++ * str8100_gpio_b_dataclear - write Data Bit Clear Register (W) of GPIO B
++ * @data:
++ */
++int str8100_gpio_b_dataclear(__u32 data)
++{
++	GPIOB_DATA_BIT_CLEAR_REG = data;
++	return 0;
++}
++/*
++Read String into Buffer, Max String buffer is 100
++*/
++ssize_t readstring(char *buff, const char *buf, size_t count){
++    	int i=0;
++        if (count) {
++                char c;
++
++            for(i=0;i<count&&i<100;i++){
++                if (get_user(c, buf+i))
++                        return -EFAULT;
++                    buff[i] = c;
++            }
++                buff[i]=0;
++        }
++        return count;
++
++}
++
++#ifdef CONFIG_STR8100_GPIO_GENERIC_INTERFACE
++static int str8100_gpio_proc(char *page, char **start,  off_t off, int count, int *eof, void *data)
++{
++	int num = 0;
++
++	num += sprintf(page+num, "********** GPIO Group A **********\n");
++	
++	num += sprintf(page+num, "GPIO IN                : %08x \n", GPIOA_DATA_INPUT_REG);
++
++	num += sprintf(page+num, "GPIO Direction         : %08x \n", GPIOA_DIRECTION_REG);
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++	num += sprintf(page+num, "GPIO Interrupt Enable  : %08x \n", GPIOA_INTERRUPT_ENABLE_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Raw     : %08x \n", GPIOA_INTERRUPT_RAW_STATUS_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Trigger : %08x \n", GPIOA_INTERRUPT_TRIGGER_METHOD_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Both    : %08x \n", GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt RiseNeg : %08x \n", GPIOA_INTERRUPT_TRIGGER_TYPE_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt MASKED  : %08x \n", GPIOA_INTERRUPT_MASK_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt MASKEDST: %08x \n", GPIOA_INTERRUPT_MASKED_STATUS_REG);
++#endif	
++
++	num+= sprintf(page+num, "********** GPIO Group B **********\n");
++	
++	num += sprintf(page+num, "GPIO IN                : %08x \n", GPIOB_DATA_INPUT_REG);
++
++	num += sprintf(page+num, "GPIO Direction         : %08x \n", GPIOB_DIRECTION_REG);
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++	num += sprintf(page+num, "GPIO Interrupt Enable  : %08x \n", GPIOB_INTERRUPT_ENABLE_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Raw     : %08x \n", GPIOB_INTERRUPT_RAW_STATUS_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Trigger : %08x \n", GPIOB_INTERRUPT_TRIGGER_METHOD_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt Both    : %08x \n", GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt RiseNeg : %08x \n", GPIOB_INTERRUPT_TRIGGER_TYPE_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt MASKED  : %08x \n", GPIOB_INTERRUPT_MASK_REG);
++
++	num += sprintf(page+num, "GPIO Interrupt MASKEDST: %08x \n", GPIOB_INTERRUPT_MASKED_STATUS_REG);
++#endif	
++
++	return num;
++}
++#endif
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++static irqreturn_t str8100_gpio_irq_handler(int this_irq, void *dev_id /*, struct pt_regs *regs */)
++{
++	unsigned int volatile    status;
++	int i;
++
++	// Clean System irq status
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++
++	HAL_GPIOA_READ_INTERRUPT_MASKED_STATUS(status);
++	for (i = 0; i < MAX_GPIOA_LINE; i++) {   
++		if (status & (1 << i))  {   		/* interrupt is detected and not masked */
++			if (gpio_a_isr[i] != NULL) {
++				gpio_a_isr[i](i);
++			}
++		}    
++	}  
++    HAL_GPIOA_CLEAR_INTERRUPT(status);
++
++	HAL_GPIOB_READ_INTERRUPT_MASKED_STATUS(status);
++	for (i = 0; i < MAX_GPIOB_LINE; i++) {   
++		if (status & (1 << i)) {			/* interrupt is detected and not masked */
++			if (gpio_b_isr[i] != NULL) {
++				gpio_b_isr[i](i);
++			}
++		}    
++	}   
++    HAL_GPIOB_CLEAR_INTERRUPT(status);
++
++	/* Unmask Intc Interrupt Status */
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	return IRQ_HANDLED;
++}
++
++int intr_a_count=0;
++int intr_b_count=0;
++/*  
++ * Setup GPIOA for Edge Trigger Interrupt mode 
++ */
++void str8100_gpio_a_set_edgeintr(void (*funcptr)(int), int trig_both, int trig_rising, int gpio_pin)
++{
++	u32 gpio_index = (0x1 << gpio_pin);
++	
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOA_LINE) {
++		HAL_GPIOA_SET_DIRECTION_INPUT(gpio_index);
++
++		if (trig_both == PIN_TRIG_BOTH) {
++			/* Set Trigger Both */
++			HAL_GPIOA_SET_INTERRUPT_BOTH_EDGE_TRIGGER_MODE(gpio_index);	
++		}
++		else if (trig_both == PIN_TRIG_SINGLE) {
++			/* Set Single Rising/Falling Edge Trigger */
++			if (trig_rising == PIN_TRIG_RISING) {
++				HAL_GPIOA_SET_INTERRUPT_SINGLE_RISING_EDGE_TRIGGER_MODE(gpio_index);
++			}
++			else if (trig_rising == PIN_TRIG_FALLING) {
++				HAL_GPIOA_SET_INTERRUPT_SINGLE_FALLING_EDGE_TRIGGER_MODE(gpio_index);
++			}
++			else {
++				printk("Trigger rising/falling error.\n");
++				return;
++			}
++		}
++		else
++		{
++			printk("Trigger both/single error.\n");
++			return;
++		}
++
++		gpio_a_isr[gpio_pin] = funcptr;
++
++		/* Enable Interrupt */
++		HAL_GPIOA_ENABLE_INTERRUPT(gpio_index);
++	}
++}
++
++/*  
++ * Setup GPIOB for Edge Trigger Interrupt mode 
++ */
++void str8100_gpio_b_set_edgeintr(void (*funcptr)(int),int trig_both,int trig_rising, int gpio_pin)
++{
++	u32 gpio_index = (0x1 << gpio_pin);
++	
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOA_LINE) {
++		HAL_GPIOB_SET_DIRECTION_INPUT(gpio_index);
++
++		if (trig_both == PIN_TRIG_BOTH) {
++			/* Set Trigger Both */
++			HAL_GPIOB_SET_INTERRUPT_BOTH_EDGE_TRIGGER_MODE(gpio_index);	
++		}
++		else if (trig_both == PIN_TRIG_SINGLE) {
++			/* Set Single Rising/Falling Edge Trigger */
++			if (trig_rising == PIN_TRIG_RISING) {
++				HAL_GPIOB_SET_INTERRUPT_SINGLE_RISING_EDGE_TRIGGER_MODE(gpio_index);
++			}
++			else if (trig_rising == PIN_TRIG_FALLING) {
++				HAL_GPIOB_SET_INTERRUPT_SINGLE_FALLING_EDGE_TRIGGER_MODE(gpio_index);
++			}
++			else {
++				printk("Trigger rising/falling error.\n");
++				return;
++			}
++		}
++		else {
++			printk("Trigger both/single error.\n");
++			return;
++		}
++
++		gpio_b_isr[gpio_pin] = funcptr;
++
++		/* Enable Interrupt */
++		HAL_GPIOB_ENABLE_INTERRUPT(gpio_index);
++	}
++}
++
++/*  
++ * Clear GPIOA Trigger Interrupt
++ */
++void str8100_gpio_a_clear_intr(int gpio_pin)
++{
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOA_LINE) {
++		/* Unregister isr of GPIOA[gpio_pin] */	
++		gpio_a_isr[gpio_pin] = NULL;	
++		/* Disable Interrupt */
++		HAL_GPIOA_DISABLE_INTERRUPT(0x1 << gpio_pin);
++	}
++}
++
++/*  
++ * Clear GPIOB Trigger Interrupt
++ */
++void str8100_gpio_b_clear_intr(int gpio_pin)
++{
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOB_LINE) {
++		/* Unregister isr of GPIOB[gpio_pin] */
++		gpio_b_isr[gpio_pin] = NULL;			
++		/* Disable Interrupt */
++		HAL_GPIOB_DISABLE_INTERRUPT(0x1 << gpio_pin);
++	}
++}
++
++/*  
++ * Setup GPIOA for LEVEL Trigger Interrupt mode 
++ */
++void str8100_gpio_a_set_levelintr(void (*funcptr)(int),int trig_level, int gpio_pin)
++{
++	u32 gpio_index = (0x1 << gpio_pin);
++
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOA_LINE) {
++		HAL_GPIOA_SET_DIRECTION_INPUT(gpio_index);
++
++		/* Set Trigger High/Low */
++		if (trig_level == PIN_TRIG_HIGH) {
++			HAL_GPIOA_SET_INTERRUPT_HIGH_LEVEL_TRIGGER_MODE(gpio_index);
++		}
++		else if (trig_level == PIN_TRIG_LOW) {
++			HAL_GPIOA_SET_INTERRUPT_LOW_LEVEL_TRIGGER_MODE(gpio_index);
++		}
++		else {
++			printk("Trigger level error.\n");
++			return;
++		}
++
++		gpio_a_isr[gpio_pin] = funcptr;
++
++		/* Enable Interrupt */
++		HAL_GPIOA_ENABLE_INTERRUPT(gpio_index);
++	}
++}
++
++/*  
++ * Setup GPIO for LEVEL Triggle Interrupt mode 
++ */
++void str8100_gpio_b_set_levelintr(void (*funcptr)(int),int trig_level, int gpio_pin)
++{
++	u32 gpio_index = (0x1 << gpio_pin);
++
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIOB_LINE) {
++		HAL_GPIOB_SET_DIRECTION_INPUT(gpio_index);
++
++		/* Set Trigger High/Low */
++		if (trig_level == PIN_TRIG_HIGH) {
++			HAL_GPIOB_SET_INTERRUPT_HIGH_LEVEL_TRIGGER_MODE(gpio_index);
++		}
++		else if (trig_level == PIN_TRIG_LOW) {
++			HAL_GPIOB_SET_INTERRUPT_LOW_LEVEL_TRIGGER_MODE(gpio_index);
++		}
++		else {
++			printk("Trigger level error.\n");
++			return;
++		}
++
++		gpio_b_isr[gpio_pin] = funcptr;
++
++		/* Enable Interrupt */
++		HAL_GPIOB_ENABLE_INTERRUPT(gpio_index);
++	}
++}
++
++EXPORT_SYMBOL(str8100_gpio_a_set_edgeintr);
++EXPORT_SYMBOL(str8100_gpio_a_clear_intr);
++EXPORT_SYMBOL(str8100_gpio_a_set_levelintr);
++EXPORT_SYMBOL(str8100_gpio_b_set_edgeintr);
++EXPORT_SYMBOL(str8100_gpio_b_clear_intr);
++EXPORT_SYMBOL(str8100_gpio_b_set_levelintr);
++
++/*  
++ * Display GPIO information at /proc/str9100/gpio
++ */
++
++#ifdef STR8100_GPIO_INTERRUPT_TEST
++void str8100_gpio_intr_test(int i)
++{
++	printk("GPIO Interrupt Service Single Active : %d \n",i);
++}
++#endif
++
++#endif
++
++#ifdef CONFIG_STR8100_GPIO_GENERIC_INTERFACE
++/***********************************************************************
++ * The STR8100 has GPIOA(32) and GPIOB(32) total 64 GPIO. For the
++ * generic GPIO interface, the GPIO pin number count from GPIOA to GPIOB.
++ * For example:
++ *      0 -> GPIOA[0]
++ *      1 -> GPIOA[1]
++ *     ......
++ *     31 -> GPIOA[31]
++ *     32 -> GPIOB[0]
++ *     33 -> GPIOB[1]
++ *     ......
++ *     63 -> GPIOB[31]
++ **********************************************************************/
++
++#define GPIOA_PIN_NO	32
++#define GPIOB_PIN_NO	32
++#define MAX_GPIO_NO	(GPIOA_PIN_NO + GPIOB_PIN_NO)
++
++/*
++ * Configure the GPIO line as an input.
++ */
++int __init_or_module gpio_direction_input(unsigned int pin)
++{
++	volatile __u32 reg;
++	unsigned long flags;
++
++	if (pin >= MAX_GPIO_NO)
++		return -EINVAL;
++
++        local_irq_save(flags);
++
++	/* Clear register bit to set as input pin. */
++	if (pin < GPIOA_PIN_NO)
++	{
++		/* GPIOA */
++		reg = GPIOA_DIRECTION_REG;
++		reg &= ~(1 << pin);
++		GPIOA_DIRECTION_REG = reg;
++	}
++	else
++	{
++		/* GPIOB */
++		reg = GPIOB_DIRECTION_REG;
++		reg &= ~(1 << (pin - GPIOA_PIN_NO));
++		GPIOB_DIRECTION_REG = reg;
++	}
++
++        local_irq_restore(flags);
++
++        return 0;
++}
++//EXPORT_SYMBOL(gpio_direction_input);
++
++/*
++ * Configure the GPIO line as an output, with default state.
++ */
++int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state)
++{
++	volatile __u32 reg;
++	unsigned long flags;
++	if (pin >= MAX_GPIO_NO)
++		return -EINVAL;
++
++        local_irq_save(flags);
++
++	if (pin < GPIOA_PIN_NO)
++	{
++		/* GPIOA */
++		/* Set register bit to set as output pin. */
++		reg = GPIOA_DIRECTION_REG;
++		reg |= (1 << pin);
++		GPIOA_DIRECTION_REG = reg;
++
++		if (state)
++			GPIOA_DATA_BIT_SET_REG = (1 << pin);
++		else
++			GPIOA_DATA_BIT_CLEAR_REG = (1 << pin);
++
++	}
++	else
++	{
++		/* GPIOB */
++		/* Set register bit to set as output pin. */
++		reg = GPIOB_DIRECTION_REG;
++		reg |= (1 << (pin - GPIOA_PIN_NO));
++		GPIOB_DIRECTION_REG = reg;
++
++		if (state)
++			GPIOB_DATA_BIT_SET_REG = (1 << (pin - GPIOA_PIN_NO));
++		else
++			GPIOB_DATA_BIT_CLEAR_REG = (1 << (pin - GPIOA_PIN_NO));
++	}
++
++        local_irq_restore(flags);
++
++        return 0;
++}
++EXPORT_SYMBOL(gpio_direction_output);
++
++
++/*
++ * Set the state of an output GPIO line.
++ */
++void gpio_set_value(unsigned int pin, unsigned int state)
++{
++	if (pin >= MAX_GPIO_NO)
++		return;
++
++	if (pin < GPIOA_PIN_NO)
++	{
++		/* GPIOA */
++		if (state)
++			GPIOA_DATA_BIT_SET_REG = (1 << pin);
++		else
++			GPIOA_DATA_BIT_CLEAR_REG = (1 << pin);
++
++	}
++	else
++	{
++		/* GPIOB */
++		if (state)
++			GPIOB_DATA_BIT_SET_REG = (1 << (pin - GPIOA_PIN_NO));
++		else
++			GPIOB_DATA_BIT_CLEAR_REG = (1 << (pin - GPIOA_PIN_NO));
++	}
++}
++EXPORT_SYMBOL(gpio_set_value);
++
++
++/*
++ * Read the state of a GPIO line.
++ */
++int gpio_get_value(unsigned int pin)
++{
++	volatile __u32 reg;
++	bool bret = 0;
++
++	if (pin >= MAX_GPIO_NO)
++		return -EINVAL;
++
++	if (pin < GPIOA_PIN_NO)
++	{
++		/* GPIOA */
++		str8100_gpio_a_datain(&reg);
++		bret = (reg & (1 << pin)) != 0;
++	}
++	else
++	{
++		/* GPIOB */
++		str8100_gpio_b_datain(&reg);
++		bret = (reg & (1 << (pin - GPIOA_PIN_NO))) != 0;
++	}
++	
++	return bret;
++}
++EXPORT_SYMBOL(gpio_get_value);
++
++
++/*
++ * Map GPIO line to IRQ number.
++ */
++int gpio_to_irq(unsigned int pin)
++{
++	return INTC_GPIO_EXTERNAL_INT_BIT_INDEX;
++}
++EXPORT_SYMBOL(gpio_to_irq);
++
++
++/*
++ * INVALID
++ */
++int irq_to_gpio(unsigned int irq)
++{
++	return -EINVAL;
++}
++EXPORT_SYMBOL(irq_to_gpio);
++
++#endif /* CONFIG_STR8100_GPIO_GENREIC_INTERFACE */
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++static void gpio_a_isr_test(int i)
++{
++	unsigned int volatile status = 0;
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	printk("gpio_a_isr_test, count:%d\n",intr_a_count+1);
++	status = GPIOA_INTERRUPT_MASKED_STATUS_REG;
++	HAL_GPIOA_CLEAR_INTERRUPT(status);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++
++	intr_a_count++;
++	if (intr_a_count >= 4) {
++		str8100_gpio_a_clear_intr(i);
++		intr_a_count = 0;
++	}
++
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++}
++
++static void gpio_b_isr_test(int i)
++{
++	unsigned int volatile status = 0;
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	printk("gpio_b_isr_test, count:%d\n",intr_b_count+1);
++	status = GPIOB_INTERRUPT_MASKED_STATUS_REG;
++	HAL_GPIOB_CLEAR_INTERRUPT(status);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++
++	intr_b_count++;
++	if (intr_b_count >= 4) {
++		str8100_gpio_b_clear_intr(i);
++		intr_b_count = 0;
++	}
++
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++}
++#endif
++
++#ifdef CONFIG_STR8100_GPIO_GENERIC_INTERFACE
++static ssize_t str8100_gpio_write_proc(struct file *file, const char __user *buffer,
++			   ssize_t count, void *data){
++	int pin = 0,state =0;
++	char read_buff[100],buf_cmd[100],buf_param1[100],buf_param2[100],buf_param3[100],buf_param4[100];
++	readstring((char *)read_buff,(const char *)buffer,count);
++	sscanf(read_buff,"%s %s %s %s %s\n",(char *)&buf_cmd,(char *)&buf_param1\
++									   ,(char *)&buf_param2, (char *)&buf_param3, (char *)&buf_param4);
++	//printk("buf_cmd:%s buf_param1:%s buf_param2:%s buf_param2:%s \n", buf_cmd,buf_param1,buf_param2,buf_param3);
++	if(strcmp(buf_cmd,"direct") == 0)
++		if(strcmp(buf_param1,"input") == 0){
++			sscanf(buf_param2, "%d", &pin);
++			//printk("direction input pin=%d \n",pin);
++			gpio_direction_input(pin);
++		}
++	if(strcmp(buf_cmd,"direct") == 0)
++		if(strcmp(buf_param1,"output") == 0){
++			sscanf(buf_param2, "%d", &pin);
++			sscanf(buf_param3, "%d", &state);
++			//printk("direction output pin=%d state=%d  \n",pin,state);
++			gpio_direction_output(pin,state);
++		}
++	if(strcmp(buf_cmd,"set") == 0)
++		if(strcmp(buf_param1,"value") == 0){
++			sscanf(buf_param2, "%d", &pin);
++			sscanf(buf_param3, "%d", &state);
++			printk("set value pin=%d state=%d  \n",pin,state);
++			gpio_set_value(pin,state);
++		}
++	if(strcmp(buf_cmd,"get") == 0)
++		if(strcmp(buf_param1,"value") == 0){
++			sscanf(buf_param2, "%d", &pin);
++			state=gpio_get_value(pin);
++			printk("get value pin=%d state=%d \n",pin,state);
++		}
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++	if(strcmp(buf_cmd,"trig") == 0){
++		if(strcmp(buf_param1,"edge") == 0){
++			if(strcmp(buf_param2,"both") == 0){
++				sscanf(buf_param3, "%d", &pin);
++				if (pin < GPIOA_PIN_NO)
++					str8100_gpio_a_set_edgeintr(&gpio_a_isr_test, 1, 0, pin);
++				else
++					str8100_gpio_b_set_edgeintr(&gpio_b_isr_test, 1, 0, pin-GPIOA_PIN_NO);		
++			}
++			if(strcmp(buf_param2,"single") == 0){
++				if(strcmp(buf_param3,"rising") == 0){
++					sscanf(buf_param4, "%d", &pin);
++					if (pin < GPIOA_PIN_NO)
++						str8100_gpio_a_set_edgeintr(&gpio_a_isr_test, 0, 0, pin);
++					else
++						str8100_gpio_b_set_edgeintr(&gpio_b_isr_test, 0, 0, pin-GPIOA_PIN_NO);
++				}
++				if(strcmp(buf_param3,"falling") == 0){
++					sscanf(buf_param4, "%d", &pin);
++					if (pin < GPIOA_PIN_NO)
++						str8100_gpio_a_set_edgeintr(&gpio_a_isr_test, 0, 1, pin);
++					else
++						str8100_gpio_b_set_edgeintr(&gpio_b_isr_test, 0, 1, pin-GPIOA_PIN_NO);
++				}		
++			}
++		}
++		if(strcmp(buf_param1,"level") == 0){
++			if(strcmp(buf_param2,"high") == 0){
++				sscanf(buf_param3, "%d", &pin);
++				if (pin < GPIOA_PIN_NO)
++					str8100_gpio_a_set_levelintr(&gpio_a_isr_test, 0, pin);
++				else
++					str8100_gpio_b_set_levelintr(&gpio_b_isr_test, 0, pin-GPIOA_PIN_NO);
++			}
++			if(strcmp(buf_param2,"low") == 0){
++				sscanf(buf_param3, "%d", &pin);
++				if (pin < GPIOA_PIN_NO)
++					str8100_gpio_a_set_levelintr(&gpio_a_isr_test, 1, pin);
++				else
++					str8100_gpio_b_set_levelintr(&gpio_b_isr_test, 1, pin-GPIOA_PIN_NO);
++			}
++		}
++	}
++#endif
++		
++	return count;
++	
++}
++
++static struct proc_dir_entry *proc_str8100_gpio;
++#endif
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++int __init str8100_gpio_init(void)
++{
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++	u32 i, ret;
++#endif
++
++	//proc_str8100_gpio = create_proc_read_entry("str8100/gpio", 0, NULL, str8100_gpio_proc, NULL) ;
++#ifdef CONFIG_STR8100_GPIO_GENERIC_INTERFACE
++	proc_str8100_gpio = create_proc_entry("str8100/gpio", S_IFREG | S_IRUGO, NULL) ;
++	proc_str8100_gpio->read_proc = str8100_gpio_proc;
++	proc_str8100_gpio->write_proc = str8100_gpio_write_proc;
++#endif
++
++#ifdef CONFIG_STR8100_GPIO_INTERRUPT
++	for (i = 0; i < MAX_GPIOA_LINE; i++) {
++		gpio_a_isr[i] = NULL;
++	}
++	for (i = 0; i < MAX_GPIOB_LINE; i++) {
++		gpio_b_isr[i] = NULL;
++	}
++
++	/* Clear All Interrupt Status */
++	HAL_GPIOA_CLEAR_INTERRUPT(0xFFFFFFFF);
++	HAL_GPIOB_CLEAR_INTERRUPT(0xFFFFFFFF);
++	str8100_set_interrupt_trigger(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, INTC_EDGE_TRIGGER, INTC_RISING_EDGE);
++	ret = request_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, str8100_gpio_irq_handler, 0, "str8100_gpio", 0);
++	if (ret < 0) {
++		printk("request_irq fail : %d \n", ret);
++		return 0;
++	} else {
++		printk("GPIO interrupt handler install ok. \n");
++	}
++#endif
++#ifdef STR8100_GPIO_INTERRUPT_TEST
++	str8100_gpio_a_set_edgeintr(&str8100_gpio_intr_test, PIN_TRIG_SINGLE, PIN_TRIG_RISING, 0);
++	str8100_gpio_a_set_levelintr(&str8100_gpio_intr_test, PIN_TRIG_HIGH, 1);
++#endif
++
++	return 0;
++}	
++
++void __exit str8100_gpio_exit(void)
++{
++	free_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, 0);
++}
++
++module_init(str8100_gpio_init);
++module_exit(str8100_gpio_exit);
++
++MODULE_LICENSE("GPL");
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_hsdma.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_hsdma.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_hsdma.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_hsdma.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,439 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/pci.h>
++#include <asm/io.h>
++#include <asm/delay.h>
++#include <mach/star_intc.h>
++#include <mach/star_hsdmac.h>
++
++//#define HSDMA_DEBUG
++#define STR8100_HSDMA_TEST
++
++#define HSDMA_MIN_XFER_SIZE		1024
++#define HSDMA_XFER_MAX_Q_LEN		32
++
++typedef struct
++{
++	struct list_head	lh;
++	hsdma_xfer_t		*xfer;
++	hsdma_llp_descr_t	*llp_descr;
++	u32			llp_descr_dma;
++	int			done_status;
++} hsdma_job_t;
++
++static u8 hsdma_dev;
++static spinlock_t hsdma_lock;
++static u8 hsdma_busy;
++static unsigned int hsdma_xfer_q_len;
++static unsigned int hsdma_done_q_len;
++static struct list_head hsdma_xfer_q;
++static struct list_head hsdma_done_q;
++static hsdma_job_t *hsdma_running_job;
++
++static void *hsdma_mem_pool;
++static u32 hsdma_mem_pool_dma;
++
++static hsdma_job_t hsdma_job_pool[HSDMA_XFER_MAX_Q_LEN];
++static struct list_head hsdma_job_q;
++static spinlock_t hsdma_job_q_lock;
++
++static void hsdma_process_xfer_job(void *data);
++static void hsdma_process_done_job(void *data);
++
++// Eileen , for linux kernel 2.6.24 , 20080425
++//static DECLARE_WORK(hsdma_xfer_task, hsdma_process_xfer_job, (void *)&hsdma_xfer_q);
++//static DECLARE_WORK(hsdma_done_task, hsdma_process_done_job, (void *)&hsdma_done_q);
++static DECLARE_WORK(hsdma_xfer_task, hsdma_process_xfer_job);
++static DECLARE_WORK(hsdma_done_task, hsdma_process_done_job);
++
++static int hsdma_job_q_init(void)
++{
++	int i;
++
++	hsdma_mem_pool = (void *)pci_alloc_consistent(NULL,
++		(HSDMA_XFER_MAX_Q_LEN * MAX_HSDMA_VEC * sizeof(hsdma_llp_descr_t)),
++	       	&hsdma_mem_pool_dma);
++
++	if (hsdma_mem_pool == NULL) {
++		return -1;
++	}
++
++	INIT_LIST_HEAD(&hsdma_job_q);
++	for (i = 0; i < HSDMA_XFER_MAX_Q_LEN; i++) {
++		INIT_LIST_HEAD(&hsdma_job_pool[i].lh);
++		hsdma_job_pool[i].llp_descr = (hsdma_llp_descr_t *)(hsdma_mem_pool + (i * (MAX_HSDMA_VEC * sizeof(hsdma_llp_descr_t))));
++		hsdma_job_pool[i].llp_descr_dma = hsdma_mem_pool_dma + (i * (MAX_HSDMA_VEC * sizeof(hsdma_llp_descr_t)));
++		list_add_tail(&hsdma_job_pool[i].lh, &hsdma_job_q);
++	}
++
++	return 0;
++}
++
++static hsdma_job_t *hsdma_job_alloc(void)
++{
++	hsdma_job_t *job;
++	unsigned long flags;
++
++	spin_lock_irqsave(&hsdma_job_q_lock, flags);
++	if (list_empty(&hsdma_job_q)) {
++		job = NULL;
++	} else {
++		job = list_entry(hsdma_job_q.next, hsdma_job_t, lh);
++		list_del_init(&job->lh);
++	}
++	spin_unlock_irqrestore(&hsdma_job_q_lock, flags);
++
++	return job;
++}
++
++static void hsdma_job_free(hsdma_job_t *job)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&hsdma_job_q_lock, flags);
++	list_add(&job->lh, &hsdma_job_q);
++	spin_unlock_irqrestore(&hsdma_job_q_lock, flags);
++}
++
++#ifdef HSDMA_DEBUG
++void hsdma_dump_reg(void)
++{
++	printk("HSDMAC_CONTROL_STATUS_REG:	0x%08x\n", HSDMAC_CONTROL_STATUS_REG);
++	printk("HSDMAC_MASTER0_ADDR_REG:	0x%08x\n", HSDMAC_MASTER0_ADDR_REG);
++	printk("HSDMAC_MASTER1_ADDR_REG:	0x%08x\n", HSDMAC_MASTER1_ADDR_REG);
++	printk("HSDMAC_LLP_REG:			0x%08x\n", HSDMAC_LLP_REG);
++	printk("HSDMAC_TOT_SIZE_REG:		0x%08x\n", HSDMAC_TOT_SIZE_REG);
++}
++#endif
++
++void hsdma_copy(hsdma_xfer_t *hsdma_xfer)
++{
++	hsdma_job_t *hsdma_job;
++	unsigned long flags;
++	int i;
++
++	if (hsdma_xfer_q_len > HSDMA_XFER_MAX_Q_LEN) {
++		hsdma_xfer->hsdma_end_io(hsdma_xfer, HSDMAC_RESPONSE_ERR);
++		return;
++	}
++
++	hsdma_job = hsdma_job_alloc();
++	if (hsdma_job == NULL) {
++		hsdma_xfer->hsdma_end_io(hsdma_xfer, HSDMAC_RESPONSE_ERR);
++		return;
++	}
++
++	memset(hsdma_job->llp_descr, 0, (hsdma_xfer->nr_vec * sizeof(hsdma_llp_descr_t)));
++	for (i = 0; i < hsdma_xfer->nr_vec; i++) {
++		if ((hsdma_xfer->vec[i].src_addr & 0x3) ||
++		    (hsdma_xfer->vec[i].dst_addr & 0x3) ||
++		    (hsdma_xfer->vec[i].size & 0x3)) {
++			hsdma_xfer->hsdma_end_io(hsdma_xfer, HSDMAC_RESPONSE_ERR);
++			hsdma_job_free(hsdma_job);
++			return;
++		}
++		hsdma_job->llp_descr[i].src_addr = (u32)virt_to_phys((void *)hsdma_xfer->vec[i].src_addr);
++		hsdma_job->llp_descr[i].dst_addr = (u32)virt_to_phys((void *)hsdma_xfer->vec[i].dst_addr);
++		hsdma_job->llp_descr[i].tot_size = (hsdma_xfer->vec[i].size >> 2) & 0xFFF;
++		hsdma_job->llp_descr[i].data_direction = hsdma_xfer->vec[i].data_direction;
++		if (i == (hsdma_xfer->nr_vec - 1)) {
++			hsdma_job->llp_descr[i].llp = 0;
++			hsdma_job->llp_descr[i].tc_mask = 0;
++		} else {
++			hsdma_job->llp_descr[i].llp = (u32)(hsdma_job->llp_descr_dma + ((i + 1) * sizeof(hsdma_llp_descr_t)));
++			hsdma_job->llp_descr[i].tc_mask = 1;
++		}
++		// Eileen , for linux kernel 2.6.24 , 20080425
++		//old : consistent_sync((void *)hsdma_xfer->vec[i].src_addr, hsdma_xfer->vec[i].size, PCI_DMA_TODEVICE);
++		//old : consistent_sync((void *)hsdma_xfer->vec[i].dst_addr, hsdma_xfer->vec[i].size, PCI_DMA_FROMDEVICE);
++		dma_cache_maint((void *)hsdma_xfer->vec[i].src_addr, hsdma_xfer->vec[i].size, PCI_DMA_TODEVICE);
++		dma_cache_maint((void *)hsdma_xfer->vec[i].dst_addr, hsdma_xfer->vec[i].size, PCI_DMA_FROMDEVICE);
++#ifdef HSDMA_DEBUG
++		printk("src_addr: 0x%08x\n", hsdma_job->llp_descr[i].src_addr);
++		printk("dst_addr: 0x%08x\n", hsdma_job->llp_descr[i].dst_addr);
++		printk("llp:      0x%08x\n", hsdma_job->llp_descr[i].llp);
++		printk("tot_size: 0x%08x\n", hsdma_job->llp_descr[i].tot_size);
++		printk("data_dir: 0x%08x\n", hsdma_job->llp_descr[i].data_direction);
++		printk("tc_mask:  0x%08x\n", hsdma_job->llp_descr[i].tc_mask);
++#endif
++	}
++
++	hsdma_job->xfer = hsdma_xfer;
++	hsdma_job->done_status = 0;
++
++	spin_lock_irqsave(&hsdma_lock, flags);
++	list_add_tail(&hsdma_job->lh, &hsdma_xfer_q);
++	hsdma_xfer_q_len++;
++	spin_unlock_irqrestore(&hsdma_lock, flags);
++
++	if (!hsdma_busy) {
++		schedule_work(&hsdma_xfer_task);
++	}
++}
++EXPORT_SYMBOL(hsdma_copy);
++
++static void hsdma_process_xfer_job(void *data)
++{
++	hsdma_job_t *hsdma_job;
++	unsigned long flags;
++
++	spin_lock_irqsave(&hsdma_lock, flags);
++	hsdma_job = list_entry(hsdma_xfer_q.next, hsdma_job_t, lh);
++	if (hsdma_job) {
++		list_del_init(&hsdma_job->lh);
++		hsdma_running_job = hsdma_job;
++		hsdma_xfer_q_len--;
++		hsdma_busy = 1;
++		if (hsdma_job->llp_descr[0].data_direction == HSDMAC_MASTER0_TO_MASTER1) {
++			HSDMAC_MASTER0_ADDR_REG = hsdma_job->llp_descr[0].src_addr;
++			HSDMAC_MASTER1_ADDR_REG = hsdma_job->llp_descr[0].dst_addr;
++			HSDMAC_TOT_SIZE_REG &= ~(0x1 << 29);
++		} else {
++			HSDMAC_MASTER0_ADDR_REG = hsdma_job->llp_descr[0].dst_addr;
++			HSDMAC_MASTER1_ADDR_REG = hsdma_job->llp_descr[0].src_addr;
++			HSDMAC_TOT_SIZE_REG |= (0x1 << 20);
++		}
++		HSDMAC_LLP_REG = (u32)hsdma_job->llp_descr[0].llp;
++		HSDMAC_TOT_SIZE_REG |= hsdma_job->llp_descr[0].tot_size;
++		if (hsdma_job->llp_descr[0].tc_mask) {
++			HSDMAC_TOT_SIZE_REG |= (0x1 << 28);
++		} else {
++			HSDMAC_TOT_SIZE_REG &= ~(0x1 << 28);
++		}
++		HAL_HSDMAC_ENABLE();
++	}
++	spin_unlock_irqrestore(&hsdma_lock, flags);
++}
++
++static void hsdma_process_done_job(void *data)
++{
++	hsdma_job_t *hsdma_job;
++	struct list_head *l, *t;
++	unsigned long flags;
++
++	spin_lock_irqsave(&hsdma_lock, flags);
++	list_for_each_safe(l, t, &hsdma_done_q) {
++		hsdma_job = list_entry(l, hsdma_job_t, lh);
++		list_del_init(&hsdma_job->lh);
++		hsdma_done_q_len--;
++		spin_unlock_irqrestore(&hsdma_lock, flags);
++		hsdma_job->xfer->hsdma_end_io(hsdma_job->xfer, hsdma_job->done_status);
++		hsdma_job_free(hsdma_job);
++		spin_lock_irqsave(&hsdma_lock, flags);
++	}
++	spin_unlock_irqrestore(&hsdma_lock, flags);
++}
++
++// Eileen , for linux kernel 2.6.24 , 20080425
++//old : irqreturn_t hsdma_isr(int irq, void *dev_id, struct pt_regs *regs)
++irqreturn_t hsdma_isr(int irq, void *dev_id)
++{
++	hsdma_job_t *hsdma_job;
++
++	hsdma_job = hsdma_running_job;
++	hsdma_running_job = NULL;
++	list_add_tail(&hsdma_job->lh, &hsdma_done_q);
++	hsdma_done_q_len++;
++
++	if (HSDMAC_CONTROL_STATUS_REG & (0x1 << 12)) {
++		hsdma_job->done_status = HSDMAC_RESPONSE_ERR;
++	} else {
++		hsdma_job->done_status = HSDMAC_RESPONSE_OK;
++	}
++
++	HAL_HSDMAC_DISABLE();
++
++	hsdma_busy = 0;
++
++	schedule_work(&hsdma_done_task);
++
++	if (hsdma_xfer_q_len) {
++		schedule_work(&hsdma_xfer_task);
++	}
++
++	return IRQ_HANDLED;
++}
++
++int hsdma_init(void)
++{
++	int retval;
++
++	// enable the HSDMA clock
++	HAL_PWRMGT_ENABLE_HSDMA_CLOCK();
++
++	// disable the HSDMA(normal mode, incremental address)
++	HSDMAC_CONTROL_STATUS_REG = 0x0;
++	HSDMAC_TOT_SIZE_REG = 0x10000000;
++
++	if (hsdma_job_q_init() != 0) {
++		return -EFAULT;
++	}
++
++	spin_lock_init(&hsdma_lock);
++	INIT_LIST_HEAD(&hsdma_xfer_q);
++	INIT_LIST_HEAD(&hsdma_done_q);
++
++	// Eileen , for linux kernel 2.6.24 , 20080425
++	//retval = request_irq(INTC_HSDMAC_BIT_INDEX, &hsdma_isr, SA_INTERRUPT, "STR8100 HSDMA", &hsdma_dev);
++	retval = request_irq(INTC_HSDMAC_BIT_INDEX, &hsdma_isr, IRQF_DISABLED, "STR8100 HSDMA", &hsdma_dev);
++	if (retval) {
++		printk("%s: unable to get IRQ %d (irqval=%d).\n", "STAR HSDMA", INTC_HSDMAC_BIT_INDEX, retval);
++		return retval;
++	}
++
++	return retval;
++}
++
++// Eileen , for linux kernel 2.6.24 , 20080425
++#ifdef STR8100_HSDMA_TEST
++	static int str8100_hsdma_test(void);
++#endif
++
++static int __init str8100_hsdma_init(void)
++{
++	int retval;
++
++	printk("STR8100 HSDMA driver init\n");
++	retval = hsdma_init();
++#ifdef STR8100_HSDMA_TEST
++	if (retval == 0) {
++		// Eileen ,for linux kernel 2.6.24 , 20080425
++		//move : static int str8100_hsdma_test(void);
++		(void)str8100_hsdma_test();
++	}
++#endif
++	return retval;
++}
++
++static void __exit str8100_hsdma_exit(void)
++{
++	        return;
++}
++
++module_init(str8100_hsdma_init);
++module_exit(str8100_hsdma_exit);
++
++#ifdef STR8100_HSDMA_TEST
++#define MEMSIZE_K		128
++#define MEMSIZE			(MEMSIZE_K*1024)
++
++#define NUM_HSDMA_VEC		16
++#define NUM_BYTES_PER_VEC	4096
++
++static hsdma_xfer_t hsdma_xfer_test;
++static u8 *src;
++static u8 *dst;
++
++static void hsdma_copy_end(hsdma_xfer_t *hsdma_xfer, int err)
++{
++	int i;
++
++	printk("STR8100 HSDMA Testing end\n");
++
++	if (err) {
++		printk("STR8100 HSDMA Testing failed!!\n");
++	} else {
++		for (i = 0; i < NUM_HSDMA_VEC; i++) {
++			if (memcmp((src + i * NUM_BYTES_PER_VEC), (dst + i * NUM_BYTES_PER_VEC), NUM_BYTES_PER_VEC) == 0) {
++				printk("STR8100 HSDMA Testing success started at offset: %04d:\n", i * NUM_BYTES_PER_VEC);
++			} else {
++				int j;
++				u8 *psrc;
++				u8 *pdst;
++
++				psrc = src + i * NUM_BYTES_PER_VEC;
++				pdst = dst + i * NUM_BYTES_PER_VEC;
++
++				printk("STR8100 HSDMA Testing error started at offset: %04d\n", i * NUM_BYTES_PER_VEC);
++
++				for (j = 0; j < NUM_BYTES_PER_VEC; j++) {
++					if ((j % 16) == 0) {
++						printk("\n 0x%08x: ", (u32)(psrc + j));
++					}
++					if (((j % 16) != 0) && ((j % 4) == 0)) {
++						printk(" ");
++					}
++					printk("%02x", psrc[j]);
++				}
++				printk("\n");
++	
++				for (j = 0; j < NUM_BYTES_PER_VEC; j++) {
++					if ((j % 16) == 0) {
++						printk("\n 0x%08x: ", (u32)(pdst + j));
++					}
++					if (((j % 16) != 0) && ((j % 4) == 0)) {
++						printk(" ");
++					}
++					printk("%02x", pdst[j]);
++				}
++				printk("\n");
++			}
++		}
++	}
++
++	kfree(src);
++	kfree(dst);
++}
++
++static int str8100_hsdma_test(void)
++{
++	int i;
++
++	src = kmalloc(MEMSIZE, GFP_KERNEL);
++	if (!src) goto out;
++	dst = kmalloc(MEMSIZE, GFP_KERNEL);
++	if (!dst) {
++		kfree(src);
++		goto out;
++	}
++
++	memset(src, 0xAF, MEMSIZE);
++	memset(dst, 0x00, MEMSIZE);
++
++	hsdma_xfer_test.nr_vec = NUM_HSDMA_VEC;
++	hsdma_xfer_test.hsdma_end_io = hsdma_copy_end;
++	for (i = 0; i < NUM_HSDMA_VEC; i++) {
++		hsdma_xfer_test.vec[i].data_direction = HSDMAC_MASTER0_TO_MASTER1;
++		hsdma_xfer_test.vec[i].src_addr = (u32)(src + i * NUM_BYTES_PER_VEC);
++		hsdma_xfer_test.vec[i].dst_addr = (u32)(dst + i * NUM_BYTES_PER_VEC);
++		hsdma_xfer_test.vec[i].size = NUM_BYTES_PER_VEC;
++	}
++
++	printk("STR8100 HSDMA Testing ...\n");
++	hsdma_copy(&hsdma_xfer_test);
++
++out:
++	return 0;
++}
++
++#endif // STR8100_HSDMA_TEST
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_i2s.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_i2s.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_i2s.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_i2s.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,743 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++/*
++ * defines for each channel
++ */
++#define DMAC_CH_DISABLE                0
++#define DMAC_CH_ENABLE                 1
++
++#define DMAC_CH_DST_SEL_M0             0
++#define DMAC_CH_DST_SEL_M1             1
++
++#define DMAC_CH_SRC_SEL_M0             0
++#define DMAC_CH_SRC_SEL_M1             1
++
++#define DMAC_CH_DSTAD_CTL_INC          0
++#define DMAC_CH_DSTAD_CTL_DEC          1
++#define DMAC_CH_DSTAD_CTL_FIX          2
++
++#define DMAC_CH_SRCAD_CTL_INC          0
++#define DMAC_CH_SRCAD_CTL_DEC          1
++#define DMAC_CH_SRCAD_CTL_FIX          2
++
++#define DMAC_CH_MODE_HW_HANDSHAKE      1
++
++#define DMAC_CH_SRC_WIDTH_8_BITS       0
++#define DMAC_CH_SRC_WIDTH_16_BITS      1
++#define DMAC_CH_SRC_WIDTH_32_BITS      2
++
++#define DMAC_CH_DST_WIDTH_8_BITS       0
++#define DMAC_CH_DST_WIDTH_16_BITS      1
++#define DMAC_CH_DST_WIDTH_32_BITS      2
++
++#define DMAC_CH_ABT_TRANSFER           1
++
++#define DMAC_CH_PROT1_PRIVILEGED_MODE  1
++#define DMAC_CH_PROT1_USER_MODE        0
++
++#define DMAC_CH_PROT2_BUFFERABLE       1
++#define DMAC_CH_PROT2_NON_BUFFERABLE   0
++
++#define DMAC_CH_PROT3_CACHEABLE        1
++#define DMAC_CH_PROT3_NON_CACHEABLE    0
++
++#define DMAC_CH_PRI_LEVEL_0            0
++#define DMAC_CH_PRI_LEVEL_1            1
++#define DMAC_CH_PRI_LEVEL_2            2
++#define DMAC_CH_PRI_LEVEL_3            3
++
++#define DMAC_CH_TC_MASK_DISABLE        0
++#define DMAC_CH_TC_MASK_ENABLE         1
++
++#define DMAC_MAX_CHANNEL_NUM           (8)
++
++
++#define DMAC_CH0_ID                    (1 << 0)
++#define DMAC_CH1_ID                    (1 << 1)
++#define DMAC_CH2_ID                    (1 << 2)
++#define DMAC_CH3_ID                    (1 << 3)
++#define DMAC_CH4_ID                    (1 << 4)
++#define DMAC_CH5_ID                    (1 << 5)
++#define DMAC_CH6_ID                    (1 << 6)
++#define DMAC_CH7_ID                    (1 << 7)
++#define DMAC_CH_ID(idx)                (1 << idx) 
++
++#define DMAC_LITTLE_ENDIAN             (0)
++#define DMAC_BIG_ENDIAN                (1)
++
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++
++#include <linux/kernel.h>	/* printk() */
++#include <linux/errno.h>	/* error codes */
++#include <linux/types.h>	/* size_t */
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++#include <linux/pci.h>
++
++#include <asm/system.h>		/* cli(), *_flags */
++#include <asm/uaccess.h>	/* copy_*_user */
++
++#include <mach/star_powermgt.h>
++#include <mach/star_misc.h>
++#include <mach/star_i2s.h>
++#include <mach/star_dmac.h>
++
++MODULE_AUTHOR("Mac Lin");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++#define CONFIG_I2S_USE_DMA
++//Debug = left only
++#define DEBUG	
++
++static struct proc_dir_entry *star_i2s_proc_entry=NULL;
++static u32 sampling_rate=32000;
++static u32 sample_size=16;
++
++#define DMA_TRANSFER_MAX_BYTE    (0xfff<<(sample_size>>4)) 
++#define BUFSIZE (0xfff<<4) //twice the 32-bit DMA transfer byte size
++
++static u8* lbuffer;
++static u8* lbuffer_p;
++static u32 llen=0;
++static u32 lpos=0;
++static u32 i2s_err_lur=0;
++
++static u32 debug=0;
++#define DEBUG_PRINT(arg...) if(debug) printk(arg);
++
++//=================================================================================
++//
++#ifdef CONFIG_I2S_USE_DMA
++typedef struct _DMAC_HARDWARE_HANDSHAKE_OBJ_    DMAC_HARDWARE_HANDSHAKE_OBJ_T;
++
++struct _DMAC_HARDWARE_HANDSHAKE_OBJ_
++{
++    unsigned int    src_addr;                     //Src address
++    unsigned int    dst_addr;                     //Dst address
++    unsigned int    src_master;                   //0:AHB0, 1:AHB1
++    unsigned int    dst_master;                   //0:AHB0, 1:AHB1
++    unsigned int    dstad_ctl;                    //0:Incr, 1:Decr, 2:Fix
++    unsigned int    srcad_ctl;                    //0:Incr, 1:Decr, 2:Fix
++    unsigned int    src_width;                    //0:8bits, 1:16bits, 2:32bits
++    unsigned int    dst_width;                    //0:8bits, 1:16bits, 2:32bits
++    unsigned int    transfer_bytes;               //Byte Count to be transferred
++    unsigned int    channel_id;                   //0~7 for Channel0-7 selection
++    unsigned int    channel_num;                   //0~7
++    unsigned int    target_select;                //target ID
++    unsigned int    src_burst_size;               //number of transfer 
++}; 
++
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8759_dma_handshake_left_tx;
++static DMAC_HARDWARE_HANDSHAKE_OBJ_T    i2s_wm8759_dma_handshake_right_tx;
++
++static u32                          i2s_wm8759_dma_right_tx_channel = 1;
++
++
++
++
++void Hal_Dmac_Configure_DMA_Handshake(DMAC_HARDWARE_HANDSHAKE_OBJ_T *dmac_obj)
++{
++    u32    channel_control,interrupt_mask_config,ch;
++
++    
++    /*
++     * Configure DMA controller for UART's hardware DMA handshake mode
++     */    
++    HAL_DMAC_DISABLE();
++    
++//#if (ENDIAN_MODE == BIG_ENDIAN)
++#if 0
++    /*Set Master0 and Master 1 endianness as Big Endian*/
++    HAL_DMAC_SET_MASTER0_BIG_ENDIAN();
++    HAL_DMAC_SET_MASTER1_BIG_ENDIAN();
++#else
++    /*Set Master0 and Master 1 endianness as Little Endian*/
++    HAL_DMAC_SET_MASTER0_LITTLE_ENDIAN();
++    HAL_DMAC_SET_MASTER1_LITTLE_ENDIAN();
++#endif
++
++    //Clear TC interrupt status    
++    HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(0xFF);        // 8 channels
++
++    //Clear Errot/Abort interrupt status    
++    HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(0x00FF00FF);    // 8 channels
++
++    /*
++     * Configure DMA's channel control
++     */   
++    channel_control = ((DMAC_CH_TC_MASK_DISABLE << 31) | \
++                       ((dmac_obj->target_select&0xf) << 25) | \
++                       (DMAC_CH_PRI_LEVEL_3 << 22) | \
++                       (DMAC_CH_PROT3_NON_CACHEABLE << 21) | \
++                       (DMAC_CH_PROT2_NON_BUFFERABLE << 20) | \
++                       (DMAC_CH_PROT1_PRIVILEGED_MODE << 19) | \
++                       ((dmac_obj->src_burst_size&0x7) << 16) | \
++                       ((dmac_obj->src_width&0x7) << 11) | \
++                       ((dmac_obj->dst_width&0x7) << 8) | \
++                       (DMAC_CH_MODE_HW_HANDSHAKE << 7) | \
++                       ((dmac_obj->srcad_ctl&0x3) << 5) | \
++                       ((dmac_obj->dstad_ctl&0x3) << 3) | \
++                       (dmac_obj->src_master << 2) | \
++                       (dmac_obj->dst_master << 1) | \
++                       (DMAC_CH_DISABLE));
++
++    for (ch = 0; ch < DMAC_MAX_CHANNEL_NUM; ch++)
++    {
++        if (dmac_obj->channel_id & DMAC_CH_ID(ch))
++        {  
++            // 1. Set CSR
++            DMAC_CH_CSR_REG(ch) = channel_control & 0xFFFFFFFE; //Disable CH(n) DMA
++                
++            // 2.1 Reset Abort/Error/Terminal Count INT 
++            DMAC_CH_CFG_REG(ch) &= ~(0x07);
++            
++            // 2.2 Disable  Abort Count INT        
++            interrupt_mask_config = (1 << 2);
++            
++            DMAC_CH_CFG_REG(ch) |= (interrupt_mask_config & 0x07);
++        }                               	
++    }
++
++    for (ch = 0; ch < DMAC_MAX_CHANNEL_NUM; ch++)
++    {
++        if (dmac_obj->channel_id & DMAC_CH_ID(ch))
++        {  
++            //Set Src address register
++            DMAC_CH_SRC_ADDR_REG(ch)= dmac_obj->src_addr;
++
++            //Set Dst address register
++            DMAC_CH_DST_ADDR_REG(ch)= dmac_obj->dst_addr;    
++
++            //Set Transfer Number
++            if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_8_BITS)
++            {
++                DMAC_CH_SIZE_REG(ch) = (dmac_obj->transfer_bytes & 0x0FFF);
++                DEBUG_PRINT("%s: 8-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_16_BITS)
++            {                                  
++                DMAC_CH_SIZE_REG(ch) = ((dmac_obj->transfer_bytes >> 1) + (dmac_obj->transfer_bytes % 2)) & 0x0FFF;
++                DEBUG_PRINT("%s: 16-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else if (dmac_obj->src_width == DMAC_CH_SRC_WIDTH_32_BITS)
++            {
++                DMAC_CH_SIZE_REG(ch) = ((dmac_obj->transfer_bytes >> 2) + ((dmac_obj->transfer_bytes % 4) ? 1 : 0)) & 0x0FFF;
++                DEBUG_PRINT("%s: 32-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,dmac_obj->transfer_bytes,ch,DMAC_CH_SIZE_REG(ch));
++            }
++            else
++            {
++            	DEBUG_PRINT("%s: dead\n",__FUNCTION__);
++                while (1);
++            }
++
++            //Enable Channel DMA transfer 
++            HAL_DMAC_ENABLE_CHANNEL(ch);
++             
++            //Set Channel's Sync logic
++            DMAC_SYNC_REG |= (1 << ch);
++
++            //For NON Chain Transfer, clear LLP registers
++            DMAC_CH_LLP_REG(ch) = 0;
++        }
++    }
++}
++
++void I2s_WM8759_Configure_DMA_Hardware_Handshake(void)
++{
++    /*
++     * Configure DMA's channel setting for I2S's Left Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    i2s_wm8759_dma_handshake_left_tx.channel_num = 0;
++    i2s_wm8759_dma_handshake_left_tx.channel_id = DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num);
++    i2s_wm8759_dma_handshake_left_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_LEFT_ID;
++    i2s_wm8759_dma_handshake_left_tx.src_addr = (u32)lbuffer_p;
++    i2s_wm8759_dma_handshake_left_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    i2s_wm8759_dma_handshake_left_tx.dst_master = DMAC_CH_DST_SEL_M0;
++    i2s_wm8759_dma_handshake_left_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    i2s_wm8759_dma_handshake_left_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++    
++	switch(sample_size){
++	case 16:
++		i2s_wm8759_dma_handshake_left_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xCA);
++		i2s_wm8759_dma_handshake_left_tx.src_width = DMAC_CH_SRC_WIDTH_16_BITS;
++		i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_16_BITS;
++		break;
++	case 32:
++		i2s_wm8759_dma_handshake_left_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xC8);
++		i2s_wm8759_dma_handshake_left_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++		i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++		break;
++	}
++
++//    i2s_wm8759_dma_handshake_left_tx.dst_width = DMAC_CH_DST_WIDTH_16_BITS;
++
++    /*
++     * Note here the total number of bytes for each DMA transfer is specified!!
++     */
++//    i2s_wm8759_dma_handshake_left_tx.transfer_bytes = DMA_TRANSFER_MAX_BYTE;
++    i2s_wm8759_dma_handshake_left_tx.transfer_bytes = (llen<DMA_TRANSFER_MAX_BYTE)?llen:DMA_TRANSFER_MAX_BYTE;
++
++    i2s_wm8759_dma_handshake_left_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8759_dma_handshake_left_tx);
++
++#ifndef DEBUG 
++    /*
++     * Configure DMA's channel setting for I2S's Right Channel Tx
++     * Specially pay attention to the settings of src_width, dst_width, and src_burst_size
++     */
++    i2s_wm8759_dma_handshake_right_tx.channel_id = DMAC_CH_ID(i2s_wm8759_dma_right_tx_channel);
++    
++    i2s_wm8759_dma_handshake_right_tx.target_select = DMAC_HW_HAND_SHAKE_I2S_TX_RIGHT_ID;
++
++    i2s_wm8759_dma_handshake_right_tx.src_addr = (u32)rbuffer_p;
++
++    i2s_wm8759_dma_handshake_right_tx.dst_addr = (SYSPA_I2S_BASE_ADDR + 0xC4);
++
++    i2s_wm8759_dma_handshake_right_tx.src_master = DMAC_CH_SRC_SEL_M1;
++    
++    i2s_wm8759_dma_handshake_right_tx.dst_master = DMAC_CH_DST_SEL_M0;
++
++    i2s_wm8759_dma_handshake_right_tx.srcad_ctl = DMAC_CH_SRCAD_CTL_INC;
++    
++    i2s_wm8759_dma_handshake_right_tx.dstad_ctl = DMAC_CH_DSTAD_CTL_FIX;
++
++    i2s_wm8759_dma_handshake_right_tx.src_width = DMAC_CH_SRC_WIDTH_32_BITS;
++    
++    i2s_wm8759_dma_handshake_right_tx.dst_width = DMAC_CH_DST_WIDTH_32_BITS;
++
++    /*
++     * Note here the total number of bytes for each DMA transfer is specified!!
++     */
++    i2s_wm8759_dma_handshake_right_tx.transfer_bytes = DMA_TRANSFER_MAX_BYTE;
++
++    i2s_wm8759_dma_handshake_right_tx.src_burst_size = DMAC_CH_SRC_BURST_SIZE_1;   
++
++    Hal_Dmac_Configure_DMA_Handshake(&i2s_wm8759_dma_handshake_right_tx);
++#endif
++    return;
++}
++#endif //CONFIG_I2S_USE_DMA
++
++
++//=================================================================================
++//
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++#ifdef CONFIG_I2S_USE_DMA
++static irqreturn_t str8100_dma_tc_irq_handler(int this_irq, void *dev_id /*, struct pt_regs *regs*/)
++{
++	u32 dma_tc_status,tot_size;
++	u32 len;
++//printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++
++    HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(dma_tc_status);
++
++    /*
++     * For DMA's Tx for I2S Left Channel
++     */
++	if (dma_tc_status & DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num))
++	{                      
++		HAL_DMAC_DISABLE_CHANNEL(i2s_wm8759_dma_handshake_left_tx.channel_num);
++		HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8759_dma_handshake_left_tx.channel_num));
++		lpos+=i2s_wm8759_dma_handshake_left_tx.transfer_bytes;
++		if(lpos<llen){
++			/*
++			 * Re-initialize DMA's channel for Left_Tx
++			 */
++			DMAC_CH_SRC_ADDR_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = (u32)lbuffer_p+lpos;
++			DMAC_CH_DST_ADDR_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = (SYSPA_I2S_BASE_ADDR + 0xC8);        
++			
++			/*
++			 * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
++			 * number of source transfer width!
++			 */        
++			len=(llen - lpos);
++			i2s_wm8759_dma_handshake_left_tx.transfer_bytes= (len<DMA_TRANSFER_MAX_BYTE)?len:DMA_TRANSFER_MAX_BYTE;
++
++			if (i2s_wm8759_dma_handshake_left_tx.src_width == DMAC_CH_SRC_WIDTH_16_BITS)
++			{
++			    tot_size = (i2s_wm8759_dma_handshake_left_tx.transfer_bytes >> 1) + ((i2s_wm8759_dma_handshake_left_tx.transfer_bytes % 2) ? 1 : 0);
++			}
++			else if (i2s_wm8759_dma_handshake_left_tx.src_width == DMAC_CH_SRC_WIDTH_32_BITS)
++			{
++			    tot_size = (i2s_wm8759_dma_handshake_left_tx.transfer_bytes >> 2) + ((i2s_wm8759_dma_handshake_left_tx.transfer_bytes % 4) ? 1 : 0);
++			}
++			else
++			{
++			    tot_size = i2s_wm8759_dma_handshake_left_tx.transfer_bytes;
++			}
++			
++			DMAC_CH_SIZE_REG(i2s_wm8759_dma_handshake_left_tx.channel_num) = tot_size & 0x0FFF;
++			HAL_DMAC_ENABLE_CHANNEL(i2s_wm8759_dma_handshake_left_tx.channel_num);
++//printk("%s: 32-bits transfer_bytes=%d, DMAC_CH_SIZE_REG(%d)=%.8x\n",__FUNCTION__,i2s_wm8759_dma_handshake_left_tx.transfer_bytes,i2s_wm8759_dma_handshake_left_tx.channel_num,DMAC_CH_SIZE_REG(i2s_wm8759_dma_handshake_left_tx.channel_num));
++
++	}else{
++		llen=lpos=0;
++	}
++	}
++
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++static irqreturn_t str8100_dma_err_irq_handler(int this_irq, void *dev_id /*, struct pt_regs *regs*/)
++{
++	u32 dma_error_status,dma_ch;
++printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++
++	HAL_DMAC_READ_ERROR_ABORT_INTERRUPT_STATUS(dma_error_status);
++	for (dma_ch = 0; dma_ch < DMAC_MAX_CHANNEL_NUM; dma_ch++)
++	{
++		if (dma_error_status & DMAC_CH_ID(dma_ch))
++		{
++			printk("%s: this_irq=%d, DMA channel error on ch %d\n",__FUNCTION__,this_irq,dma_ch);
++			HAL_DMAC_DISABLE_CHANNEL(dma_ch);
++			HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(DMAC_CH_ID(dma_ch));
++		}
++	}	
++	
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++	return IRQ_HANDLED;
++}
++#endif //CONFIG_I2S_USE_DMA
++
++static irqreturn_t str8100_i2s_irq_handler(int this_irq, void *dev_id /*, struct pt_regs *regs*/)
++{
++	u32 interrupt_status;
++	DEBUG_PRINT("%s: this_irq=%d, I2S_INTERRUPT_STATUS_REG=0x%.8x,llen=%d,lpos=%d\n",__FUNCTION__,this_irq,I2S_INTERRUPT_STATUS_REG,llen,lpos);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	//todo:
++	interrupt_status = I2S_INTERRUPT_STATUS_REG;   
++if((llen<lpos)||llen==0)     HAL_I2S_DISABLE_I2S();
++
++#ifndef CONFIG_I2S_USE_DMA
++		I2S_RIGHT_TRANSMIT_DATA_REG=0;
++
++	if ((lpos<=llen) && (interrupt_status & I2S_TXBF_L_EMPTY_FLAG)){
++		switch(sample_size){
++			case 16:
++				I2S_LEFT_TRANSMIT_DATA_REG=(*((u16*)(&lbuffer[lpos])))<<16;lpos+=2;
++				break;
++			case 32:
++				I2S_LEFT_TRANSMIT_DATA_REG=*((u32*)(&lbuffer[lpos]));lpos+=4;
++				break;
++		}
++		
++		if(lpos>llen){
++			// Disable Left Channel's Transmit Buffer Interrupt Sources
++			I2S_INTERRUPT_ENABLE_REG &= ~(I2S_TXBF_L_EMPTY_FLAG | I2S_TXBF_L_UR_FLAG);
++			lpos=llen=0;
++		}
++	}
++#endif //!CONFIG_I2S_USE_DMA
++
++
++	if (llen>=lpos && (interrupt_status & I2S_TXBF_L_UR_FLAG)){
++		// Clear I2S interrupt status
++		i2s_err_lur++;
++		if(i2s_err_lur>10)
++			I2S_INTERRUPT_ENABLE_REG &= ~(I2S_TXBF_L_UR_FLAG);
++//			HAL_I2S_DISABLE_I2S();
++		
++		printk("%s: Left Channel Tx Underrun!,llen=%d, lpos=%d, interrupt_status=%.8x,i2s_err_lur=%d\n",__FUNCTION__,llen,lpos,interrupt_status,i2s_err_lur);
++	}
++	I2S_INTERRUPT_STATUS_REG &= 0xf0;
++
++	
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++static int str8100_i2s_init(void){
++	DEBUG_PRINT("%s: \n",__FUNCTION__);
++	int ret;
++	u32 tmp;
++	
++
++	/*
++	 * Select I2S clock source; here we use 48K sampling rate for the target file.
++	 */
++	 
++	switch(sampling_rate){
++	case 48000: 
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_12288000HZ(); 
++		break; 
++	case 44100:
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_11289600HZ(); 
++		break;
++	case 32000: 
++		HAL_PWRMGT_I2S_CLOCK_SOURCE_8192000HZ(); 
++		break; 
++	}
++	HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(11,0);
++	
++	// Enable I2S pins
++	HAL_MISC_ENABLE_I2S_PINS();
++	
++	// Enable I2S clock
++	HAL_PWRMGT_ENABLE_I2S_CLOCK(); 
++
++	//Hal_Pwrmgt_Software_Reset(PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX);
++
++    /*
++     * Configure I2S to be Master & Transmitter
++     * Note the I2S's WS Clock is derived from Clock & Power Management Functional
++     * Block!!
++     */
++	I2S_CONFIGURATION_REG = /*(I2S_DATA_16_BIT << 0) |*/
++												(I2S_DATA_32_BIT << 0) |
++                        (0x0 << 4) |
++                        (0x0 << 12) |   /* Disable loopback */
++                        (0x0 << 15) |   /* Disable clock phase invert */
++                        (0x0 << 24) |   /* Disable I2S data swap */
++                        (I2S_CLOCK_256S_MODE << 25) |
++                        (I2S_I2S_MODE << 26) |
++                        (0x0 << 29) |   /* Enable I2S Transmitter */
++												(I2S_MASTER_MODE << 30) |
++												(0x0 << 31);	/* Disable I2S */
++
++	//Enable none while initializing
++	I2S_INTERRUPT_ENABLE_REG = 0x0;
++//	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG | I2S_TXBF_R_EMPTY_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++
++    // Clear spurious interrupt sources
++    I2S_INTERRUPT_STATUS_REG = 0xF0;
++
++    tmp = I2S_LEFT_RECEIVE_DATA_REG;
++    tmp = I2S_RIGHT_RECEIVE_DATA_REG;
++
++    // Disable I2S
++    HAL_I2S_DISABLE_I2S();
++
++	return 0;
++}
++
++
++//=================================================================================
++static int proc_read_i2s(char *buf, char **start, off_t offset,
++                   int count, int *eof, void *data)
++{
++	int len=0;
++	DEBUG_PRINT("%s:\n",__FUNCTION__);
++	len += sprintf(buf,	"sampling_rate=%d\n"
++				"sample_size=%d\n"
++			,sampling_rate,sample_size); 
++	*eof = 1;
++	return len;
++}
++
++static proc_write_i2s(struct file *file, const char *buffer, unsigned long count, void *data){
++	int len=0;
++	DEBUG_PRINT("%s: sample size %d, sampling rate %d, count=%d\n",__FUNCTION__,sample_size,sampling_rate,count);
++	
++	//is buffer free?
++	if(lpos!=llen){
++		printk("%s: buffer not free\n");
++		return -EBUSY;
++	}
++	if(sampling_rate!=32000&&sampling_rate!=44100&&sampling_rate!=48000){
++		printk("%s: invalid sampling rate(%d)\n",sampling_rate);
++		return -EFAULT;
++	}
++	if(sample_size!=16&&sample_size!=32){
++		printk("%s: invalid sample size(%d)\n",sample_size);
++		return -EFAULT;
++	}
++
++	//copy the raw data to local buffer	
++	if(count>BUFSIZE) len=BUFSIZE;
++	else len=count;
++	
++	if(copy_from_user(lbuffer,buffer,len)){
++		return -EFAULT;	
++	}
++	llen=len;
++	lpos=0;
++	i2s_err_lur=0;
++	
++	str8100_i2s_init();
++
++#ifdef CONFIG_I2S_USE_DMA
++    /*
++     * Configure DMA for hardware handshake for I2S
++     * Note the DMA is NOT enabled after invoking the following function, but the specified
++     * DMA channels are enabled!!
++     */
++    i2s_wm8759_dma_right_tx_channel = 1;   
++
++    I2s_WM8759_Configure_DMA_Hardware_Handshake();  
++
++#endif //CONFIG_I2S_USE_DMA
++	//fill the tx left/right registers
++
++		switch(sample_size){
++			case 16:
++				I2S_LEFT_TRANSMIT_DATA_REG=(*((u16*)(&lbuffer[lpos])))<<16;lpos+=2;
++				break;
++			case 32:
++				I2S_LEFT_TRANSMIT_DATA_REG=*((u32*)(&lbuffer[lpos]));lpos+=4;
++				break;
++		}
++
++	I2S_RIGHT_TRANSMIT_DATA_REG=0;
++
++#ifdef CONFIG_I2S_USE_DMA
++	/*
++	 * Enable I2S's interrupt sources
++	 * Note for DMA hardware handshake, we only need to enable Left/Right Channel's 
++	 * Transmit Buffer Underrun.
++	 */
++#ifdef DEBUG	
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_L_UR_FLAG);
++#else
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG);
++#endif
++#else //CONFIG_I2S_USE_DMA
++#ifdef DEBUG	
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_L_UR_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++#else
++	I2S_INTERRUPT_ENABLE_REG |= (I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG | I2S_TXBF_R_EMPTY_FLAG | I2S_TXBF_L_EMPTY_FLAG);
++#endif
++#endif //CONFIG_I2S_USE_DMA
++
++	// Enable CPU interrupt
++	local_irq_enable();
++	
++#ifdef CONFIG_I2S_USE_DMA
++	/*
++	 * Note DMA must be enabled first before I2S is enabled
++	 */
++	HAL_DMAC_ENABLE();
++#endif //CONFIG_I2S_USE_DMA
++	HAL_I2S_ENABLE_I2S();
++
++
++	while (1){
++		local_irq_disable();
++		if (lpos>llen||llen==0){
++			// Disable I2S
++			HAL_I2S_DISABLE_I2S();
++			break;
++		}
++		local_irq_enable();
++	}
++	DEBUG_PRINT("%s: exit. i2s_err_lur=%d\n",__FUNCTION__,i2s_err_lur);
++
++	local_irq_enable();
++
++	return len;
++
++debug:
++	HAL_I2S_DISABLE_I2S();
++	return count;
++}
++
++static void __devexit i2s_exit_module(void)
++{
++	printk("%s:\n",__FUNCTION__);
++	remove_proc_entry("str8100/i2s", NULL);
++	free_irq(INTC_I2S_BIT_INDEX, NULL);
++#ifdef CONFIG_I2S_USE_DMA
++	free_irq(INTC_GDMAC_TC_BIT_INDEX, NULL);
++	free_irq(INTC_GDMAC_ERROR_BIT_INDEX, NULL);
++#endif //CONFIG_I2S_USE_DMA
++	if(lbuffer) {
++		pci_free_consistent(NULL, BUFSIZE, lbuffer, lbuffer_p);
++		lbuffer=lbuffer_p=NULL;
++	}
++}
++
++static int __devinit i2s_init_module(void)
++{
++	u32 ret;
++	
++	printk("%s:\n",__FUNCTION__);
++#ifdef CONFIG_I2S_USE_DMA
++	printk("%s: DMA Enabled...\n",__FUNCTION__);
++#endif //CONFIG_I2S_USE_DMA
++
++	star_i2s_proc_entry = create_proc_entry("str8100/i2s", S_IFREG | S_IRUGO, NULL);
++	if(!star_i2s_proc_entry){
++		return -EBUSY;
++	}
++	star_i2s_proc_entry->read_proc=proc_read_i2s;
++	star_i2s_proc_entry->write_proc=proc_write_i2s;
++	
++	lbuffer = pci_alloc_consistent(NULL, BUFSIZE, &lbuffer_p);
++	if(!lbuffer){
++		printk("%s: alloc lbuffer failed.\n",__FUNCTION__);
++		goto exit1;
++	}
++
++	str8100_set_interrupt_trigger (INTC_I2S_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_LOW);
++	if ((ret=request_irq(INTC_I2S_BIT_INDEX, str8100_i2s_irq_handler, 0, "i2s", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_I2S_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++
++#ifdef CONFIG_I2S_USE_DMA
++	str8100_set_interrupt_trigger (INTC_GDMAC_TC_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_TC_BIT_INDEX, str8100_dma_tc_irq_handler, 0, "dma tc", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_TC_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++	str8100_set_interrupt_trigger (INTC_GDMAC_ERROR_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GDMAC_ERROR_BIT_INDEX, str8100_dma_err_irq_handler, 0, "dma error", NULL))){
++		printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_GDMAC_ERROR_BIT_INDEX,ret,-EBUSY);
++		goto exit1;
++	}
++#endif //CONFIG_I2S_USE_DMA
++
++	return 0;
++exit1:
++	i2s_exit_module();
++	return -EBUSY;
++}
++
++module_init(i2s_init_module);
++module_exit(i2s_exit_module);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_intc.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_intc.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_intc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_intc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,222 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++
++#include <mach/hardware.h>
++#include <asm/mach/irq.h>
++#include <asm/irq.h>
++
++#define INTC_TRIGGER_UNKNOWN -1
++
++typedef struct
++{
++	int	mode;
++	int	level;
++} intc_trigger_t;
++
++static intc_trigger_t intc_trigger_table[] =
++{
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 0
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 1
++	{ INTC_EDGE_TRIGGER,	INTC_FALLING_EDGE	},	// 2
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 3
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 4
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 5
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 6
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 7
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 8
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 9
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 10
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 11
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 12
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 13
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 14
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 15
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 16
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 17
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 18
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 19
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 20
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 21
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 22
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 23
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 24
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 25
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 26
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 27
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 28
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 29
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 30
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 31
++};
++
++static u32 intc_edge_trigger_bitmap;
++
++/*
++ * Configure interrupt trigger mode to be level trigger or edge trigger
++ */
++static inline void str8100_set_irq_mode(unsigned int irq, unsigned int mode)
++{
++	volatile unsigned int val;
++
++	if (irq < 0 || irq > NR_IRQS) {
++		return;
++	}
++
++	if ((mode != INTC_LEVEL_TRIGGER) &&
++		(mode != INTC_EDGE_TRIGGER)) {
++		return;
++	}
++
++	val = INTC_INTERRUPT_TRIGGER_MODE_REG;
++
++	if (mode == INTC_LEVEL_TRIGGER) {
++		if (val & (1UL << irq)) {
++			val &= ~(1UL << irq);
++			INTC_INTERRUPT_TRIGGER_MODE_REG = val;
++		}
++	} else {
++		intc_edge_trigger_bitmap |= (1UL << irq);
++		if (!(val & (1UL << irq))) {
++			val |= (1UL << irq);
++			INTC_INTERRUPT_TRIGGER_MODE_REG = val;
++		}
++	}
++}	
++
++/*
++ * Configure interrupt trigger level to be Active High/Low or Rising/Falling Edge
++ */
++static inline void str8100_set_irq_level(unsigned int irq, unsigned int level)
++{
++	volatile unsigned int val;
++
++	if (irq < 0 || irq > NR_IRQS) {
++		return;
++	}
++
++	if ((level != INTC_ACTIVE_HIGH) &&
++		(level != INTC_ACTIVE_LOW) &&
++		(level != INTC_RISING_EDGE) &&
++		(level != INTC_FALLING_EDGE)) {
++		return;
++	}
++
++	val = INTC_INTERRUPT_TRIGGER_LEVEL_REG;
++
++	if ((level == INTC_ACTIVE_HIGH) ||
++		(level == INTC_RISING_EDGE)) {
++		if (val & (1UL << irq)) {
++			val &= ~(1UL << irq);
++			INTC_INTERRUPT_TRIGGER_LEVEL_REG = val;
++		}
++	} else {
++		if (!(val & (1UL << irq))) {
++			val |= (1UL << irq);
++			INTC_INTERRUPT_TRIGGER_LEVEL_REG = val;
++		}
++	}
++}
++
++/*
++ * Configure interrupt trigger mode and trigger level
++ */
++void str8100_set_interrupt_trigger(unsigned int irq, unsigned int mode, unsigned int level)
++{
++	str8100_set_irq_mode(irq, mode);
++	str8100_set_irq_level(irq, level);
++}
++EXPORT_SYMBOL(str8100_set_interrupt_trigger);
++
++/*
++ * Mask/Disable this interrupt source
++ */
++void str8100_mask_irq(unsigned int irq)
++{
++      
++//	if (irq != INTC_NIC_RXRC_BIT_INDEX && irq != INTC_NIC_RXQF_BIT_INDEX) {
++		// Mask/Disable this interrupt source
++		INTC_INTERRUPT_MASK_REG = (1UL << irq);
++//	}
++}
++
++/*
++ * Un-Mask/Enable this interrupt source
++ */
++void str8100_unmask_irq(unsigned int irq)
++{
++         
++#ifndef CONFIG_VIC_INTERRUPT
++	// Clear interrupt status of the interrupt source which is edge-triggered
++	INTC_EDGE_INTERRUPT_SOURCE_CLEAR_REG = (1UL << irq);
++#endif
++	// Enable this interrupt source
++	INTC_INTERRUPT_MASK_CLEAR_REG = (1UL << irq);
++}
++
++static struct irq_chip str8100_irqchip = {
++	.ack	= str8100_mask_irq,
++	.mask	= str8100_mask_irq,
++	.unmask	= str8100_unmask_irq,
++};
++
++void __init str8100_init_irq(void)
++{
++	int i;
++
++   //printk("str8100_init_irq()\n");
++      
++   disable_hlt();
++   
++	INTC_INTERRUPT_MASK_REG = 0xFFFFFFFF;
++	INTC_EDGE_INTERRUPT_SOURCE_CLEAR_REG = 0xFFFFFFFF;
++	INTC_SOFTWARE_INTERRUPT_CLEAR_REG = 0xFFFFFFFF;
++	INTC_SOFTWARE_PRIORITY_MASK_REG = 0x0;
++	INTC_FIQ_SELECT_REG = 0x0;
++#ifdef CONFIG_VIC_INTERRUPT
++	for (i = 0; i < NR_IRQS; i++) {
++		(*((u32 volatile *)(SYSVA_VIC_BASE_ADDR + 0x40 + (i << 2)))) = i;
++	}
++	INTC_VECTOR_INTERRUPT_ENABLE_REG = 1;
++#else
++	INTC_VECTOR_INTERRUPT_ENABLE_REG = 0;
++#endif
++
++	for (i = 0; i < NR_IRQS; i++) {
++		if (intc_trigger_table[i].mode != INTC_TRIGGER_UNKNOWN) {
++			str8100_set_irq_mode(i, intc_trigger_table[i].mode);
++			str8100_set_irq_level(i, intc_trigger_table[i].level);
++		}
++	}
++	
++	for (i = 0; i < NR_IRQS;  i++) {
++		set_irq_chip(i, &str8100_irqchip);
++		/* scott.patch */
++		set_irq_handler(i, handle_level_irq);
++		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
++	}
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_misc.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_misc.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_misc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_misc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,210 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/proc_fs.h>
++#include <asm/mach/map.h>
++#include <mach/hardware.h>
++
++static struct map_desc str8100_map_desc[64];
++static int str8100_map_desc_count;
++
++#define REG_DEBUG_CMD_BUFFER_SIZE	128
++#define REG_DEBUG_RESULT_BUFFER_SIZE	256
++
++struct proc_dir_entry *str8100_proc_dir;
++EXPORT_SYMBOL(str8100_proc_dir);
++static struct proc_dir_entry *star_reg_debug_proc_entry;
++static char str8100_reg_debug_cmd_buf[REG_DEBUG_CMD_BUFFER_SIZE];
++static char str8100_reg_debug_result_buf[REG_DEBUG_RESULT_BUFFER_SIZE];
++
++void str8100_register_map_desc(struct map_desc *map, int count)
++{
++	if (count) {
++		if (str8100_map_desc) {
++			int i;
++			for (i = 0; i < count; i++) {
++				str8100_map_desc[i].virtual = map->virtual;
++				str8100_map_desc[i].pfn = map->pfn;
++				str8100_map_desc[i].length = map->length;
++				str8100_map_desc[i].type = map->type;
++				map++;
++			}
++			str8100_map_desc_count = count;
++		}
++	}
++}
++
++u32 str8100_query_map_desc_by_phy(u32 addr)
++{
++	struct map_desc *map;
++	int i;
++	u32 ret_addr = 0;
++	for (i = 0; i < str8100_map_desc_count; i++) {
++		map = &str8100_map_desc[i];
++		if (addr >= (map->pfn << PAGE_SHIFT) && addr < ((map->pfn << PAGE_SHIFT) + map->length)) {
++			ret_addr = map->virtual + (addr - (map->pfn << PAGE_SHIFT));
++			break;
++		}
++	}
++
++	return ret_addr;
++}
++
++u32 str8100_query_map_desc_by_vir(u32 addr)
++{
++	struct map_desc *map;
++	int i;
++	u32 ret_addr = 0;
++	for (i = 0; i < str8100_map_desc_count; i++) {
++		map = &str8100_map_desc[i];
++		if (addr >= map->virtual && addr < (map->virtual + map->length)) {
++			ret_addr = (map->pfn << PAGE_SHIFT) + (addr - map->virtual);
++			break;
++		}
++	}
++
++	return ret_addr;
++}
++
++static int star_reg_debug_read_proc(char *buffer, char **start, off_t offset,
++	int length, int *eof, void *data)
++{
++	int count;
++	int num = 0;
++
++	if (str8100_reg_debug_cmd_buf[0]) {
++		count = strlen(str8100_reg_debug_cmd_buf);
++		sprintf(buffer, str8100_reg_debug_cmd_buf, count);
++		num += count;
++	}
++	if (str8100_reg_debug_result_buf[0]) {
++		count = strlen(str8100_reg_debug_result_buf);
++		sprintf(buffer + num, str8100_reg_debug_result_buf, count);
++		num += count;
++	}
++
++	return num;
++}
++
++static int
++star_reg_debug_write_proc(struct file *file, const char __user *buffer,
++	unsigned long count, void *data)
++{
++	char *str;
++	char *cmd;
++
++	if (count > 0) {
++		str = (char *)buffer,
++		cmd = strsep(&str, "\t \n");
++		if (!cmd) goto err_out;
++		if (strcmp(cmd, "dump") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 16);
++			if (addr & 0x3) goto err_out;
++			vir_addr = str8100_query_map_desc_by_phy(addr);
++			sprintf(str8100_reg_debug_cmd_buf,
++				"dump 0x%08x\n",
++				addr);
++			if (!vir_addr) goto err_out;
++			sprintf(str8100_reg_debug_result_buf,
++				"physical addr: 0x%08x content: 0x%08x\n",
++				addr,
++				*(volatile unsigned int __force *)(vir_addr));
++		} else if (strcmp(cmd, "write") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			u32 data;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 16);
++			arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			data = simple_strtoul(arg, &arg, 16);
++			if (addr & 0x3) goto err_out;
++			vir_addr = str8100_query_map_desc_by_phy(addr);
++			if (!vir_addr) goto err_out;
++			*(volatile unsigned int __force *)(vir_addr) = data;
++			sprintf(str8100_reg_debug_cmd_buf,
++				"write 0x%08x 0x%08x\n",
++				addr, data);
++			sprintf(str8100_reg_debug_result_buf,
++				"physical addr: 0x%08x content: 0x%08x\n",
++				addr,
++				*(volatile unsigned int __force *)(vir_addr));
++		} else {
++			goto err_out;
++		}
++	}
++
++	return count;
++
++err_out:
++	return -EFAULT;
++}
++
++static int __init star_reg_debug_proc_init(void)
++{
++	star_reg_debug_proc_entry = create_proc_entry("str8100/reg_debug", S_IFREG | S_IRUGO, NULL);
++	if (star_reg_debug_proc_entry) {
++		star_reg_debug_proc_entry->read_proc = star_reg_debug_read_proc;
++		star_reg_debug_proc_entry->write_proc = star_reg_debug_write_proc;
++	}
++
++	return 0;
++}
++
++static int __init str8100_proc_dir_create(void)
++{
++	str8100_proc_dir = proc_mkdir("str8100", NULL);
++	if (!str8100_proc_dir) {
++		printk("Error: cannot create str8100 proc dir entry at /proc/str8100\n");
++		return -EINVAL;
++	}
++
++	if (str8100_map_desc_count) {
++		(void)star_reg_debug_proc_init();
++	}
++
++	return 0;
++}
++
++extern int __init str8100_counter_setup(void);
++static int __init str8100_misc_init(void)
++{
++	str8100_proc_dir_create();
++	str8100_counter_setup();
++	return 0;
++}
++
++module_init(str8100_misc_init);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Star Semi Corporation");
++MODULE_DESCRIPTION("STR8100 MISC");
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_pci.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_pci.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_pci.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_pci.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,337 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++//#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/init.h>
++
++#include <mach/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/mach/pci.h>
++
++#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | ((bus) << 16) | ((device_fn) << 8) | ((where) & ~3))
++
++static struct pci_dev *pci_bridge = NULL;
++static u32 pci_config_addr;				// PCI configuration register address port
++static u32 pci_config_data;				// PCI configuration register data port
++u32 str8100_pci_irqs[4] = {0, INTC_PCI_INTA_BIT_INDEX, INTC_PCI_INTB_BIT_INDEX, 0};
++
++static int str8100_pci_read_config(struct pci_bus *bus,
++	unsigned int devfn, int where, int size, u32 *val)
++{
++	u32 v = 0;
++	u32 shift;
++	unsigned long flags;
++
++	switch (size) {
++	case 1:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		v = (v >> shift) & 0xff;
++		break;
++
++	case 2:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		v = (v >> shift) & 0xffff;
++
++		break;
++
++	case 4:
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		break;
++	}
++
++	*val = v;
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int str8100_pci_write_config(struct pci_bus *bus,
++	unsigned int devfn, int where, int size, u32 val)
++{
++	u32 v;
++	u32 shift;
++	unsigned long flags;
++
++	switch (size) {
++	case 1:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		v = (v & ~(0xff << shift)) | (val << shift);
++		__raw_writel(v, pci_config_data);
++		local_irq_restore(flags);
++		break;
++
++	case 2:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		v = (v & ~(0xffff << shift)) | (val << shift);
++		__raw_writel(v, pci_config_data);
++		local_irq_restore(flags);
++		break;
++
++	case 4:
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		__raw_writel(val, pci_config_data);
++		local_irq_restore(flags);
++		break;
++	}
++
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops str8100_pci_ops = {
++	.read	= str8100_pci_read_config,
++	.write	= str8100_pci_write_config,
++};
++
++static struct resource str8100_pci_io = {
++	.name	= "PCI I/O space",
++	.start	= PCI_IO_SPACE_START,
++	.end	= PCI_IO_SPACE_END, //albert : 20040714
++	.flags	= IORESOURCE_IO,
++};
++
++static struct resource str8100_pci_nprefetch_mem = {
++	.name	= "PCI non-prefetchable",
++	.start	= PCI_NPREFETCH_MEMORY_SPACE_START,
++	.end	= PCI_NPREFETCH_MEMORY_SPACE_END,
++	.flags	= IORESOURCE_MEM,
++};
++
++static struct resource str8100_pci_prefetch_mem = {
++	.name	= "PCI prefetchable",
++	.start	= PCI_PREFETCH_MEMORY_SPACE_START,
++	.end	= PCI_PREFETCH_MEMORY_SPACE_END,
++	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
++};
++
++static int __init str8100_pci_setup_resources(struct resource **resource)
++{
++	int ret = -1;
++
++	ret = request_resource(&iomem_resource, &str8100_pci_io);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate I/O "
++		       "memory region (%d)\n", ret);
++		goto out;
++	}
++	ret = request_resource(&iomem_resource, &str8100_pci_nprefetch_mem);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
++		       "memory region (%d)\n", ret);
++		goto release_io;
++	}
++	ret = request_resource(&iomem_resource, &str8100_pci_prefetch_mem);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate prefetchable "
++		       "memory region (%d)\n", ret);
++		goto release_nprefetch_mem;
++	}
++
++	/*
++	 * bus->resource[0] is the IO resource for this bus
++	 * bus->resource[1] is the mem resource for this bus
++	 * bus->resource[2] is the prefetch mem resource for this bus
++	 */
++	resource[0] = &str8100_pci_io;
++	resource[1] = &str8100_pci_nprefetch_mem;
++	resource[2] = &str8100_pci_prefetch_mem;
++
++	ret = 0;
++
++	goto out;
++
++release_nprefetch_mem:
++	release_resource(&str8100_pci_nprefetch_mem);
++release_io:
++	release_resource(&str8100_pci_io);
++out:
++	return ret;
++}
++
++static irqreturn_t PCI_AHB2PCIB_ISR(int irq, void *dev_id /*, struct pt_regs * regs*/)
++{
++	u32 status;
++
++	//disable_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX);
++	pci_read_config_dword(pci_bridge, PCI_COMMAND, &status);
++	printk("AHB to bridge interrupt status: 0x%x\n", status);
++	pci_write_config_dword(pci_bridge, PCI_COMMAND, status);
++	//enable_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX);
++
++	return IRQ_HANDLED;
++}
++
++static irqreturn_t PCI_BROKEN_ISR(int irq, void *dev_id /*, struct pt_regs *regs*/)
++{
++	u32 status;
++
++	status = MISC_PCI_BROKEN_STATUS_REG & 0x1f;
++	printk("PCI BROKEN interrupt status: 0x%x\n", status);
++	MISC_PCI_BROKEN_STATUS_REG = status;
++
++	return IRQ_HANDLED;
++}
++
++int __init str8100_pci_setup(int nr, struct pci_sys_data *sys)
++{
++	if (nr != 0) {
++		return 0;
++	}
++
++	if (str8100_pci_setup_resources(sys->resource)) {
++		BUG();
++	}
++
++	return 1;
++}
++
++struct pci_bus * __devinit str8100_pci_scan_bus(int nr, struct pci_sys_data *sys)
++{
++	return pci_scan_bus(sys->busnr, &str8100_pci_ops, sys);
++}
++
++void __init str8100_pci_preinit(void)
++{
++	pci_config_addr = SYSVA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR + PCI_BRIDGE_CONFIG_ADDR_REG_OFFSET;
++	pci_config_data = SYSVA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR + PCI_BRIDGE_CONFIG_DATA_REG_OFFSET;
++
++	HAL_MISC_ENABLE_PCI_PINS();
++
++#ifdef  CONFIG_STR8100_PCI66M
++	printk("PCI clock at 66M\n");
++	HAL_PWRMGT_ENABLE_PCI_BRIDGE_66M_CLOCK();
++#else
++	printk("PCI clock at 33M\n");
++	HAL_PWRMGT_ENABLE_PCI_BRIDGE_33M_CLOCK();
++#endif
++}
++
++void __init str8100_pci_postinit(void)
++{
++//	pci_bridge = pci_find_device(PCIB_VENDOR_ID, PCIB_DEVICE_ID, NULL);
++	pci_bridge = pci_get_device(PCIB_VENDOR_ID, PCIB_DEVICE_ID, NULL);
++	if (pci_bridge == NULL) {
++		printk("PCI Bridge not found\n");
++		return;
++	} else {
++		printk("PCI Bridge found\n");
++	} 
++
++	/* scott.patch 
++	request_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX, PCI_AHB2PCIB_ISR, SA_INTERRUPT, "pci bridge", pci_bridge);
++	*/
++	request_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX, PCI_AHB2PCIB_ISR, IRQF_DISABLED, "pci bridge", (void*)pci_bridge);
++
++	MISC_PCI_CONTROL_BROKEN_MASK_REG &= ~0x1f;
++
++	/* scott.patch */
++	request_irq(INTC_PCI_BROKEN_BIT_INDEX, PCI_BROKEN_ISR, IRQF_DISABLED, "pci broken", pci_bridge);
++
++	//albert :20040803
++	pci_write_config_dword(pci_bridge, PCI_BASE_ADDRESS_0, 0x0); // = 0x0, can NOT use 0x20000000
++	pci_write_config_dword(pci_bridge, PCI_BASE_ADDRESS_1, 0x0); // = 0x0, can NOT use 0x20000000
++
++	// if we enable pci on u-boot
++	// the pci_enable_device will complain with resource collisions
++	// use this to fixup
++	{
++		int i;
++		struct resource *r;
++
++		for (i = 0; i < 6; i++) {
++			r = pci_bridge->resource + i;
++			r->start = 0;
++			r->end = 0;
++		}
++	}
++
++	pci_enable_device(pci_bridge);
++	pci_set_master(pci_bridge);
++
++	pci_write_config_byte(pci_bridge, PCI_CACHE_LINE_SIZE, 0x8); //configure cache line size
++	pci_write_config_byte(pci_bridge, PCI_LATENCY_TIMER, 0x30); //configure latency timer
++}
++
++/*
++ * map the specified device/slot/pin to an IRQ.   Different backplanes may need to modify this.
++ */
++static int __init str8100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++	int irq;
++
++	/* slot,  pin,	irq
++	 * 0      1     0
++	 * 1      1     5
++	 * 2      1     6
++	 * 3      1     0
++	 */
++	irq = str8100_pci_irqs[((slot + pin - 1) & 3)];
++
++	printk("PCI map irq: %02x:%02x.%02x slot %d, pin %d, irq: %d\n",
++		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
++		slot, pin, irq);
++
++	return irq;
++}
++
++static struct hw_pci str8100_pci __initdata = {
++	.swizzle		= pci_std_swizzle,
++	.map_irq		= str8100_pci_map_irq,
++	.nr_controllers		= 1,
++	.setup			= str8100_pci_setup,
++	.scan			= str8100_pci_scan_bus,
++	.preinit		= str8100_pci_preinit,
++	.postinit		= str8100_pci_postinit,
++};
++
++static int __init str8100_pci_init(void)
++{
++	pci_common_init(&str8100_pci);
++	return 0;
++}
++
++subsys_initcall(str8100_pci_init);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_pm.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_pm.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_pm.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_pm.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,162 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/pm.h>
++#include <linux/sched.h>
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/mach/time.h>
++#include <asm/mach/irq.h>
++
++#include <asm/mach-types.h>
++#include <linux/suspend.h>
++
++#ifdef CONFIG_PM
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_Cpu_Enter_Sleep_Mode
++ * PURPOSE:   
++ *
++ ******************************************************************************/
++#ifdef CONFIG_PM_DEBUG
++#define PM_DEBUG printk
++#else
++#define PM_DEBUG(_parm,...) 
++#endif
++void inline Hal_Cpu_Enter_Sleep_Mode(void)
++{
++	__asm__ volatile (
++				"nop\n"
++				"mcr	p15, 0, r0, c7, c0, 5\n");
++}
++
++static int str8100_pm_prepare(suspend_state_t state)
++{
++	int error = 0;
++	PM_DEBUG("%s: state=%d\n",__FUNCTION__,state);
++	switch (state)
++	{
++	case PM_SUSPEND_STANDBY:
++	case PM_SUSPEND_MEM:
++		break;
++
++	default:
++		return -EINVAL;
++	}
++
++	return error;
++}
++
++extern int str8100_nic_suspend(suspend_state_t);
++extern int str8100_nic_resume(void);
++static int str8100_pm_enter(suspend_state_t state)
++{
++	PM_DEBUG("%s: state=%d\n",__FUNCTION__,state);
++	switch (state)
++	{
++	case PM_SUSPEND_STANDBY:
++	case PM_SUSPEND_MEM:
++
++#ifdef DEBUG
++		/*
++		* Configure system Xtal clock to be output to CLKOUT pin
++		*/
++		HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(0, 0);
++#endif
++
++		/*
++		* 1. Disable DRAM Controller's clock
++		* 2. Power-down sytem 25MHz XTAL pad
++		* 3. Force CPU into sleep mode, and wait until wake-up interrupt happens!!
++		*    When in sleep mode, CPU internal clock and system PLLs and/or 25MHZ XTAL 
++		*    pad will be power-down!!
++		*/
++
++//int 16, 18, 28-30
++//#define WAKEUP_INT 0x70050000
++//int 16, 18, 29-30
++//#define WAKEUP_INT 0x60050000
++//int 18, 29-30
++#define WAKEUP_INT 0x60040000
++//int 29-30
++//#define WAKEUP_INT 0x60000000
++//#define WAKEUP_INT 0xffffffff
++		PM_DEBUG("%s: int that can wake cpu up, WAKEUP_INT=%.8x\n",__FUNCTION__,WAKEUP_INT);
++//		HAL_INTC_SELECT_INTERRUPT_SOURCE_FOR_SLEEP_WAKEUP(30);
++		INTC_POWER_MANAGEMENT_INTERRUPT_REG=WAKEUP_INT;
++		HAL_PWRMGT_DISABLE_DRAMC_CLOCK();
++#ifndef CONFIG_STAR_NIC_PHY_INTERNAL_PHY
++		HAL_PWRMGT_POWER_DOWN_SYSTEM_XTAL_PAD();
++#endif
++
++		PM_DEBUG("%s: bye...\n",__FUNCTION__);
++		str8100_nic_suspend(state);
++		local_irq_enable();
++		Hal_Cpu_Enter_Sleep_Mode();
++		local_irq_disable();
++		str8100_nic_resume();
++		PM_DEBUG("%s: awake from sleep\n",__FUNCTION__);
++
++		break;
++
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++}
++/*
++static int str8100_pm_finish(suspend_state_t state)
++{
++printk("%s: \n",__FUNCTION__);
++	return 0;
++}
++*/
++
++static struct platform_suspend_ops str8100_pm_ops ={
++        .prepare        = str8100_pm_prepare,
++        .enter          = str8100_pm_enter,
++//		.finish         = str8100_pm_finish,
++};
++
++static int __init str8100_pm_init(void)
++{
++	int ret;
++printk("%s: \n",__FUNCTION__);
++
++    /*
++     * Configure system Xtal clock to be output to CLKOUT pin
++     */
++	HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(0, 0);
++
++	suspend_set_ops(&str8100_pm_ops);
++	return 0;
++}
++__initcall(str8100_pm_init);
++
++
++#endif//CONFIG_PM
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_rtc.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_rtc.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_rtc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_rtc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,497 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/miscdevice.h>
++#include <linux/ioport.h>
++#include <linux/fcntl.h>
++#include <linux/init.h>
++#include <linux/poll.h>
++#include <linux/proc_fs.h>
++#include <linux/spinlock.h>
++#include <linux/sysctl.h>
++#include <linux/rtc.h>
++#include <linux/interrupt.h>
++
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/system.h>
++
++#include <mach/star_rtc.h>
++#include <mach/star_intc.h>
++
++#define STR8100_RTC_DATE       "20060628"
++#define STR8100_RTC_VERSION    "1.0.0"
++#define DEVICE_NAME            "rtc"
++#define SECS_PER_HOUR   (60 * 60)
++#define SECS_PER_DAY    (SECS_PER_HOUR * 24)
++#define TM_YEAR_BASE            1900
++#define EPOCH_YEAR              1970
++#define RTC_INTR_ALARM		0x20
++
++extern spinlock_t rtc_lock;
++
++static int rtc_busy = 0;
++static unsigned long epoch = 1900;
++static unsigned int  rtc_interrupt_flag = 0;
++static time_t local_rtc_offset, set_rtc_offset, current_rtc_time;
++static DECLARE_WAIT_QUEUE_HEAD(str8100_rtc_wait);
++
++
++# define __isleap(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
++
++static const unsigned char days_in_mo[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
++                                                                                
++static const unsigned short int __mon_yday[2][13] =
++{
++    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
++    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
++};
++
++static int offtime (const time_t *t, long int offset, struct rtc_time *tp)
++{
++    long int days, rem, y;
++    const unsigned short int *ip;
++				                                                                                
++    days = *t / SECS_PER_DAY;
++    rem = *t % SECS_PER_DAY;
++    rem += offset;
++    while (rem < 0)
++    {
++         rem += SECS_PER_DAY;
++   	 --days;
++    }
++    while (rem >= SECS_PER_DAY)
++    {
++         rem -= SECS_PER_DAY;
++  	 ++days;
++    }
++    tp->tm_hour = rem / SECS_PER_HOUR;
++    rem %= SECS_PER_HOUR;
++    tp->tm_min = rem / 60;
++    tp->tm_sec = rem % 60;
++    tp->tm_wday = (4 + days) % 7;
++    if (tp->tm_wday < 0)
++      tp->tm_wday += 7;
++    y = 1970;														                                                                                
++#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
++#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))							                                                                                
++    while (days < 0 || days >= (__isleap (y) ? 366 : 365))
++    {
++   	 long int yg = y + days / 365 - (days % 365 < 0);  
++   	 days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1)- LEAPS_THRU_END_OF (y - 1));
++   	 y = yg;
++    }
++    tp->tm_year = y - 1900;
++    if (tp->tm_year != y - 1900)
++      return 0;
++    tp->tm_yday = days;
++    ip = __mon_yday[__isleap(y)];
++    for (y = 11; days < (long int) ip[y]; --y)
++       continue;
++    days -= ip[y];
++    tp->tm_mon = y;
++    tp->tm_mday = days + 1;
++    return 1;
++}
++
++static time_t ydhms_tm_diff (int year, int yday, int hour, int min, int sec, const struct rtc_time *tp)
++{
++    if (!tp) return 1;
++    else {
++      int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
++      int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
++      int a100 = a4 / 25 - (a4 % 25 < 0);
++      int b100 = b4 / 25 - (b4 % 25 < 0);
++      int a400 = a100 >> 2;
++      int b400 = b100 >> 2;
++      int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
++      time_t years = year - (time_t) tp->tm_year;
++      time_t days = (365 * years + intervening_leap_days + (yday - tp->tm_yday));
++      return (60 * (60 * (24 * days+(hour - tp->tm_hour))+(min - tp->tm_min))+(sec - tp->tm_sec));
++    }
++}
++
++static time_t _mktime(struct rtc_time *tp, time_t *offset)
++{
++    time_t t;
++    struct rtc_time tm;
++    int sec = tp->tm_sec;
++    int min = tp->tm_min;
++    int hour = tp->tm_hour;
++    int mday = tp->tm_mday;
++    int mon = tp->tm_mon;
++    int year_requested = tp->tm_year;
++
++    int mon_remainder = mon % 12;
++    int negative_mon_remainder = mon_remainder < 0;
++    int mon_years = mon / 12 - negative_mon_remainder;
++    int year = year_requested + mon_years;
++    int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
++  	       [mon_remainder + 12 * negative_mon_remainder])
++  	       + mday - 1);
++    if (year < 69) return -1;
++    tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
++    tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
++    t = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
++    if (year == 69)
++    {
++      if (t < 0 || t > 2 * 24 * 60 * 60) return -1;
++    }
++    *tp = tm;
++    return t;
++}
++
++void get_rtc_time (struct rtc_time *rtc_tm)
++{
++    time_t update_time;	
++    
++    spin_lock (&rtc_lock);
++    update_time =  RTC_SECOND_REG + RTC_MINUTE_REG * 60 + RTC_HOUR_REG * 60 * 60 + RTC_DAY_REG * 60 * 60 * 24 - local_rtc_offset + set_rtc_offset;
++    offtime(&update_time, 0, rtc_tm);	
++    if ((rtc_tm->tm_year += (epoch - 1900)) <= 69)
++      rtc_tm->tm_year += 100; 
++    spin_unlock (&rtc_lock);
++}
++
++int set_rtc_time (struct rtc_time *rtc_tm)
++{
++    unsigned char mon, day, hrs, min, sec, leap_yr;
++    unsigned int yrs;
++    
++    spin_lock (&rtc_lock);
++    yrs = rtc_tm->tm_year + 1900;
++    mon = rtc_tm->tm_mon + 1;  
++    day = rtc_tm->tm_mday;
++    hrs = rtc_tm->tm_hour;
++    min = rtc_tm->tm_min;
++    sec = rtc_tm->tm_sec; 
++    if (yrs < 1970) return -EINVAL;
++    leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
++    if ((mon > 12) || (day == 0)) return -EINVAL;
++    if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) return -EINVAL;
++    if ((hrs >= 24) || (min >= 60) || (sec >= 60)) return -EINVAL;
++    if ((yrs -= epoch) > 255) return -EINVAL;   
++    local_rtc_offset = RTC_SECOND_REG + RTC_MINUTE_REG * 60 + RTC_HOUR_REG * 60 * 60 + RTC_DAY_REG * 60 * 60 * 24;
++    set_rtc_offset = _mktime(rtc_tm, 0);
++    spin_unlock (&rtc_lock);
++    return 0;
++}
++
++int set_rtc_alm_time (struct rtc_time *alm_tm)
++{
++    unsigned char hrs, min, sec;
++    unsigned long alm_sec;
++    unsigned int volatile rtc_int_status;
++    
++    spin_lock_irq(&rtc_lock);
++    alm_sec = alm_tm->tm_hour * 3600 + alm_tm->tm_min * 60 + alm_tm->tm_sec;
++    hrs = alm_sec / 3600;
++    min = (alm_sec % 3600) / 60;
++    sec = (alm_sec % 3600) % 60;
++    RTC_HOUR_ALARM_REG = hrs;
++    RTC_MINUTE_ALARM_REG = min;
++    RTC_SECOND_ALARM_REG = sec;
++    RTC_CONTROL_REG = RTC_MATCH_ALARM_ENABLE_BIT;
++    rtc_int_status = RTC_INTERRUPT_STATUS_REG;
++    RTC_INTERRUPT_STATUS_REG = rtc_int_status;                      
++    spin_unlock_irq(&rtc_lock);    
++    return 0;
++}
++
++static loff_t rtc_lseek(struct file *file, loff_t offset, int origin)
++{
++    return -ESPIPE;
++}
++
++static void mask_rtc_irq_bit(unsigned char bit)
++{
++    unsigned char val;
++    unsigned int volatile rtc_int_status;
++
++    spin_lock_irq(&rtc_lock);
++    val = RTC_CONTROL_REG;
++    val &=  ~bit;
++    RTC_CONTROL_REG = val;
++    rtc_int_status = RTC_INTERRUPT_STATUS_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static void set_rtc_irq_bit(unsigned char bit)
++{
++    unsigned char val;
++    unsigned int volatile rtc_int_status;	
++        
++    spin_lock_irq(&rtc_lock);
++    val = RTC_CONTROL_REG;
++    val |= bit;
++    RTC_CONTROL_REG = val;
++    rtc_int_status = RTC_INTERRUPT_STATUS_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static void get_rtc_alm_time(struct rtc_time *alm_tm)
++{
++    spin_lock_irq(&rtc_lock);
++    alm_tm->tm_sec = RTC_SECOND_ALARM_REG;
++    alm_tm->tm_min = RTC_MINUTE_ALARM_REG;
++    alm_tm->tm_hour = RTC_HOUR_ALARM_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg)
++{
++    struct rtc_time wtime; 
++
++    switch (cmd)
++    {
++	case RTC_RD_TIME:
++	        memset(&wtime, 0, sizeof(struct rtc_time));
++		get_rtc_time(&wtime);
++		break;
++	case RTC_SET_TIME:
++	{         
++		struct rtc_time rtc_tm;
++		if (!capable(CAP_SYS_TIME))
++		  return -EPERM;
++		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
++		  return -EFAULT;
++		set_rtc_time(&rtc_tm);
++		return 0;
++	}	
++        case RTC_ALM_SET:
++        {
++        	struct rtc_time alm_tm; 
++		if (copy_from_user(&alm_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
++		  return -EFAULT;
++		memset(&wtime, 0, sizeof(struct rtc_time));  
++		set_rtc_alm_time(&alm_tm);
++		return 0;
++	}	
++	case RTC_ALM_READ:
++	        memset(&wtime, 0, sizeof(struct rtc_time));
++		get_rtc_alm_time(&wtime);
++		break;
++	case RTC_AIE_OFF:
++	        mask_rtc_irq_bit(RTC_INTR_ALARM);	
++		return 0;
++	case RTC_AIE_ON:
++	        set_rtc_irq_bit(RTC_INTR_ALARM);
++		return 0;	
++	default:
++		return -EINVAL;
++    }
++    return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
++}
++
++// Eileen , for linux kernel 2.6.24 , 20080417
++// old : static irqreturn_t rtc_fire(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t rtc_fire(int irq, void *dev_id)
++{
++    unsigned int volatile    rtc_int_status;	
++    
++    HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_RTC_BIT_INDEX);
++    HAL_RTC_READ_INTERRUPT_STATUS(rtc_int_status);
++    HAL_RTC_WRITE_INTERRUPT_STATUS(rtc_int_status);
++//    HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_RTC_BIT_INDEX);
++//    return IRQ_HANDLED; 
++    if (rtc_int_status & RTC_AUTO_SECOND_ALARM_INTR_BIT) rtc_interrupt_flag |= RTC_AUTO_SECOND_ALARM_INTR_BIT;
++    if (rtc_int_status & RTC_AUTO_MINUTE_ALARM_INTR_BIT) rtc_interrupt_flag |= RTC_AUTO_MINUTE_ALARM_INTR_BIT;
++    if (rtc_int_status & RTC_AUTO_HOUR_ALARM_INTR_BIT) rtc_interrupt_flag |= RTC_AUTO_HOUR_ALARM_INTR_BIT;
++    if (rtc_int_status & RTC_AUTO_DAY_ALARM_INTR_BIT) rtc_interrupt_flag |= RTC_AUTO_DAY_ALARM_INTR_BIT;
++    if (rtc_int_status & RTC_MATCH_ALARM_INTR_BIT) {rtc_interrupt_flag |= RTC_MATCH_ALARM_INTR_BIT;
++      wake_up_interruptible(&str8100_rtc_wait);
++    }
++    if (rtc_int_status & RTC_BATTERY_LOW_VOLTAGE_INTR_BIT)
++    {
++    	rtc_interrupt_flag |= RTC_BATTERY_LOW_VOLTAGE_INTR_BIT;
++        printk(" str8100 rtc: Low Battery Voltage!!\n");
++    }
++    if (!(rtc_interrupt_flag & RTC_MATCH_ALARM_INTR_BIT)) HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_RTC_BIT_INDEX);
++
++    return IRQ_HANDLED; 
++}
++
++static void rtc_str8100_hwinit(int ctrl, int hour, int min, int sec)
++{    	
++    RTC_CONTROL_REG &= ~(RTC_ENABLE_BIT);	
++    if (ctrl & RTC_MATCH_ALARM_ENABLE_BIT)
++    {
++      RTC_SECOND_ALARM_REG = sec;
++      RTC_MINUTE_ALARM_REG = min;
++      RTC_HOUR_ALARM_REG = hour;    	
++    }else{
++      RTC_SECOND_ALARM_REG = 0;
++      RTC_MINUTE_ALARM_REG = 0;
++      RTC_HOUR_ALARM_REG = 0;
++    } 
++    RTC_CONTROL_REG = ctrl;
++} 
++
++static int rtc_open(struct inode *inode, struct file *file)
++{
++    if (rtc_busy) return -EBUSY;
++
++    rtc_busy = 1;
++    return 0;
++}
++
++static ssize_t rtc_read(struct file * file, char *buf, size_t count, loff_t * ppos)
++{
++    DECLARE_WAITQUEUE(wait, current);
++    unsigned long data;
++    ssize_t retval;
++
++    if (count < sizeof(unsigned long))
++      return -EINVAL;
++
++    add_wait_queue(&str8100_rtc_wait, &wait);
++    set_current_state(TASK_INTERRUPTIBLE);
++    for (;;) {
++	spin_lock(&rtc_lock);
++	data = rtc_interrupt_flag;
++	if (data != 0) {
++	  rtc_interrupt_flag = 0;
++	  break;
++	}
++        spin_unlock(&rtc_lock);
++        if (file->f_flags & O_NONBLOCK) {
++	  retval = -EAGAIN;
++	  goto out;
++	}
++	if (signal_pending(current)) {
++	  retval = -ERESTARTSYS;
++	  goto out;
++	}
++        schedule();
++    }
++    spin_unlock(&rtc_lock);
++    retval = put_user(data, (unsigned long *) buf);
++    if (!retval) retval = sizeof(unsigned long);
++out:
++    mask_rtc_irq_bit(RTC_INTR_ALARM);
++    set_current_state(TASK_RUNNING);
++    remove_wait_queue(&str8100_rtc_wait, &wait);
++    return retval;
++}
++
++static int rtc_release(struct inode *inode, struct file *file)
++{
++    rtc_busy = 0;
++    return 0;
++}
++
++static struct file_operations rtc_fops = {
++    owner:	THIS_MODULE,
++    llseek:	rtc_lseek,
++    ioctl:	rtc_ioctl,
++    open:	rtc_open,
++    read:       rtc_read,
++    release:	rtc_release
++};
++
++static struct miscdevice rtc_dev = { RTC_MINOR, "rtc", &rtc_fops };
++
++static int rtc_proc_output (char *buf)
++{
++    char *p;
++    struct rtc_time tm;
++    
++    p = buf;
++    get_rtc_time(&tm);
++    p += sprintf(p,"rtc_time\t: %02d:%02d:%02d\n"
++		   "rtc_date\t: %04d-%02d-%02d\n"
++	 	   "rtc_epoch\t: %04lu\n",
++		   tm.tm_hour, tm.tm_min, tm.tm_sec,
++		   tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
++    get_rtc_alm_time(&tm);
++    p += sprintf(p, "alarm\t\t: ");
++    if (tm.tm_hour <= 24)
++      p += sprintf(p, "%02d:", tm.tm_hour);
++    else
++      p += sprintf(p, "**:");
++    if (tm.tm_min <= 59)
++      p += sprintf(p, "%02d:", tm.tm_min);
++    else
++      p += sprintf(p, "**:");
++    if (tm.tm_sec <= 59)
++      p += sprintf(p, "%02d\n", tm.tm_sec);
++    else
++      p += sprintf(p, "**\n");	
++    return  p - buf;
++}
++
++static int rtc_read_proc(char *page, char **start, off_t off,int count, int *eof, void *data)
++{
++    int len = rtc_proc_output (page);
++    
++    if (len <= off+count) *eof = 1;
++    *start = page + off;
++    len -= off;
++    if (len>count) len = count;
++    if (len<0) len = 0;
++    return len;
++}
++
++static int __init str8100_rtc_init(void)
++{
++    int error;
++
++    error = misc_register(&rtc_dev);
++    if (error) {
++      printk(KERN_ERR "rtc: unable to get misc minor\n");
++      return error;
++    }	
++    printk(KERN_INFO "str8100_rtc.o: rtc module version %s\n", STR8100_RTC_VERSION);
++    rtc_str8100_hwinit(0,0,0,0);
++    HAL_RTC_ENABLE();
++    request_irq(INTC_RTC_BIT_INDEX, rtc_fire, 0, DEVICE_NAME, NULL);
++    create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
++    local_rtc_offset = 0;
++    set_rtc_offset = current_rtc_time = 0;        
++    return 0;
++}
++
++static void __exit str8100_rtc_exit (void)
++{
++    char buf[64];
++    	
++    HAL_RTC_DISABLE();		
++    // Eileen , for linux kernel 2.6.24 , 20080417
++    // cleanup_sysctl();
++    sprintf (buf,"driver/%s",DEVICE_NAME);
++    remove_proc_entry (buf, NULL);
++    misc_deregister(&rtc_dev);
++    free_irq (INTC_RTC_BIT_INDEX, NULL);
++}
++
++module_init(str8100_rtc_init);
++module_exit(str8100_rtc_exit);
++// Eileen , for linux kernel 2.6.24 , 20080417
++//EXPORT_NO_SYMBOLS;
++
++MODULE_AUTHOR("Rober Hsu");
++MODULE_LICENSE("GPL");
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_setup.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_setup.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_setup.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_setup.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,569 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/mm.h>
++#include <linux/init.h>
++//#include <linux/config.h>
++#include <linux/major.h>
++#include <linux/fs.h>
++#include <linux/platform_device.h>
++#include <linux/serial.h>
++#include <linux/tty.h>
++#include <linux/serial_8250.h>
++#ifdef CONFIG_SPI_STR8100
++#include <mach/star_spi.h>
++#include <linux/spi/spi.h>
++#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
++#include <linux/spi/flash.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#endif
++#endif // CONFIG_SPI_STR8100
++
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++#include <asm/mach/map.h>
++#include <asm/setup.h>
++#include <asm/system.h>
++#include <asm/memory.h>
++#include <mach/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++
++
++
++#if 1 // on ASIC
++#define STR8100_UART_XTAL 24000000
++#else // on FPGA
++#define STR8100_UART_XTAL 13000000
++#endif
++
++#define EARLY_REGISTER_CONSOLE
++#define DEVICE_REGISTER_MULTIPLE
++
++/*
++ * Standard IO mapping
++ */
++static struct map_desc str8100_std_desc[] __initdata = {
++	{
++		.virtual	= SYSVA_FLASH_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_FLASH_SRAM_BANK0_BASE_ADDR),
++		.length		= SZ_8M,
++		.type		= MT_DEVICE
++	}, 	{
++		.virtual	= SYSVA_IDE_DEVICE_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_IDE_DEVICE_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_GDMAC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_GDMAC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_NIC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_NIC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_SPI_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_SPI_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCM_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCM_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_I2C_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_I2C_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_I2S_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_I2S_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_DDRC_SDRC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_DDRC_SDRC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_SMC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_SMC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_IDE_CONTROLLER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_IDE_CONTROLLER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_MISC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_MISC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_POWER_MANAGEMENT_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_POWER_MANAGEMENT_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_UART0_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_UART0_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_UART1_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_UART1_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_TIMER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_TIMER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_WATCHDOG_TIMER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_WATCHDOG_TIMER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_RTC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_RTC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_GPIOA_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_GPIOA_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_GPIOB_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_GPIOB_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB11_CONFIG_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB11_CONFIG_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB11_OPERATION_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB11_OPERATION_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB20_CONFIG_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB20_CONFIG_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB20_OPERATION_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB20_OPERATION_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB20_DEVICE_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB20_DEVICE_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_VIC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_VIC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}
++};
++
++#ifdef EARLY_REGISTER_CONSOLE
++static struct uart_port str8100_serial_ports[] = {
++	{
++		.membase	= (char*)(SYSVA_UART0_BASE_ADDR),
++		.mapbase	= (SYSPA_UART0_BASE_ADDR),
++		.irq		= INTC_UART0_BIT_INDEX,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++		.iotype		= UPIO_MEM,
++		.regshift	= 2,
++		.uartclk	= STR8100_UART_XTAL,
++		.line		= 0,
++		.type		= PORT_16550A,
++		.fifosize	= 16
++	} , {
++		.membase	= (char*)(SYSVA_UART1_BASE_ADDR),
++		.mapbase	= (SYSPA_UART1_BASE_ADDR),
++		.irq		= INTC_UART1_BIT_INDEX,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++		.iotype		= UPIO_MEM,
++		.regshift	= 2,
++		.uartclk	= STR8100_UART_XTAL,
++		.line		= 1,
++		.type		= PORT_16550A,
++		.fifosize	= 16
++	}
++};
++#else
++static struct resource str8100_uart0_resources[] = {
++	[0] = {
++		.start	= SYSPA_UART0_BASE_ADDR,
++		.end	= SYSPA_UART0_BASE_ADDR + 0xff,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_UART0_BIT_INDEX,
++		.end	= INTC_UART0_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ
++	}
++};
++
++static struct resource str8100_uart1_resources[] = {
++	[0] = {
++		.start	= SYSPA_UART1_BASE_ADDR,
++		.end	= SYSPA_UART1_BASE_ADDR + 0xff,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_UART1_BIT_INDEX,
++		.end	= INTC_UART1_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ
++	}
++};
++
++static struct plat_serial8250_port str8100_uart0_data[] = {
++	{
++		.membase	= (char*)(SYSVA_UART0_BASE_ADDR),
++		.mapbase	= (SYSPA_UART0_BASE_ADDR),
++		.irq		= INTC_UART0_BIT_INDEX,
++		.uartclk	= STR8100_UART_XTAL,
++		.regshift	= 2,
++		.iotype		= UPIO_MEM,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++	},
++	{  },
++};
++
++static struct plat_serial8250_port str8100_uart1_data[] = {
++	{
++		.membase	= (char*)(SYSVA_UART1_BASE_ADDR),
++		.mapbase	= (SYSPA_UART1_BASE_ADDR),
++		.irq		= INTC_UART1_BIT_INDEX,
++		.uartclk	= STR8100_UART_XTAL,
++		.regshift	= 2,
++		.iotype		= UPIO_MEM,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++	},
++	{  },
++};
++
++static struct platform_device str8100_uart0_device = {
++	.name = "serial8250",
++	.id = 0,
++	.dev.platform_data = str8100_uart0_data,
++	.num_resources = 2,
++	.resource = str8100_uart0_resources,
++};
++
++static struct platform_device str8100_uart1_device = {
++	.name = "serial8250",
++	.id = 1,
++	.dev.platform_data = str8100_uart1_data,
++	.num_resources = 2,
++	.resource = str8100_uart1_resources,
++};
++#endif
++
++
++static u64 usb_dmamask = 0xffffffffULL;
++static struct resource str8100_usb11_resources[] = {
++	[0] = {
++		.start	= SYSPA_USB11_CONFIG_BASE_ADDR,
++		.end	= SYSPA_USB11_CONFIG_BASE_ADDR + SZ_1M - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_USB11_BIT_INDEX,
++		.end	= INTC_USB11_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device str8100_usb11_device = {
++	.name		= "str8100-ohci",
++	.id		= -1,
++	.dev = {
++		.dma_mask		= &usb_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.resource	= str8100_usb11_resources,
++	.num_resources	= ARRAY_SIZE(str8100_usb11_resources),
++};
++
++static struct resource str8100_usb20_resources[] = {
++	[0] = {
++		.start	= SYSPA_USB20_CONFIG_BASE_ADDR,
++		.end	= SYSPA_USB20_CONFIG_BASE_ADDR + SZ_1M - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_USB20_BIT_INDEX,
++		.end	= INTC_USB20_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device str8100_usb20_device = {
++	.name		= "str8100-ehci",
++	.id		= -1,
++	.dev		= {
++		.dma_mask		= &usb_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.resource	= str8100_usb20_resources,
++	.num_resources	= ARRAY_SIZE(str8100_usb20_resources),
++};
++
++#ifdef CONFIG_SPI_STR8100
++#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
++static struct mtd_partition str8100_spi_flash_partitions[] = {
++	{
++		.name =		"all",
++		.offset =	CONFIG_ARMBOOT_OFFSET,
++		.size =		0x800000-CONFIG_ARMBOOT_OFFSET,
++	},{
++		.name =		"ARMBOOT",
++		.offset =	CONFIG_ARMBOOT_OFFSET,
++		.size =		CONFIG_KERNEL_OFFSET-CONFIG_ARMBOOT_OFFSET,
++	},{
++		.name =		"Linux Kernel",
++		.offset =	CONFIG_KERNEL_OFFSET,
++		.size =		CONFIG_ROOTFS_OFFSET-CONFIG_KERNEL_OFFSET,
++	},{
++		.name =		"MTD Disk1",
++		.offset =	CONFIG_ROOTFS_OFFSET,
++		.size =		CONFIG_CFG_OFFSET-CONFIG_ROOTFS_OFFSET,
++	},{
++		.name =		"MTD Disk2",
++		.offset =	CONFIG_CFG_OFFSET,
++		.size =		0x800000-CONFIG_CFG_OFFSET,
++	}
++};
++
++static struct flash_platform_data str8100_spi_flash_data = {
++	.name = "m25p80",
++	.parts = str8100_spi_flash_partitions,
++	.nr_parts = ARRAY_SIZE(str8100_spi_flash_partitions),
++	.type = "m25p64",
++};
++
++#if defined(CONFIG_LE88221_CONTROL)
++static struct str8100_spi_dev_attr str8100_spi_le88221_attr = {
++	.spi_serial_mode = STR8100_SPI_SERIAL_MODE_MICROPROCESSOR,
++};
++#endif
++
++static struct spi_board_info str8100_spi_board_info[] = {
++        {
++		.modalias	= "m25p80",
++		.chip_select	= 0,
++		.max_speed_hz	= 25 * 1000 * 1000,
++		.bus_num	= 1,
++		.platform_data = &str8100_spi_flash_data,
++        },
++
++#if defined(CONFIG_LE88221_CONTROL)
++	{
++		.modalias	= "le88221",
++		.chip_select	= 1,
++		.max_speed_hz	= 25 * 1000 * 1000,
++		.bus_num	= 1,
++		.platform_data	= NULL,
++		.controller_data = &str8100_spi_le88221_attr,
++        },
++#endif
++};
++#endif
++
++static u64 spi_dmamask = 0xffffffffUL;
++static struct resource str8100_spi_resources[] = {
++	[0] = {
++		.start	= SYSPA_SPI_BASE_ADDR,
++		.end	= SYSPA_SPI_BASE_ADDR + SZ_4K - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_SPI_BIT_INDEX,
++		.end	= INTC_SPI_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device str8100_spi_master_device = {
++	.name		= "str8100_spi",
++	.id		= -1,
++	.dev		= {
++		.dma_mask		= &spi_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.resource	= str8100_spi_resources,
++	.num_resources	= ARRAY_SIZE(str8100_spi_resources),
++};
++#endif // CONFIG_SPI_STR8100
++
++#ifdef DEVICE_REGISTER_MULTIPLE
++static struct platform_device *str8100_devices[] __initdata = {
++#ifndef EARLY_REGISTER_CONSOLE
++	&str8100_uart0_device,
++	&str8100_uart1_device,
++#endif
++#ifdef CONFIG_SPI_STR8100
++	&str8100_spi_master_device,
++#endif
++	&str8100_usb11_device,
++	&str8100_usb20_device
++};
++#endif
++
++static void __init str8100_fixup(struct machine_desc *desc,
++	struct tag *tags, char **cmdline, struct meminfo *mi)
++{      
++   mi->nr_banks = 1;
++	mi->bank[0].start = CONFIG_SYSTEM_DRAM_BASE;
++	mi->bank[0].size = CONFIG_SYSTEM_DRAM_SIZE << 20;
++	//mi->bank[0].node = 0;
++}
++
++/* ######################################################################### */
++#ifdef CONFIG_CPU_ISPAD_ENABLE 
++extern unsigned long __ispad_begin; 
++#endif
++u32 PLL_clock;
++u32 CPU_clock;
++u32 AHB_clock;
++u32 APB_clock;
++EXPORT_SYMBOL(PLL_clock);
++EXPORT_SYMBOL(CPU_clock);
++EXPORT_SYMBOL(AHB_clock);
++EXPORT_SYMBOL(APB_clock);
++// This function is called just after the
++// page table and cpu have been initialized
++
++#include "asm/procinfo.h"
++#include "asm/cacheflush.h"
++#include "asm/system.h"
++void __init str8100_early_init(void)
++{
++   //printk("str8100_early_init()\n");
++        
++	switch (PWRMGT_SYSTEM_CLOCK_CONTROL_REG & 0x3) {
++	case 0x0:
++		PLL_clock = 175000000;
++		break;
++	case 0x1:
++		PLL_clock = 200000000;
++		break;
++	case 0x2:
++		PLL_clock = 225000000;
++		break;
++	case 0x3:
++		PLL_clock = 250000000;
++		break;
++	}
++
++	CPU_clock = PLL_clock / (((PWRMGT_SYSTEM_CLOCK_CONTROL_REG >> 2) & 0x3) + 1);
++	AHB_clock = CPU_clock / (((PWRMGT_SYSTEM_CLOCK_CONTROL_REG >> 4) & 0x3) + 1);
++	APB_clock = AHB_clock / (((PWRMGT_SYSTEM_CLOCK_CONTROL_REG >> 8) & 0x3) + 1);
++
++	printk("PLL clock at %dMHz\n", PLL_clock / 1000000);
++	printk("CPU clock at %dMHz\n", CPU_clock / 1000000);
++	printk("AHB clock at %dMHz\n", AHB_clock / 1000000);
++	printk("APB clock at %dMHz\n", APB_clock / 1000000);
++}
++/* ######################################################################### */
++
++void __init str8100_init(void)
++{
++//   printk("str8100_init()\n");
++   
++#ifdef DEVICE_REGISTER_MULTIPLE
++	platform_add_devices(str8100_devices, ARRAY_SIZE(str8100_devices));
++#ifdef CONFIG_SPI_STR8100
++#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
++	spi_register_board_info(str8100_spi_board_info, ARRAY_SIZE(str8100_spi_board_info));
++#endif
++#endif // CONFIG_SPI_STR8100
++#else // DEVICE_REGISTER_MULTIPLE
++#ifndef EARLY_REGISTER_CONSOLE
++	platform_device_register(&str8100_uart0_device);
++	platform_device_register(&str8100_uart1_device);
++#endif
++#ifdef CONFIG_SPI_STR8100
++	platform_device_register(&str8100_spi_master_device);
++#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
++	spi_register_board_info(str8100_spi_board_info, ARRAY_SIZE(str8100_spi_board_info));
++#endif
++#endif
++	platform_device_register(&str8100_usb11_device);
++	platform_device_register(&str8100_usb20_device);
++#endif
++}
++
++extern void str8100_register_map_desc(struct map_desc *map, int count);
++void __init str8100_map_io(void)
++{
++//   printk("str8100_map_io()\n");
++   
++	iotable_init(str8100_std_desc, ARRAY_SIZE(str8100_std_desc));
++	str8100_register_map_desc(str8100_std_desc, ARRAY_SIZE(str8100_std_desc));
++#ifdef EARLY_REGISTER_CONSOLE
++	early_serial_setup(&str8100_serial_ports[0]);
++	early_serial_setup(&str8100_serial_ports[1]);
++#endif
++}
++
++extern void str8100_init_irq(void);
++extern struct sys_timer str8100_timer;
++
++MACHINE_START(STR8100, "STAR STR8100")
++	.phys_io	= SYSPA_UART0_BASE_ADDR,
++	.io_pg_offst	= ((SYSVA_UART0_BASE_ADDR) >> 18) & 0xfffc, // virtual, physical
++	.fixup		= str8100_fixup,
++	.map_io		= str8100_map_io,
++	.init_irq	= str8100_init_irq,
++	.timer		= &str8100_timer,
++	.boot_params	= 0x0100,
++	.init_machine	= str8100_init,
++MACHINE_END
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str8100/str8100_timer.c linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_timer.c
+--- linux-2.6.35.11/arch/arm/mach-str8100/str8100_timer.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str8100/str8100_timer.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,224 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/init.h>
++#include <linux/timex.h>
++
++#include <mach/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/time.h>
++
++#if 1
++// for timer clock < 100MHz
++#define uSECS_PER_TICK	(1000000 / APB_clock)
++#define TICKS2USECS(x)  ((x) * uSECS_PER_TICK)
++#else
++// for timer clock >= 100MHz
++#define TICKS_PER_uSEC	(APB_clock / 1000000)
++#define TICKS2USECS(x)  ((x) / TICKS_PER_uSEC)
++#endif
++
++extern u32 APB_clock;
++static u32 timer_counter_value;
++
++static inline unsigned int str8100_read_timer_counter(void)
++{
++	return TIMER1_COUNTER_REG;
++}
++
++static inline unsigned int str8100_read_timer_interrupt_status(void)
++{
++	return TIMER1_TIMER2_INTERRUPT_STATUS_REG;
++}
++
++static inline void str8100_clear_timer_interrupt_status(unsigned int irq)
++{
++	TIMER1_TIMER2_INTERRUPT_STATUS_REG &= ~(1 << TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX);
++}
++
++static void str8100_setup_timer(unsigned int counter_value)
++{
++	unsigned long control_value;
++	unsigned long mask_value;    
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++	mask_value = TIMER1_TIMER2_INTERRUPT_MASK_REG;
++
++	TIMER1_COUNTER_REG = counter_value;
++	TIMER1_AUTO_RELOAD_VALUE_REG = counter_value;
++	TIMER1_MATCH_VALUE1_REG = 0;
++	TIMER1_MATCH_VALUE2_REG = 0;
++
++	// Clock Source: PCLK
++	control_value &= ~(1 << TIMER1_CLOCK_SOURCE_BIT_INDEX);
++
++	// Down Count Mode
++	control_value |= (1 << TIMER1_UP_DOWN_COUNT_BIT_INDEX);
++
++	// un-mask overflow, match2 and match1 interrupt sources
++	mask_value &= ~(0x7);
++
++	// mask match2 and match1 interrupt sources
++	mask_value |= 0x03;
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++	TIMER1_TIMER2_INTERRUPT_MASK_REG = mask_value;
++}
++
++static void str8100_timer_enable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++
++	// enable overflow mode
++	control_value |= (1 << TIMER1_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value |= (1 << TIMER1_ENABLE_BIT_INDEX);
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++}
++
++static void str8100_timer_disable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER1_TIMER2_CONTROL_REG;
++
++	// disable overflow mode
++	control_value &= ~(1 << TIMER1_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// disable the timer
++	control_value &= ~(1 << TIMER1_ENABLE_BIT_INDEX);
++
++	TIMER1_TIMER2_CONTROL_REG = control_value;
++}
++
++/*
++ * Returns number of us since last clock interrupt.  Note that interrupts
++ * will have been disabled by do_gettimeoffset()
++ */
++static unsigned long str8100_gettimeoffset(void)
++{
++	unsigned long ticks1, ticks2;
++	unsigned long interrupt_status;
++
++	/*
++	 * Get the current number of ticks.  Note that there is a race
++	 * condition between us reading the timer and checking for
++	 * an interrupt.  We get around this by ensuring that the
++	 * counter has not reloaded between our two reads.
++	 */
++	ticks2 = str8100_read_timer_counter();
++	do {
++		ticks1 = ticks2;
++		interrupt_status = str8100_read_timer_interrupt_status();
++		ticks2 = str8100_read_timer_counter();
++	} while (ticks2 > ticks1);
++
++	/*
++	 * Number of ticks since last interrupt
++	 */
++	ticks1 = timer_counter_value - ticks2;
++
++	/*
++	 * Interrupt pending?  If so, we've reloaded once already.
++	 */
++	if (interrupt_status) {
++		ticks1 += timer_counter_value;
++	}
++
++	/*
++	 * Convert the ticks to usecs
++	 */
++	return TICKS2USECS(ticks1);
++}
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t
++str8100_timer_interrupt(int irq, void *dev_id /*, struct pt_regs *regs*/)
++{     
++  		
++#ifndef CONFIG_VIC_INTERRUPT
++	str8100_clear_timer_interrupt_status((unsigned int)irq);
++#endif
++	/* scot.patch
++	timer_tick(regs);
++	*/
++	timer_tick();
++		
++	return IRQ_HANDLED;
++}
++
++static struct irqaction str8100_timer_irq = {
++	.name		= "STR8100 Timer Tick",
++/* scott.patch
++	.flags		= SA_INTERRUPT | SA_TIMER,
++*/
++	.flags		= IRQF_DISABLED | IRQF_TIMER, 
++	.handler	= str8100_timer_interrupt,
++};
++
++/*
++ * Set up timer interrupt, and return the current time in seconds.
++ */
++ 
++
++static void __init str8100_timer_init(void)
++{
++	/*
++	 * prepare timer-related values
++	 */
++	timer_counter_value = APB_clock / HZ;
++
++	/*
++	 * setup timer-related values
++	 */
++	str8100_setup_timer(timer_counter_value);
++
++	
++	/*
++	 * Make irqs happen for the system timer
++	 */
++	setup_irq(INTC_TIMER1_BIT_INDEX, &str8100_timer_irq);
++
++	str8100_timer_enable();
++		
++	
++}
++
++struct sys_timer str8100_timer = {
++	.init		= str8100_timer_init,
++#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET	
++	.offset		= str8100_gettimeoffset,
++#endif	
++};
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/Kconfig linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Kconfig
+--- linux-2.6.35.11/arch/arm/mach-str9100/Kconfig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,99 @@
++if ARCH_STR9100
++
++menu "STR9100 Options"
++
++config CONSOLE_BAUD_RATE
++	int "Console Baud Rate"
++	default 115200
++	help
++	  set the console baudrate
++
++config CPU_ISPAD_ENABLE
++	bool "Enable I-Scratch Pad Support"
++	default y
++	help
++	  enable I-Scratch Pad support
++
++choice
++	prompt "DRAM SIZE"
++	default STR9100_DRAM_16M
++
++config STR9100_DRAM_16M
++	bool "16MBytes"
++
++config STR9100_DRAM_32M
++	bool "32MBytes"
++
++config STR9100_DRAM_64M
++	bool "64MBytes"
++
++endchoice
++
++if PCI
++choice
++	prompt "PCI Frequency"
++	default STAR9100_PCI33M
++
++config STR9100_PCI33M
++	bool "PCI_33Mhz"
++
++config STR9100_PCI66M
++	bool "PCI_66Mhz"
++
++endchoice
++endif
++
++config STR9100_RTC
++	bool "STR9100 Real Time Clock Support"
++
++config STR9100_GPIO
++	bool "STR9100 GPIO Support"
++
++config STR9100_GPIO_INTERRUPT
++	bool "Interrupt Library Support"
++	depends on STR9100_GPIO
++
++config STR9100_INFO
++	bool "STR9100 Infomation at /proc/str9100/info"
++
++comment "Flash MAP"
++config STR9100_FLASH_PART
++	bool "STR9100 flash partition setting"
++
++if STR9100_FLASH_PART
++	config ARMBOOT_OFFSET
++	hex "ARMBOOT OFFSET"
++	default 0x0
++	help
++	  The armboot start offset in flash layout
++
++	config KERNEL_OFFSET
++	hex "KERNEL OFFSET"
++	default 0x40000
++	help
++	  The kernel start offset in flash layout
++
++	config ROOTFS_OFFSET
++	hex "ROOTFS OFFSET"
++	default 0x140000
++	help
++	  The rootfs start offset in flash layout
++
++	config CFG_OFFSET
++	hex "CFG OFFSET"
++	default 0x7f0000
++	help
++	  The cfg start offset in flash layout
++endif
++
++comment "Third Party Support"
++
++config STR9100_EWC_SUPPORT
++	bool "EWC(802.11N) Support"
++
++config SWITCH_IOCTL
++	bool "SUPPORT SWITCH IOCTL"
++
++endmenu
++
++endif
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/Makefile linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Makefile
+--- linux-2.6.35.11/arch/arm/mach-str9100/Makefile	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,14 @@
++#
++# Makefile for the linux kernel.
++#
++
++# Object file lists.
++
++obj-y			:= str9100_debug.o str9100_setup.o str9100_timer.o str9100_intc.o str9100_counter.o str9100_misc.o
++obj-m			:=
++obj-n			:=
++obj-			:=
++
++obj-$(CONFIG_PCI) += str9100_pci.o
++obj-$(CONFIG_STR9100_GPIO)	+= str9100_gpio.o
++obj-$(CONFIG_STR9100_RTC)	+= str9100_rtc.o
+\ No newline at end of file
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/Makefile.boot linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Makefile.boot
+--- linux-2.6.35.11/arch/arm/mach-str9100/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/Makefile.boot	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,10 @@
++# Note: the following conditions must always be true:
++#   ZRELADDR == virt_to_phys(TEXTADDR)
++#   PARAMS_PHYS must be within 4MB of ZRELADDR
++#   INITRD_PHYS must be in RAM
++
++   zreladdr-y	:= 0x00008000
++params_phys-y	:= 0x00000100
++initrd_phys-y	:= 0x00C00000
++kernel_phys-y	:= 0x00400000
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_counter.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_counter.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_counter.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_counter.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,214 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/init.h>
++#include <linux/timex.h>
++#include <linux/proc_fs.h>
++#include <linux/module.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/time.h>
++
++u64 volatile str9100_counter_tick;
++EXPORT_SYMBOL(str9100_counter_tick);
++
++static struct proc_dir_entry *str9100_counter_proc_entry;
++
++#if 0
++// this is defined in include/asm/arch-str9100/system.h
++u64 str9100_read_counter(void)
++{
++	return (str9100_counter_tick + TIMER2_COUNTER_REG);
++}
++EXPORT_SYMBOL(str9100_read_counter);
++#endif
++
++static int match1=0;
++static int match2=0;
++static void str9100_setup_counter(void)
++{
++	unsigned long control_value;
++	unsigned long mask_value;    
++	unsigned long val;    
++
++	control_value = TIMER_CONTROL_REG;
++	mask_value = TIMER_INTERRUPT_MASK_REG;
++
++	TIMER2_COUNTER_REG		= 0;
++	TIMER2_AUTO_RELOAD_VALUE_REG	= 0;
++	TIMER2_MATCH_VALUE1_REG		= match1;
++	TIMER2_MATCH_VALUE2_REG		= match2;
++
++	// Clock Source: PCLK
++	control_value &= ~(1 << TIMER2_CLOCK_SOURCE_BIT_INDEX);
++
++	// UP Count Mode
++	control_value &= ~(1 << TIMER2_UP_DOWN_COUNT_BIT_INDEX);
++
++	// un-mask match1, match2, and overflow interrupt sources
++	mask_value &= ~(0x7 << 3);
++
++	// mask match1, match2 interrupt sources
++	//mask_value |= (0x3 << 3);
++	val=0;
++	if(!match1) val|=0x1;
++	if(!match2) val|=0x2;
++	mask_value |= (val<< 3);
++
++	TIMER_CONTROL_REG = control_value;
++	TIMER_INTERRUPT_MASK_REG = mask_value;
++}
++
++static void str9100_counter_enable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER_CONTROL_REG;
++
++	// enable overflow mode
++	control_value |= (1 << TIMER2_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value |= (1 << TIMER2_ENABLE_BIT_INDEX);
++
++	TIMER_CONTROL_REG = control_value;
++}
++
++static void str9100_counter_disable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER_CONTROL_REG;
++
++	// enable overflow mode
++	control_value &= ~(1 << TIMER2_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value &= ~(1 << TIMER2_ENABLE_BIT_INDEX);
++
++	TIMER_CONTROL_REG = control_value;
++}
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t
++str9100_counter_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	// clear counter interrrupt status
++	TIMER_INTERRUPT_STATUS_REG &= ~(1 << TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX);
++	str9100_counter_tick += (1ULL << 32);
++	if(match1){
++		TIMER2_MATCH_VALUE1_REG=TIMER2_COUNTER_REG+match1;
++		TIMER_INTERRUPT_MASK_REG |= (0x1<<3);
++	}
++	if(match2){
++		TIMER2_MATCH_VALUE2_REG=TIMER2_COUNTER_REG+match2;
++		TIMER_INTERRUPT_MASK_REG |= (0x2<<3);
++	}
++	return IRQ_HANDLED;
++}
++
++static struct irqaction str9100_counter_irq = {
++	.name		= "STR9100 Counter Tick",
++	/* scott.patch */
++	.flags		= IRQF_DISABLED | IRQF_TIMER,
++	.handler	= str9100_counter_interrupt,
++};
++
++static int str9100_counter_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
++{
++	return sprintf(page, "str9100_counter_tick: %llu\n", str9100_counter_tick + TIMER2_COUNTER_REG);
++}
++static int
++str9100_counter_write_proc(struct file *file, const char __user *buffer,
++	unsigned long count, void *data)
++{
++	char *str;
++	char *cmd;
++
++	if (count > 0) {
++		str = (char *)buffer,
++		cmd = strsep(&str, "\t \n");
++		if (!cmd) goto err_out;
++		if (strcmp(cmd, "match1") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 10);
++			match1=addr;
++
++		} else if (strcmp(cmd, "match2") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 10);
++			match2=addr;
++
++
++		} else {
++			goto err_out;
++		}
++	}
++	if(match1){
++		TIMER2_MATCH_VALUE1_REG=TIMER2_COUNTER_REG+match1;
++		TIMER_INTERRUPT_MASK_REG |= (0x1<<3);
++	}
++	if(match2){
++		TIMER2_MATCH_VALUE2_REG=TIMER2_COUNTER_REG+match2;
++		TIMER_INTERRUPT_MASK_REG |= (0x2<<3);
++	}
++
++	return count;
++
++err_out:
++	return -EFAULT;
++}
++
++/*
++ * Set up timer interrupt, and return the current time in seconds.
++ */
++int __init str9100_counter_setup(void)
++{
++	str9100_setup_counter();
++	setup_irq(INTC_TIMER2_BIT_INDEX, &str9100_counter_irq);
++	str9100_counter_enable();
++	str9100_counter_proc_entry = create_proc_entry("str9100/counter", S_IFREG | S_IRUGO, NULL);
++	if (str9100_counter_proc_entry) {
++		str9100_counter_proc_entry->read_proc = str9100_counter_read_proc;
++		str9100_counter_proc_entry->write_proc = str9100_counter_write_proc;
++
++	}
++
++	return 0;
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_debug.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_debug.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_debug.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_debug.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,48 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/types.h>
++#include <asm/hardware.h>
++
++void debug_puts(const char *s)
++{
++	while (*s) {
++		volatile unsigned int status = 0;
++		do {
++			status = _UART_LSR;
++		} while (!((status & THR_EMPTY) == THR_EMPTY));
++
++		_UART_THR = *s;
++
++		if (*s == '\n') {
++			do {
++				status = _UART_LSR;
++			} while (!((status & THR_EMPTY) == THR_EMPTY));
++
++			_UART_THR = '\r';
++
++		}
++		s++;
++	}
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_gpio.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_gpio.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_gpio.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_gpio.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,532 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/miscdevice.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/proc_fs.h>
++#include <linux/interrupt.h>
++
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/arch/star_gpio.h>
++
++#include <linux/str9100/str9100_gpio.h>
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++#define MAX_GPIO_LINE		21
++void (*gpio_isr[MAX_GPIO_LINE])(int i);
++#endif
++
++/* 
++ * Read GPIO input data from register
++ */
++int str9100_gpio_in(volatile __u32 *data)
++{
++	*data = GPIO_DATA_IN_REG;
++	return 0;
++}
++
++/* 
++ * Write data to  GPIO output register
++ */
++int str9100_gpio_out(__u32 data)
++{
++	GPIO_DATA_OUT_REG = data;
++	return 0;
++}
++
++/* 
++ * Read GPIO direction Register
++ */
++int str9100_gpio_read_direction(volatile __u32 *data)
++{
++	*data = GPIO_PIN_DIR_REG;
++	return 0;
++}
++
++/* 
++ * Write GPIO direction Register
++ */
++int str9100_gpio_write_direction(__u32 data)
++{
++	GPIO_PIN_DIR_REG = data;
++	return 0;
++}
++
++/* 
++ * Write GPIO set Register
++ */
++int str9100_gpio_dataset(__u32 data)
++{
++	GPIO_DATA_SET_REG = data;
++	return 0;
++}
++
++/* 
++ * Write GPIO clear Register
++ */
++int str9100_gpio_dataclear(__u32 data)
++{
++	GPIO_DATA_CLEAR_REG = data;
++	return 0;
++}
++
++/* Read GPIO Data, but only one bit */
++int str9100_gpio_in_bit(volatile __u32 *data, int bit)
++{
++	u32 temp;
++	if (bit >= 0 && bit <= 20) {
++		str9100_gpio_in(&temp);
++		*data = ((temp >> bit)&0x1);
++	}
++	return 0;
++}
++
++/* Write GPIO Data, but only one bit */
++int str9100_gpio_out_bit(__u32 data, int bit)
++{
++	u32 temp;
++	if (bit >= 0 && bit <= 20) {
++		str9100_gpio_in(&temp);
++		temp &= ~(1 <<bit);
++		temp |= (data &0x1)<< bit;
++		str9100_gpio_out(temp);
++	}
++	return 0;
++
++}
++
++int str9100_gpio_read_direction_bit(volatile __u32 *data, int bit)
++{
++	u32 temp;
++	if (bit >= 0 && bit <= 20) {
++		str9100_gpio_read_direction(&temp);
++		*data = ((temp >> bit)&0x1);
++	}
++	return 0;
++}
++
++int str9100_gpio_write_direction_bit(__u32 data, int bit)
++{
++	u32 temp;
++	if (bit >= 0 && bit <= 20) {
++		str9100_gpio_read_direction(&temp);
++		temp &= ~(1 <<bit);
++		temp |= (data &0x1)<< bit;
++		str9100_gpio_write_direction(temp);
++	}
++	return 0;
++}
++
++int str9100_gpio_dataset_bit(__u32 data, int bit)
++{
++	u32 temp=0;
++	if (bit >= 0 && bit <= 20) {
++		temp |= (data &0x1)<< bit;
++		str9100_gpio_dataset(temp);
++	}
++	return 0;
++}
++
++int str9100_gpio_dataclear_bit(__u32 data, int bit)
++{
++	u32 temp=0;
++	if (bit >= 0 && bit <= 20) {
++		temp |= (data &0x1)<< bit;
++		str9100_gpio_dataclear(temp);
++	}
++	return 0;
++}
++
++#define GEN_GPIO_WRITE_SCRIPT(regname)\
++int str9100_gpio_write_##regname##_bit(volatile __u32 data,int bit) \
++{ \
++	u32 temp=0; \
++	if (bit >= 0 && bit <= 20) { \
++		temp |= ((data &0x1)<< bit); \
++		str9100_gpio_write_##regname(temp); \
++	} \
++	return 0; \
++} 
++//EXPORT_SYMBOL(str9100_gpio_write_##regname_bit);
++
++#define GEN_GPIO_READ_SCRIPT(regname) \
++int str9100_gpio_read_##regname##_bit(volatile __u32 *data,int bit) \
++{ \
++	u32 temp; \
++	if (bit >= 0 && bit <= 20) { \
++		str9100_gpio_read_##regname(&temp); \
++		*data = ((temp >> bit)&0x1); \
++	} \
++	return 0; \
++} 
++//EXPORT_SYMBOL(str9100_gpio_read_##regname_bit);
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++int str9100_gpio_read_intrenable(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_ENABLE_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrenable);
++
++int str9100_gpio_write_intrenable(__u32 data)
++{
++	GPIO_INTERRUPT_ENABLE_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrenable);
++
++int str9100_gpio_read_intrrawstate(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_RAW_STATE_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrrawstate);
++
++int str9100_gpio_read_intrmaskedstatus(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_MASKED_STATE_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrmaskedstatus);
++
++int str9100_gpio_read_intrmask(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_MASK_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrmask);
++
++int str9100_gpio_write_intrmask(__u32 data)
++{
++	GPIO_INTERRUPT_MASK_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrmask);
++
++int str9100_gpio_read_intrclear(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_CLEAR_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrclear);
++
++int str9100_gpio_write_intrclear(__u32 data)
++{
++	GPIO_INTERRUPT_CLEAR_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrclear);
++
++int str9100_gpio_read_intrtrigger(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_TRIGGER_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrtrigger);
++
++int str9100_gpio_write_intrtrigger(__u32 data)
++{
++	GPIO_INTERRUPT_TRIGGER_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrtrigger);
++
++int str9100_gpio_read_intrboth(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_BOTH_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrboth);
++
++int str9100_gpio_write_intrboth(__u32 data)
++{
++	GPIO_INTERRUPT_BOTH_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrboth);
++
++int str9100_gpio_read_intrriseneg(volatile __u32 *data)
++{
++	*data = GPIO_INTERRUPT_RISE_NEG_REG;
++	return 0;
++}
++GEN_GPIO_READ_SCRIPT(intrriseneg);
++
++int str9100_gpio_write_intrriseneg(__u32 data)
++{
++	GPIO_INTERRUPT_RISE_NEG_REG = data;
++	return 0;
++}
++GEN_GPIO_WRITE_SCRIPT(intrriseneg);
++
++#endif
++
++#if 0
++EXPORT_SYMBOL(str9100_gpio_in);
++EXPORT_SYMBOL(str9100_gpio_out);
++EXPORT_SYMBOL(str9100_gpio_in_bit);
++EXPORT_SYMBOL(str9100_gpio_out_bit);
++EXPORT_SYMBOL(str9100_gpio_read_direction);
++EXPORT_SYMBOL(str9100_gpio_write_direction);
++EXPORT_SYMBOL(str9100_gpio_read_direction_bit);
++EXPORT_SYMBOL(str9100_gpio_write_direction_bit);
++EXPORT_SYMBOL(str9100_gpio_dataset);
++EXPORT_SYMBOL(str9100_gpio_dataclear);
++EXPORT_SYMBOL(str9100_gpio_dataset_bit);
++EXPORT_SYMBOL(str9100_gpio_dataclear_bit);
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++EXPORT_SYMBOL(str9100_gpio_read_intrenable);
++EXPORT_SYMBOL(str9100_gpio_write_intrenable);
++EXPORT_SYMBOL(str9100_gpio_read_intrrawstate);
++EXPORT_SYMBOL(str9100_gpio_read_intrmaskedstatus);
++EXPORT_SYMBOL(str9100_gpio_read_intrmask);
++EXPORT_SYMBOL(str9100_gpio_write_intrmask);
++EXPORT_SYMBOL(str9100_gpio_read_intrclear);
++EXPORT_SYMBOL(str9100_gpio_write_intrclear);
++EXPORT_SYMBOL(str9100_gpio_read_intrtrigger);
++EXPORT_SYMBOL(str9100_gpio_write_intrtrigger);
++EXPORT_SYMBOL(str9100_gpio_read_intrboth);
++EXPORT_SYMBOL(str9100_gpio_write_intrboth);
++EXPORT_SYMBOL(str9100_gpio_read_intrriseneg);
++EXPORT_SYMBOL(str9100_gpio_write_intrriseneg);
++#endif
++#endif
++
++static int str9100_gpio_proc(char *page, char **start,  off_t off, int count, int *eof, void *data)
++{
++	u32 temp;
++	int num=0;
++
++	str9100_gpio_in(&temp);
++	num += sprintf(page+num, "GPIO IN                : %08x \n", temp);
++
++	str9100_gpio_read_direction(&temp);
++	num += sprintf(page+num, "GPIO Direction         : %08x \n", temp);
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++	str9100_gpio_read_intrenable(&temp);
++	num += sprintf(page+num, "GPIO Interrupt Enable  : %08x \n", temp);
++
++	str9100_gpio_read_intrrawstate(&temp);
++	num += sprintf(page+num, "GPIO Interrupt Raw     : %08x \n", temp);
++
++	str9100_gpio_read_intrtrigger(&temp);
++	num += sprintf(page+num, "GPIO Interrupt Trigger : %08x \n", temp);
++
++	str9100_gpio_read_intrboth(&temp);
++	num += sprintf(page+num, "GPIO Interrupt Both    : %08x \n", temp);
++
++	str9100_gpio_read_intrriseneg(&temp);
++	num += sprintf(page+num, "GPIO Interrupt RiseNeg : %08x \n", temp);
++
++	str9100_gpio_read_intrmask(&temp);
++	num += sprintf(page+num, "GPIO Interrupt MASKED  : %08x \n", temp);
++
++	str9100_gpio_read_intrmaskedstatus(&temp);
++	num += sprintf(page+num, "GPIO Interrupt MASKEDST: %08x \n", temp);
++#endif	
++
++	return num;
++}
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++static void str9100_gpio_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	int i;
++	u32 gpio_intr;
++
++	// Clean System irq status
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	INTC_INTERRUPT_MASK_REG |= (0x1 << INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++
++	str9100_gpio_read_intrrawstate(&gpio_intr);
++	//printk("GPIO INTERRUPT : %08x \n",gpio_intr);
++
++	for (i = 0; i < MAX_GPIO_LINE; i++) {
++		if ((gpio_intr &0x1) == 0x1) {
++			if (gpio_isr[i] != NULL) {
++				gpio_isr[i](i);
++			}
++		}
++		gpio_intr = gpio_intr >> 1;
++	}
++	/* Clear All Interrupt Status */
++	str9100_gpio_write_intrclear(0x1FFFFF);
++	/* Unmask Intc Interrupt Status */
++	INTC_INTERRUPT_MASK_REG &= ~(0x1 << INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++}
++
++/*  
++ * Setup GPIO for Edge Triggle Interrupt mode 
++ */
++void str9100_gpio_set_edgeintr(void (*funcptr)(int),int trig_both,int trig_rising, int gpio_pin)
++{
++	u32 intrtmp;
++	
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIO_LINE) {
++		str9100_gpio_write_direction_bit(PIN_INPUT,gpio_pin);
++
++		/* Set Triggle Level */
++		str9100_gpio_read_intrtrigger(&intrtmp);
++		intrtmp &= ~(0x1 << gpio_pin);
++		intrtmp |= (PIN_TRIG_EDGE << gpio_pin);
++		str9100_gpio_write_intrtrigger(intrtmp);
++
++		/* Set Triggle Both */
++		str9100_gpio_read_intrboth(&intrtmp);
++		intrtmp &= ~(0x1 << gpio_pin);
++		intrtmp |= (trig_both << gpio_pin);
++		str9100_gpio_write_intrboth(intrtmp);
++
++		/* Set Triggle Rising/Falling */
++		str9100_gpio_read_intrriseneg(&intrtmp);
++		intrtmp &= ~(0x1 << gpio_pin);
++		intrtmp |= (trig_rising << gpio_pin);
++		str9100_gpio_write_intrriseneg(intrtmp);
++
++		gpio_isr[gpio_pin] = funcptr;
++
++		// Enable Interrupt
++		str9100_gpio_read_intrenable(&intrtmp);
++		intrtmp |= (0x1 << gpio_pin);
++		str9100_gpio_write_intrenable(intrtmp);
++	}
++}
++/*  
++ * Clear GPIO Triggle Interrupt
++ */
++void str9100_gpio_clear_intr(int gpio_pin)
++{
++	u32 intrtmp;
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIO_LINE) {
++		gpio_isr[gpio_pin] = NULL;
++		// Disable Interrupt
++		str9100_gpio_read_intrenable(&intrtmp);
++		intrtmp &= ~( 0x1 << gpio_pin);
++		str9100_gpio_write_intrenable(intrtmp);
++	}
++}
++
++/*  
++ * Setup GPIO for LEVEL Triggle Interrupt mode 
++ */
++void str9100_gpio_set_levelintr(void (*funcptr)(int),int trig_level, int gpio_pin)
++{
++	u32 intrtmp;
++	if (gpio_pin >= 0 && gpio_pin < MAX_GPIO_LINE) {
++		str9100_gpio_write_direction_bit(PIN_INPUT,gpio_pin);
++		/* Set Triggle Level */
++		str9100_gpio_read_intrtrigger(&intrtmp);
++		intrtmp &= ~(0x1 << gpio_pin);
++		intrtmp |= (PIN_TRIG_LEVEL << gpio_pin);
++		str9100_gpio_write_intrtrigger(intrtmp);
++
++		/* Set Triggle High/Low */
++		str9100_gpio_read_intrriseneg(&intrtmp);
++		intrtmp &= ~(0x1 << gpio_pin);
++		intrtmp |= (trig_level << gpio_pin);
++		str9100_gpio_write_intrriseneg(intrtmp);
++
++		gpio_isr[gpio_pin] = funcptr;
++
++		// Enable Interrupt
++		str9100_gpio_read_intrenable(&intrtmp);
++		intrtmp |= (0x1 << gpio_pin);
++		str9100_gpio_write_intrenable(intrtmp);
++	}
++}
++EXPORT_SYMBOL(str9100_gpio_set_edgeintr);
++EXPORT_SYMBOL(str9100_gpio_clear_intr);
++EXPORT_SYMBOL(str9100_gpio_set_levelintr);
++
++/*  
++ * Display GPIO information at /proc/str9100/gpio
++ */
++
++#ifdef STR9100_GPIO_INTERRUPT_TEST
++void str9100_gpio_intr_test(int i)
++{
++	printk("GPIO Interrupt Service Single Active : %d \n",i);
++}
++#endif
++
++#endif
++static struct proc_dir_entry *proc_str9100_gpio;
++int __init str9100_gpio_init(void)
++{
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++	u32 i, ret;
++#endif
++#ifdef STR9100_GPIO_INTERRUPT_TEST
++	/* test script */
++	u32 temp;
++	str9100_gpio_read_direction(&temp);
++	printk("direction: %08X\n",temp);
++	str9100_gpio_write_direction_bit(PIN_OUTPUT,15);
++	str9100_gpio_read_direction(&temp);
++	printk("direction: %08X\n",temp);
++	str9100_gpio_in(&temp);
++	printk("data: %08X\n",temp);
++#endif
++
++	proc_str9100_gpio = create_proc_read_entry("str9100/gpio", 0, NULL, str9100_gpio_proc, NULL) ;
++
++#ifdef CONFIG_STR9100_GPIO_INTERRUPT
++	for (i = 0; i < MAX_GPIO_LINE; i++) {
++		gpio_isr[i] = NULL;
++	}
++	/* Clear All Interrupt Status */
++	str9100_gpio_write_intrclear(0x1FFFFF);
++	str9100_set_interrupt_trigger(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, INTC_EDGE_TRIGGER, INTC_RISING_EDGE);
++	ret = request_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, str9100_gpio_irq_handler, 0, "str9100_gpio", 0);
++	if (ret < 0) {
++		printk("request_irq fail : %d \n", ret);
++		return 0;
++	} else {
++		printk("GPIO interrupt handler install ok. \n");
++	}
++#endif
++#ifdef STR9100_GPIO_INTERRUPT_TEST
++	str9100_gpio_set_edgeintr(&str9100_gpio_intr_test,PIN_TRIG_SINGLE,PIN_TRIG_RISING,12);
++#endif
++
++	return 0;
++}	
++
++void __exit str9100_gpio_exit(void)
++{
++	free_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX,0);
++}
++
++module_init(str9100_gpio_init);
++module_exit(str9100_gpio_exit);
++
++MODULE_LICENSE("GPL");
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_intc.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_intc.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_intc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_intc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,193 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++
++#include <asm/hardware.h>
++#include <asm/mach/irq.h>
++#include <asm/irq.h>
++
++#define INTC_TRIGGER_UNKNOWN -1
++
++typedef struct
++{
++	int	mode;
++	int	level;
++} intc_trigger_t;
++
++static intc_trigger_t intc_trigger_table[] =
++{
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 0
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 1
++	{ INTC_EDGE_TRIGGER,	INTC_FALLING_EDGE	},	// 2
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 3
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 4
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 5
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 6
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 7
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 8
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 9
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 10
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 11
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 12
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 13
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 14
++	{ INTC_EDGE_TRIGGER,	INTC_FALLING_EDGE	},	// 15
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 16
++	{ INTC_TRIGGER_UNKNOWN,	INTC_TRIGGER_UNKNOWN	},	// 17
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_HIGH	},	// 18
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 19
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 20
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 21
++	{ INTC_EDGE_TRIGGER,	INTC_RISING_EDGE	},	// 22
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 23
++	{ INTC_LEVEL_TRIGGER,	INTC_ACTIVE_LOW		},	// 24
++};
++
++/*
++ * Configure interrupt trigger mode to be level trigger or edge trigger
++ */
++static inline void str9100_set_irq_mode(unsigned int irq, unsigned int mode)
++{
++	unsigned int val;
++
++	if (irq < 0 || irq > NR_IRQS) {
++		return;
++	}
++
++	if ((mode != INTC_LEVEL_TRIGGER) &&
++		(mode != INTC_EDGE_TRIGGER)) {
++		return;
++	}
++
++	val = INTC_INTERRUPT_TRIGGER_MODE_REG;
++
++	if (mode == INTC_LEVEL_TRIGGER) {
++		if (val & (1UL << irq)) {
++			val &= ~(1UL << irq);
++			INTC_INTERRUPT_TRIGGER_MODE_REG = val;
++		}
++	} else {
++		if (!(val & (1UL << irq))) {
++			val |= (1UL << irq);
++			INTC_INTERRUPT_TRIGGER_MODE_REG = val;
++		}
++	}
++}	
++
++/*
++ * Configure interrupt trigger level to be Active High/Low or Rising/Falling Edge
++ */
++static inline void str9100_set_irq_level(unsigned int irq, unsigned int level)
++{
++	unsigned int val;
++
++	if (irq < 0 || irq > NR_IRQS) {
++		return;
++	}
++
++	if ((level != INTC_ACTIVE_HIGH) &&
++		(level != INTC_ACTIVE_LOW) &&
++		(level != INTC_RISING_EDGE) &&
++		(level != INTC_FALLING_EDGE)) {
++		return;
++	}
++
++	val = INTC_INTERRUPT_TRIGGER_LEVEL_REG;
++
++	if ((level == INTC_ACTIVE_HIGH) ||
++		(level == INTC_RISING_EDGE)) {
++		if (val & (1UL << irq)) {
++			val &= ~(1UL << irq);
++			INTC_INTERRUPT_TRIGGER_LEVEL_REG = val;
++		}
++	} else {
++		if (!(val & (1UL << irq))) {
++			val |= (1UL << irq);
++			INTC_INTERRUPT_TRIGGER_LEVEL_REG = val;
++		}
++	}
++}
++
++/*
++ * Configure interrupt trigger mode and trigger level
++ */
++void str9100_set_interrupt_trigger(unsigned int irq, unsigned int mode, unsigned int level)
++{
++	str9100_set_irq_mode(irq, mode);
++	str9100_set_irq_level(irq, level);
++}
++EXPORT_SYMBOL(str9100_set_interrupt_trigger);
++
++/*
++ * Mask/Disable this interrupt source
++ */
++static void str9100_mask_irq(unsigned int irq)
++{
++	// Mask/Disable this interrupt source
++	INTC_INTERRUPT_MASK_REG |= (1UL << irq);
++}
++
++/*
++ * Un-Mask/Enable this interrupt source
++ */
++static void str9100_unmask_irq(unsigned int irq)
++{
++	// Clear interrupt status of the interrupt source which is edge-triggered
++	INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG |= (1UL << irq);
++
++	// Mask/Disable this interrupt source
++	INTC_INTERRUPT_MASK_REG &= ~(1UL << irq);
++}
++
++static struct irq_chip str9100_irqchip = {
++	.ack	= str9100_mask_irq,
++	.mask	= str9100_mask_irq,
++	.unmask	= str9100_unmask_irq,
++};
++
++void __init str9100_init_irq(void)
++{
++	int i;
++
++	INTC_INTERRUPT_MASK_REG = 0xFFFFFFFF;
++	INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG = 0xFFFFFFFF;	
++	INTC_FIQ_MODE_SELECT_REG = 0x0;
++
++	for (i = 0; i < NR_IRQS; i++) {
++		if (intc_trigger_table[i].mode != INTC_TRIGGER_UNKNOWN) {
++			str9100_set_irq_mode(i, intc_trigger_table[i].mode);
++			str9100_set_irq_level(i, intc_trigger_table[i].level);
++		}
++	}
++	
++	for (i = 0; i < NR_IRQS;  i++) {
++		set_irq_chip(i, &str9100_irqchip);
++		/* scott.patch */
++		set_irq_handler(i, handle_level_irq);
++		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
++	}
++}
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_misc.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_misc.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_misc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_misc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,249 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/proc_fs.h>
++#include <asm/mach/map.h>
++#include <asm/hardware.h>
++
++// enable I-Scratchpad
++int str9100_enable_ispad(u32 base_addr)
++{
++	u32 ispad_config = 0;
++	u32 flush_ispad = 0;
++	u32 ispad_size = 4; // 8K on STR9100
++	u32 cp15 = 1, cp15_off = 0;
++
++	// Configure Base
++	ispad_config |= (base_addr & 0xfffffc00);
++
++	// Configure Size
++	ispad_config &= ~(0xf << 2);
++	ispad_config |= ((ispad_size & 0xf) << 2) | (0x1 << 2);
++
++	// Enable
++	ispad_config |= 0x1;
++
++	// 1. set cp15, cr1-1(ECR) register value to 0x1
++	// 2. set up the base and size configuration
++	// 3. Invalidate IScratchpad All(flushed ISpad)
++	// 4. clear cp15, cr1-1(ECR) register value to 0x0
++	__asm__ __volatile__ (
++	"mcr p15,0,%0,c1,c1,0\n\t"
++	"mcr p15,0,%1,c9,c1,1\n\t"
++	"mcr p15,0,%2,c7,c5,5\n\t"
++	"mcr p15,0,%3,c1,c1,0\n\t"
++	"nop\n\t"
++	"nop\n\t"
++	"nop\n\t"
++	"nop\n\t"
++	"nop\n\t"
++	:
++	: "r"(cp15), "r"(ispad_config), "r"(flush_ispad), "r"(cp15_off));
++	
++	return 0;
++}
++
++static struct map_desc str9100_map_desc[64];
++static int str9100_map_desc_count;
++#define REG_DEBUG_CMD_BUFFER_SIZE	128
++#define REG_DEBUG_RESULT_BUFFER_SIZE	256
++static struct proc_dir_entry *star_reg_debug_proc_entry;
++static char str9100_reg_debug_cmd_buf[REG_DEBUG_CMD_BUFFER_SIZE];
++static char str9100_reg_debug_result_buf[REG_DEBUG_RESULT_BUFFER_SIZE];
++
++struct proc_dir_entry *str9100_proc_dir;
++EXPORT_SYMBOL(str9100_proc_dir);
++
++void str9100_register_map_desc(struct map_desc *map, int count)
++{
++	if (count) {
++		if (str9100_map_desc) {
++			int i;
++			for (i = 0; i < count; i++) {
++				str9100_map_desc[i].virtual = map->virtual;
++				str9100_map_desc[i].pfn = map->pfn;
++				str9100_map_desc[i].length = map->length;
++				str9100_map_desc[i].type = map->type;
++				map++;
++			}
++			str9100_map_desc_count = count;
++		}
++	}
++}
++
++u32 str9100_query_map_desc_by_phy(u32 addr)
++{
++	struct map_desc *map;
++	int i;
++	u32 ret_addr = 0;
++	for (i = 0; i < str9100_map_desc_count; i++) {
++		map = &str9100_map_desc[i];
++		if (addr >= (map->pfn << PAGE_SHIFT) && addr < ((map->pfn << PAGE_SHIFT) + map->length)) {
++			ret_addr = map->virtual + (addr - (map->pfn << PAGE_SHIFT));
++			break;
++		}
++	}
++
++	return ret_addr;
++}
++
++u32 str9100_query_map_desc_by_vir(u32 addr)
++{
++	struct map_desc *map;
++	int i;
++	u32 ret_addr = 0;
++	for (i = 0; i < str9100_map_desc_count; i++) {
++		map = &str9100_map_desc[i];
++		if (addr >= map->virtual && addr < (map->virtual + map->length)) {
++			ret_addr = (map->pfn << PAGE_SHIFT) + (addr - map->virtual);
++			break;
++		}
++	}
++
++	return ret_addr;
++}
++
++static int star_reg_debug_read_proc(char *buffer, char **start, off_t offset,
++	int length, int *eof, void *data)
++{
++	int count;
++	int num = 0;
++
++	if (str9100_reg_debug_cmd_buf[0]) {
++		count = strlen(str9100_reg_debug_cmd_buf);
++		sprintf(buffer, str9100_reg_debug_cmd_buf, count);
++		num += count;
++	}
++	if (str9100_reg_debug_result_buf[0]) {
++		count = strlen(str9100_reg_debug_result_buf);
++		sprintf(buffer + num, str9100_reg_debug_result_buf, count);
++		num += count;
++	}
++
++	return num;
++}
++
++static int
++star_reg_debug_write_proc(struct file *file, const char __user *buffer,
++	unsigned long count, void *data)
++{
++	char *str;
++	char *cmd;
++
++	if (count > 0) {
++		str = (char *)buffer,
++		cmd = strsep(&str, "\t \n");
++		if (!cmd) goto err_out;
++		if (strcmp(cmd, "dump") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 16);
++			if (addr & 0x3) goto err_out;
++			vir_addr = str9100_query_map_desc_by_phy(addr);
++			sprintf(str9100_reg_debug_cmd_buf,
++				"dump 0x%08x\n",
++				addr);
++			if (!vir_addr) goto err_out;
++			sprintf(str9100_reg_debug_result_buf,
++				"physical addr: 0x%08x content: 0x%08x\n",
++				addr,
++				*(volatile unsigned int __force *)(vir_addr));
++		} else if (strcmp(cmd, "write") == 0) {
++			u32 addr;
++			u32 vir_addr;
++			u32 data;
++			char *arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			addr = simple_strtoul(arg, &arg, 16);
++			arg = strsep(&str, "\t \n");
++			if (!arg) goto err_out;
++			data = simple_strtoul(arg, &arg, 16);
++			if (addr & 0x3) goto err_out;
++			vir_addr = str9100_query_map_desc_by_phy(addr);
++			if (!vir_addr) goto err_out;
++			*(volatile unsigned int __force *)(vir_addr) = data;
++			sprintf(str9100_reg_debug_cmd_buf,
++				"write 0x%08x 0x%08x\n",
++				addr, data);
++			sprintf(str9100_reg_debug_result_buf,
++				"physical addr: 0x%08x content: 0x%08x\n",
++				addr,
++				*(volatile unsigned int __force *)(vir_addr));
++		} else {
++			goto err_out;
++		}
++	}
++
++	return count;
++
++err_out:
++	return -EFAULT;
++}
++
++static int __init star_reg_debug_proc_init(void)
++{
++	star_reg_debug_proc_entry = create_proc_entry("str9100/reg_debug", S_IFREG | S_IRUGO, NULL);
++	if (star_reg_debug_proc_entry) {
++		star_reg_debug_proc_entry->read_proc = star_reg_debug_read_proc;
++		star_reg_debug_proc_entry->write_proc = star_reg_debug_write_proc;
++	}
++
++	return 0;
++}
++
++static int __init str9100_proc_dir_create(void)
++{
++	str9100_proc_dir = proc_mkdir("str9100", NULL);
++	if (str9100_proc_dir) {
++		str9100_proc_dir->owner = THIS_MODULE;
++	} else {
++		printk("Error: cannot crete str9100 proc dir entry at /proc/str9100\n");
++		return -EINVAL;
++	}
++
++	if (str9100_map_desc_count) {
++		(void)star_reg_debug_proc_init();
++	}
++
++	return 0;
++}
++
++extern int __init str9100_counter_setup(void);
++static int __init str9100_misc_init(void)
++{
++	str9100_proc_dir_create();
++	str9100_counter_setup();
++	return 0;
++}
++
++module_init(str9100_misc_init);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Star Semi Corporation");
++MODULE_DESCRIPTION("STR9100 MISC");
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_pci.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_pci.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_pci.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_pci.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,331 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/init.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/mach/pci.h>
++
++#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | ((bus) << 16) | ((device_fn) << 8) | ((where) & ~3))
++
++static struct pci_dev *pci_bridge = NULL;
++static u32 pci_config_addr;				// PCI configuration register address port
++static u32 pci_config_data;				// PCI configuration register data port
++u32 str9100_pci_irqs[4] = {0, INTC_PCI_INTA_BIT_INDEX, INTC_PCI_INTB_BIT_INDEX, 0};
++
++static int str9100_pci_read_config(struct pci_bus *bus,
++	unsigned int devfn, int where, int size, u32 *val)
++{
++	u32 v = 0;
++	u32 shift;
++	unsigned long flags;
++
++	switch (size) {
++	case 1:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		v = (v >> shift) & 0xff;
++		break;
++
++	case 2:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		v = (v >> shift) & 0xffff;
++
++		break;
++
++	case 4:
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		local_irq_restore(flags);
++		break;
++	}
++
++	*val = v;
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static int str9100_pci_write_config(struct pci_bus *bus,
++	unsigned int devfn, int where, int size, u32 val)
++{
++	u32 v;
++	u32 shift;
++	unsigned long flags;
++
++	switch (size) {
++	case 1:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		v = (v & ~(0xff << shift)) | (val << shift);
++		__raw_writel(v, pci_config_data);
++		local_irq_restore(flags);
++		break;
++
++	case 2:
++		shift = (where & 0x3) << 3;
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		v = __raw_readl(pci_config_data);
++		v = (v & ~(0xffff << shift)) | (val << shift);
++		__raw_writel(v, pci_config_data);
++		local_irq_restore(flags);
++		break;
++
++	case 4:
++		local_irq_save(flags);
++		__raw_writel(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
++		__raw_writel(val, pci_config_data);
++		local_irq_restore(flags);
++		break;
++	}
++
++	return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops str9100_pci_ops = {
++	.read	= str9100_pci_read_config,
++	.write	= str9100_pci_write_config,
++};
++
++static struct resource str9100_pci_io = {
++	.name	= "PCI I/O space",
++	.start	= PCI_IO_SPACE_START,
++	.end	= PCI_IO_SPACE_END, //albert : 20040714
++	.flags	= IORESOURCE_IO,
++};
++
++static struct resource str9100_pci_nprefetch_mem = {
++	.name	= "PCI non-prefetchable",
++	.start	= PCI_NPREFETCH_MEMORY_SPACE_START,
++	.end	= PCI_NPREFETCH_MEMORY_SPACE_END,
++	.flags	= IORESOURCE_MEM,
++};
++
++static struct resource str9100_pci_prefetch_mem = {
++	.name	= "PCI prefetchable",
++	.start	= PCI_PREFETCH_MEMORY_SPACE_START,
++	.end	= PCI_PREFETCH_MEMORY_SPACE_END,
++	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
++};
++
++static int __init str9100_pci_setup_resources(struct resource **resource)
++{
++	int ret = -1;
++
++	ret = request_resource(&iomem_resource, &str9100_pci_io);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate I/O "
++		       "memory region (%d)\n", ret);
++		goto out;
++	}
++	ret = request_resource(&iomem_resource, &str9100_pci_nprefetch_mem);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
++		       "memory region (%d)\n", ret);
++		goto release_io;
++	}
++	ret = request_resource(&iomem_resource, &str9100_pci_prefetch_mem);
++	if (ret) {
++		printk(KERN_ERR "PCI: unable to allocate prefetchable "
++		       "memory region (%d)\n", ret);
++		goto release_nprefetch_mem;
++	}
++
++	/*
++	 * bus->resource[0] is the IO resource for this bus
++	 * bus->resource[1] is the mem resource for this bus
++	 * bus->resource[2] is the prefetch mem resource for this bus
++	 */
++	resource[0] = &str9100_pci_io;
++	resource[1] = &str9100_pci_nprefetch_mem;
++	resource[2] = &str9100_pci_prefetch_mem;
++
++	ret = 0;
++
++	goto out;
++
++release_nprefetch_mem:
++	release_resource(&str9100_pci_nprefetch_mem);
++release_io:
++	release_resource(&str9100_pci_io);
++out:
++	return ret;
++}
++
++static irqreturn_t PCI_AHB2PCIB_ISR(int irq, void *dev_id, struct pt_regs * regs)
++{
++	u32 status;
++
++	//disable_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX);
++	pci_read_config_dword(pci_bridge, PCI_COMMAND, &status);
++	printk("AHB to bridge interrupt status: 0x%x\n", status);
++	pci_write_config_dword(pci_bridge, PCI_COMMAND, status);
++	//enable_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX);
++
++	return IRQ_HANDLED;
++}
++
++static irqreturn_t PCI_BROKEN_ISR(int irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 status;
++
++	status = MISC_PCI_BROKEN_STATUS_REG & 0x1f;
++	printk("PCI BROKEN interrupt status: 0x%x\n", status);
++	MISC_PCI_BROKEN_STATUS_REG = status;
++
++	return IRQ_HANDLED;
++}
++
++int __init str9100_pci_setup(int nr, struct pci_sys_data *sys)
++{
++	if (nr != 0) {
++		return 0;
++	}
++
++	if (str9100_pci_setup_resources(sys->resource)) {
++		BUG();
++	}
++
++	return 1;
++}
++
++struct pci_bus *str9100_pci_scan_bus(int nr, struct pci_sys_data *sys)
++{
++	return pci_scan_bus(sys->busnr, &str9100_pci_ops, sys);
++}
++
++void __init str9100_pci_preinit(void)
++{
++	pci_config_addr = SYSVA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR + PCI_BRIDGE_CONFIG_ADDR_REG_OFFSET;
++	pci_config_data = SYSVA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR + PCI_BRIDGE_CONFIG_DATA_REG_OFFSET;
++
++#if defined(CONFIG_STAR9100_PCI66M)
++	printk("PCI clock at 66M\n");
++	HAL_PWRMGT_ENABLE_PCI_BRIDGE_66MM();
++#elif defined(CONFIG_STAR9100_PCI33M)
++	printk("PCI clock at 33M\n");
++	HAL_PWRMGT_ENABLE_PCI_BRIDGE_33M();
++#else
++	printk("PCI clock at 33M\n");
++	HAL_PWRMGT_ENABLE_PCI_BRIDGE_33M();
++#endif
++}
++
++void __init str9100_pci_postinit(void)
++{
++	pci_bridge = pci_get_device(PCIB_VENDOR_ID, PCIB_DEVICE_ID, NULL);
++	if (pci_bridge == NULL) {
++		printk("PCI Bridge not found\n");
++		return;
++	} else {
++		printk("PCI Bridge found\n");
++	}
++
++	/* scott.patch */
++	request_irq(INTC_PCI_AHB2BRIDGE_BIT_INDEX, PCI_AHB2PCIB_ISR, IRQF_DISABLED, "pci bridge", pci_bridge);
++
++	MISC_PCI_ARBITER_INTERRUPT_MASK_REG &= ~0x1f;
++
++	/* scott.patch */
++	request_irq(INTC_PCI_ARBITOR_BIT_INDEX, PCI_BROKEN_ISR, IRQF_DISABLED, "pci broken", pci_bridge);
++
++	pci_write_config_dword(pci_bridge, PCI_BASE_ADDRESS_0, 0x0); // = 0x0, can NOT use 0x20000000
++	pci_write_config_dword(pci_bridge, PCI_BASE_ADDRESS_1, 0x0); // = 0x0, can NOT use 0x20000000
++
++	// if we enable pci on u-boot
++	// the pci_enable_device will complain with resource collisions
++	// use this to fixup
++	{
++		int i;
++		struct resource *r;
++
++		for (i = 0; i < 6; i++) {
++			r = pci_bridge->resource + i;
++			r->start = 0;
++			r->end = 0;
++		}
++	}
++
++	pci_enable_device(pci_bridge);
++	pci_set_master(pci_bridge);
++}
++
++/*
++ * map the specified device/slot/pin to an IRQ.   Different backplanes may need to modify this.
++ */
++static int __init str9100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++	int irq;
++
++	/* slot,  pin,	irq
++	 * 0      1     0
++	 * 1      1     5
++	 * 2      1     6
++	 * 3      1     0
++	 */
++	irq = str9100_pci_irqs[((slot + pin - 1) & 3)];
++
++	printk("PCI map irq: %02x:%02x.%02x slot %d, pin %d, irq: %d\n",
++		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
++		slot, pin, irq);
++
++	return irq;
++}
++
++static struct hw_pci str9100_pci __initdata = {
++	.swizzle		= pci_std_swizzle,
++	.map_irq		= str9100_pci_map_irq,
++	.nr_controllers		= 1,
++	.setup			= str9100_pci_setup,
++	.scan			= str9100_pci_scan_bus,
++	.preinit		= str9100_pci_preinit,
++	.postinit		= str9100_pci_postinit,
++};
++
++static int __init str9100_pci_init(void)
++{
++	pci_common_init(&str9100_pci);
++	return 0;
++}
++
++subsys_initcall(str9100_pci_init);
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_rtc.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_rtc.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_rtc.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_rtc.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,493 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/miscdevice.h>
++#include <linux/ioport.h>
++#include <linux/fcntl.h>
++#include <linux/init.h>
++#include <linux/poll.h>
++#include <linux/proc_fs.h>
++#include <linux/spinlock.h>
++#include <linux/sysctl.h>
++#include <linux/rtc.h>
++#include <linux/interrupt.h>
++
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/system.h>
++
++#include <asm/arch/star_rtc.h>
++#include <asm/arch/star_intc.h>
++
++#define STR9100_RTC_DATE        "20060628"
++#define STR9100_RTC_VERSION     "2.0.0"
++#define DEVICE_NAME             "rtc"
++#define SECS_PER_HOUR           (60 * 60)
++#define SECS_PER_DAY            (SECS_PER_HOUR * 24)
++#define TM_YEAR_BASE            1900
++#define EPOCH_YEAR              1970
++#define RTC_INTR_ALARM		0x20
++
++extern spinlock_t rtc_lock;
++
++static int rtc_busy = 0;
++static unsigned long epoch = 1900;
++static unsigned int  rtc_interrupt_flag = 0;
++static time_t local_rtc_offset, set_rtc_offset, current_rtc_time;
++static DECLARE_WAIT_QUEUE_HEAD(str9100_rtc_wait);
++
++# define __isleap(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
++
++static const unsigned char days_in_mo[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
++                                                                                
++static const unsigned short int __mon_yday[2][13] =
++{
++    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
++    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
++};
++
++static int offtime (const time_t *t, long int offset, struct rtc_time *tp)
++{
++    long int days, rem, y;
++    const unsigned short int *ip;
++				                                                                                
++    days = *t / SECS_PER_DAY;
++    rem = *t % SECS_PER_DAY;
++    rem += offset;
++    while (rem < 0)
++    {
++         rem += SECS_PER_DAY;
++   	 --days;
++    }
++    while (rem >= SECS_PER_DAY)
++    {
++         rem -= SECS_PER_DAY;
++  	 ++days;
++    }
++    tp->tm_hour = rem / SECS_PER_HOUR;
++    rem %= SECS_PER_HOUR;
++    tp->tm_min = rem / 60;
++    tp->tm_sec = rem % 60;
++    tp->tm_wday = (4 + days) % 7;
++    if (tp->tm_wday < 0)
++      tp->tm_wday += 7;
++    y = 1970;
++#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
++#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
++    while (days < 0 || days >= (__isleap (y) ? 366 : 365))
++    {
++   	 long int yg = y + days / 365 - (days % 365 < 0);  
++   	 days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1)- LEAPS_THRU_END_OF (y - 1));
++   	 y = yg;
++    }
++    tp->tm_year = y - 1900;
++    if (tp->tm_year != y - 1900)
++      return 0;
++    tp->tm_yday = days;
++    ip = __mon_yday[__isleap(y)];
++    for (y = 11; days < (long int) ip[y]; --y)
++       continue;
++    days -= ip[y];
++    tp->tm_mon = y;
++    tp->tm_mday = days + 1;
++    return 1;
++}
++
++static time_t ydhms_tm_diff (int year, int yday, int hour, int min, int sec, const struct rtc_time *tp)
++{
++    if (!tp) return 1;
++    else {
++      int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
++      int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
++      int a100 = a4 / 25 - (a4 % 25 < 0);
++      int b100 = b4 / 25 - (b4 % 25 < 0);
++      int a400 = a100 >> 2;
++      int b400 = b100 >> 2;
++      int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
++      time_t years = year - (time_t) tp->tm_year;
++      time_t days = (365 * years + intervening_leap_days + (yday - tp->tm_yday));
++      return (60 * (60 * (24 * days+(hour - tp->tm_hour))+(min - tp->tm_min))+(sec - tp->tm_sec));
++    }
++}
++
++static time_t _mktime(struct rtc_time *tp, time_t *offset)
++{
++    time_t t;
++    struct rtc_time tm;
++    int sec = tp->tm_sec;
++    int min = tp->tm_min;
++    int hour = tp->tm_hour;
++    int mday = tp->tm_mday;
++    int mon = tp->tm_mon;
++    int year_requested = tp->tm_year;
++
++    int mon_remainder = mon % 12;
++    int negative_mon_remainder = mon_remainder < 0;
++    int mon_years = mon / 12 - negative_mon_remainder;
++    int year = year_requested + mon_years;
++    int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
++  	       [mon_remainder + 12 * negative_mon_remainder])
++  	       + mday - 1);
++    if (year < 69) return -1;
++    tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
++    tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
++    t = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
++    if (year == 69)
++    {
++      if (t < 0 || t > 2 * 24 * 60 * 60) return -1;
++    }
++    *tp = tm;
++    return t;
++}
++
++void get_rtc_time (struct rtc_time *rtc_tm)
++{
++    time_t update_time;
++    static time_t old_time = 0;	
++    
++    spin_lock (&rtc_lock);
++    update_time =  RTC_SECOND_REG + RTC_MINUTE_REG * 60 + RTC_HOUR_REG * 60 * 60 + RTC_DAY_REG * 60 * 60 * 24 - local_rtc_offset + set_rtc_offset;
++    if (old_time > 0)
++    {
++      printk ("\n\n Old time is %d, last time is %d, diff is %d\n",old_time,update_time,update_time-old_time);
++      printk (" Throughput is %d B/s, %d KB/s\n\n",106096775/(update_time-old_time),(106096775/1024)/(update_time-old_time));
++    }
++    old_time = update_time;
++    offtime(&update_time, 0, rtc_tm);	
++    if ((rtc_tm->tm_year += (epoch - 1900)) <= 69)
++      rtc_tm->tm_year += 100; 
++    spin_unlock (&rtc_lock);
++}
++
++int set_rtc_time (struct rtc_time *rtc_tm)
++{
++    unsigned char mon, day, hrs, min, sec, leap_yr;
++    unsigned int yrs;
++    
++    spin_lock (&rtc_lock);
++    yrs = rtc_tm->tm_year + 1900;
++    mon = rtc_tm->tm_mon + 1;  
++    day = rtc_tm->tm_mday;
++    hrs = rtc_tm->tm_hour;
++    min = rtc_tm->tm_min;
++    sec = rtc_tm->tm_sec; 
++    if (yrs < 1970) return -EINVAL;
++    leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
++    if ((mon > 12) || (day == 0)) return -EINVAL;
++    if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) return -EINVAL;
++    if ((hrs >= 24) || (min >= 60) || (sec >= 60)) return -EINVAL;
++    if ((yrs -= epoch) > 255) return -EINVAL;   
++    local_rtc_offset = RTC_SECOND_REG + RTC_MINUTE_REG * 60 + RTC_HOUR_REG * 60 * 60 + RTC_DAY_REG * 60 * 60 * 24;
++    set_rtc_offset = _mktime(rtc_tm, 0);
++    spin_unlock (&rtc_lock);
++    return 0;
++}
++
++int set_rtc_alm_time (struct rtc_time *alm_tm)
++{
++    unsigned char hrs, min, sec;
++    unsigned long alm_sec;
++    unsigned int volatile rtc_int_status;
++    
++    spin_lock_irq(&rtc_lock);
++    alm_sec = alm_tm->tm_hour * 3600 + alm_tm->tm_min * 60 + alm_tm->tm_sec;
++    hrs = alm_sec / 3600;
++    min = (alm_sec % 3600) / 60;
++    sec = (alm_sec % 3600) % 60;
++    RTC_ALARM_HOUR_REG = hrs;
++    RTC_ALARM_MINUTE_REG = min;
++    RTC_ALARM_SECOND_REG = sec;
++    RTC_CONTROL_REG = RTC_MATCH_ALARM_ENABLE_BIT;
++    rtc_int_status = RTC_INTERRUPT_STATE_REG;
++    RTC_INTERRUPT_STATE_REG = rtc_int_status;                      
++    spin_unlock_irq(&rtc_lock);    
++    return 0;
++}
++
++static loff_t rtc_lseek(struct file *file, loff_t offset, int origin)
++{
++    return -ESPIPE;
++}
++
++static void mask_rtc_irq_bit(unsigned char bit)
++{
++    unsigned char val;
++    unsigned int volatile rtc_int_status;
++
++    spin_lock_irq(&rtc_lock);
++    val = RTC_CONTROL_REG;
++    val &=  ~bit;
++    RTC_CONTROL_REG = val;
++    rtc_int_status = RTC_INTERRUPT_STATE_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static void set_rtc_irq_bit(unsigned char bit)
++{
++    unsigned char val;
++    unsigned int volatile rtc_int_status;	
++        
++    spin_lock_irq(&rtc_lock);
++    val = RTC_CONTROL_REG;
++    val |= bit;
++    RTC_CONTROL_REG = val;
++    rtc_int_status = RTC_INTERRUPT_STATE_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static void get_rtc_alm_time(struct rtc_time *alm_tm)
++{
++    spin_lock_irq(&rtc_lock);
++    alm_tm->tm_sec = RTC_ALARM_SECOND_REG;
++    alm_tm->tm_min = RTC_ALARM_MINUTE_REG;
++    alm_tm->tm_hour = RTC_ALARM_HOUR_REG;
++    spin_unlock_irq(&rtc_lock);
++}
++
++static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg)
++{
++    struct rtc_time wtime; 
++
++    switch (cmd)
++    {
++	case RTC_RD_TIME:
++	        memset(&wtime, 0, sizeof(struct rtc_time));
++		get_rtc_time(&wtime);
++		break;
++	case RTC_SET_TIME:
++	{         
++		struct rtc_time rtc_tm;
++		if (!capable(CAP_SYS_TIME))
++		  return -EPERM;
++		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
++		  return -EFAULT;
++		set_rtc_time(&rtc_tm);
++		return 0;
++	}	
++        case RTC_ALM_SET:
++        {
++        	struct rtc_time alm_tm; 
++		if (copy_from_user(&alm_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
++		  return -EFAULT;
++		memset(&wtime, 0, sizeof(struct rtc_time));  
++		set_rtc_alm_time(&alm_tm);
++		return 0;
++	}	
++	case RTC_ALM_READ:
++	        memset(&wtime, 0, sizeof(struct rtc_time));
++		get_rtc_alm_time(&wtime);
++		break;
++	case RTC_AIE_OFF:
++	        mask_rtc_irq_bit(RTC_INTR_ALARM);	
++		return 0;
++	case RTC_AIE_ON:
++	        set_rtc_irq_bit(RTC_INTR_ALARM);
++		return 0;	
++	default:
++		return -EINVAL;
++    }
++    return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
++}
++
++static void rtc_fire(int irq, void *dev_id, struct pt_regs *regs)
++{
++    unsigned int volatile    rtc_int_status;	
++    
++    HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_RTC_BIT_INDEX);
++    HAL_RTC_READ_INTERRUPT_STATUS(rtc_int_status);
++    HAL_RTC_WRITE_INTERRUPT_STATUS(rtc_int_status);
++    if (rtc_int_status & RTC_AUTO_SECOND_ALARM_INTERRUPT_BIT) rtc_interrupt_flag |= RTC_AUTO_SECOND_ALARM_INTERRUPT_BIT;
++    if (rtc_int_status & RTC_AUTO_MINUTE_ALARM_INTERRUPT_BIT) rtc_interrupt_flag |= RTC_AUTO_MINUTE_ALARM_INTERRUPT_BIT;
++    if (rtc_int_status & RTC_AUTO_HOUR_ALARM_INTERRUPT_BIT) rtc_interrupt_flag |= RTC_AUTO_HOUR_ALARM_INTERRUPT_BIT;
++    if (rtc_int_status & RTC_AUTO_DAY_ALARM_INTERRUPT_BIT) rtc_interrupt_flag |= RTC_AUTO_DAY_ALARM_INTERRUPT_BIT;
++    if (rtc_int_status & RTC_MATCH_ALARM_INTERRUPT_BIT) {rtc_interrupt_flag |= RTC_MATCH_ALARM_INTERRUPT_BIT;
++      wake_up_interruptible(&str9100_rtc_wait);
++    }
++    if (rtc_int_status & RTC_BATTERY_LOW_VOLTAGE_INTR_BIT)
++    {
++      rtc_interrupt_flag |= RTC_BATTERY_LOW_VOLTAGE_INTR_BIT;
++      printk("str9100 rtc: Low Battery Voltage!!\n");
++    }
++    if (!(rtc_interrupt_flag & RTC_MATCH_ALARM_INTERRUPT_BIT)) HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_RTC_BIT_INDEX);
++}
++
++static void rtc_str9100_hwinit(int ctrl, int hour, int min, int sec)
++{    	
++    RTC_CONTROL_REG &= ~(RTC_ENABLE_BIT);	
++    if (ctrl & RTC_MATCH_ALARM_ENABLE_BIT)
++    {
++      RTC_ALARM_SECOND_REG = sec;
++      RTC_ALARM_MINUTE_REG = min;
++      RTC_ALARM_HOUR_REG = hour;    	
++    }else{
++      RTC_ALARM_SECOND_REG = 0;
++      RTC_ALARM_MINUTE_REG = 0;
++      RTC_ALARM_HOUR_REG = 0;
++    } 
++    RTC_CONTROL_REG = ctrl;
++} 
++
++static int rtc_open(struct inode *inode, struct file *file)
++{
++    if (rtc_busy) return -EBUSY;
++
++    rtc_busy = 1;
++    return 0;
++}
++
++static ssize_t rtc_read(struct file * file, char *buf, size_t count, loff_t * ppos)
++{
++    DECLARE_WAITQUEUE(wait, current);
++    unsigned long data;
++    ssize_t retval;
++
++    if (count < sizeof(unsigned long))
++      return -EINVAL;
++
++    add_wait_queue(&str9100_rtc_wait, &wait);
++    set_current_state(TASK_INTERRUPTIBLE);
++    for (;;) {
++	spin_lock(&rtc_lock);
++	data = rtc_interrupt_flag;
++	if (data != 0) {
++	  rtc_interrupt_flag = 0;
++	  break;
++	}
++        spin_unlock(&rtc_lock);
++        if (file->f_flags & O_NONBLOCK) {
++	  retval = -EAGAIN;
++	  goto out;
++	}
++	if (signal_pending(current)) {
++	  retval = -ERESTARTSYS;
++	  goto out;
++	}
++        schedule();
++    }
++    spin_unlock(&rtc_lock);
++    retval = put_user(data, (unsigned long *) buf);
++    if (!retval) retval = sizeof(unsigned long);
++out:
++    mask_rtc_irq_bit(RTC_INTR_ALARM);
++    set_current_state(TASK_RUNNING);
++    remove_wait_queue(&str9100_rtc_wait, &wait);
++    return retval;
++}
++
++static int rtc_release(struct inode *inode, struct file *file)
++{
++    rtc_busy = 0;
++    return 0;
++}
++
++static struct file_operations rtc_fops = {
++    owner:	THIS_MODULE,
++    llseek:	rtc_lseek,
++    ioctl:	rtc_ioctl,
++    open:	rtc_open,
++    read:       rtc_read,
++    release:	rtc_release
++};
++
++static struct miscdevice rtc_dev = { RTC_MINOR, "rtc", &rtc_fops };
++
++static int rtc_proc_output (char *buf)
++{
++    char *p;
++    struct rtc_time tm;
++    
++    p = buf;
++    get_rtc_time(&tm);
++    p += sprintf(p,"rtc_time\t: %02d:%02d:%02d\n"
++		   "rtc_date\t: %04d-%02d-%02d\n"
++	 	   "rtc_epoch\t: %04lu\n",
++		   tm.tm_hour, tm.tm_min, tm.tm_sec,
++		   tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
++    get_rtc_alm_time(&tm);
++    p += sprintf(p, "alarm\t\t: ");
++    if (tm.tm_hour <= 24)
++      p += sprintf(p, "%02d:", tm.tm_hour);
++    else
++      p += sprintf(p, "**:");
++    if (tm.tm_min <= 59)
++      p += sprintf(p, "%02d:", tm.tm_min);
++    else
++      p += sprintf(p, "**:");
++    if (tm.tm_sec <= 59)
++      p += sprintf(p, "%02d\n", tm.tm_sec);
++    else
++      p += sprintf(p, "**\n");	
++    return  p - buf;
++}
++
++static int rtc_read_proc(char *page, char **start, off_t off,int count, int *eof, void *data)
++{
++    int len = rtc_proc_output (page);
++    
++    if (len <= off+count) *eof = 1;
++    *start = page + off;
++    len -= off;
++    if (len>count) len = count;
++    if (len<0) len = 0;
++    return len;
++}
++
++static int __init str9100_rtc_init(void)
++{
++    int error;
++
++    error = misc_register(&rtc_dev);
++    if (error) {
++      printk(KERN_ERR "rtc: unable to get misc minor\n");
++      return error;
++    }	
++    printk(KERN_INFO "STR9100 Real Time Clock Driver v" STR9100_RTC_VERSION "\n");
++    rtc_str9100_hwinit(0,0,0,0);
++    HAL_RTC_ENABLE();
++    request_irq(INTC_RTC_BIT_INDEX, rtc_fire, 0, DEVICE_NAME, NULL);
++    create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
++    local_rtc_offset = 0;
++    set_rtc_offset = current_rtc_time = 0;        
++    return 0;
++}
++
++static void __exit str9100_rtc_exit (void)
++{
++    char buf[64];
++    	
++    HAL_RTC_DISABLE();		
++    cleanup_sysctl();
++    sprintf (buf,"driver/%s",DEVICE_NAME);
++    remove_proc_entry (buf, NULL);
++    misc_deregister(&rtc_dev);
++    free_irq (INTC_RTC_BIT_INDEX, NULL);
++}
++
++module_init(str9100_rtc_init);
++module_exit(str9100_rtc_exit);
++
++MODULE_LICENSE("GPL");
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_setup.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_setup.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_setup.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_setup.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,357 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/mm.h>
++#include <linux/init.h>
++#include <linux/config.h>
++#include <linux/major.h>
++#include <linux/fs.h>
++#include <linux/platform_device.h>
++#include <linux/serial.h>
++#include <linux/tty.h>
++#include <linux/serial_8250.h>
++
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++#include <asm/mach/map.h>
++#include <asm/setup.h>
++#include <asm/system.h>
++#include <asm/memory.h>
++#include <asm/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++
++#define STR9100_UART_XTAL 14769230
++
++#define EARLY_REGISTER_CONSOLE
++
++/*
++ * Standard IO mapping
++ */
++static struct map_desc str9100_std_desc[] __initdata = {
++	{
++		.virtual	= SYSVA_FLASH_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_FLASH_BASE_ADDR),
++		.length		= SZ_8M,
++		.type		= MT_DEVICE
++	}, 	{
++		.virtual	= SYSVA_SMC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_SMC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_DDR_SDRAM_CONTROLLER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_DDR_SDRAM_CONTROLLER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_DMAC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_DMAC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_GSW_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_GSW_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_HNAT_SRAM_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_HNAT_SRAM_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_MISC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_MISC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_POWER_MANAGEMENT_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_POWER_MANAGEMENT_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_UART_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_UART_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_TIMER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_TIMER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_WATCHDOG_TIMER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_WATCHDOG_TIMER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_RTC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_RTC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_GPIO_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_GPIO_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_INTC_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_INTC_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCMCIA_CONTROLLER_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCMCIA_CONTROLLER_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB11_CONFIG_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB11_CONFIG_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB11_OPERATION_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB11_OPERATION_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB20_CONFIG_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB20_CONFIG_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= SYSVA_USB20_OPERATION_BASE_ADDR,
++		.pfn		= __phys_to_pfn(SYSPA_USB20_OPERATION_BASE_ADDR),
++		.length		= SZ_4K,
++		.type		= MT_DEVICE
++	}
++};
++
++#ifdef EARLY_REGISTER_CONSOLE
++static struct uart_port str9100_serial_ports[] = {
++	{
++		.membase	= (char*)(SYSVA_UART_BASE_ADDR),
++		.mapbase	= (SYSPA_UART_BASE_ADDR),
++		.irq		= INTC_UART_BIT_INDEX,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++		.iotype		= UPIO_MEM,
++		.regshift	= 2,
++		.uartclk	= STR9100_UART_XTAL,
++		.line		= 0,
++		.type		= PORT_16550A,
++		.fifosize	= 16
++	}
++};
++#else
++static struct resource str9100_uart0_resources[] = {
++	[0] = {
++		.start	= SYSPA_UART_BASE_ADDR,
++		.end	= SYSPA_UART_BASE_ADDR + 0xff,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_UART_BIT_INDEX,
++		.end	= INTC_UART_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ
++	}
++};
++
++static struct plat_serial8250_port str9100_uart0_data[] = {
++	{
++		.membase	= (char*)(SYSVA_UART_BASE_ADDR),
++		.mapbase	= (SYSPA_UART_BASE_ADDR),
++		.irq		= INTC_UART_BIT_INDEX,
++		.uartclk	= STR9100_UART_XTAL,
++		.regshift	= 2,
++		.iotype		= UPIO_MEM,
++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++	},
++	{  },
++};
++
++static struct platform_device str9100_uart0_device = {
++	.name			= "serial8250",
++	.id			= 0,
++	.dev.platform_data	= str9100_uart0_data,
++	.num_resources		= 2,
++	.resource		= str9100_uart0_resources,
++};
++#endif
++
++static u64 usb_dmamask = 0xffffffffULL;
++static struct resource str9100_usb11_resources[] = {
++	[0] = {
++		.start	= SYSPA_USB11_CONFIG_BASE_ADDR,
++		.end	= SYSPA_USB11_CONFIG_BASE_ADDR + SZ_1M - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_USB11_BIT_INDEX,
++		.end	= INTC_USB11_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device str9100_usb11_device = {
++	.name		= "str9100-ohci",
++	.id		= -1,
++	.dev = {
++		.dma_mask		= &usb_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.resource	= str9100_usb11_resources,
++	.num_resources	= ARRAY_SIZE(str9100_usb11_resources),
++};
++
++static struct resource str9100_usb20_resources[] = {
++	[0] = {
++		.start	= SYSPA_USB20_CONFIG_BASE_ADDR,
++		.end	= SYSPA_USB20_CONFIG_BASE_ADDR + SZ_1M - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= INTC_USB20_BIT_INDEX,
++		.end	= INTC_USB20_BIT_INDEX,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device str9100_usb20_device = {
++	.name		= "str9100-ehci",
++	.id		= -1,
++	.dev		= {
++		.dma_mask		= &usb_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++	},
++	.resource	= str9100_usb20_resources,
++	.num_resources	= ARRAY_SIZE(str9100_usb20_resources),
++};
++
++static struct platform_device *str9100_devices[] __initdata = {
++#ifndef EARLY_REGISTER_CONSOLE
++	&str9100_uart0_device,
++#endif
++	&str9100_usb11_device,
++	&str9100_usb20_device
++};
++
++static void __init str9100_fixup(struct machine_desc *desc,
++	struct tag *tags, char **cmdline, struct meminfo *mi)
++{
++        mi->nr_banks = 1;
++	mi->bank[0].start = CONFIG_SYSTEM_DRAM_BASE;
++	mi->bank[0].size = CONFIG_SYSTEM_DRAM_SIZE << 20;
++	mi->bank[0].node = 0;
++}
++
++/* ######################################################################### */
++#ifdef CONFIG_CPU_ISPAD_ENABLE 
++extern unsigned long __ispad_begin; 
++extern int str9100_enable_ispad(unsigned long); 
++#endif
++u32 CPU_clock;
++u32 AHB_clock;
++u32 APB_clock;
++// This function is called just after the
++// page table and cpu have been initialized
++void __init str9100_early_init(void)
++{
++	switch ((PWRMGT_RESET_LATCH_CONFIGURATION_REG >> 6) & 0x03) {
++	case 0x00:
++		CPU_clock = 175000000;
++		break;
++
++	case 0x01:
++		CPU_clock = 200000000;
++		break;
++
++	case 0x02:
++		CPU_clock = 225000000;
++		break;
++
++	case 0x03:
++		CPU_clock = 250000000;
++		break;
++	}
++
++	AHB_clock = CPU_clock >> 1;
++	APB_clock = AHB_clock >> 1;
++
++	printk("CPU clock at %dMHz\n", CPU_clock / 1000000);
++	printk("AHB clock at %dMHz\n", AHB_clock / 1000000);
++	printk("APB clock at %dMHz\n", APB_clock / 1000000);
++
++#ifdef CONFIG_CPU_ISPAD_ENABLE
++	str9100_enable_ispad((unsigned long)&__ispad_begin);
++#endif
++}
++/* ######################################################################### */
++
++void __init str9100_init(void)
++{
++#if 1
++	platform_add_devices(str9100_devices, ARRAY_SIZE(str9100_devices));
++#else
++#ifndef EARLY_REGISTER_CONSOLE
++	platform_device_register(&str9100_uart0_device);
++#endif
++	platform_device_register(&str9100_usb11_device);
++	platform_device_register(&str9100_usb20_device);
++#endif
++}
++
++extern void str9100_register_map_desc(struct map_desc *map, int count);
++void __init str9100_map_io(void)
++{
++	iotable_init(str9100_std_desc, ARRAY_SIZE(str9100_std_desc));
++	str9100_register_map_desc(str9100_std_desc, ARRAY_SIZE(str9100_std_desc));
++#ifdef EARLY_REGISTER_CONSOLE
++	early_serial_setup(&str9100_serial_ports[0]);
++#endif
++}
++
++extern void str9100_init_irq(void);
++extern struct sys_timer str9100_timer;
++
++MACHINE_START(STR9100, "STAR STR9100")
++	.phys_io	= SYSPA_UART_BASE_ADDR,
++	.io_pg_offst	= ((SYSVA_UART_BASE_ADDR) >> 18) & 0xfffc, // virtual, physical
++	.fixup		= str9100_fixup,
++	.map_io		= str9100_map_io,
++	.init_irq	= str9100_init_irq,
++	.timer		= &str9100_timer,
++	.boot_params	= 0x0100,
++	.init_machine	= str9100_init,
++MACHINE_END
++
+diff -rupN linux-2.6.35.11/arch/arm/mach-str9100/str9100_timer.c linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_timer.c
+--- linux-2.6.35.11/arch/arm/mach-str9100/str9100_timer.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mach-str9100/str9100_timer.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,219 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/init.h>
++#include <linux/timex.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/time.h>
++
++#if 1
++// for timer clock < 100MHz
++#define uSECS_PER_TICK	(1000000 / APB_clock)
++#define TICKS2USECS(x)  ((x) * uSECS_PER_TICK)
++#else
++// for timer clock >= 100MHz
++#define TICKS_PER_uSEC	(APB_clock / 1000000)
++#define TICKS2USECS(x)  ((x) / TICKS_PER_uSEC)
++#endif
++
++extern u32 APB_clock;
++static u32 timer_counter_value;
++
++static inline unsigned int str9100_read_timer_counter(void)
++{
++	return TIMER1_COUNTER_REG;
++}
++
++static inline unsigned int str9100_read_timer_interrupt_status(void)
++{
++	return TIMER_INTERRUPT_STATUS_REG;
++}
++
++static inline void str9100_clear_timer_interrupt_status(unsigned int irq)
++{
++	TIMER_INTERRUPT_STATUS_REG &= ~(1 << TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX);
++}
++
++static void str9100_setup_timer(unsigned int counter_value)
++{
++	unsigned long control_value;
++	unsigned long mask_value;    
++
++	control_value = TIMER_CONTROL_REG;
++	mask_value = TIMER_INTERRUPT_MASK_REG;
++
++	TIMER1_COUNTER_REG = counter_value;
++	TIMER1_AUTO_RELOAD_VALUE_REG = counter_value;
++	TIMER1_MATCH_VALUE1_REG = 0;
++	TIMER1_MATCH_VALUE2_REG = 0;
++
++	// Clock Source: PCLK
++	control_value &= ~(1 << TIMER1_CLOCK_SOURCE_BIT_INDEX);
++
++	// Down Count Mode
++	control_value |= (1 << TIMER1_UP_DOWN_COUNT_BIT_INDEX);
++
++	// un-mask overflow, match2 and match1 interrupt sources
++	mask_value &= ~(0x7);
++
++	// mask match2 and match1 interrupt sources
++	mask_value |= 0x03;
++
++	TIMER_CONTROL_REG = control_value;
++	TIMER_INTERRUPT_MASK_REG = mask_value;
++}
++
++static void str9100_timer_enable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER_CONTROL_REG;
++
++	// enable overflow mode
++	control_value |= (1 << TIMER1_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// enable the timer
++	control_value |= (1 << TIMER1_ENABLE_BIT_INDEX);
++
++	TIMER_CONTROL_REG = control_value;
++}
++
++static void str9100_timer_disable(void)
++{
++	unsigned long control_value;
++
++	control_value = TIMER_CONTROL_REG;
++
++	// disable overflow mode
++	control_value &= ~(1 << TIMER1_OVERFLOW_ENABLE_BIT_INDEX);
++
++	// disable the timer
++	control_value &= ~(1 << TIMER1_ENABLE_BIT_INDEX);
++
++	TIMER_CONTROL_REG = control_value;
++}
++
++/*
++ * Returns number of us since last clock interrupt.  Note that interrupts
++ * will have been disabled by do_gettimeoffset()
++ */
++static unsigned long str9100_gettimeoffset(void)
++{
++	unsigned long ticks1, ticks2;
++	unsigned long interrupt_status;
++
++	/*
++	 * Get the current number of ticks.  Note that there is a race
++	 * condition between us reading the timer and checking for
++	 * an interrupt.  We get around this by ensuring that the
++	 * counter has not reloaded between our two reads.
++	 */
++	ticks2 = str9100_read_timer_counter();
++	do {
++		ticks1 = ticks2;
++		interrupt_status = str9100_read_timer_interrupt_status();
++		ticks2 = str9100_read_timer_counter();
++	} while (ticks2 > ticks1);
++
++	/*
++	 * Number of ticks since last interrupt
++	 */
++	ticks1 = timer_counter_value - ticks2;
++
++	/*
++	 * Interrupt pending?  If so, we've reloaded once already.
++	 */
++	if (interrupt_status) {
++		ticks1 += timer_counter_value;
++	}
++
++	/*
++	 * Convert the ticks to usecs
++	 */
++	return TICKS2USECS(ticks1);
++}
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t
++str9100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	write_seqlock(&xtime_lock);
++
++	str9100_clear_timer_interrupt_status((unsigned int)irq);
++	/* 2008/05/12 Richard 
++	timer_tick(regs);
++	 */
++	timer_tick();
++
++	write_sequnlock(&xtime_lock);
++
++	return IRQ_HANDLED;
++}
++
++static struct irqaction str9100_timer_irq = {
++	.name		= "STR9100 Timer Tick",
++/* 2008/05/12 Richard
++	.flags		= SA_INTERRUPT | SA_TIMER,
++ */
++	.flags          = IRQF_DISABLED | IRQF_TIMER,
++	.handler	= str9100_timer_interrupt,
++};
++
++/*
++ * Set up timer interrupt, and return the current time in seconds.
++ */
++static void __init str9100_timer_init(void)
++{
++	/*
++	 * prepare timer-related values
++	 */
++	timer_counter_value = APB_clock / HZ;
++
++	/*
++	 * setup timer-related values
++	 */
++	str9100_setup_timer(timer_counter_value);
++
++	/*
++	 * Make irqs happen for the system timer
++	 */
++	setup_irq(INTC_TIMER1_BIT_INDEX, &str9100_timer_irq);
++
++	str9100_timer_enable();
++}
++
++struct sys_timer str9100_timer = {
++	.init		= str9100_timer_init,
++	.offset		= str9100_gettimeoffset,
++};
++
+diff -rupN linux-2.6.35.11/arch/arm/Makefile linux-2.6.35.11-ts7500/arch/arm/Makefile
+--- linux-2.6.35.11/arch/arm/Makefile	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -18,6 +18,7 @@ endif
+ OBJCOPYFLAGS	:=-O binary -R .note -R .note.gnu.build-id -R .comment -S
+ GZFLAGS		:=-9
+ #KBUILD_CFLAGS	+=-pipe
++KBUILD_CFLAGS	+=-pipe -gdwarf-2
+ # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
+ KBUILD_CFLAGS	+=$(call cc-option,-marm,)
+ 
+@@ -186,6 +187,10 @@ machine-$(CONFIG_MACH_SPEAR300)		:= spea
+ machine-$(CONFIG_MACH_SPEAR310)		:= spear3xx
+ machine-$(CONFIG_MACH_SPEAR320)		:= spear3xx
+ machine-$(CONFIG_MACH_SPEAR600)		:= spear6xx
++machine-$(CONFIG_ARCH_STR9100)    := str9100
++machine-$(CONFIG_ARCH_STR8100)    := str8100
++
++
+ 
+ # Platform directory name.  This list is sorted alphanumerically
+ # by CONFIG_* macro name.
+diff -rupN linux-2.6.35.11/arch/arm/Makefile.orig linux-2.6.35.11-ts7500/arch/arm/Makefile.orig
+--- linux-2.6.35.11/arch/arm/Makefile.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/Makefile.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,294 @@
++#
++# arch/arm/Makefile
++#
++# This file is included by the global makefile so that you can add your own
++# architecture-specific flags and dependencies.
++#
++# 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) 1995-2001 by Russell King
++
++LDFLAGS_vmlinux	:=-p --no-undefined -X
++ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
++LDFLAGS_vmlinux	+= --be8
++endif
++
++OBJCOPYFLAGS	:=-O binary -R .note -R .note.gnu.build-id -R .comment -S
++GZFLAGS		:=-9
++#KBUILD_CFLAGS	+=-pipe
++# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
++KBUILD_CFLAGS	+=$(call cc-option,-marm,)
++
++# Do not use arch/arm/defconfig - it's always outdated.
++# Select a platform tht is kept up-to-date
++KBUILD_DEFCONFIG := versatile_defconfig
++
++# defines filename extension depending memory management type.
++ifeq ($(CONFIG_MMU),)
++MMUEXT		:= -nommu
++endif
++
++ifeq ($(CONFIG_FRAME_POINTER),y)
++KBUILD_CFLAGS	+=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
++endif
++
++ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
++KBUILD_CPPFLAGS	+= -mbig-endian
++AS		+= -EB
++LD		+= -EB
++else
++KBUILD_CPPFLAGS	+= -mlittle-endian
++AS		+= -EL
++LD		+= -EL
++endif
++
++comma = ,
++
++# This selects which instruction set is used.
++# Note that GCC does not numerically define an architecture version
++# macro, but instead defines a whole series of macros which makes
++# testing for a specific architecture or later rather impossible.
++arch-$(CONFIG_CPU_32v7)		:=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
++arch-$(CONFIG_CPU_32v6)		:=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
++# Only override the compiler option if ARMv6. The ARMv6K extensions are
++# always available in ARMv7
++ifeq ($(CONFIG_CPU_32v6),y)
++arch-$(CONFIG_CPU_32v6K)	:=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
++endif
++arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
++arch-$(CONFIG_CPU_32v4T)	:=-D__LINUX_ARM_ARCH__=4 -march=armv4t
++arch-$(CONFIG_CPU_32v4)		:=-D__LINUX_ARM_ARCH__=4 -march=armv4
++arch-$(CONFIG_CPU_32v3)		:=-D__LINUX_ARM_ARCH__=3 -march=armv3
++
++# This selects how we optimise for the processor.
++tune-$(CONFIG_CPU_ARM610)	:=-mtune=arm610
++tune-$(CONFIG_CPU_ARM710)	:=-mtune=arm710
++tune-$(CONFIG_CPU_ARM7TDMI)	:=-mtune=arm7tdmi
++tune-$(CONFIG_CPU_ARM720T)	:=-mtune=arm7tdmi
++tune-$(CONFIG_CPU_ARM740T)	:=-mtune=arm7tdmi
++tune-$(CONFIG_CPU_ARM9TDMI)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_ARM940T)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_ARM946E)	:=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi)
++tune-$(CONFIG_CPU_ARM920T)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_ARM922T)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_ARM925T)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_ARM926T)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_FA526)	:=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
++tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
++tune-$(CONFIG_CPU_XSCALE)	:=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
++tune-$(CONFIG_CPU_XSC3)		:=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
++tune-$(CONFIG_CPU_FEROCEON)	:=$(call cc-option,-mtune=marvell-f,-mtune=xscale)
++tune-$(CONFIG_CPU_V6)		:=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
++
++ifeq ($(CONFIG_AEABI),y)
++CFLAGS_ABI	:=-mabi=aapcs-linux -mno-thumb-interwork
++else
++CFLAGS_ABI	:=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
++endif
++
++ifeq ($(CONFIG_ARM_UNWIND),y)
++CFLAGS_ABI	+=-funwind-tables
++endif
++
++ifeq ($(CONFIG_THUMB2_KERNEL),y)
++AFLAGS_AUTOIT	:=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mauto-it)
++AFLAGS_NOWARN	:=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
++CFLAGS_THUMB2	:=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
++AFLAGS_THUMB2	:=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb
++endif
++
++# Need -Uarm for gcc < 3.x
++KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
++KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
++
++CHECKFLAGS	+= -D__arm__
++
++#Default value
++head-y		:= arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
++textofs-y	:= 0x00008000
++textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
++# We don't want the htc bootloader to corrupt kernel during resume
++textofs-$(CONFIG_PM_H1940)      := 0x00108000
++# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
++ifeq ($(CONFIG_ARCH_SA1100),y)
++textofs-$(CONFIG_SA1111) := 0x00208000
++endif
++
++# Machine directory name.  This list is sorted alphanumerically
++# by CONFIG_* macro name.
++machine-$(CONFIG_ARCH_AAEC2000)		:= aaec2000
++machine-$(CONFIG_ARCH_AT91)		:= at91
++machine-$(CONFIG_ARCH_BCMRING)		:= bcmring
++machine-$(CONFIG_ARCH_CLPS711X)		:= clps711x
++machine-$(CONFIG_ARCH_CNS3XXX)		:= cns3xxx
++machine-$(CONFIG_ARCH_DAVINCI)		:= davinci
++machine-$(CONFIG_ARCH_DOVE)		:= dove
++machine-$(CONFIG_ARCH_EBSA110)		:= ebsa110
++machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
++machine-$(CONFIG_ARCH_GEMINI)		:= gemini
++machine-$(CONFIG_ARCH_H720X)		:= h720x
++machine-$(CONFIG_ARCH_INTEGRATOR)	:= integrator
++machine-$(CONFIG_ARCH_IOP13XX)		:= iop13xx
++machine-$(CONFIG_ARCH_IOP32X)		:= iop32x
++machine-$(CONFIG_ARCH_IOP33X)		:= iop33x
++machine-$(CONFIG_ARCH_IXP2000)		:= ixp2000
++machine-$(CONFIG_ARCH_IXP23XX)		:= ixp23xx
++machine-$(CONFIG_ARCH_IXP4XX)		:= ixp4xx
++machine-$(CONFIG_ARCH_KIRKWOOD)		:= kirkwood
++machine-$(CONFIG_ARCH_KS8695)		:= ks8695
++machine-$(CONFIG_ARCH_L7200)		:= l7200
++machine-$(CONFIG_ARCH_LH7A40X)		:= lh7a40x
++machine-$(CONFIG_ARCH_LOKI) 		:= loki
++machine-$(CONFIG_ARCH_MMP)		:= mmp
++machine-$(CONFIG_ARCH_MSM)		:= msm
++machine-$(CONFIG_ARCH_MV78XX0)		:= mv78xx0
++machine-$(CONFIG_ARCH_MX1)		:= mx1
++machine-$(CONFIG_ARCH_MX2)		:= mx2
++machine-$(CONFIG_ARCH_MX25)		:= mx25
++machine-$(CONFIG_ARCH_MX3)		:= mx3
++machine-$(CONFIG_ARCH_MX5)		:= mx5
++machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
++machine-$(CONFIG_ARCH_NETX)		:= netx
++machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
++machine-$(CONFIG_ARCH_NS9XXX)		:= ns9xxx
++machine-$(CONFIG_ARCH_OMAP1)		:= omap1
++machine-$(CONFIG_ARCH_OMAP2)		:= omap2
++machine-$(CONFIG_ARCH_OMAP3)		:= omap2
++machine-$(CONFIG_ARCH_OMAP4)		:= omap2
++machine-$(CONFIG_ARCH_ORION5X)		:= orion5x
++machine-$(CONFIG_ARCH_PNX4008)		:= pnx4008
++machine-$(CONFIG_ARCH_PXA)		:= pxa
++machine-$(CONFIG_ARCH_REALVIEW)		:= realview
++machine-$(CONFIG_ARCH_RPC)		:= rpc
++machine-$(CONFIG_ARCH_S3C2410)		:= s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443
++machine-$(CONFIG_ARCH_S3C24A0)		:= s3c24a0
++machine-$(CONFIG_ARCH_S3C64XX)		:= s3c64xx
++machine-$(CONFIG_ARCH_S5P6440)		:= s5p6440
++machine-$(CONFIG_ARCH_S5P6442)		:= s5p6442
++machine-$(CONFIG_ARCH_S5PC100)		:= s5pc100
++machine-$(CONFIG_ARCH_S5PV210)		:= s5pv210
++machine-$(CONFIG_ARCH_SA1100)		:= sa1100
++machine-$(CONFIG_ARCH_SHARK)		:= shark
++machine-$(CONFIG_ARCH_SHMOBILE) 	:= shmobile
++machine-$(CONFIG_ARCH_STMP378X)		:= stmp378x
++machine-$(CONFIG_ARCH_STMP37XX)		:= stmp37xx
++machine-$(CONFIG_ARCH_U300)		:= u300
++machine-$(CONFIG_ARCH_U8500)		:= ux500
++machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
++machine-$(CONFIG_ARCH_VEXPRESS)		:= vexpress
++machine-$(CONFIG_ARCH_W90X900)		:= w90x900
++machine-$(CONFIG_ARCH_NUC93X)		:= nuc93x
++machine-$(CONFIG_FOOTBRIDGE)		:= footbridge
++machine-$(CONFIG_MACH_SPEAR300)		:= spear3xx
++machine-$(CONFIG_MACH_SPEAR310)		:= spear3xx
++machine-$(CONFIG_MACH_SPEAR320)		:= spear3xx
++machine-$(CONFIG_MACH_SPEAR600)		:= spear6xx
++
++# Platform directory name.  This list is sorted alphanumerically
++# by CONFIG_* macro name.
++plat-$(CONFIG_ARCH_MXC)		:= mxc
++plat-$(CONFIG_ARCH_OMAP)	:= omap
++plat-$(CONFIG_ARCH_S3C64XX)	:= samsung
++plat-$(CONFIG_ARCH_STMP3XXX)	:= stmp3xxx
++plat-$(CONFIG_PLAT_IOP)		:= iop
++plat-$(CONFIG_PLAT_NOMADIK)	:= nomadik
++plat-$(CONFIG_PLAT_ORION)	:= orion
++plat-$(CONFIG_PLAT_PXA)		:= pxa
++plat-$(CONFIG_PLAT_S3C24XX)	:= s3c24xx samsung
++plat-$(CONFIG_PLAT_S5P)		:= s5p samsung
++plat-$(CONFIG_PLAT_SPEAR)	:= spear
++plat-$(CONFIG_PLAT_VERSATILE)	:= versatile
++
++ifeq ($(CONFIG_ARCH_EBSA110),y)
++# This is what happens if you forget the IOCS16 line.
++# PCMCIA cards stop working.
++CFLAGS_3c589_cs.o :=-DISA_SIXTEEN_BIT_PERIPHERAL
++export CFLAGS_3c589_cs.o
++endif
++
++# The byte offset of the kernel image in RAM from the start of RAM.
++TEXT_OFFSET := $(textofs-y)
++
++# The first directory contains additional information for the boot setup code
++ifneq ($(machine-y),)
++MACHINE  := arch/arm/mach-$(word 1,$(machine-y))/
++else
++MACHINE  :=
++endif
++
++machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
++platdirs := $(patsubst %,arch/arm/plat-%/,$(plat-y))
++
++ifeq ($(KBUILD_SRC),)
++KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(machdirs) $(platdirs))
++else
++KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs))
++endif
++
++export	TEXT_OFFSET GZFLAGS MMUEXT
++
++# Do we have FASTFPE?
++FASTFPE		:=arch/arm/fastfpe
++ifeq ($(FASTFPE),$(wildcard $(FASTFPE)))
++FASTFPE_OBJ	:=$(FASTFPE)/
++endif
++
++# If we have a machine-specific directory, then include it in the build.
++core-y				+= arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
++core-y				+= $(machdirs) $(platdirs)
++core-$(CONFIG_FPE_NWFPE)	+= arch/arm/nwfpe/
++core-$(CONFIG_FPE_FASTFPE)	+= $(FASTFPE_OBJ)
++core-$(CONFIG_VFP)		+= arch/arm/vfp/
++
++drivers-$(CONFIG_OPROFILE)      += arch/arm/oprofile/
++
++libs-y				:= arch/arm/lib/ $(libs-y)
++
++# Default target when executing plain make
++ifeq ($(CONFIG_XIP_KERNEL),y)
++KBUILD_IMAGE := xipImage
++else
++KBUILD_IMAGE := zImage
++endif
++
++all:	$(KBUILD_IMAGE)
++
++boot := arch/arm/boot
++
++archprepare:
++	$(Q)$(MAKE) $(build)=arch/arm/tools include/generated/mach-types.h
++
++# Convert bzImage to zImage
++bzImage: zImage
++
++zImage Image xipImage bootpImage uImage: vmlinux
++	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
++
++zinstall install: vmlinux
++	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
++
++# We use MRPROPER_FILES and CLEAN_FILES now
++archclean:
++	$(Q)$(MAKE) $(clean)=$(boot)
++
++# My testing targets (bypasses dependencies)
++bp:;	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage
++i zi:;	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
++
++
++define archhelp
++  echo  '* zImage        - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
++  echo  '  Image         - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
++  echo  '* xipImage      - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)'
++  echo  '  uImage        - U-Boot wrapped zImage'
++  echo  '  bootpImage    - Combined zImage and initial RAM disk' 
++  echo  '                  (supply initrd image via make variable INITRD=<path>)'
++  echo  '  install       - Install uncompressed kernel'
++  echo  '  zinstall      - Install compressed kernel'
++  echo  '                  Install using (your) ~/bin/$(INSTALLKERNEL) or'
++  echo  '                  (distribution) /sbin/$(INSTALLKERNEL) or'
++  echo  '                  install to $$(INSTALL_PATH) and run lilo'
++endef
+diff -rupN linux-2.6.35.11/arch/arm/mm/cache-fa.S linux-2.6.35.11-ts7500/arch/arm/mm/cache-fa.S
+--- linux-2.6.35.11/arch/arm/mm/cache-fa.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/cache-fa.S	2011-03-14 11:18:24.000000000 -0400
+@@ -1,3 +1,4 @@
++#if (1)
+ /*
+  *  linux/arch/arm/mm/cache-fa.S
+  *
+@@ -34,6 +35,7 @@
+ #define CACHE_DSIZE	16384 
+ #endif 
+ 
++
+ /* FIXME: put optimal value here. Current one is just estimation */
+ #define CACHE_DLIMIT	(CACHE_DSIZE * 2)
+ 
+@@ -142,7 +144,9 @@ ENTRY(fa_flush_kern_dcache_area)
+ 	cmp	r0, r1
+ 	blo	1b
+ 	mov	r0, #0
++/*
+ 	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
++*/
+ 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+ 	mov	pc, lr
+ 
+@@ -157,7 +161,7 @@ ENTRY(fa_flush_kern_dcache_area)
+  *	- start  - virtual start address
+  *	- end	 - virtual end address
+  */
+-fa_dma_inv_range:
++ENTRY(fa_dma_inv_range)
+ 	tst	r0, #CACHE_DLINESIZE - 1
+ 	bic	r0, r0, #CACHE_DLINESIZE - 1
+ 	mcrne	p15, 0, r0, c7, c14, 1		@ clean & invalidate D entry
+@@ -180,7 +184,7 @@ fa_dma_inv_range:
+  *	- start  - virtual start address
+  *	- end	 - virtual end address
+  */
+-fa_dma_clean_range:
++ENTRY(fa_dma_clean_range)
+ 	bic	r0, r0, #CACHE_DLINESIZE - 1
+ 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+ 	add	r0, r0, #CACHE_DLINESIZE
+@@ -229,6 +233,10 @@ ENTRY(fa_dma_unmap_area)
+ 	mov	pc, lr
+ ENDPROC(fa_dma_unmap_area)
+ 
++
++
++
++
+ 	__INITDATA
+ 
+ 	.type	fa_cache_fns, #object
+@@ -243,3 +251,408 @@ ENTRY(fa_cache_fns)
+ 	.long	fa_dma_unmap_area
+ 	.long	fa_dma_flush_range
+ 	.size	fa_cache_fns, . - fa_cache_fns
++#else
++
++/* Most of the following is from 2.6.24-cavium */
++
++/*
++ *  linux/arch/arm/mm/cache-fa.S
++ *
++ *  Copyright (C) 2005 Faraday Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  Processors: FA520 FA526 FA626	
++ * 03/31/2005 :	Luke Lee created, modified from cache-v4wb.S
++ * 04/06/2005 :	1. Read CR0-1 and determine the cache size dynamically,
++ *		   to suit all Faraday CPU series
++ *	        2. Fixed all functions
++ * 04/08/2005 :	insert CONFIG_CPU_ICACHE_DISABLE and CONFIG_CPU_DCACHE_DISABLE
++ * 04/12/2005 :	TODO: make this processor dependent or a self-modifying code to 
++ *	        inline cache len/size info into the instructions, as reading cache 
++ *	        size and len info in memory could cause another cache miss.
++ * 05/05/2005 :	Modify fa_flush_user_cache_range to comply APCS.
++ * 05/19/2005 :	Adjust for boundary conditions.
++ */
++//#include <linux/config.h>
++#include <linux/linkage.h>
++#include <linux/init.h>
++#include <mach/hardware.h>
++#include <asm/page.h>
++#include "proc-macros.S"
++
++#define CACHE_DLINESIZE	   16
++#define CACHE_DSIZE	   16384
++#define CACHE_ILINESIZE	   16
++#define CACHE_ISIZE	   16384
++
++/*
++ *	initialize_cache_info()
++ *
++ *	Automatic detection of DSIZE, DLEN, ISIZE, ILEN variables according to 
++ *	system register CR0-1
++ *	Destroyed register: r0, r1, r2, r3, ip
++ */
++	.align
++ENTRY(fa_initialize_cache_info)
++	mov	r3, #1				@ r3 always = 1
++	adr	ip, __fa_cache_ilen
++	
++	mrc	p15, 0, r0, c0, c0, 1
++	/* ILEN */
++	and	r1, r0, #3			@ bits [1:0]
++	add	r1, r1, #3			@ cache line size is at least 8 bytes (2^3)
++	mov	r2, r3, lsl r1			@ r2 = 1<<r1
++	str	r2, [ip], #4
++	/* ISIZE */
++	mov	r1, r0, lsr #6			@ bits [8:6]
++	and	r1, r1, #7
++	add	r1, r1, #9			@ cache size is at least 512 bytes (2^9)
++	mov	r2, r3, lsl r1
++	str	r2, [ip], #4
++	/* DLEN */
++	mov	r1, r0, lsr #12
++	and	r1, r1, #3			@ bits [13:12]
++	add	r1, r1, #3			@ cache line size is at least 8 bytes (2^3)
++	mov	r2, r3, lsl r1			@ r2 = 1<<r1
++	str	r2, [ip], #4
++	/* DSIZE */
++	mov	r1, r0, lsr #18			@ bits [20:18]
++	and	r1, r1, #7
++	add	r1, r1, #9			@ cache size is at least 512 bytes (2^9)
++	mov	r2, r3, lsl r1
++	str	r2, [ip]
++	mov	pc, lr
++
++	/* Warning : Do not change the order ! Successive codes depends on this */
++	.align
++	.globl __fa_cache_ilen, __fa_cache_isize, __fa_cache_dlen, __fa_cache_dsize
++__fa_cache_ilen:
++	.word	0				@ instruction cache line length
++__fa_cache_isize:
++	.word	0				@ instruction cache size
++__fa_cache_dlen:
++	.word	0				@ data cahce line length	
++__fa_cache_dsize:
++	.word	0				@ data cache size
++
++/*
++ *	flush_user_cache_all()
++ *
++ *	Clean and invalidate all cache entries in a particular address
++ *	space.
++ */
++ENTRY(fa_flush_user_cache_all)
++	/* FALLTHROUGH */
++/*
++ *	flush_kern_cache_all()
++ *
++ *	Clean and invalidate the entire cache.
++ */
++ENTRY(fa_flush_kern_cache_all)
++	mov	ip, #0
++	
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
++#endif
++	
++__flush_whole_cache:
++	
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++	mov	ip, #0
++#  ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
++#  else
++	mcr	p15, 0, ip, c7,c14, 0		@ clean/invalidate D cache
++#  endif
++#endif /*CONFIG_CPU_DCACHE_DISABLE*/
++	
++#ifndef CONFIG_CPU_FA_WB_DISABLE	
++	mcr	p15, 0, ip, c7, c10, 4		@ drain write buffer
++#endif
++	
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, ip, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++#endif
++	
++	mov	pc, lr
++
++/*
++ *	flush_user_cache_range(start, end, flags)
++ *
++ *	Invalidate a range of cache entries in the specified
++ *	address space.
++ *
++ *	- start - start address (inclusive, page aligned)
++ *	- end	- end address (exclusive, page aligned)
++ *	- flags	- vma_area_struct flags describing address space
++ */
++ENTRY(fa_flush_user_cache_range)
++	mov	ip, #0
++	sub	r3, r1, r0			@ calculate total size
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++	tst	r2, #VM_EXEC			@ executable region?
++	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
++#endif
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE	
++	cmp	r3, #CACHE_DSIZE		@ total size >= limit?
++	bhs	__flush_whole_cache		@ flush whole D cache
++
++1:
++	
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
++#else
++	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
++#endif
++	add	r0, r0, #CACHE_DLINESIZE
++	cmp	r0, r1
++	bls	1b
++#endif	/* CONFIG_CPU_DCACHE_DISABLE */
++	
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	tst	r2, #VM_EXEC
++	mcreq	p15, 0, r4, c7, c10, 4		@ drain write buffer
++#endif
++
++#ifdef CONFIG_CPU_FA_BTB
++        tst     r2, #VM_EXEC
++	mov	ip, #0
++	mcrne	p15, 0, ip, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++#endif
++	mov	pc, lr
++
++/*
++ *	flush_kern_dcache_page(void *page)
++ *
++ *	Ensure no D cache aliasing occurs, either with itself or
++ *	the I cache
++ *
++ *	- addr	- page aligned address
++ */
++ENTRY(fa_flush_kern_dcache_page)
++	add	r1, r0, #PAGE_SZ
++	/* fall through */
++
++/*
++ *	coherent_kern_range(start, end)
++ *
++ *	Ensure coherency between the Icache and the Dcache in the
++ *	region described by start.  If you have non-snooping
++ *	Harvard caches, you need to implement this function.
++ *
++ *	- start  - virtual start address
++ *	- end	 - virtual end address
++ */
++ENTRY(fa_coherent_kern_range)
++	/* fall through */
++
++/*
++ *	coherent_user_range(start, end)
++ *
++ *	Ensure coherency between the Icache and the Dcache in the
++ *	region described by start.  If you have non-snooping
++ *	Harvard caches, you need to implement this function.
++ *
++ *	- start  - virtual start address
++ *	- end	 - virtual end address
++ */
++ENTRY(fa_coherent_user_range)
++	bic	r0, r0, #CACHE_DLINESIZE-1
++
++#if !(defined(CONFIG_CPU_DCACHE_DISABLE) && defined(CONFIG_CPU_ICACHE_DISABLE))
++1:
++#ifndef CONFIG_CPU_DCACHE_DISABLE	
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
++#else
++	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
++#endif
++#endif /* CONFIG_CPU_DCACHE_DISABLE */
++	
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I entry
++#endif
++	add	r0, r0, #CACHE_DLINESIZE
++	cmp	r0, r1
++	bls	1b				@ Luke Lee 05/19/2005 blo->bls	
++#endif /* !(defined(CONFIG_CPU_DCACHE_DISABLE) && defined(CONFIG_CPU_ICACHE_DISABLE)) */
++
++	mov	ip, #0
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, ip, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++#endif
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
++#endif
++	
++	mov	pc, lr
++
++/*
++ *	dma_inv_range(start, end)
++ *
++ *	Invalidate (discard) the specified virtual address range.
++ *	May not write back any entries.  If 'start' or 'end'
++ *	are not cache line aligned, those lines must be written
++ *	back.
++ *
++ *	- start  - virtual start address
++ *	- end	 - virtual end address
++ */
++ENTRY(fa_dma_inv_range)
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE	
++
++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
++	tst	r0, #CACHE_DLINESIZE -1
++	bic	r0, r0, #CACHE_DLINESIZE -1
++	mcrne	p15, 0, r0, c7, c10, 1		@ clean boundary D entry
++	mcr	p15, 0, r1, c7, c10, 1		@ clean boundary D entry
++#else
++	bic	r0, r0, #CACHE_DLINESIZE -1	
++#endif
++	
++1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
++	add	r0, r0, #CACHE_DLINESIZE
++	cmp	r0, r1
++	bls	1b				@ Luke Lee 05/19/2005 blo->bls
++#endif /* CONFIG_CPU_DCACHE_DISABLE */
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mov	r0, #0
++	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
++#endif	
++	mov	pc, lr
++
++	
++	
++	
++	
++	
++	
++	
++/***** The following was lifted from 2.6.34 */   
++/*
++ *	flush_kern_dcache_area(void *addr, size_t size)
++ *
++ *	Ensure that the data held in the page kaddr is written back
++ *	to the page in question.
++ *
++ *	- addr	- kernel address
++ *	- size	- size of region
++ */
++ENTRY(fa_flush_kern_dcache_area)
++	add	r1, r0, r1
++1:	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line
++	add	r0, r0, #CACHE_DLINESIZE
++	cmp	r0, r1
++	blo	1b
++	mov	r0, #0
++	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
++	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
++	mov	pc, lr
++   
++/*
++ *	dma_map_area(start, size, dir)
++ *	- start	- kernel virtual start address
++ *	- size	- size of region
++ *	- dir	- DMA direction
++ */
++ENTRY(fa_dma_map_area)
++	add	r1, r1, r0
++	cmp	r2, #DMA_TO_DEVICE
++	beq	fa_dma_clean_range
++	bcs	fa_dma_inv_range
++	b	fa_dma_flush_range
++ENDPROC(fa_dma_map_area)
++
++/*
++ *	dma_unmap_area(start, size, dir)
++ *	- start	- kernel virtual start address
++ *	- size	- size of region
++ *	- dir	- DMA direction
++ */
++ENTRY(fa_dma_unmap_area)
++	mov	pc, lr
++ENDPROC(fa_dma_unmap_area)   
++
++
++/********************/
++	
++	
++	
++	
++	
++	
++
++	
++	
++/*
++ *	dma_clean_range(start, end)
++ *
++ *	Clean (write back) the specified virtual address range.
++ *
++ *	- start  - virtual start address
++ *	- end	 - virtual end address
++ */
++ENTRY(fa_dma_clean_range)
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE	
++
++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
++	bic	r0, r0, #CACHE_DLINESIZE - 1
++1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
++	add	r0, r0, #CACHE_DLINESIZE
++	cmp	r0, r1
++	bls	1b				@ Luke Lee 05/19/2005 blo->bls
++
++#endif
++#endif /* CONFIG_CPU_DCACHE_DISABLE */
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mov	r0, #0	
++	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
++#endif	
++	mov	pc, lr
++
++/*
++ *	dma_flush_range(start, end)
++ *
++ *	Clean and invalidate the specified virtual address range.
++ *
++ *	- start  - virtual start address
++ *	- end	 - virtual end address
++ *
++ *	This is actually the same as fa_coherent_kern_range()
++ */
++	.globl	fa_dma_flush_range
++	.set	fa_dma_flush_range, fa_coherent_kern_range
++
++	__INITDATA
++
++	.type	fa_cache_fns, #object
++ENTRY(fa_cache_fns)
++	.long	fa_flush_kern_cache_all
++	.long	fa_flush_user_cache_all
++	.long	fa_flush_user_cache_range
++	.long	fa_coherent_kern_range
++	.long	fa_coherent_user_range
++	.long	fa_flush_kern_dcache_page
++	.long	fa_dma_inv_range
++	.long	fa_dma_clean_range
++	.long	fa_dma_flush_range
++	.size	fa_cache_fns, . - fa_cache_fns
++   
++
++   
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mm/copypage-fa.c linux-2.6.35.11-ts7500/arch/arm/mm/copypage-fa.c
+--- linux-2.6.35.11/arch/arm/mm/copypage-fa.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/copypage-fa.c	2011-03-14 11:18:24.000000000 -0400
+@@ -14,6 +14,7 @@
+ #include <linux/init.h>
+ #include <linux/highmem.h>
+ 
++#include <asm/page.h>
+ /*
+  * Faraday optimised copy_user_page
+  */
+diff -rupN linux-2.6.35.11/arch/arm/mm/dma-mapping.c linux-2.6.35.11-ts7500/arch/arm/mm/dma-mapping.c
+--- linux-2.6.35.11/arch/arm/mm/dma-mapping.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/dma-mapping.c	2011-03-14 11:18:24.000000000 -0400
+@@ -576,7 +576,8 @@ EXPORT_SYMBOL(dma_unmap_sg);
+  * @nents: number of buffers to map (returned from dma_map_sg)
+  * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+  */
+-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
++void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist 
++*sg,
+ 			int nents, enum dma_data_direction dir)
+ {
+ 	struct scatterlist *s;
+diff -rupN linux-2.6.35.11/arch/arm/mm/dma-mapping.c.orig linux-2.6.35.11-ts7500/arch/arm/mm/dma-mapping.c.orig
+--- linux-2.6.35.11/arch/arm/mm/dma-mapping.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/dma-mapping.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,618 @@
++/*
++ *  linux/arch/arm/mm/dma-mapping.c
++ *
++ *  Copyright (C) 2000-2004 Russell King
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  DMA uncached mapping support.
++ */
++#include <linux/module.h>
++#include <linux/mm.h>
++#include <linux/gfp.h>
++#include <linux/errno.h>
++#include <linux/list.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++
++#include <asm/memory.h>
++#include <asm/highmem.h>
++#include <asm/cacheflush.h>
++#include <asm/tlbflush.h>
++#include <asm/sizes.h>
++
++static u64 get_coherent_dma_mask(struct device *dev)
++{
++	u64 mask = ISA_DMA_THRESHOLD;
++
++	if (dev) {
++		mask = dev->coherent_dma_mask;
++
++		/*
++		 * Sanity check the DMA mask - it must be non-zero, and
++		 * must be able to be satisfied by a DMA allocation.
++		 */
++		if (mask == 0) {
++			dev_warn(dev, "coherent DMA mask is unset\n");
++			return 0;
++		}
++
++		if ((~mask) & ISA_DMA_THRESHOLD) {
++			dev_warn(dev, "coherent DMA mask %#llx is smaller "
++				 "than system GFP_DMA mask %#llx\n",
++				 mask, (unsigned long long)ISA_DMA_THRESHOLD);
++			return 0;
++		}
++	}
++
++	return mask;
++}
++
++/*
++ * Allocate a DMA buffer for 'dev' of size 'size' using the
++ * specified gfp mask.  Note that 'size' must be page aligned.
++ */
++static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
++{
++	unsigned long order = get_order(size);
++	struct page *page, *p, *e;
++	void *ptr;
++	u64 mask = get_coherent_dma_mask(dev);
++
++#ifdef CONFIG_DMA_API_DEBUG
++	u64 limit = (mask + 1) & ~mask;
++	if (limit && size >= limit) {
++		dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
++			size, mask);
++		return NULL;
++	}
++#endif
++
++	if (!mask)
++		return NULL;
++
++	if (mask < 0xffffffffULL)
++		gfp |= GFP_DMA;
++
++	page = alloc_pages(gfp, order);
++	if (!page)
++		return NULL;
++
++	/*
++	 * Now split the huge page and free the excess pages
++	 */
++	split_page(page, order);
++	for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
++		__free_page(p);
++
++	/*
++	 * Ensure that the allocated pages are zeroed, and that any data
++	 * lurking in the kernel direct-mapped region is invalidated.
++	 */
++	ptr = page_address(page);
++	memset(ptr, 0, size);
++	dmac_flush_range(ptr, ptr + size);
++	outer_flush_range(__pa(ptr), __pa(ptr) + size);
++
++	return page;
++}
++
++/*
++ * Free a DMA buffer.  'size' must be page aligned.
++ */
++static void __dma_free_buffer(struct page *page, size_t size)
++{
++	struct page *e = page + (size >> PAGE_SHIFT);
++
++	while (page < e) {
++		__free_page(page);
++		page++;
++	}
++}
++
++#ifdef CONFIG_MMU
++/* Sanity check size */
++#if (CONSISTENT_DMA_SIZE % SZ_2M)
++#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
++#endif
++
++#define CONSISTENT_OFFSET(x)	(((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
++#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
++#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
++
++/*
++ * These are the page tables (2MB each) covering uncached, DMA consistent allocations
++ */
++static pte_t *consistent_pte[NUM_CONSISTENT_PTES];
++
++#include "vmregion.h"
++
++static struct arm_vmregion_head consistent_head = {
++	.vm_lock	= __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),
++	.vm_list	= LIST_HEAD_INIT(consistent_head.vm_list),
++	.vm_start	= CONSISTENT_BASE,
++	.vm_end		= CONSISTENT_END,
++};
++
++#ifdef CONFIG_HUGETLB_PAGE
++#error ARM Coherent DMA allocator does not (yet) support huge TLB
++#endif
++
++/*
++ * Initialise the consistent memory allocation.
++ */
++static int __init consistent_init(void)
++{
++	int ret = 0;
++	pgd_t *pgd;
++	pmd_t *pmd;
++	pte_t *pte;
++	int i = 0;
++	u32 base = CONSISTENT_BASE;
++
++	do {
++		pgd = pgd_offset(&init_mm, base);
++		pmd = pmd_alloc(&init_mm, pgd, base);
++		if (!pmd) {
++			printk(KERN_ERR "%s: no pmd tables\n", __func__);
++			ret = -ENOMEM;
++			break;
++		}
++		WARN_ON(!pmd_none(*pmd));
++
++		pte = pte_alloc_kernel(pmd, base);
++		if (!pte) {
++			printk(KERN_ERR "%s: no pte tables\n", __func__);
++			ret = -ENOMEM;
++			break;
++		}
++
++		consistent_pte[i++] = pte;
++		base += (1 << PGDIR_SHIFT);
++	} while (base < CONSISTENT_END);
++
++	return ret;
++}
++
++core_initcall(consistent_init);
++
++static void *
++__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
++{
++	struct arm_vmregion *c;
++
++	if (!consistent_pte[0]) {
++		printk(KERN_ERR "%s: not initialised\n", __func__);
++		dump_stack();
++		return NULL;
++	}
++
++	/*
++	 * Allocate a virtual address in the consistent mapping region.
++	 */
++	c = arm_vmregion_alloc(&consistent_head, size,
++			    gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
++	if (c) {
++		pte_t *pte;
++		int idx = CONSISTENT_PTE_INDEX(c->vm_start);
++		u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
++
++		pte = consistent_pte[idx] + off;
++		c->vm_pages = page;
++
++		do {
++			BUG_ON(!pte_none(*pte));
++
++			set_pte_ext(pte, mk_pte(page, prot), 0);
++			page++;
++			pte++;
++			off++;
++			if (off >= PTRS_PER_PTE) {
++				off = 0;
++				pte = consistent_pte[++idx];
++			}
++		} while (size -= PAGE_SIZE);
++
++		return (void *)c->vm_start;
++	}
++	return NULL;
++}
++
++static void __dma_free_remap(void *cpu_addr, size_t size)
++{
++	struct arm_vmregion *c;
++	unsigned long addr;
++	pte_t *ptep;
++	int idx;
++	u32 off;
++
++	c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
++	if (!c) {
++		printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
++		       __func__, cpu_addr);
++		dump_stack();
++		return;
++	}
++
++	if ((c->vm_end - c->vm_start) != size) {
++		printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
++		       __func__, c->vm_end - c->vm_start, size);
++		dump_stack();
++		size = c->vm_end - c->vm_start;
++	}
++
++	idx = CONSISTENT_PTE_INDEX(c->vm_start);
++	off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
++	ptep = consistent_pte[idx] + off;
++	addr = c->vm_start;
++	do {
++		pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
++
++		ptep++;
++		addr += PAGE_SIZE;
++		off++;
++		if (off >= PTRS_PER_PTE) {
++			off = 0;
++			ptep = consistent_pte[++idx];
++		}
++
++		if (pte_none(pte) || !pte_present(pte))
++			printk(KERN_CRIT "%s: bad page in kernel page table\n",
++			       __func__);
++	} while (size -= PAGE_SIZE);
++
++	flush_tlb_kernel_range(c->vm_start, c->vm_end);
++
++	arm_vmregion_free(&consistent_head, c);
++}
++
++#else	/* !CONFIG_MMU */
++
++#define __dma_alloc_remap(page, size, gfp, prot)	page_address(page)
++#define __dma_free_remap(addr, size)			do { } while (0)
++
++#endif	/* CONFIG_MMU */
++
++static void *
++__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
++	    pgprot_t prot)
++{
++	struct page *page;
++	void *addr;
++
++	*handle = ~0;
++	size = PAGE_ALIGN(size);
++
++	page = __dma_alloc_buffer(dev, size, gfp);
++	if (!page)
++		return NULL;
++
++	if (!arch_is_coherent())
++		addr = __dma_alloc_remap(page, size, gfp, prot);
++	else
++		addr = page_address(page);
++
++	if (addr)
++		*handle = page_to_dma(dev, page);
++
++	return addr;
++}
++
++/*
++ * Allocate DMA-coherent memory space and return both the kernel remapped
++ * virtual and bus address for that space.
++ */
++void *
++dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
++{
++	void *memory;
++
++	if (dma_alloc_from_coherent(dev, size, handle, &memory))
++		return memory;
++
++	return __dma_alloc(dev, size, handle, gfp,
++			   pgprot_dmacoherent(pgprot_kernel));
++}
++EXPORT_SYMBOL(dma_alloc_coherent);
++
++/*
++ * Allocate a writecombining region, in much the same way as
++ * dma_alloc_coherent above.
++ */
++void *
++dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
++{
++	return __dma_alloc(dev, size, handle, gfp,
++			   pgprot_writecombine(pgprot_kernel));
++}
++EXPORT_SYMBOL(dma_alloc_writecombine);
++
++static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
++		    void *cpu_addr, dma_addr_t dma_addr, size_t size)
++{
++	int ret = -ENXIO;
++#ifdef CONFIG_MMU
++	unsigned long user_size, kern_size;
++	struct arm_vmregion *c;
++
++	user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
++
++	c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
++	if (c) {
++		unsigned long off = vma->vm_pgoff;
++
++		kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT;
++
++		if (off < kern_size &&
++		    user_size <= (kern_size - off)) {
++			ret = remap_pfn_range(vma, vma->vm_start,
++					      page_to_pfn(c->vm_pages) + off,
++					      user_size << PAGE_SHIFT,
++					      vma->vm_page_prot);
++		}
++	}
++#endif	/* CONFIG_MMU */
++
++	return ret;
++}
++
++int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
++		      void *cpu_addr, dma_addr_t dma_addr, size_t size)
++{
++	vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot);
++	return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
++}
++EXPORT_SYMBOL(dma_mmap_coherent);
++
++int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
++			  void *cpu_addr, dma_addr_t dma_addr, size_t size)
++{
++	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
++	return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
++}
++EXPORT_SYMBOL(dma_mmap_writecombine);
++
++/*
++ * free a page as defined by the above mapping.
++ * Must not be called with IRQs disabled.
++ */
++void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
++{
++	WARN_ON(irqs_disabled());
++
++	if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
++		return;
++
++	size = PAGE_ALIGN(size);
++
++	if (!arch_is_coherent())
++		__dma_free_remap(cpu_addr, size);
++
++	__dma_free_buffer(dma_to_page(dev, handle), size);
++}
++EXPORT_SYMBOL(dma_free_coherent);
++
++/*
++ * Make an area consistent for devices.
++ * Note: Drivers should NOT use this function directly, as it will break
++ * platforms with CONFIG_DMABOUNCE.
++ * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
++ */
++void ___dma_single_cpu_to_dev(const void *kaddr, size_t size,
++	enum dma_data_direction dir)
++{
++	unsigned long paddr;
++
++	BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
++
++	dmac_map_area(kaddr, size, dir);
++
++	paddr = __pa(kaddr);
++	if (dir == DMA_FROM_DEVICE) {
++		outer_inv_range(paddr, paddr + size);
++	} else {
++		outer_clean_range(paddr, paddr + size);
++	}
++	/* FIXME: non-speculating: flush on bidirectional mappings? */
++}
++EXPORT_SYMBOL(___dma_single_cpu_to_dev);
++
++void ___dma_single_dev_to_cpu(const void *kaddr, size_t size,
++	enum dma_data_direction dir)
++{
++	BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
++
++	/* FIXME: non-speculating: not required */
++	/* don't bother invalidating if DMA to device */
++	if (dir != DMA_TO_DEVICE) {
++		unsigned long paddr = __pa(kaddr);
++		outer_inv_range(paddr, paddr + size);
++	}
++
++	dmac_unmap_area(kaddr, size, dir);
++}
++EXPORT_SYMBOL(___dma_single_dev_to_cpu);
++
++static void dma_cache_maint_page(struct page *page, unsigned long offset,
++	size_t size, enum dma_data_direction dir,
++	void (*op)(const void *, size_t, int))
++{
++	/*
++	 * A single sg entry may refer to multiple physically contiguous
++	 * pages.  But we still need to process highmem pages individually.
++	 * If highmem is not configured then the bulk of this loop gets
++	 * optimized out.
++	 */
++	size_t left = size;
++	do {
++		size_t len = left;
++		void *vaddr;
++
++		if (PageHighMem(page)) {
++			if (len + offset > PAGE_SIZE) {
++				if (offset >= PAGE_SIZE) {
++					page += offset / PAGE_SIZE;
++					offset %= PAGE_SIZE;
++				}
++				len = PAGE_SIZE - offset;
++			}
++			vaddr = kmap_high_get(page);
++			if (vaddr) {
++				vaddr += offset;
++				op(vaddr, len, dir);
++				kunmap_high(page);
++			} else if (cache_is_vipt()) {
++				pte_t saved_pte;
++				vaddr = kmap_high_l1_vipt(page, &saved_pte);
++				op(vaddr + offset, len, dir);
++				kunmap_high_l1_vipt(page, saved_pte);
++			}
++		} else {
++			vaddr = page_address(page) + offset;
++			op(vaddr, len, dir);
++		}
++		offset = 0;
++		page++;
++		left -= len;
++	} while (left);
++}
++
++void ___dma_page_cpu_to_dev(struct page *page, unsigned long off,
++	size_t size, enum dma_data_direction dir)
++{
++	unsigned long paddr;
++
++	dma_cache_maint_page(page, off, size, dir, dmac_map_area);
++
++	paddr = page_to_phys(page) + off;
++	if (dir == DMA_FROM_DEVICE) {
++		outer_inv_range(paddr, paddr + size);
++	} else {
++		outer_clean_range(paddr, paddr + size);
++	}
++	/* FIXME: non-speculating: flush on bidirectional mappings? */
++}
++EXPORT_SYMBOL(___dma_page_cpu_to_dev);
++
++void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
++	size_t size, enum dma_data_direction dir)
++{
++	unsigned long paddr = page_to_phys(page) + off;
++
++	/* FIXME: non-speculating: not required */
++	/* don't bother invalidating if DMA to device */
++	if (dir != DMA_TO_DEVICE)
++		outer_inv_range(paddr, paddr + size);
++
++	dma_cache_maint_page(page, off, size, dir, dmac_unmap_area);
++}
++EXPORT_SYMBOL(___dma_page_dev_to_cpu);
++
++/**
++ * dma_map_sg - map a set of SG buffers for streaming mode DMA
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @sg: list of buffers
++ * @nents: number of buffers to map
++ * @dir: DMA transfer direction
++ *
++ * Map a set of buffers described by scatterlist in streaming mode for DMA.
++ * This is the scatter-gather version of the dma_map_single interface.
++ * Here the scatter gather list elements are each tagged with the
++ * appropriate dma address and length.  They are obtained via
++ * sg_dma_{address,length}.
++ *
++ * Device ownership issues as mentioned for dma_map_single are the same
++ * here.
++ */
++int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
++		enum dma_data_direction dir)
++{
++	struct scatterlist *s;
++	int i, j;
++
++	for_each_sg(sg, s, nents, i) {
++		s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
++						s->length, dir);
++		if (dma_mapping_error(dev, s->dma_address))
++			goto bad_mapping;
++	}
++	return nents;
++
++ bad_mapping:
++	for_each_sg(sg, s, i, j)
++		dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
++	return 0;
++}
++EXPORT_SYMBOL(dma_map_sg);
++
++/**
++ * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @sg: list of buffers
++ * @nents: number of buffers to unmap (returned from dma_map_sg)
++ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
++ *
++ * Unmap a set of streaming mode DMA translations.  Again, CPU access
++ * rules concerning calls here are the same as for dma_unmap_single().
++ */
++void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
++		enum dma_data_direction dir)
++{
++	struct scatterlist *s;
++	int i;
++
++	for_each_sg(sg, s, nents, i)
++		dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
++}
++EXPORT_SYMBOL(dma_unmap_sg);
++
++/**
++ * dma_sync_sg_for_cpu
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @sg: list of buffers
++ * @nents: number of buffers to map (returned from dma_map_sg)
++ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
++ */
++void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
++			int nents, enum dma_data_direction dir)
++{
++	struct scatterlist *s;
++	int i;
++
++	for_each_sg(sg, s, nents, i) {
++		if (!dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
++					    sg_dma_len(s), dir))
++			continue;
++
++		__dma_page_dev_to_cpu(sg_page(s), s->offset,
++				      s->length, dir);
++	}
++}
++EXPORT_SYMBOL(dma_sync_sg_for_cpu);
++
++/**
++ * dma_sync_sg_for_device
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @sg: list of buffers
++ * @nents: number of buffers to map (returned from dma_map_sg)
++ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
++ */
++void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
++			int nents, enum dma_data_direction dir)
++{
++	struct scatterlist *s;
++	int i;
++
++	for_each_sg(sg, s, nents, i) {
++		if (!dmabounce_sync_for_device(dev, sg_dma_address(s), 0,
++					sg_dma_len(s), dir))
++			continue;
++
++		__dma_page_cpu_to_dev(sg_page(s), s->offset,
++				      s->length, dir);
++	}
++}
++EXPORT_SYMBOL(dma_sync_sg_for_device);
+diff -rupN linux-2.6.35.11/arch/arm/mm/flush.c linux-2.6.35.11-ts7500/arch/arm/mm/flush.c
+--- linux-2.6.35.11/arch/arm/mm/flush.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/flush.c	2011-03-14 11:18:24.000000000 -0400
+@@ -290,7 +290,7 @@ void __flush_anon_page(struct vm_area_st
+ 		 * userspace address only.
+ 		 */
+ 		flush_pfn_alias(pfn, vmaddr);
+-		__flush_icache_all();
++		__flush_icache_all(); 
+ 	}
+ 
+ 	/*
+diff -rupN linux-2.6.35.11/arch/arm/mm/Kconfig linux-2.6.35.11-ts7500/arch/arm/mm/Kconfig
+--- linux-2.6.35.11/arch/arm/mm/Kconfig	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -142,6 +142,54 @@ config CPU_ARM922T
+ 	  Say Y if you want support for the ARM922T processor.
+ 	  Otherwise, say N.
+ 
++# FA520/FA526/FA626
++
++choice
++	prompt "Faraday processor (ARM9 compatible) type"
++	default CPU_FA526
++	depends on ARCH_STR9100 || ARCH_STR8100
++
++#config CPU_FA520
++#       bool  "FA520 processor"
++#       depends on ARCH_STR9100 || ARCH_STR8100
++#       select CPU_32v4
++#       select CPU_ABRT_EV4
++#       select CPU_CACHE_FA
++#       select CPU_CACHE_VIVT
++#       select CPU_COPY_V4WB
++#       select CPU_TLB_FA
++#       help
++#         //TODO: FA520 help info
++
++config CPU_FA526
++	bool  "FA526 processor"
++	depends on ARCH_STR9100 || ARCH_STR8100
++	select CPU_32v4
++   select CPU_PABRT_LEGACY
++	select CPU_ABRT_EV4
++   select CPU_CP15_MMU
++   select CPU_CACHE_FA
++   select CPU_CACHE_VIVT
++	select CPU_COPY_FA if MMU
++	select CPU_TLB_FA if MMU
++	help
++	  //TODO: FA526 help info
++
++#config CPU_FA626
++#       bool  "FA626 processor"
++#       depends on ARCH_STR9100 || ARCH_STR8100
++#       select CPU_32v4
++#       select CPU_ABRT_EV4
++#       select CPU_CACHE_FA
++#       select CPU_CACHE_VIPT
++#       select CPU_COPY_V4WB
++#       select CPU_TLB_FA
++#       help
++#         //TODO: FA626 help info
++
++endchoice
++     
++     
+ # ARM925T
+ config CPU_ARM925T
+  	bool "Support ARM925T processor" if ARCH_OMAP1
+@@ -180,22 +228,22 @@ config CPU_ARM926T
+ 	  Otherwise, say N.
+ 
+ # FA526
+-config CPU_FA526
+-	bool
+-	select CPU_32v4
+-	select CPU_ABRT_EV4
+-	select CPU_PABRT_LEGACY
+-	select CPU_CACHE_VIVT
+-	select CPU_CP15_MMU
+-	select CPU_CACHE_FA
+-	select CPU_COPY_FA if MMU
+-	select CPU_TLB_FA if MMU
+-	help
+-	  The FA526 is a version of the ARMv4 compatible processor with
+-	  Branch Target Buffer, Unified TLB and cache line size 16.
+-
+-	  Say Y if you want support for the FA526 processor.
+-	  Otherwise, say N.
++#config CPU_FA526
++#	bool
++#	select CPU_32v4
++#	select CPU_ABRT_EV4
++#	select CPU_PABRT_LEGACY
++#	select CPU_CACHE_VIVT
++#	select CPU_CP15_MMU
++#	select CPU_CACHE_FA
++#	select CPU_COPY_FA if MMU
++#	select CPU_TLB_FA if MMU
++#	help
++#	  The FA526 is a version of the ARMv4 compatible processor with
++#	  Branch Target Buffer, Unified TLB and cache line size 16.
++#
++#	  Say Y if you want support for the FA526 processor.
++#	  Otherwise, say N.
+ 
+ # ARM940T
+ config CPU_ARM940T
+@@ -566,6 +614,7 @@ config CPU_TLB_FA
+ 	  and invalidate instruction cache entry. Branch target buffer is
+ 	  also supported.
+ 
++      
+ config CPU_TLB_V6
+ 	bool
+ 
+@@ -664,14 +713,16 @@ config CPU_HIGH_VECTOR
+ 
+ config CPU_ICACHE_DISABLE
+ 	bool "Disable I-Cache (I-bit)"
+-	depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3)
++#	depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3 || CPU_FA520 || CPU_FA526 || CPU_FA626)
++   depends on CPU_CP15
+ 	help
+ 	  Say Y here to disable the processor instruction cache. Unless
+ 	  you have a reason not to or are unsure, say N.
+ 
+ config CPU_DCACHE_DISABLE
+ 	bool "Disable D-Cache (C-bit)"
+-	depends on CPU_CP15
++#	depends on CPU_CP15 && !(CPU_FA520 || CPU_FA526 || CPU_FA626)
++ 	depends on CPU_CP15  
+ 	help
+ 	  Say Y here to disable the processor data cache. Unless
+ 	  you have a reason not to or are unsure, say N.
+@@ -697,6 +748,19 @@ config CPU_DCACHE_WRITETHROUGH
+ 	  Say Y here to use the data cache in writethrough mode. Unless you
+ 	  specifically require this or are unsure, say N.
+ 
++config CPU_FA_BTB
++ 	bool "BTB support (EXPERIMENTAL)"
++ 	depends on CPU_FA520 || CPU_FA526 || CPU_FA626
++ 	default y
++ 	help
++ 	//TODO: FA BTB
++
++config CPU_FA_WB_DISABLE
++ 	bool "Disable write buffer (EXPERIMENTAL)"
++ 	depends on CPU_FA520 || CPU_FA526 || CPU_FA626
++ 	help
++ 	//TODO: FA write buffer     
++     
+ config CPU_CACHE_ROUND_ROBIN
+ 	bool "Round robin I and D cache replacement algorithm"
+ 	depends on (CPU_ARM926T || CPU_ARM946E || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE)
+diff -rupN linux-2.6.35.11/arch/arm/mm/proc-fa526.S linux-2.6.35.11-ts7500/arch/arm/mm/proc-fa526.S
+--- linux-2.6.35.11/arch/arm/mm/proc-fa526.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/proc-fa526.S	2011-03-14 11:18:24.000000000 -0400
+@@ -1,3 +1,4 @@
++#if (1)
+ /*
+  *  linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526
+  *
+@@ -138,6 +139,7 @@ ENTRY(cpu_fa526_set_pte_ext)
+ #endif
+ 	mov	pc, lr
+ 
++   
+ 	__INIT
+ 
+ 	.type	__fa526_setup, #function
+@@ -246,3 +248,428 @@ __fa526_proc_info:
+ 	.long	fa_user_fns
+ 	.long	fa_cache_fns
+ 	.size	__fa526_proc_info, . - __fa526_proc_info
++   
++#else
++/*
++ *  linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526
++ *
++ *  Copyright (C) 2005 Faraday Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ *
++ * These are the low level assembler for performing cache and TLB
++ * functions on the fa526.
++ *
++ *  Written by : Luke Lee
++ */
++#include <linux/linkage.h>
++//#include <linux/config.h>
++#include <linux/init.h>
++#include <asm/assembler.h>
++#include <asm/pgtable.h>
++/* scott.test
++#include <asm/procinfo.h>
++*/
++#include <mach/hardware.h>
++#include <asm/page.h>
++#include <asm/ptrace.h>
++#include <asm/system.h>
++#include "proc-macros.S"
++
++#define CACHE_DLINESIZE	   16
++
++	.text
++/*
++ * cpu_fa526_proc_init()
++ */
++ENTRY(cpu_fa526_proc_init)
++	/* MMU is already ON here, ICACHE, DCACHE conditionally disabled */
++
++        mov     r0, #1
++	nop
++	nop
++        mcr     p15, 0, r0, c1, c1, 0		@ turn-on ECR
++	nop
++	nop
++
++	mrc	p15, 0, r0, c1, c0, 0		@ read ctrl register
++
++#ifdef CONFIG_CPU_FA_BTB
++	orr	r0, r0, #CR_Z
++#else
++	bic	r0, r0, #CR_Z	
++#endif
++#ifdef CONFIG_CPU_FA_WB_DISABLE
++	mov	r1, #0
++	mcr	p15, 0, r1, c7, c10, 4		@ drain write buffer
++	nop
++	nop
++	bic	r0, r0, #CR_W
++#else
++	orr	r0, r0, #CR_W
++#endif
++#ifdef CONFIG_CPU_DCACHE_DISABLE
++	bic	r0, r0, #CR_C
++#else
++	orr	r0, r0, #CR_C	
++#endif
++#ifdef CONFIG_CPU_ICACHE_DISABLE
++	bic	r0, r0, #CR_I
++#else
++	orr	r0, r0, #CR_I	
++#endif
++	
++	nop
++	nop
++    	mcr	p15, 0, r0, c1, c0, 0
++	nop
++	nop
++
++	mov	r5, lr
++	bl	fa_initialize_cache_info	@ destroy r0~r4	
++	mov	pc, r5				@ return
++
++
++/*
++ * cpu_fa526_proc_fin()
++ */
++ENTRY(cpu_fa526_proc_fin)
++	stmfd	sp!, {lr}
++	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
++	msr	cpsr_c, ip
++
++	bl	fa_flush_kern_cache_all
++	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
++	bic	r0, r0, #0x1000			@ ...i............
++	bic	r0, r0, #0x000e			@ ............wca.
++	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
++
++	nop
++	nop
++	ldmfd	sp!, {pc}
++
++/*
++ * cpu_fa526_reset(loc)
++ *
++ * Perform a soft reset of the system.  Put the CPU into the
++ * same state as it would be if it had been reset, and branch
++ * to what would be the reset vector.
++ *
++ * loc: location to jump to for soft reset
++ */
++	.align	4
++ENTRY(cpu_fa526_reset)
++	mov	ip, #0
++	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
++#ifndef CONFIG_CPU_FA_WB_DISABLE	
++	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
++#endif	
++	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
++	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
++	bic	ip, ip, #0x000f			@ ............wcam
++	bic	ip, ip, #0x1100			@ ...i...s........
++
++	bic	ip, ip, #0x0800			@ BTB off
++	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
++	nop
++	nop
++	mov	pc, r0
++
++/*
++ * cpu_fa526_do_idle()
++ */
++	.align	4
++ENTRY(cpu_fa526_do_idle)
++
++#ifdef CONFIG_CPU_FA_IDLE
++	nop
++	nop
++	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt (IDLE mode)
++#endif
++	mov	pc, lr
++
++
++ENTRY(cpu_fa526_dcache_clean_area)
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
++1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
++	add	r0, r0, #CACHE_DLINESIZE
++	subs	r1, r1, #CACHE_DLINESIZE
++	bhi	1b
++#endif
++#endif	
++	mov	pc, lr
++	
++
++/* =============================== PageTable ============================== */
++
++/*
++ * cpu_fa526_switch_mm(pgd)
++ *
++ * Set the translation base pointer to be as described by pgd.
++ *
++ * pgd: new page tables
++ */
++	.align	4
++
++	.globl	fault_address
++fault_address:	
++	.long	0
++	
++ENTRY(cpu_fa526_switch_mm)
++
++	mov	ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE	
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
++#else
++	mcr	p15, 0, ip, c7, c14, 0		@ Clean and invalidate whole DCache
++#endif
++#endif /*CONFIG_CPU_DCACHE_DISABLE*/
++	
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
++#endif	
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
++#endif	
++
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, ip, c7, c5, 6		@ invalidate BTB since mm changed
++	nop
++	nop
++#endif
++	bic	r0, r0, #0xff			@ clear bits [7:0]
++	bic	r0, r0, #0x3f00			@ clear bits [13:8]
++	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
++	mcr	p15, 0, ip, c8, c7, 0		@ invalidate UTLB
++	nop
++	nop
++	mov	pc, lr
++
++/*
++ * cpu_fa526_set_pte_ext(ptep, pte, ext)
++ *
++ * Set a PTE and flush it out
++ */
++	.align	4
++ENTRY(cpu_fa526_set_pte_ext)
++	str	r1, [r0], #-2048		@ linux version
++	
++	eor	r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
++
++	bic	r2, r1, #PTE_SMALL_AP_MASK
++	bic	r2, r2, #PTE_TYPE_MASK
++	orr	r2, r2, #PTE_TYPE_SMALL
++
++	tst	r1, #L_PTE_USER			@ User?
++	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
++
++	tst	r1, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
++	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
++
++	tst	r1, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
++	movne	r2, #0
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	eor	r3, r2, #0x0a			@ C & small page?  1010
++	tst	r3, #0x0b			@		   1011
++	biceq	r2, r2, #4
++#endif
++	str	r2, [r0]			@ hardware version
++
++	mov	r2, #0
++	mcr	p15, 0, r2, c7, c10, 0		@ clean D cache	all
++	
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
++#endif
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, r2, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++#endif
++	mov	pc, lr
++	
++   
++#ifdef CONFIG_DEBUG_LL
++str_fa526_setup: .asciz "str_fa526_setup\n"   
++str_fa526_setup_done: .asciz "str_fa526_setup_done\n"
++.align 4
++#endif   
++	__INIT
++
++	.type	__fa526_setup, #function
++__fa526_setup:
++#ifdef CONFIG_DEBUG_LL
++   adr	r0, str_fa526_setup
++	bl	printascii
++#endif
++	/* On return of this routine, r0 must carry correct flags for CFG register */	
++	mov	r0, #0
++	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
++	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
++	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
++
++	mcr	p15, 0, r0, c7, c5, 5		@ invalidate IScratchpad RAM
++
++        mov     r0, #1
++        mcr     p15, 0, r0, c1, c1, 0		@ turn-on ECR
++
++	mrc	p15, 0, r0, c9, c1, 0		@ DScratchpad
++	bic	r0, r0, #1
++	mcr	p15, 0, r0, c9, c1, 0
++	mrc	p15, 0, r0, c9, c1, 1		@ IScratchpad
++	bic	r0, r0, #1
++	mcr	p15, 0, r0, c9, c1, 1
++
++	mov	r0, #0
++	mcr	p15, 0, r0, c1, c1, 0		@ turn-off ECR
++	
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, r0, c7, c5, 6		@ invalidate BTB All
++	nop
++	nop
++#endif		
++		
++	mov	r0, #0x1f			@ Domains 0, 1 = manager, 2 = client
++	mcr	p15, 0, r0, c3, c0		@ load domain access register
++	
++	mrc	p15, 0, r0, c1, c0		@ get control register v4
++	ldr	r5, fa526_cr1_clear
++	bic	r0, r0, r5
++	ldr	r5, fa526_cr1_set
++	orr	r0, r0, r5
++
++#ifdef CONFIG_CPU_FA_BTB
++	orr	r0, r0, #CR_Z
++#else
++	bic	r0, r0, #CR_Z	
++#endif
++#ifdef CONFIG_CPU_FA_WB_DISABLE
++	mov	r12, #0
++	mcr	p15, 0, r12, c7, c10, 4		@ drain write buffer
++	nop
++	nop
++	bic	r0, r0, #CR_W			@ .... .... .... 1...
++#else
++	orr	r0, r0, #CR_W
++#endif
++
++#ifdef CONFIG_DEBUG_LL
++   adr	r0, str_fa526_setup_done
++	bl	printascii
++#endif
++
++	mov	pc, lr
++	.size	__fa526_setup, . - __fa526_setup
++
++	/*
++	 * .RVI ZFRS BLDP WCAM
++	 * ..11 0001 .111 1101
++	 * 
++	 */
++	.type	fa526_cr1_clear, #object
++	.type	fa526_cr1_set, #object
++fa526_cr1_clear:
++	.word	0x3f3f
++fa526_cr1_set:
++	.word	0x317D
++
++	__INITDATA
++
++/*
++ * Purpose : Function pointers used to access above functions - all calls
++ *	     come through these
++ */
++	.type	fa526_processor_functions, #object
++fa526_processor_functions:
++	.word	v4_early_abort
++	.word	legacy_pabort            @ Ian added	
++	.word	cpu_fa526_proc_init
++	.word	cpu_fa526_proc_fin
++	.word	cpu_fa526_reset
++	.word   cpu_fa526_do_idle
++	.word	cpu_fa526_dcache_clean_area
++	.word	cpu_fa526_switch_mm
++	.word	cpu_fa526_set_pte_ext
++	.size	fa526_processor_functions, . - fa526_processor_functions
++
++	.section ".rodata"
++
++	.type	cpu_arch_name, #object
++cpu_arch_name:
++	.asciz	"armv4"
++	.size	cpu_arch_name, . - cpu_arch_name
++
++	.type	cpu_elf_name, #object
++cpu_elf_name:
++	.asciz	"v4"
++	.size	cpu_elf_name, . - cpu_elf_name
++
++	.type	cpu_fa526_name, #object
++cpu_fa526_name:
++	.ascii	"FA526"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++	.ascii	"i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++	.ascii	"d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	.ascii	"(wt)"
++#else
++	.ascii	"(wb)"
++#endif
++#endif
++	.ascii	"\0"
++	.size	cpu_fa526_name, . - cpu_fa526_name
++
++	.align
++
++	.section ".proc.info.init", #alloc, #execinstr
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++#define __PMD_SECT_BUFFERABLE	0
++#else
++#define __PMD_SECT_BUFFERABLE	PMD_SECT_BUFFERABLE
++#endif
++
++	.type	__fa526_proc_info,#object
++__fa526_proc_info:
++	.long	0x66015261
++	.long	0xff01fff1
++	.long   PMD_TYPE_SECT | \
++		__PMD_SECT_BUFFERABLE | \
++		PMD_SECT_CACHEABLE | \
++		PMD_BIT4 | \
++		PMD_SECT_AP_WRITE | \
++		PMD_SECT_AP_READ
++	.long   PMD_TYPE_SECT | \
++		PMD_SECT_AP_WRITE | \
++		PMD_SECT_AP_READ
++	b	__fa526_setup
++	.long	cpu_arch_name
++	.long	cpu_elf_name
++	.long	HWCAP_SWP | HWCAP_HALF
++	.long	cpu_fa526_name
++	.long	fa526_processor_functions
++	.long	fa_tlb_fns
++	.long	fa_user_fns
++	.long	fa_cache_fns
++	.size	__fa526_proc_info, . - __fa526_proc_info
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/mm/proc-fa526.S.orig linux-2.6.35.11-ts7500/arch/arm/mm/proc-fa526.S.orig
+--- linux-2.6.35.11/arch/arm/mm/proc-fa526.S.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/proc-fa526.S.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,248 @@
++/*
++ *  linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526
++ *
++ *  Written by : Luke Lee
++ *  Copyright (C) 2005 Faraday Corp.
++ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ *
++ * These are the low level assembler for performing cache and TLB
++ * functions on the fa526.
++ */
++#include <linux/linkage.h>
++#include <linux/init.h>
++#include <asm/assembler.h>
++#include <asm/hwcap.h>
++#include <asm/pgtable-hwdef.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++#include <asm/ptrace.h>
++#include <asm/system.h>
++
++#include "proc-macros.S"
++
++#define CACHE_DLINESIZE	16
++
++	.text
++/*
++ * cpu_fa526_proc_init()
++ */
++ENTRY(cpu_fa526_proc_init)
++	mov	pc, lr
++
++/*
++ * cpu_fa526_proc_fin()
++ */
++ENTRY(cpu_fa526_proc_fin)
++	stmfd	sp!, {lr}
++	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
++	msr	cpsr_c, ip
++	bl	fa_flush_kern_cache_all
++	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
++	bic	r0, r0, #0x1000			@ ...i............
++	bic	r0, r0, #0x000e			@ ............wca.
++	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
++	nop
++	nop
++	ldmfd	sp!, {pc}
++
++/*
++ * cpu_fa526_reset(loc)
++ *
++ * Perform a soft reset of the system.  Put the CPU into the
++ * same state as it would be if it had been reset, and branch
++ * to what would be the reset vector.
++ *
++ * loc: location to jump to for soft reset
++ */
++	.align	4
++ENTRY(cpu_fa526_reset)
++/* TODO: Use CP8 if possible... */
++	mov	ip, #0
++	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
++	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
++#ifdef CONFIG_MMU
++	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
++#endif
++	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
++	bic	ip, ip, #0x000f			@ ............wcam
++	bic	ip, ip, #0x1100			@ ...i...s........
++	bic	ip, ip, #0x0800			@ BTB off
++	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
++	nop
++	nop
++	mov	pc, r0
++
++/*
++ * cpu_fa526_do_idle()
++ */
++	.align	4
++ENTRY(cpu_fa526_do_idle)
++	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
++	mov	pc, lr
++
++
++ENTRY(cpu_fa526_dcache_clean_area)
++1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
++	add	r0, r0, #CACHE_DLINESIZE
++	subs	r1, r1, #CACHE_DLINESIZE
++	bhi	1b
++	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
++	mov	pc, lr
++
++/* =============================== PageTable ============================== */
++
++/*
++ * cpu_fa526_switch_mm(pgd)
++ *
++ * Set the translation base pointer to be as described by pgd.
++ *
++ * pgd: new page tables
++ */
++	.align	4
++ENTRY(cpu_fa526_switch_mm)
++#ifdef CONFIG_MMU
++	mov	ip, #0
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
++#else
++	mcr	p15, 0, ip, c7, c14, 0		@ clean and invalidate whole D cache
++#endif
++	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
++	mcr	p15, 0, ip, c7, c5, 6		@ invalidate BTB since mm changed
++	mcr	p15, 0, ip, c7, c10, 4		@ data write barrier
++	mcr	p15, 0, ip, c7, c5, 4		@ prefetch flush
++	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
++	mcr	p15, 0, ip, c8, c7, 0		@ invalidate UTLB
++#endif
++	mov	pc, lr
++
++/*
++ * cpu_fa526_set_pte_ext(ptep, pte, ext)
++ *
++ * Set a PTE and flush it out
++ */
++	.align	4
++ENTRY(cpu_fa526_set_pte_ext)
++#ifdef CONFIG_MMU
++	armv3_set_pte_ext
++	mov	r0, r0
++	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
++	mov	r0, #0
++	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
++#endif
++	mov	pc, lr
++
++	__INIT
++
++	.type	__fa526_setup, #function
++__fa526_setup:
++	/* On return of this routine, r0 must carry correct flags for CFG register */
++	mov	r0, #0
++	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
++	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
++#ifdef CONFIG_MMU
++	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
++#endif
++	mcr	p15, 0, r0, c7, c5, 5		@ invalidate IScratchpad RAM
++
++	mov	r0, #1
++	mcr	p15, 0, r0, c1, c1, 0		@ turn-on ECR
++
++	mov	r0, #0
++	mcr	p15, 0, r0, c7, c5, 6		@ invalidate BTB All
++	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
++	mcr	p15, 0, r0, c7, c5, 4		@ prefetch flush
++
++	mov	r0, #0x1f			@ Domains 0, 1 = manager, 2 = client
++	mcr	p15, 0, r0, c3, c0		@ load domain access register
++
++	mrc	p15, 0, r0, c1, c0		@ get control register v4
++	ldr	r5, fa526_cr1_clear
++	bic	r0, r0, r5
++	ldr	r5, fa526_cr1_set
++	orr	r0, r0, r5
++	mov	pc, lr
++	.size	__fa526_setup, . - __fa526_setup
++
++	/*
++	 * .RVI ZFRS BLDP WCAM
++	 * ..11 1001 .111 1101
++	 *
++	 */
++	.type	fa526_cr1_clear, #object
++	.type	fa526_cr1_set, #object
++fa526_cr1_clear:
++	.word	0x3f3f
++fa526_cr1_set:
++	.word	0x397D
++
++	__INITDATA
++
++/*
++ * Purpose : Function pointers used to access above functions - all calls
++ *	     come through these
++ */
++	.type	fa526_processor_functions, #object
++fa526_processor_functions:
++	.word	v4_early_abort
++	.word	legacy_pabort
++	.word	cpu_fa526_proc_init
++	.word	cpu_fa526_proc_fin
++	.word	cpu_fa526_reset
++	.word   cpu_fa526_do_idle
++	.word	cpu_fa526_dcache_clean_area
++	.word	cpu_fa526_switch_mm
++	.word	cpu_fa526_set_pte_ext
++	.size	fa526_processor_functions, . - fa526_processor_functions
++
++	.section ".rodata"
++
++	.type	cpu_arch_name, #object
++cpu_arch_name:
++	.asciz	"armv4"
++	.size	cpu_arch_name, . - cpu_arch_name
++
++	.type	cpu_elf_name, #object
++cpu_elf_name:
++	.asciz	"v4"
++	.size	cpu_elf_name, . - cpu_elf_name
++
++	.type	cpu_fa526_name, #object
++cpu_fa526_name:
++	.asciz	"FA526"
++	.size	cpu_fa526_name, . - cpu_fa526_name
++
++	.align
++
++	.section ".proc.info.init", #alloc, #execinstr
++
++	.type	__fa526_proc_info,#object
++__fa526_proc_info:
++	.long	0x66015261
++	.long	0xff01fff1
++	.long   PMD_TYPE_SECT | \
++		PMD_SECT_BUFFERABLE | \
++		PMD_SECT_CACHEABLE | \
++		PMD_BIT4 | \
++		PMD_SECT_AP_WRITE | \
++		PMD_SECT_AP_READ
++	.long   PMD_TYPE_SECT | \
++		PMD_BIT4 | \
++		PMD_SECT_AP_WRITE | \
++		PMD_SECT_AP_READ
++	b	__fa526_setup
++	.long	cpu_arch_name
++	.long	cpu_elf_name
++	.long	HWCAP_SWP | HWCAP_HALF
++	.long	cpu_fa526_name
++	.long	fa526_processor_functions
++	.long	fa_tlb_fns
++	.long	fa_user_fns
++	.long	fa_cache_fns
++	.size	__fa526_proc_info, . - __fa526_proc_info
+diff -rupN linux-2.6.35.11/arch/arm/mm/tlb-fa.S linux-2.6.35.11-ts7500/arch/arm/mm/tlb-fa.S
+--- linux-2.6.35.11/arch/arm/mm/tlb-fa.S	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/mm/tlb-fa.S	2011-03-14 11:18:24.000000000 -0400
+@@ -1,3 +1,4 @@
++#if (0)
+ /*
+  *  linux/arch/arm/mm/tlb-fa.S
+  *
+@@ -73,3 +74,103 @@ ENTRY(fa_tlb_fns)
+ 	.long	fa_flush_kern_tlb_range
+ 	.long	fa_tlb_flags
+ 	.size	fa_tlb_fns, . - fa_tlb_fns
++#else
++/*
++ *  linux/arch/arm/mm/tlb-fa.S
++ *
++ *  Copyright (C) 2005 Faraday Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  ARM architecture version 4, Faraday variation. 
++ *  This assume an unified TLBs, with a write buffer, and branch target buffer (BTB)
++ *
++ *  Processors: FA520 FA526 FA626
++ *  03/31/2005 : Created by Luke Lee, modified from tlb-v4wbi.S
++ *  05/06/2005 : Fixed buggy CPU versions that did not invalidate the associated
++ *               data cache entries when invalidating TLB entries.
++ */
++#include <linux/linkage.h>
++#include <linux/init.h>
++#include <asm/asm-offsets.h>
++//#include <asm/constants.h>
++#include <asm/tlbflush.h>
++#include "proc-macros.S"
++
++
++/*
++ *	flush_user_tlb_range(start, end, mm)
++ *
++ *	Invalidate a range of TLB entries in the specified address space.
++ *
++ *	- start - range start address
++ *	- end   - range end address
++ *	- mm    - mm_struct describing address space
++ */
++	.align	4
++ENTRY(fa_flush_user_tlb_range)
++	
++	vma_vm_mm ip, r2
++	act_mm	r3				@ get current->active_mm
++	eors	r3, ip, r3			@ == mm ?
++	movne	pc, lr				@ no, we dont do anything
++	mov	r3, #0
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
++#endif
++
++	vma_vm_flags r2, r2
++	bic	r0, r0, #0x0ff
++	bic	r0, r0, #0xf00
++
++1:	mcr	p15, 0, r0, c8, c7, 1		@ invalidate UTLB entry
++	add	r0, r0, #PAGE_SZ
++	cmp	r0, r1
++	bls	1b				@ Luke Lee 05/19/2005 blo -> bls
++
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, r3, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++#endif	
++	mov	pc, lr
++
++
++ENTRY(fa_flush_kern_tlb_range)
++	mov	r3, #0
++
++	mcr	p15, 0, r3, c7, c10, 0		@ clean Dcache all 06/03/2005
++		
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
++#endif
++
++	bic	r0, r0, #0x0ff
++	bic	r0, r0, #0xf00
++1:
++	mcr	p15, 0, r0, c8, c7, 1		@ invalidate UTLB entry
++	add	r0, r0, #PAGE_SZ
++	cmp	r0, r1
++	bls	1b				@ Luke Lee 05/19/2005 blo -> bls
++
++#ifdef CONFIG_CPU_FA_BTB
++	mcr	p15, 0, r3, c7, c5, 6		@ invalidate BTB
++	nop
++	nop
++#endif
++	mov	pc, lr
++
++
++	__INITDATA
++
++	.type	fa_tlb_fns, #object
++ENTRY(fa_tlb_fns)
++	.long	fa_flush_user_tlb_range
++	.long	fa_flush_kern_tlb_range
++	.long	fa_tlb_flags
++	.size	fa_tlb_fns, . - fa_tlb_fns
++
++#endif
+diff -rupN linux-2.6.35.11/arch/arm/tools/mach-types linux-2.6.35.11-ts7500/arch/arm/tools/mach-types
+--- linux-2.6.35.11/arch/arm/tools/mach-types	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/tools/mach-types	2011-03-14 11:39:00.000000000 -0400
+@@ -2950,3 +2950,4 @@ davinci_dm365_dvr	MACH_DAVINCI_DM365_DVR
+ netviz			MACH_NETVIZ		NETVIZ			2964
+ flexibity		MACH_FLEXIBITY		FLEXIBITY		2965
+ wlan_computer		MACH_WLAN_COMPUTER	WLAN_COMPUTER		2966
++str8100                 ARCH_STR8100            STR8100                 2001
+diff -rupN linux-2.6.35.11/arch/arm/tools/mach-types~ linux-2.6.35.11-ts7500/arch/arm/tools/mach-types~
+--- linux-2.6.35.11/arch/arm/tools/mach-types~	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/tools/mach-types~	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,2952 @@
++# Database of machine macros and numbers
++#
++# This file is linux/arch/arm/tools/mach-types
++#
++# Up to date versions of this file can be obtained from:
++#
++#   http://www.arm.linux.org.uk/developer/machines/download.php
++#
++# Please do not send patches to this file; it is automatically generated!
++# To add an entry into this database, please see Documentation/arm/README,
++# or visit:
++#
++#   http://www.arm.linux.org.uk/developer/machines/?action=new
++#
++# Last update: Mon Jul 12 21:10:14 2010
++#
++# machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
++#
++ebsa110			ARCH_EBSA110		EBSA110			0
++riscpc			ARCH_RPC		RISCPC			1
++nexuspci		ARCH_NEXUSPCI		NEXUSPCI		3
++ebsa285			ARCH_EBSA285		EBSA285			4
++netwinder		ARCH_NETWINDER		NETWINDER		5
++cats			ARCH_CATS		CATS			6
++tbox			ARCH_TBOX		TBOX			7
++co285			ARCH_CO285		CO285			8
++clps7110		ARCH_CLPS7110		CLPS7110		9
++archimedes		ARCH_ARC		ARCHIMEDES		10
++a5k			ARCH_A5K		A5K			11
++etoile			ARCH_ETOILE		ETOILE			12
++lacie_nas		ARCH_LACIE_NAS		LACIE_NAS		13
++clps7500		ARCH_CLPS7500		CLPS7500		14
++shark			ARCH_SHARK		SHARK			15
++brutus			SA1100_BRUTUS		BRUTUS			16
++personal_server		ARCH_PERSONAL_SERVER	PERSONAL_SERVER		17
++itsy			SA1100_ITSY		ITSY			18
++l7200			ARCH_L7200		L7200			19
++pleb			SA1100_PLEB		PLEB			20
++integrator		ARCH_INTEGRATOR		INTEGRATOR		21
++h3600			SA1100_H3600		H3600			22
++ixp1200			ARCH_IXP1200		IXP1200			23
++p720t			ARCH_P720T		P720T			24
++assabet			SA1100_ASSABET		ASSABET			25
++victor			SA1100_VICTOR		VICTOR			26
++lart			SA1100_LART		LART			27
++ranger			SA1100_RANGER		RANGER			28
++graphicsclient		SA1100_GRAPHICSCLIENT	GRAPHICSCLIENT		29
++xp860			SA1100_XP860		XP860			30
++cerf			SA1100_CERF		CERF			31
++nanoengine		SA1100_NANOENGINE	NANOENGINE		32
++fpic			SA1100_FPIC		FPIC			33
++extenex1		SA1100_EXTENEX1		EXTENEX1		34
++sherman			SA1100_SHERMAN		SHERMAN			35
++accelent_sa		SA1100_ACCELENT		ACCELENT_SA		36
++accelent_l7200		ARCH_L7200_ACCELENT	ACCELENT_L7200		37
++netport			SA1100_NETPORT		NETPORT			38
++pangolin		SA1100_PANGOLIN		PANGOLIN		39
++yopy			SA1100_YOPY		YOPY			40
++coolidge		SA1100_COOLIDGE		COOLIDGE		41
++huw_webpanel		SA1100_HUW_WEBPANEL	HUW_WEBPANEL		42
++spotme			ARCH_SPOTME		SPOTME			43
++freebird		ARCH_FREEBIRD		FREEBIRD		44
++ti925			ARCH_TI925		TI925			45
++riscstation		ARCH_RISCSTATION	RISCSTATION		46
++cavy			SA1100_CAVY		CAVY			47
++jornada720		SA1100_JORNADA720	JORNADA720		48
++omnimeter		SA1100_OMNIMETER	OMNIMETER		49
++edb7211			ARCH_EDB7211		EDB7211			50
++citygo			SA1100_CITYGO		CITYGO			51
++pfs168			SA1100_PFS168		PFS168			52
++spot			SA1100_SPOT		SPOT			53
++flexanet		SA1100_FLEXANET		FLEXANET		54
++webpal			ARCH_WEBPAL		WEBPAL			55
++linpda			SA1100_LINPDA		LINPDA			56
++anakin			ARCH_ANAKIN		ANAKIN			57
++mvi			SA1100_MVI		MVI			58
++jupiter			SA1100_JUPITER		JUPITER			59
++psionw			ARCH_PSIONW		PSIONW			60
++aln			SA1100_ALN		ALN			61
++epxa			ARCH_CAMELOT		CAMELOT			62
++gds2200			SA1100_GDS2200		GDS2200			63
++netbook			SA1100_PSION_SERIES7	PSION_SERIES7		64
++xfile			SA1100_XFILE		XFILE			65
++accelent_ep9312		ARCH_ACCELENT_EP9312	ACCELENT_EP9312		66
++ic200			ARCH_IC200		IC200			67
++creditlart		SA1100_CREDITLART	CREDITLART		68
++htm			SA1100_HTM		HTM			69
++iq80310			ARCH_IQ80310		IQ80310			70
++freebot			SA1100_FREEBOT		FREEBOT			71
++entel			ARCH_ENTEL		ENTEL			72
++enp3510			ARCH_ENP3510		ENP3510			73
++trizeps			SA1100_TRIZEPS		TRIZEPS			74
++nesa			SA1100_NESA		NESA			75
++venus			ARCH_VENUS		VENUS			76
++tardis			ARCH_TARDIS		TARDIS			77
++mercury			ARCH_MERCURY		MERCURY			78
++empeg			SA1100_EMPEG		EMPEG			79
++adi_evb			ARCH_I80200FCC		I80200FCC		80
++itt_cpb			SA1100_ITT_CPB		ITT_CPB			81
++svc			SA1100_SVC		SVC			82
++alpha2			SA1100_ALPHA2		ALPHA2			84
++alpha1			SA1100_ALPHA1		ALPHA1			85
++netarm			ARCH_NETARM		NETARM			86
++simpad			SA1100_SIMPAD		SIMPAD			87
++pda1			ARCH_PDA1		PDA1			88
++lubbock			ARCH_LUBBOCK		LUBBOCK			89
++aniko			ARCH_ANIKO		ANIKO			90
++clep7212		ARCH_CLEP7212		CLEP7212		91
++cs89712			ARCH_CS89712		CS89712			92
++weararm			SA1100_WEARARM		WEARARM			93
++possio_px		SA1100_POSSIO_PX	POSSIO_PX		94
++sidearm			SA1100_SIDEARM		SIDEARM			95
++stork			SA1100_STORK		STORK			96
++shannon			SA1100_SHANNON		SHANNON			97
++ace			ARCH_ACE		ACE			98
++ballyarm		SA1100_BALLYARM		BALLYARM		99
++simputer		SA1100_SIMPUTER		SIMPUTER		100
++nexterm			SA1100_NEXTERM		NEXTERM			101
++sa1100_elf		SA1100_SA1100_ELF	SA1100_ELF		102
++gator			SA1100_GATOR		GATOR			103
++granite			ARCH_GRANITE		GRANITE			104
++consus			SA1100_CONSUS		CONSUS			105
++aaed2000		ARCH_AAED2000		AAED2000		106
++cdb89712		ARCH_CDB89712		CDB89712		107
++graphicsmaster		SA1100_GRAPHICSMASTER	GRAPHICSMASTER		108
++adsbitsy		SA1100_ADSBITSY		ADSBITSY		109
++pxa_idp			ARCH_PXA_IDP		PXA_IDP			110
++plce			ARCH_PLCE		PLCE			111
++pt_system3		SA1100_PT_SYSTEM3	PT_SYSTEM3		112
++murphy			ARCH_MEDALB		MEDALB			113
++eagle			ARCH_EAGLE		EAGLE			114
++dsc21			ARCH_DSC21		DSC21			115
++dsc24			ARCH_DSC24		DSC24			116
++ti5472			ARCH_TI5472		TI5472			117
++autcpu12		ARCH_AUTCPU12		AUTCPU12		118
++uengine			ARCH_UENGINE		UENGINE			119
++bluestem		SA1100_BLUESTEM		BLUESTEM		120
++xingu8			ARCH_XINGU8		XINGU8			121
++bushstb			ARCH_BUSHSTB		BUSHSTB			122
++epsilon1		SA1100_EPSILON1		EPSILON1		123
++balloon			SA1100_BALLOON		BALLOON			124
++puppy			ARCH_PUPPY		PUPPY			125
++elroy			SA1100_ELROY		ELROY			126
++gms720			ARCH_GMS720		GMS720			127
++s24x			ARCH_S24X		S24X			128
++jtel_clep7312		ARCH_JTEL_CLEP7312	JTEL_CLEP7312		129
++cx821xx			ARCH_CX821XX		CX821XX			130
++edb7312			ARCH_EDB7312		EDB7312			131
++bsa1110			SA1100_BSA1110		BSA1110			132
++powerpin		ARCH_POWERPIN		POWERPIN		133
++openarm			ARCH_OPENARM		OPENARM			134
++whitechapel		SA1100_WHITECHAPEL	WHITECHAPEL		135
++h3100			SA1100_H3100		H3100			136
++h3800			SA1100_H3800		H3800			137
++blue_v1			ARCH_BLUE_V1		BLUE_V1			138
++pxa_cerf		ARCH_PXA_CERF		PXA_CERF		139
++arm7tevb		ARCH_ARM7TEVB		ARM7TEVB		140
++d7400			SA1100_D7400		D7400			141
++piranha			ARCH_PIRANHA		PIRANHA			142
++sbcamelot		SA1100_SBCAMELOT	SBCAMELOT		143
++kings			SA1100_KINGS		KINGS			144
++smdk2400		ARCH_SMDK2400		SMDK2400		145
++collie			SA1100_COLLIE		COLLIE			146
++idr			ARCH_IDR		IDR			147
++badge4			SA1100_BADGE4		BADGE4			148
++webnet			ARCH_WEBNET		WEBNET			149
++d7300			SA1100_D7300		D7300			150
++cep			SA1100_CEP		CEP			151
++fortunet		ARCH_FORTUNET		FORTUNET		152
++vc547x			ARCH_VC547X		VC547X			153
++filewalker		SA1100_FILEWALKER	FILEWALKER		154
++netgateway		SA1100_NETGATEWAY	NETGATEWAY		155
++symbol2800		SA1100_SYMBOL2800	SYMBOL2800		156
++suns			SA1100_SUNS		SUNS			157
++frodo			SA1100_FRODO		FRODO			158
++ms301			SA1100_MACH_TYTE_MS301	MACH_TYTE_MS301		159
++mx1ads			ARCH_MX1ADS		MX1ADS			160
++h7201			ARCH_H7201		H7201			161
++h7202			ARCH_H7202		H7202			162
++amico			ARCH_AMICO		AMICO			163
++iam			SA1100_IAM		IAM			164
++tt530			SA1100_TT530		TT530			165
++sam2400			ARCH_SAM2400		SAM2400			166
++jornada56x		SA1100_JORNADA56X	JORNADA56X		167
++active			SA1100_ACTIVE		ACTIVE			168
++iq80321			ARCH_IQ80321		IQ80321			169
++wid			SA1100_WID		WID			170
++sabinal			ARCH_SABINAL		SABINAL			171
++ixp425_matacumbe	ARCH_IXP425_MATACUMBE	IXP425_MATACUMBE	172
++miniprint		SA1100_MINIPRINT	MINIPRINT		173
++adm510x			ARCH_ADM510X		ADM510X			174
++svs200			SA1100_SVS200		SVS200			175
++atg_tcu			ARCH_ATG_TCU		ATG_TCU			176
++jornada820		SA1100_JORNADA820	JORNADA820		177
++s3c44b0			ARCH_S3C44B0		S3C44B0			178
++margis2			ARCH_MARGIS2		MARGIS2			179
++ks8695			ARCH_KS8695		KS8695			180
++brh			ARCH_BRH		BRH			181
++s3c2410			ARCH_S3C2410		S3C2410			182
++possio_px30		ARCH_POSSIO_PX30	POSSIO_PX30		183
++s3c2800			ARCH_S3C2800		S3C2800			184
++fleetwood		SA1100_FLEETWOOD	FLEETWOOD		185
++omaha			ARCH_OMAHA		OMAHA			186
++ta7			ARCH_TA7		TA7			187
++nova			SA1100_NOVA		NOVA			188
++hmk			ARCH_HMK		HMK			189
++karo			ARCH_KARO		KARO			190
++fester			SA1100_FESTER		FESTER			191
++gpi			ARCH_GPI		GPI			192
++smdk2410		ARCH_SMDK2410		SMDK2410		193
++i519			ARCH_I519		I519			194
++nexio			SA1100_NEXIO		NEXIO			195
++bitbox			SA1100_BITBOX		BITBOX			196
++g200			SA1100_G200		G200			197
++gill			SA1100_GILL		GILL			198
++pxa_mercury		ARCH_PXA_MERCURY	PXA_MERCURY		199
++ceiva			ARCH_CEIVA		CEIVA			200
++fret			SA1100_FRET		FRET			201
++emailphone		SA1100_EMAILPHONE	EMAILPHONE		202
++h3900			ARCH_H3900		H3900			203
++pxa1			ARCH_PXA1		PXA1			204
++koan369			SA1100_KOAN369		KOAN369			205
++cogent			ARCH_COGENT		COGENT			206
++esl_simputer		ARCH_ESL_SIMPUTER	ESL_SIMPUTER		207
++esl_simputer_clr	ARCH_ESL_SIMPUTER_CLR	ESL_SIMPUTER_CLR	208
++esl_simputer_bw		ARCH_ESL_SIMPUTER_BW	ESL_SIMPUTER_BW		209
++hhp_cradle		ARCH_HHP_CRADLE		HHP_CRADLE		210
++he500			ARCH_HE500		HE500			211
++inhandelf2		SA1100_INHANDELF2	INHANDELF2		212
++inhandftip		SA1100_INHANDFTIP	INHANDFTIP		213
++dnp1110			SA1100_DNP1110		DNP1110			214
++pnp1110			SA1100_PNP1110		PNP1110			215
++csb226			ARCH_CSB226		CSB226			216
++arnold			SA1100_ARNOLD		ARNOLD			217
++voiceblue		MACH_VOICEBLUE		VOICEBLUE		218
++jz8028			ARCH_JZ8028		JZ8028			219
++h5400			ARCH_H5400		H5400			220
++forte			SA1100_FORTE		FORTE			221
++acam			SA1100_ACAM		ACAM			222
++abox			SA1100_ABOX		ABOX			223
++atmel			ARCH_ATMEL		ATMEL			224
++sitsang			ARCH_SITSANG		SITSANG			225
++cpu1110lcdnet		SA1100_CPU1110LCDNET	CPU1110LCDNET		226
++mpl_vcma9		ARCH_MPL_VCMA9		MPL_VCMA9		227
++opus_a1			ARCH_OPUS_A1		OPUS_A1			228
++daytona			ARCH_DAYTONA		DAYTONA			229
++killbear		SA1100_KILLBEAR		KILLBEAR		230
++yoho			ARCH_YOHO		YOHO			231
++jasper			ARCH_JASPER		JASPER			232
++dsc25			ARCH_DSC25		DSC25			233
++omap_innovator		MACH_OMAP_INNOVATOR	OMAP_INNOVATOR		234
++mnci			ARCH_RAMSES		RAMSES			235
++s28x			ARCH_S28X		S28X			236
++mport3			ARCH_MPORT3		MPORT3			237
++pxa_eagle250		ARCH_PXA_EAGLE250	PXA_EAGLE250		238
++pdb			ARCH_PDB		PDB			239
++blue_2g			SA1100_BLUE_2G		BLUE_2G			240
++bluearch		SA1100_BLUEARCH		BLUEARCH		241
++ixdp2400		ARCH_IXDP2400		IXDP2400		242
++ixdp2800		ARCH_IXDP2800		IXDP2800		243
++explorer		SA1100_EXPLORER		EXPLORER		244
++ixdp425			ARCH_IXDP425		IXDP425			245
++chimp			ARCH_CHIMP		CHIMP			246
++stork_nest		ARCH_STORK_NEST		STORK_NEST		247
++stork_egg		ARCH_STORK_EGG		STORK_EGG		248
++wismo			SA1100_WISMO		WISMO			249
++ezlinx			ARCH_EZLINX		EZLINX			250
++at91rm9200		ARCH_AT91RM9200		AT91RM9200		251
++adtech_orion		ARCH_ADTECH_ORION	ADTECH_ORION		252
++neptune			ARCH_NEPTUNE		NEPTUNE			253
++hackkit			SA1100_HACKKIT		HACKKIT			254
++pxa_wins30		ARCH_PXA_WINS30		PXA_WINS30		255
++lavinna			SA1100_LAVINNA		LAVINNA			256
++pxa_uengine		ARCH_PXA_UENGINE	PXA_UENGINE		257
++innokom			ARCH_INNOKOM		INNOKOM			258
++bms			ARCH_BMS		BMS			259
++ixcdp1100		ARCH_IXCDP1100		IXCDP1100		260
++prpmc1100		ARCH_PRPMC1100		PRPMC1100		261
++at91rm9200dk		ARCH_AT91RM9200DK	AT91RM9200DK		262
++armstick		ARCH_ARMSTICK		ARMSTICK		263
++armonie			ARCH_ARMONIE		ARMONIE			264
++mport1			ARCH_MPORT1		MPORT1			265
++s3c5410			ARCH_S3C5410		S3C5410			266
++zcp320a			ARCH_ZCP320A		ZCP320A			267
++i_box			ARCH_I_BOX		I_BOX			268
++stlc1502		ARCH_STLC1502		STLC1502		269
++siren			ARCH_SIREN		SIREN			270
++greenlake		ARCH_GREENLAKE		GREENLAKE		271
++argus			ARCH_ARGUS		ARGUS			272
++combadge		SA1100_COMBADGE		COMBADGE		273
++rokepxa			ARCH_ROKEPXA		ROKEPXA			274
++cintegrator		ARCH_CINTEGRATOR	CINTEGRATOR		275
++guidea07		ARCH_GUIDEA07		GUIDEA07		276
++tat257			ARCH_TAT257		TAT257			277
++igp2425			ARCH_IGP2425		IGP2425			278
++bluegrama		ARCH_BLUEGRAMMA		BLUEGRAMMA		279
++ipod			ARCH_IPOD		IPOD			280
++adsbitsyx		ARCH_ADSBITSYX		ADSBITSYX		281
++trizeps2		ARCH_TRIZEPS2		TRIZEPS2		282
++viper			ARCH_VIPER		VIPER			283
++adsbitsyplus		SA1100_ADSBITSYPLUS	ADSBITSYPLUS		284
++adsagc			SA1100_ADSAGC		ADSAGC			285
++stp7312			ARCH_STP7312		STP7312			286
++nx_phnx			MACH_NX_PHNX		NX_PHNX			287
++wep_ep250		ARCH_WEP_EP250		WEP_EP250		288
++inhandelf3		ARCH_INHANDELF3		INHANDELF3		289
++adi_coyote		ARCH_ADI_COYOTE		ADI_COYOTE		290
++iyonix			ARCH_IYONIX		IYONIX			291
++damicam1		ARCH_DAMICAM_SA1110	DAMICAM_SA1110		292
++meg03			ARCH_MEG03		MEG03			293
++pxa_whitechapel		ARCH_PXA_WHITECHAPEL	PXA_WHITECHAPEL		294
++nwsc			ARCH_NWSC		NWSC			295
++nwlarm			ARCH_NWLARM		NWLARM			296
++ixp425_mguard		ARCH_IXP425_MGUARD	IXP425_MGUARD		297
++pxa_netdcu4		ARCH_PXA_NETDCU4	PXA_NETDCU4		298
++ixdp2401		ARCH_IXDP2401		IXDP2401		299
++ixdp2801		ARCH_IXDP2801		IXDP2801		300
++zodiac			ARCH_ZODIAC		ZODIAC			301
++armmodul		ARCH_ARMMODUL		ARMMODUL		302
++ketop			SA1100_KETOP		KETOP			303
++av7200			ARCH_AV7200		AV7200			304
++arch_ti925		ARCH_ARCH_TI925		ARCH_TI925		305
++acq200			ARCH_ACQ200		ACQ200			306
++pt_dafit		SA1100_PT_DAFIT		PT_DAFIT		307
++ihba			ARCH_IHBA		IHBA			308
++quinque			ARCH_QUINQUE		QUINQUE			309
++nimbraone		ARCH_NIMBRAONE		NIMBRAONE		310
++nimbra29x		ARCH_NIMBRA29X		NIMBRA29X		311
++nimbra210		ARCH_NIMBRA210		NIMBRA210		312
++hhp_d95xx		ARCH_HHP_D95XX		HHP_D95XX		313
++labarm			ARCH_LABARM		LABARM			314
++m825xx			ARCH_M825XX		M825XX			315
++m7100			SA1100_M7100		M7100			316
++nipc2			ARCH_NIPC2		NIPC2			317
++fu7202			ARCH_FU7202		FU7202			318
++adsagx			ARCH_ADSAGX		ADSAGX			319
++pxa_pooh		ARCH_PXA_POOH		PXA_POOH		320
++bandon			ARCH_BANDON		BANDON			321
++pcm7210			ARCH_PCM7210		PCM7210			322
++nms9200			ARCH_NMS9200		NMS9200			323
++logodl			ARCH_LOGODL		LOGODL			324
++m7140			SA1100_M7140		M7140			325
++korebot			ARCH_KOREBOT		KOREBOT			326
++iq31244			ARCH_IQ31244		IQ31244			327
++koan393			SA1100_KOAN393		KOAN393			328
++inhandftip3		ARCH_INHANDFTIP3	INHANDFTIP3		329
++gonzo			ARCH_GONZO		GONZO			330
++bast			ARCH_BAST		BAST			331
++scanpass		ARCH_SCANPASS		SCANPASS		332
++ep7312_pooh		ARCH_EP7312_POOH	EP7312_POOH		333
++ta7s			ARCH_TA7S		TA7S			334
++ta7v			ARCH_TA7V		TA7V			335
++icarus			SA1100_ICARUS		ICARUS			336
++h1900			ARCH_H1900		H1900			337
++gemini			SA1100_GEMINI		GEMINI			338
++axim			ARCH_AXIM		AXIM			339
++audiotron		ARCH_AUDIOTRON		AUDIOTRON		340
++h2200			ARCH_H2200		H2200			341
++loox600			ARCH_LOOX600		LOOX600			342
++niop			ARCH_NIOP		NIOP			343
++dm310			ARCH_DM310		DM310			344
++seedpxa_c2		ARCH_SEEDPXA_C2		SEEDPXA_C2		345
++ixp4xx_mguardpci	ARCH_IXP4XX_MGUARD_PCI	IXP4XX_MGUARD_PCI	346
++h1940			ARCH_H1940		H1940			347
++scorpio			ARCH_SCORPIO		SCORPIO			348
++viva			ARCH_VIVA		VIVA			349
++pxa_xcard		ARCH_PXA_XCARD		PXA_XCARD		350
++csb335			ARCH_CSB335		CSB335			351
++ixrd425			ARCH_IXRD425		IXRD425			352
++iq80315			ARCH_IQ80315		IQ80315			353
++nmp7312			ARCH_NMP7312		NMP7312			354
++cx861xx			ARCH_CX861XX		CX861XX			355
++enp2611			ARCH_ENP2611		ENP2611			356
++xda			SA1100_XDA		XDA			357
++csir_ims		ARCH_CSIR_IMS		CSIR_IMS		358
++ixp421_dnaeeth		ARCH_IXP421_DNAEETH	IXP421_DNAEETH		359
++pocketserv9200		ARCH_POCKETSERV9200	POCKETSERV9200		360
++toto			ARCH_TOTO		TOTO			361
++s3c2440			ARCH_S3C2440		S3C2440			362
++ks8695p			ARCH_KS8695P		KS8695P			363
++se4000			ARCH_SE4000		SE4000			364
++quadriceps		ARCH_QUADRICEPS		QUADRICEPS		365
++bronco			ARCH_BRONCO		BRONCO			366
++esl_wireless_tab	ARCH_ESL_WIRELESS_TAB	ESL_WIRELESS_TAB	367
++esl_sofcomp		ARCH_ESL_SOFCOMP	ESL_SOFCOMP		368
++s5c7375			ARCH_S5C7375		S5C7375			369
++spearhead		ARCH_SPEARHEAD		SPEARHEAD		370
++pantera			ARCH_PANTERA		PANTERA			371
++prayoglite		ARCH_PRAYOGLITE		PRAYOGLITE		372
++gumstix			ARCH_GUMSTIX		GUMSTIX			373
++rcube			ARCH_RCUBE		RCUBE			374
++rea_olv			ARCH_REA_OLV		REA_OLV			375
++pxa_iphone		ARCH_PXA_IPHONE		PXA_IPHONE		376
++s3c3410			ARCH_S3C3410		S3C3410			377
++espd_4510b		ARCH_ESPD_4510B		ESPD_4510B		378
++mp1x			ARCH_MP1X		MP1X			379
++at91rm9200tb		ARCH_AT91RM9200TB	AT91RM9200TB		380
++adsvgx			ARCH_ADSVGX		ADSVGX			381
++omap_h2			MACH_OMAP_H2		OMAP_H2			382
++pelee			ARCH_PELEE		PELEE			383
++e740			MACH_E740		E740			384
++iq80331			ARCH_IQ80331		IQ80331			385
++versatile_pb		ARCH_VERSATILE_PB	VERSATILE_PB		387
++kev7a400		MACH_KEV7A400		KEV7A400		388
++lpd7a400		MACH_LPD7A400		LPD7A400		389
++lpd7a404		MACH_LPD7A404		LPD7A404		390
++fujitsu_camelot		ARCH_FUJITSU_CAMELOT	FUJITSU_CAMELOT		391
++janus2m			ARCH_JANUS2M		JANUS2M			392
++embtf			MACH_EMBTF		EMBTF			393
++hpm			MACH_HPM		HPM			394
++smdk2410tk		MACH_SMDK2410TK		SMDK2410TK		395
++smdk2410aj		MACH_SMDK2410AJ		SMDK2410AJ		396
++streetracer		MACH_STREETRACER	STREETRACER		397
++eframe			MACH_EFRAME		EFRAME			398
++csb337			MACH_CSB337		CSB337			399
++pxa_lark		MACH_PXA_LARK		PXA_LARK		400
++pxa_pnp2110		MACH_PNP2110		PNP2110			401
++tcc72x			MACH_TCC72X		TCC72X			402
++altair			MACH_ALTAIR		ALTAIR			403
++kc3			MACH_KC3		KC3			404
++sinteftd		MACH_SINTEFTD		SINTEFTD		405
++mainstone		MACH_MAINSTONE		MAINSTONE		406
++aday4x			MACH_ADAY4X		ADAY4X			407
++lite300			MACH_LITE300		LITE300			408
++s5c7376			MACH_S5C7376		S5C7376			409
++mt02			MACH_MT02		MT02			410
++mport3s			MACH_MPORT3S		MPORT3S			411
++ra_alpha		MACH_RA_ALPHA		RA_ALPHA		412
++xcep			MACH_XCEP		XCEP			413
++arcom_vulcan		MACH_ARCOM_VULCAN	ARCOM_VULCAN		414
++stargate		MACH_STARGATE		STARGATE		415
++armadilloj		MACH_ARMADILLOJ		ARMADILLOJ		416
++elroy_jack		MACH_ELROY_JACK		ELROY_JACK		417
++backend			MACH_BACKEND		BACKEND			418
++s5linbox		MACH_S5LINBOX		S5LINBOX		419
++nomadik			MACH_NOMADIK		NOMADIK			420
++ia_cpu_9200		MACH_IA_CPU_9200	IA_CPU_9200		421
++at91_bja1		MACH_AT91_BJA1		AT91_BJA1		422
++corgi			MACH_CORGI		CORGI			423
++poodle			MACH_POODLE		POODLE			424
++ten			MACH_TEN		TEN			425
++roverp5p		MACH_ROVERP5P		ROVERP5P		426
++sc2700			MACH_SC2700		SC2700			427
++ex_eagle		MACH_EX_EAGLE		EX_EAGLE		428
++nx_pxa12		MACH_NX_PXA12		NX_PXA12		429
++nx_pxa5			MACH_NX_PXA5		NX_PXA5			430
++blackboard2		MACH_BLACKBOARD2	BLACKBOARD2		431
++i819			MACH_I819		I819			432
++ixmb995e		MACH_IXMB995E		IXMB995E		433
++skyrider		MACH_SKYRIDER		SKYRIDER		434
++skyhawk			MACH_SKYHAWK		SKYHAWK			435
++enterprise		MACH_ENTERPRISE		ENTERPRISE		436
++dep2410			MACH_DEP2410		DEP2410			437
++armcore			MACH_ARMCORE		ARMCORE			438
++hobbit			MACH_HOBBIT		HOBBIT			439
++h7210			MACH_H7210		H7210			440
++pxa_netdcu5		MACH_PXA_NETDCU5	PXA_NETDCU5		441
++acc			MACH_ACC		ACC			442
++esl_sarva		MACH_ESL_SARVA		ESL_SARVA		443
++xm250			MACH_XM250		XM250			444
++t6tc1xb			MACH_T6TC1XB		T6TC1XB			445
++ess710			MACH_ESS710		ESS710			446
++mx31ads			MACH_MX31ADS		MX31ADS			447
++himalaya		MACH_HIMALAYA		HIMALAYA		448
++bolfenk			MACH_BOLFENK		BOLFENK			449
++at91rm9200kr		MACH_AT91RM9200KR	AT91RM9200KR		450
++edb9312			MACH_EDB9312		EDB9312			451
++omap_generic		MACH_OMAP_GENERIC	OMAP_GENERIC		452
++aximx3			MACH_AXIMX3		AXIMX3			453
++eb67xdip		MACH_EB67XDIP		EB67XDIP		454
++webtxs			MACH_WEBTXS		WEBTXS			455
++hawk			MACH_HAWK		HAWK			456
++ccat91sbc001		MACH_CCAT91SBC001	CCAT91SBC001		457
++expresso		MACH_EXPRESSO		EXPRESSO		458
++h4000			MACH_H4000		H4000			459
++dino			MACH_DINO		DINO			460
++ml675k			MACH_ML675K		ML675K			461
++edb9301			MACH_EDB9301		EDB9301			462
++edb9315			MACH_EDB9315		EDB9315			463
++reciva_tt		MACH_RECIVA_TT		RECIVA_TT		464
++cstcb01			MACH_CSTCB01		CSTCB01			465
++cstcb1			MACH_CSTCB1		CSTCB1			466
++shadwell		MACH_SHADWELL		SHADWELL		467
++goepel263		MACH_GOEPEL263		GOEPEL263		468
++acq100			MACH_ACQ100		ACQ100			469
++mx1fs2			MACH_MX1FS2		MX1FS2			470
++hiptop_g1		MACH_HIPTOP_G1		HIPTOP_G1		471
++sparky			MACH_SPARKY		SPARKY			472
++ns9750			MACH_NS9750		NS9750			473
++phoenix			MACH_PHOENIX		PHOENIX			474
++vr1000			MACH_VR1000		VR1000			475
++deisterpxa		MACH_DEISTERPXA		DEISTERPXA		476
++bcm1160			MACH_BCM1160		BCM1160			477
++pcm022			MACH_PCM022		PCM022			478
++adsgcx			MACH_ADSGCX		ADSGCX			479
++dreadnaught		MACH_DREADNAUGHT	DREADNAUGHT		480
++dm320			MACH_DM320		DM320			481
++markov			MACH_MARKOV		MARKOV			482
++cos7a400		MACH_COS7A400		COS7A400		483
++milano			MACH_MILANO		MILANO			484
++ue9328			MACH_UE9328		UE9328			485
++uex255			MACH_UEX255		UEX255			486
++ue2410			MACH_UE2410		UE2410			487
++a620			MACH_A620		A620			488
++ocelot			MACH_OCELOT		OCELOT			489
++cheetah			MACH_CHEETAH		CHEETAH			490
++omap_perseus2		MACH_OMAP_PERSEUS2	OMAP_PERSEUS2		491
++zvue			MACH_ZVUE		ZVUE			492
++roverp1			MACH_ROVERP1		ROVERP1			493
++asidial2		MACH_ASIDIAL2		ASIDIAL2		494
++s3c24a0			MACH_S3C24A0		S3C24A0			495
++e800			MACH_E800		E800			496
++e750			MACH_E750		E750			497
++s3c5500			MACH_S3C5500		S3C5500			498
++smdk5500		MACH_SMDK5500		SMDK5500		499
++signalsync		MACH_SIGNALSYNC		SIGNALSYNC		500
++nbc			MACH_NBC		NBC			501
++kodiak			MACH_KODIAK		KODIAK			502
++netbookpro		MACH_NETBOOKPRO		NETBOOKPRO		503
++hw90200			MACH_HW90200		HW90200			504
++condor			MACH_CONDOR		CONDOR			505
++cup			MACH_CUP		CUP			506
++kite			MACH_KITE		KITE			507
++scb9328			MACH_SCB9328		SCB9328			508
++omap_h3			MACH_OMAP_H3		OMAP_H3			509
++omap_h4			MACH_OMAP_H4		OMAP_H4			510
++n10			MACH_N10		N10			511
++montejade		MACH_MONTAJADE		MONTAJADE		512
++sg560			MACH_SG560		SG560			513
++dp1000			MACH_DP1000		DP1000			514
++omap_osk		MACH_OMAP_OSK		OMAP_OSK		515
++rg100v3			MACH_RG100V3		RG100V3			516
++mx2ads			MACH_MX2ADS		MX2ADS			517
++pxa_kilo		MACH_PXA_KILO		PXA_KILO		518
++ixp4xx_eagle		MACH_IXP4XX_EAGLE	IXP4XX_EAGLE		519
++tosa			MACH_TOSA		TOSA			520
++mb2520f			MACH_MB2520F		MB2520F			521
++emc1000			MACH_EMC1000		EMC1000			522
++tidsc25			MACH_TIDSC25		TIDSC25			523
++akcpmxl			MACH_AKCPMXL		AKCPMXL			524
++av3xx			MACH_AV3XX		AV3XX			525
++avila			MACH_AVILA		AVILA			526
++pxa_mpm10		MACH_PXA_MPM10		PXA_MPM10		527
++pxa_kyanite		MACH_PXA_KYANITE	PXA_KYANITE		528
++sgold			MACH_SGOLD		SGOLD			529
++oscar			MACH_OSCAR		OSCAR			530
++epxa4usb2		MACH_EPXA4USB2		EPXA4USB2		531
++xsengine		MACH_XSENGINE		XSENGINE		532
++ip600			MACH_IP600		IP600			533
++mcan2			MACH_MCAN2		MCAN2			534
++ddi_blueridge		MACH_DDI_BLUERIDGE	DDI_BLUERIDGE		535
++skyminder		MACH_SKYMINDER		SKYMINDER		536
++lpd79520		MACH_LPD79520		LPD79520		537
++edb9302			MACH_EDB9302		EDB9302			538
++hw90340			MACH_HW90340		HW90340			539
++cip_box			MACH_CIP_BOX		CIP_BOX			540
++ivpn			MACH_IVPN		IVPN			541
++rsoc2			MACH_RSOC2		RSOC2			542
++husky			MACH_HUSKY		HUSKY			543
++boxer			MACH_BOXER		BOXER			544
++shepherd		MACH_SHEPHERD		SHEPHERD		545
++aml42800aa		MACH_AML42800AA		AML42800AA		546
++lpc2294			MACH_LPC2294		LPC2294			548
++switchgrass		MACH_SWITCHGRASS	SWITCHGRASS		549
++ens_cmu			MACH_ENS_CMU		ENS_CMU			550
++mm6_sdb			MACH_MM6_SDB		MM6_SDB			551
++saturn			MACH_SATURN		SATURN			552
++i30030evb		MACH_I30030EVB		I30030EVB		553
++mxc27530evb		MACH_MXC27530EVB	MXC27530EVB		554
++smdk2800		MACH_SMDK2800		SMDK2800		555
++mtwilson		MACH_MTWILSON		MTWILSON		556
++ziti			MACH_ZITI		ZITI			557
++grandfather		MACH_GRANDFATHER	GRANDFATHER		558
++tengine			MACH_TENGINE		TENGINE			559
++s3c2460			MACH_S3C2460		S3C2460			560
++pdm			MACH_PDM		PDM			561
++h4700			MACH_H4700		H4700			562
++h6300			MACH_H6300		H6300			563
++rz1700			MACH_RZ1700		RZ1700			564
++a716			MACH_A716		A716			565
++estk2440a		MACH_ESTK2440A		ESTK2440A		566
++atwixp425		MACH_ATWIXP425		ATWIXP425		567
++csb336			MACH_CSB336		CSB336			568
++rirm2			MACH_RIRM2		RIRM2			569
++cx23518			MACH_CX23518		CX23518			570
++cx2351x			MACH_CX2351X		CX2351X			571
++computime		MACH_COMPUTIME		COMPUTIME		572
++izarus			MACH_IZARUS		IZARUS			573
++pxa_rts			MACH_RTS		RTS			574
++se5100			MACH_SE5100		SE5100			575
++s3c2510			MACH_S3C2510		S3C2510			576
++csb437tl		MACH_CSB437TL		CSB437TL		577
++slauson			MACH_SLAUSON		SLAUSON			578
++pearlriver		MACH_PEARLRIVER		PEARLRIVER		579
++tdc_p210		MACH_TDC_P210		TDC_P210		580
++sg580			MACH_SG580		SG580			581
++wrsbcarm7		MACH_WRSBCARM7		WRSBCARM7		582
++ipd			MACH_IPD		IPD			583
++pxa_dnp2110		MACH_PXA_DNP2110	PXA_DNP2110		584
++xaeniax			MACH_XAENIAX		XAENIAX			585
++somn4250		MACH_SOMN4250		SOMN4250		586
++pleb2			MACH_PLEB2		PLEB2			587
++cornwallis		MACH_CORNWALLIS		CORNWALLIS		588
++gurney_drv		MACH_GURNEY_DRV		GURNEY_DRV		589
++chaffee			MACH_CHAFFEE		CHAFFEE			590
++rms101			MACH_RMS101		RMS101			591
++rx3715			MACH_RX3715		RX3715			592
++swift			MACH_SWIFT		SWIFT			593
++roverp7			MACH_ROVERP7		ROVERP7			594
++pr818s			MACH_PR818S		PR818S			595
++trxpro			MACH_TRXPRO		TRXPRO			596
++nslu2			MACH_NSLU2		NSLU2			597
++e400			MACH_E400		E400			598
++trab			MACH_TRAB		TRAB			599
++cmc_pu2			MACH_CMC_PU2		CMC_PU2			600
++fulcrum			MACH_FULCRUM		FULCRUM			601
++netgate42x		MACH_NETGATE42X		NETGATE42X		602
++str710			MACH_STR710		STR710			603
++ixdpg425		MACH_IXDPG425		IXDPG425		604
++tomtomgo		MACH_TOMTOMGO		TOMTOMGO		605
++versatile_ab		MACH_VERSATILE_AB	VERSATILE_AB		606
++edb9307			MACH_EDB9307		EDB9307			607
++sg565			MACH_SG565		SG565			608
++lpd79524		MACH_LPD79524		LPD79524		609
++lpd79525		MACH_LPD79525		LPD79525		610
++rms100			MACH_RMS100		RMS100			611
++kb9200			MACH_KB9200		KB9200			612
++sx1			MACH_SX1		SX1			613
++hms39c7092		MACH_HMS39C7092		HMS39C7092		614
++armadillo		MACH_ARMADILLO		ARMADILLO		615
++ipcu			MACH_IPCU		IPCU			616
++loox720			MACH_LOOX720		LOOX720			617
++ixdp465			MACH_IXDP465		IXDP465			618
++ixdp2351		MACH_IXDP2351		IXDP2351		619
++adsvix			MACH_ADSVIX		ADSVIX			620
++dm270			MACH_DM270		DM270			621
++socltplus		MACH_SOCLTPLUS		SOCLTPLUS		622
++ecia			MACH_ECIA		ECIA			623
++cm4008			MACH_CM4008		CM4008			624
++p2001			MACH_P2001		P2001			625
++twister			MACH_TWISTER		TWISTER			626
++mudshark		MACH_MUDSHARK		MUDSHARK		627
++hb2			MACH_HB2		HB2			628
++iq80332			MACH_IQ80332		IQ80332			629
++sendt			MACH_SENDT		SENDT			630
++mx2jazz			MACH_MX2JAZZ		MX2JAZZ			631
++multiio			MACH_MULTIIO		MULTIIO			632
++hrdisplay		MACH_HRDISPLAY		HRDISPLAY		633
++mxc27530ads		MACH_MXC27530ADS	MXC27530ADS		634
++trizeps3		MACH_TRIZEPS3		TRIZEPS3		635
++zefeerdza		MACH_ZEFEERDZA		ZEFEERDZA		636
++zefeerdzb		MACH_ZEFEERDZB		ZEFEERDZB		637
++zefeerdzg		MACH_ZEFEERDZG		ZEFEERDZG		638
++zefeerdzn		MACH_ZEFEERDZN		ZEFEERDZN		639
++zefeerdzq		MACH_ZEFEERDZQ		ZEFEERDZQ		640
++gtwx5715		MACH_GTWX5715		GTWX5715		641
++astro_jack		MACH_ASTRO_JACK		ASTRO_JACK		643
++tip03			MACH_TIP03		TIP03			644
++a9200ec			MACH_A9200EC		A9200EC			645
++pnx0105			MACH_PNX0105		PNX0105			646
++adcpoecpu		MACH_ADCPOECPU		ADCPOECPU		647
++csb637			MACH_CSB637		CSB637			648
++mb9200			MACH_MB9200		MB9200			650
++kulun			MACH_KULUN		KULUN			651
++snapper			MACH_SNAPPER		SNAPPER			652
++optima			MACH_OPTIMA		OPTIMA			653
++dlhsbc			MACH_DLHSBC		DLHSBC			654
++x30			MACH_X30		X30			655
++n30			MACH_N30		N30			656
++manga_ks8695		MACH_MANGA_KS8695	MANGA_KS8695		657
++ajax			MACH_AJAX		AJAX			658
++nec_mp900		MACH_NEC_MP900		NEC_MP900		659
++vvtk1000		MACH_VVTK1000		VVTK1000		661
++kafa			MACH_KAFA		KAFA			662
++vvtk3000		MACH_VVTK3000		VVTK3000		663
++pimx1			MACH_PIMX1		PIMX1			664
++ollie			MACH_OLLIE		OLLIE			665
++skymax			MACH_SKYMAX		SKYMAX			666
++jazz			MACH_JAZZ		JAZZ			667
++tel_t3			MACH_TEL_T3		TEL_T3			668
++aisino_fcr255		MACH_AISINO_FCR255	AISINO_FCR255		669
++btweb			MACH_BTWEB		BTWEB			670
++dbg_lh79520		MACH_DBG_LH79520	DBG_LH79520		671
++cm41xx			MACH_CM41XX		CM41XX			672
++ts72xx			MACH_TS72XX		TS72XX			673
++nggpxa			MACH_NGGPXA		NGGPXA			674
++csb535			MACH_CSB535		CSB535			675
++csb536			MACH_CSB536		CSB536			676
++pxa_trakpod		MACH_PXA_TRAKPOD	PXA_TRAKPOD		677
++praxis			MACH_PRAXIS		PRAXIS			678
++lh75411			MACH_LH75411		LH75411			679
++otom			MACH_OTOM		OTOM			680
++nexcoder_2440		MACH_NEXCODER_2440	NEXCODER_2440		681
++loox410			MACH_LOOX410		LOOX410			682
++westlake		MACH_WESTLAKE		WESTLAKE		683
++nsb			MACH_NSB		NSB			684
++esl_sarva_stn		MACH_ESL_SARVA_STN	ESL_SARVA_STN		685
++esl_sarva_tft		MACH_ESL_SARVA_TFT	ESL_SARVA_TFT		686
++esl_sarva_iad		MACH_ESL_SARVA_IAD	ESL_SARVA_IAD		687
++esl_sarva_acc		MACH_ESL_SARVA_ACC	ESL_SARVA_ACC		688
++typhoon			MACH_TYPHOON		TYPHOON			689
++cnav			MACH_CNAV		CNAV			690
++a730			MACH_A730		A730			691
++netstar			MACH_NETSTAR		NETSTAR			692
++supercon		MACH_PHASEFALE_SUPERCON	PHASEFALE_SUPERCON	693
++shiva1100		MACH_SHIVA1100		SHIVA1100		694
++etexsc			MACH_ETEXSC		ETEXSC			695
++ixdpg465		MACH_IXDPG465		IXDPG465		696
++a9m2410			MACH_A9M2410		A9M2410			697
++a9m2440			MACH_A9M2440		A9M2440			698
++a9m9750			MACH_A9M9750		A9M9750			699
++a9m9360			MACH_A9M9360		A9M9360			700
++unc90			MACH_UNC90		UNC90			701
++eco920			MACH_ECO920		ECO920			702
++satview			MACH_SATVIEW		SATVIEW			703
++roadrunner		MACH_ROADRUNNER		ROADRUNNER		704
++at91rm9200ek		MACH_AT91RM9200EK	AT91RM9200EK		705
++gp32			MACH_GP32		GP32			706
++gem			MACH_GEM		GEM			707
++i858			MACH_I858		I858			708
++hx2750			MACH_HX2750		HX2750			709
++mxc91131evb		MACH_MXC91131EVB	MXC91131EVB		710
++p700			MACH_P700		P700			711
++cpe			MACH_CPE		CPE			712
++spitz			MACH_SPITZ		SPITZ			713
++nimbra340		MACH_NIMBRA340		NIMBRA340		714
++lpc22xx			MACH_LPC22XX		LPC22XX			715
++omap_comet3		MACH_COMET3		COMET3			716
++omap_comet4		MACH_COMET4		COMET4			717
++csb625			MACH_CSB625		CSB625			718
++fortunet2		MACH_FORTUNET2		FORTUNET2		719
++s5h2200			MACH_S5H2200		S5H2200			720
++optorm920		MACH_OPTORM920		OPTORM920		721
++adsbitsyxb		MACH_ADSBITSYXB		ADSBITSYXB		722
++adssphere		MACH_ADSSPHERE		ADSSPHERE		723
++adsportal		MACH_ADSPORTAL		ADSPORTAL		724
++ln2410sbc		MACH_LN2410SBC		LN2410SBC		725
++cb3rufc			MACH_CB3RUFC		CB3RUFC			726
++mp2usb			MACH_MP2USB		MP2USB			727
++ntnp425c		MACH_NTNP425C		NTNP425C		728
++colibri			MACH_COLIBRI		COLIBRI			729
++pcm7220			MACH_PCM7220		PCM7220			730
++gateway7001		MACH_GATEWAY7001	GATEWAY7001		731
++pcm027			MACH_PCM027		PCM027			732
++cmpxa			MACH_CMPXA		CMPXA			733
++anubis			MACH_ANUBIS		ANUBIS			734
++ite8152			MACH_ITE8152		ITE8152			735
++lpc3xxx			MACH_LPC3XXX		LPC3XXX			736
++puppeteer		MACH_PUPPETEER		PUPPETEER		737
++e570			MACH_E570		E570			739
++x50			MACH_X50		X50			740
++recon			MACH_RECON		RECON			741
++xboardgp8		MACH_XBOARDGP8		XBOARDGP8		742
++fpic2			MACH_FPIC2		FPIC2			743
++akita			MACH_AKITA		AKITA			744
++a81			MACH_A81		A81			745
++svm_sc25x		MACH_SVM_SC25X		SVM_SC25X		746
++vt020			MACH_VADATECH020	VADATECH020		747
++tli			MACH_TLI		TLI			748
++edb9315lc		MACH_EDB9315LC		EDB9315LC		749
++passec			MACH_PASSEC		PASSEC			750
++ds_tiger		MACH_DS_TIGER		DS_TIGER		751
++e310			MACH_E310		E310			752
++e330			MACH_E330		E330			753
++rt3000			MACH_RT3000		RT3000			754
++nokia770		MACH_NOKIA770		NOKIA770		755
++pnx0106			MACH_PNX0106		PNX0106			756
++hx21xx			MACH_HX21XX		HX21XX			757
++faraday			MACH_FARADAY		FARADAY			758
++sbc9312			MACH_SBC9312		SBC9312			759
++batman			MACH_BATMAN		BATMAN			760
++jpd201			MACH_JPD201		JPD201			761
++mipsa			MACH_MIPSA		MIPSA			762
++kacom			MACH_KACOM		KACOM			763
++swarcocpu		MACH_SWARCOCPU		SWARCOCPU		764
++swarcodsl		MACH_SWARCODSL		SWARCODSL		765
++blueangel		MACH_BLUEANGEL		BLUEANGEL		766
++hairygrama		MACH_HAIRYGRAMA		HAIRYGRAMA		767
++banff			MACH_BANFF		BANFF			768
++carmeva			MACH_CARMEVA		CARMEVA			769
++sam255			MACH_SAM255		SAM255			770
++ppm10			MACH_PPM10		PPM10			771
++edb9315a		MACH_EDB9315A		EDB9315A		772
++sunset			MACH_SUNSET		SUNSET			773
++stargate2		MACH_STARGATE2		STARGATE2		774
++intelmote2		MACH_INTELMOTE2		INTELMOTE2		775
++trizeps4		MACH_TRIZEPS4		TRIZEPS4		776
++mainstone2		MACH_MAINSTONE2		MAINSTONE2		777
++ez_ixp42x		MACH_EZ_IXP42X		EZ_IXP42X		778
++tapwave_zodiac		MACH_TAPWAVE_ZODIAC	TAPWAVE_ZODIAC		779
++universalmeter		MACH_UNIVERSALMETER	UNIVERSALMETER		780
++hicoarm9		MACH_HICOARM9		HICOARM9		781
++pnx4008			MACH_PNX4008		PNX4008			782
++kws6000			MACH_KWS6000		KWS6000			783
++portux920t		MACH_PORTUX920T		PORTUX920T		784
++ez_x5			MACH_EZ_X5		EZ_X5			785
++omap_rudolph		MACH_OMAP_RUDOLPH	OMAP_RUDOLPH		786
++cpuat91			MACH_CPUAT91		CPUAT91			787
++rea9200			MACH_REA9200		REA9200			788
++acts_pune_sa1110	MACH_ACTS_PUNE_SA1110	ACTS_PUNE_SA1110	789
++ixp425			MACH_IXP425		IXP425			790
++i30030ads		MACH_I30030ADS		I30030ADS		791
++perch			MACH_PERCH		PERCH			792
++eis05r1			MACH_EIS05R1		EIS05R1			793
++pepperpad		MACH_PEPPERPAD		PEPPERPAD		794
++sb3010			MACH_SB3010		SB3010			795
++rm9200			MACH_RM9200		RM9200			796
++dma03			MACH_DMA03		DMA03			797
++road_s101		MACH_ROAD_S101		ROAD_S101		798
++iq81340sc		MACH_IQ81340SC		IQ81340SC		799
++iq_nextgen_b		MACH_IQ_NEXTGEN_B	IQ_NEXTGEN_B		800
++iq81340mc		MACH_IQ81340MC		IQ81340MC		801
++iq_nextgen_d		MACH_IQ_NEXTGEN_D	IQ_NEXTGEN_D		802
++iq_nextgen_e		MACH_IQ_NEXTGEN_E	IQ_NEXTGEN_E		803
++mallow_at91		MACH_MALLOW_AT91	MALLOW_AT91		804
++cybertracker_i		MACH_CYBERTRACKER_I	CYBERTRACKER_I		805
++gesbc931x		MACH_GESBC931X		GESBC931X		806
++centipad		MACH_CENTIPAD		CENTIPAD		807
++armsoc			MACH_ARMSOC		ARMSOC			808
++se4200			MACH_SE4200		SE4200			809
++ems197a			MACH_EMS197A		EMS197A			810
++micro9			MACH_MICRO9		MICRO9			811
++micro9l			MACH_MICRO9L		MICRO9L			812
++uc5471dsp		MACH_UC5471DSP		UC5471DSP		813
++sj5471eng		MACH_SJ5471ENG		SJ5471ENG		814
++none			MACH_CMPXA26X		CMPXA26X		815
++nc1			MACH_NC			NC			816
++omap_palmte		MACH_OMAP_PALMTE	OMAP_PALMTE		817
++ajax52x			MACH_AJAX52X		AJAX52X			818
++siriustar		MACH_SIRIUSTAR		SIRIUSTAR		819
++iodata_hdlg		MACH_IODATA_HDLG	IODATA_HDLG		820
++at91rm9200utl		MACH_AT91RM9200UTL	AT91RM9200UTL		821
++biosafe			MACH_BIOSAFE		BIOSAFE			822
++mp1000			MACH_MP1000		MP1000			823
++parsy			MACH_PARSY		PARSY			824
++ccxp270			MACH_CCXP		CCXP			825
++omap_gsample		MACH_OMAP_GSAMPLE	OMAP_GSAMPLE		826
++realview_eb		MACH_REALVIEW_EB	REALVIEW_EB		827
++samoa			MACH_SAMOA		SAMOA			828
++palmt3			MACH_PALMT3		PALMT3			829
++i878			MACH_I878		I878			830
++borzoi			MACH_BORZOI		BORZOI			831
++gecko			MACH_GECKO		GECKO			832
++ds101			MACH_DS101		DS101			833
++omap_palmtt2		MACH_OMAP_PALMTT2	OMAP_PALMTT2		834
++palmld			MACH_PALMLD		PALMLD			835
++cc9c			MACH_CC9C		CC9C			836
++sbc1670			MACH_SBC1670		SBC1670			837
++ixdp28x5		MACH_IXDP28X5		IXDP28X5		838
++omap_palmtt		MACH_OMAP_PALMTT	OMAP_PALMTT		839
++ml696k			MACH_ML696K		ML696K			840
++arcom_zeus		MACH_ARCOM_ZEUS		ARCOM_ZEUS		841
++osiris			MACH_OSIRIS		OSIRIS			842
++maestro			MACH_MAESTRO		MAESTRO			843
++palmte2			MACH_PALMTE2		PALMTE2			844
++ixbbm			MACH_IXBBM		IXBBM			845
++mx27ads			MACH_MX27ADS		MX27ADS			846
++ax8004			MACH_AX8004		AX8004			847
++at91sam9261ek		MACH_AT91SAM9261EK	AT91SAM9261EK		848
++loft			MACH_LOFT		LOFT			849
++magpie			MACH_MAGPIE		MAGPIE			850
++mx21ads			MACH_MX21ADS		MX21ADS			851
++mb87m3400		MACH_MB87M3400		MB87M3400		852
++mguard_delta		MACH_MGUARD_DELTA	MGUARD_DELTA		853
++davinci_dvdp		MACH_DAVINCI_DVDP	DAVINCI_DVDP		854
++htcuniversal		MACH_HTCUNIVERSAL	HTCUNIVERSAL		855
++tpad			MACH_TPAD		TPAD			856
++roverp3			MACH_ROVERP3		ROVERP3			857
++jornada928		MACH_JORNADA928		JORNADA928		858
++mv88fxx81		MACH_MV88FXX81		MV88FXX81		859
++stmp36xx		MACH_STMP36XX		STMP36XX		860
++sxni79524		MACH_SXNI79524		SXNI79524		861
++ams_delta		MACH_AMS_DELTA		AMS_DELTA		862
++uranium			MACH_URANIUM		URANIUM			863
++ucon			MACH_UCON		UCON			864
++nas100d			MACH_NAS100D		NAS100D			865
++l083			MACH_L083_1000		L083_1000		866
++ezx			MACH_EZX		EZX			867
++pnx5220			MACH_PNX5220		PNX5220			868
++butte			MACH_BUTTE		BUTTE			869
++srm2			MACH_SRM2		SRM2			870
++dsbr			MACH_DSBR		DSBR			871
++crystalball		MACH_CRYSTALBALL	CRYSTALBALL		872
++tinypxa27x		MACH_TINYPXA27X		TINYPXA27X		873
++herbie			MACH_HERBIE		HERBIE			874
++magician		MACH_MAGICIAN		MAGICIAN		875
++cm4002			MACH_CM4002		CM4002			876
++b4			MACH_B4			B4			877
++maui			MACH_MAUI		MAUI			878
++cybertracker_g		MACH_CYBERTRACKER_G	CYBERTRACKER_G		879
++nxdkn			MACH_NXDKN		NXDKN			880
++mio8390			MACH_MIO8390		MIO8390			881
++omi_board		MACH_OMI_BOARD		OMI_BOARD		882
++mx21civ			MACH_MX21CIV		MX21CIV			883
++mahi_cdac		MACH_MAHI_CDAC		MAHI_CDAC		884
++palmtx			MACH_PALMTX		PALMTX			885
++s3c2413			MACH_S3C2413		S3C2413			887
++samsys_ep0		MACH_SAMSYS_EP0		SAMSYS_EP0		888
++wg302v1			MACH_WG302V1		WG302V1			889
++wg302v2			MACH_WG302V2		WG302V2			890
++eb42x			MACH_EB42X		EB42X			891
++iq331es			MACH_IQ331ES		IQ331ES			892
++cosydsp			MACH_COSYDSP		COSYDSP			893
++uplat7d_proto		MACH_UPLAT7D		UPLAT7D			894
++ptdavinci		MACH_PTDAVINCI		PTDAVINCI		895
++mbus			MACH_MBUS		MBUS			896
++nadia2vb		MACH_NADIA2VB		NADIA2VB		897
++r1000			MACH_R1000		R1000			898
++hw90250			MACH_HW90250		HW90250			899
++omap_2430sdp		MACH_OMAP_2430SDP	OMAP_2430SDP		900
++davinci_evm		MACH_DAVINCI_EVM	DAVINCI_EVM		901
++omap_tornado		MACH_OMAP_TORNADO	OMAP_TORNADO		902
++olocreek		MACH_OLOCREEK		OLOCREEK		903
++palmz72			MACH_PALMZ72		PALMZ72			904
++nxdb500			MACH_NXDB500		NXDB500			905
++apf9328			MACH_APF9328		APF9328			906
++omap_wipoq		MACH_OMAP_WIPOQ		OMAP_WIPOQ		907
++omap_twip		MACH_OMAP_TWIP		OMAP_TWIP		908
++treo650			MACH_TREO650		TREO650			909
++acumen			MACH_ACUMEN		ACUMEN			910
++xp100			MACH_XP100		XP100			911
++fs2410			MACH_FS2410		FS2410			912
++pxa270_cerf		MACH_PXA270_CERF	PXA270_CERF		913
++sq2ftlpalm		MACH_SQ2FTLPALM		SQ2FTLPALM		914
++bsemserver		MACH_BSEMSERVER		BSEMSERVER		915
++netclient		MACH_NETCLIENT		NETCLIENT		916
++palmt5			MACH_PALMT5		PALMT5			917
++palmtc			MACH_PALMTC		PALMTC			918
++omap_apollon		MACH_OMAP_APOLLON	OMAP_APOLLON		919
++mxc30030evb		MACH_MXC30030EVB	MXC30030EVB		920
++rea_cpu2		MACH_REA_2D		REA_2D			921
++eti3e524		MACH_TI3E524		TI3E524			922
++ateb9200		MACH_ATEB9200		ATEB9200		923
++auckland		MACH_AUCKLAND		AUCKLAND		924
++ak3220m			MACH_AK3320M		AK3320M			925
++duramax			MACH_DURAMAX		DURAMAX			926
++n35			MACH_N35		N35			927
++pronghorn		MACH_PRONGHORN		PRONGHORN		928
++fundy			MACH_FUNDY		FUNDY			929
++logicpd_pxa270		MACH_LOGICPD_PXA270	LOGICPD_PXA270		930
++cpu777			MACH_CPU777		CPU777			931
++simicon9201		MACH_SIMICON9201	SIMICON9201		932
++leap2_hpm		MACH_LEAP2_HPM		LEAP2_HPM		933
++cm922txa10		MACH_CM922TXA10		CM922TXA10		934
++sandgate		MACH_PXA		PXA			935
++sandgate2		MACH_SANDGATE2		SANDGATE2		936
++sandgate2g		MACH_SANDGATE2G		SANDGATE2G		937
++sandgate2p		MACH_SANDGATE2P		SANDGATE2P		938
++fred_jack		MACH_FRED_JACK		FRED_JACK		939
++ttg_color1		MACH_TTG_COLOR1		TTG_COLOR1		940
++nxeb500hmi		MACH_NXEB500HMI		NXEB500HMI		941
++netdcu8			MACH_NETDCU8		NETDCU8			942
++ng_fvx538		MACH_NG_FVX538		NG_FVX538		944
++ng_fvs338		MACH_NG_FVS338		NG_FVS338		945
++pnx4103			MACH_PNX4103		PNX4103			946
++hesdb			MACH_HESDB		HESDB			947
++xsilo			MACH_XSILO		XSILO			948
++espresso		MACH_ESPRESSO		ESPRESSO		949
++emlc			MACH_EMLC		EMLC			950
++sisteron		MACH_SISTERON		SISTERON		951
++rx1950			MACH_RX1950		RX1950			952
++tsc_venus		MACH_TSC_VENUS		TSC_VENUS		953
++ds101j			MACH_DS101J		DS101J			954
++mxc30030ads		MACH_MXC30030ADS	MXC30030ADS		955
++fujitsu_wimaxsoc	MACH_FUJITSU_WIMAXSOC	FUJITSU_WIMAXSOC	956
++dualpcmodem		MACH_DUALPCMODEM	DUALPCMODEM		957
++gesbc9312		MACH_GESBC9312		GESBC9312		958
++htcapache		MACH_HTCAPACHE		HTCAPACHE		959
++ixdp435			MACH_IXDP435		IXDP435			960
++catprovt100		MACH_CATPROVT100	CATPROVT100		961
++picotux1xx		MACH_PICOTUX1XX		PICOTUX1XX		962
++picotux2xx		MACH_PICOTUX2XX		PICOTUX2XX		963
++dsmg600			MACH_DSMG600		DSMG600			964
++empc2			MACH_EMPC2		EMPC2			965
++ventura			MACH_VENTURA		VENTURA			966
++phidget_sbc		MACH_PHIDGET_SBC	PHIDGET_SBC		967
++ij3k			MACH_IJ3K		IJ3K			968
++pisgah			MACH_PISGAH		PISGAH			969
++omap_fsample		MACH_OMAP_FSAMPLE	OMAP_FSAMPLE		970
++sg720			MACH_SG720		SG720			971
++redfox			MACH_REDFOX		REDFOX			972
++mysh_ep9315_1		MACH_MYSH_EP9315_1	MYSH_EP9315_1		973
++tpf106			MACH_TPF106		TPF106			974
++at91rm9200kg		MACH_AT91RM9200KG	AT91RM9200KG		975
++rcmt2			MACH_SLEDB		SLEDB			976
++ontrack			MACH_ONTRACK		ONTRACK			977
++pm1200			MACH_PM1200		PM1200			978
++ess24562		MACH_ESS24XXX		ESS24XXX		979
++coremp7			MACH_COREMP7		COREMP7			980
++nexcoder_6446		MACH_NEXCODER_6446	NEXCODER_6446		981
++stvc8380		MACH_STVC8380		STVC8380		982
++teklynx			MACH_TEKLYNX		TEKLYNX			983
++carbonado		MACH_CARBONADO		CARBONADO		984
++sysmos_mp730		MACH_SYSMOS_MP730	SYSMOS_MP730		985
++snapper_cl15		MACH_SNAPPER_CL15	SNAPPER_CL15		986
++pgigim			MACH_PGIGIM		PGIGIM			987
++ptx9160p2		MACH_PTX9160P2		PTX9160P2		988
++dcore1			MACH_DCORE1		DCORE1			989
++victorpxa		MACH_VICTORPXA		VICTORPXA		990
++mx2dtb			MACH_MX2DTB		MX2DTB			991
++pxa_irex_er0100		MACH_PXA_IREX_ER0100	PXA_IREX_ER0100		992
++omap_palmz71		MACH_OMAP_PALMZ71	OMAP_PALMZ71		993
++bartec_deg		MACH_BARTEC_DEG		BARTEC_DEG		994
++hw50251			MACH_HW50251		HW50251			995
++ibox			MACH_IBOX		IBOX			996
++atlaslh7a404		MACH_ATLASLH7A404	ATLASLH7A404		997
++pt2026			MACH_PT2026		PT2026			998
++htcalpine		MACH_HTCALPINE		HTCALPINE		999
++bartec_vtu		MACH_BARTEC_VTU		BARTEC_VTU		1000
++vcoreii			MACH_VCOREII		VCOREII			1001
++pdnb3			MACH_PDNB3		PDNB3			1002
++htcbeetles		MACH_HTCBEETLES		HTCBEETLES		1003
++s3c6400			MACH_S3C6400		S3C6400			1004
++s3c2443			MACH_S3C2443		S3C2443			1005
++omap_ldk		MACH_OMAP_LDK		OMAP_LDK		1006
++smdk2460		MACH_SMDK2460		SMDK2460		1007
++smdk2440		MACH_SMDK2440		SMDK2440		1008
++smdk2412		MACH_SMDK2412		SMDK2412		1009
++webbox			MACH_WEBBOX		WEBBOX			1010
++cwwndp			MACH_CWWNDP		CWWNDP			1011
++i839			MACH_DRAGON		DRAGON			1012
++opendo_cpu_board	MACH_OPENDO_CPU_BOARD	OPENDO_CPU_BOARD	1013
++ccm2200			MACH_CCM2200		CCM2200			1014
++etwarm			MACH_ETWARM		ETWARM			1015
++m93030			MACH_M93030		M93030			1016
++cc7u			MACH_CC7U		CC7U			1017
++mtt_ranger		MACH_MTT_RANGER		MTT_RANGER		1018
++nexus			MACH_NEXUS		NEXUS			1019
++desman			MACH_DESMAN		DESMAN			1020
++bkde303			MACH_BKDE303		BKDE303			1021
++smdk2413		MACH_SMDK2413		SMDK2413		1022
++aml_m7200		MACH_AML_M7200		AML_M7200		1023
++aml_m5900		MACH_AML_M5900		AML_M5900		1024
++sg640			MACH_SG640		SG640			1025
++edg79524		MACH_EDG79524		EDG79524		1026
++ai2410			MACH_AI2410		AI2410			1027
++ixp465			MACH_IXP465		IXP465			1028
++balloon3		MACH_BALLOON3		BALLOON3		1029
++heins			MACH_HEINS		HEINS			1030
++mpluseva		MACH_MPLUSEVA		MPLUSEVA		1031
++rt042			MACH_RT042		RT042			1032
++cwiem			MACH_CWIEM		CWIEM			1033
++cm_x270			MACH_CM_X270		CM_X270			1034
++cm_x255			MACH_CM_X255		CM_X255			1035
++esh_at91		MACH_ESH_AT91		ESH_AT91		1036
++sandgate3		MACH_SANDGATE3		SANDGATE3		1037
++primo			MACH_PRIMO		PRIMO			1038
++gemstone		MACH_GEMSTONE		GEMSTONE		1039
++pronghorn_metro		MACH_PRONGHORNMETRO	PRONGHORNMETRO		1040
++sidewinder		MACH_SIDEWINDER		SIDEWINDER		1041
++picomod1		MACH_PICOMOD1		PICOMOD1		1042
++sg590			MACH_SG590		SG590			1043
++akai9307		MACH_AKAI9307		AKAI9307		1044
++fontaine		MACH_FONTAINE		FONTAINE		1045
++wombat			MACH_WOMBAT		WOMBAT			1046
++acq300			MACH_ACQ300		ACQ300			1047
++mod272			MACH_MOD_270		MOD_270			1048
++vmc_vc0820		MACH_VC0820		VC0820			1049
++ani_aim			MACH_ANI_AIM		ANI_AIM			1050
++jellyfish		MACH_JELLYFISH		JELLYFISH		1051
++amanita			MACH_AMANITA		AMANITA			1052
++vlink			MACH_VLINK		VLINK			1053
++dexflex			MACH_DEXFLEX		DEXFLEX			1054
++eigen_ttq		MACH_EIGEN_TTQ		EIGEN_TTQ		1055
++arcom_titan		MACH_ARCOM_TITAN	ARCOM_TITAN		1056
++tabla			MACH_TABLA		TABLA			1057
++mdirac3			MACH_MDIRAC3		MDIRAC3			1058
++mrhfbp2			MACH_MRHFBP2		MRHFBP2			1059
++at91rm9200rb		MACH_AT91RM9200RB	AT91RM9200RB		1060
++ani_apm			MACH_ANI_APM		ANI_APM			1061
++ella1			MACH_ELLA1		ELLA1			1062
++inhand_pxa27x		MACH_INHAND_PXA27X	INHAND_PXA27X		1063
++inhand_pxa25x		MACH_INHAND_PXA25X	INHAND_PXA25X		1064
++empos_xm		MACH_EMPOS_XM		EMPOS_XM		1065
++empos			MACH_EMPOS		EMPOS			1066
++empos_tiny		MACH_EMPOS_TINY		EMPOS_TINY		1067
++empos_sm		MACH_EMPOS_SM		EMPOS_SM		1068
++egret			MACH_EGRET		EGRET			1069
++ostrich			MACH_OSTRICH		OSTRICH			1070
++n50			MACH_N50		N50			1071
++ecbat91			MACH_ECBAT91		ECBAT91			1072
++stareast		MACH_STAREAST		STAREAST		1073
++dspg_dw			MACH_DSPG_DW		DSPG_DW			1074
++onearm			MACH_ONEARM		ONEARM			1075
++mrg110_6		MACH_MRG110_6		MRG110_6		1076
++wrt300nv2		MACH_WRT300NV2		WRT300NV2		1077
++xm_bulverde		MACH_XM_BULVERDE	XM_BULVERDE		1078
++msm6100			MACH_MSM6100		MSM6100			1079
++eti_b1			MACH_ETI_B1		ETI_B1			1080
++za9l_series		MACH_ZILOG_ZA9L		ZILOG_ZA9L		1081
++bit2440			MACH_BIT2440		BIT2440			1082
++nbi			MACH_NBI		NBI			1083
++smdk2443		MACH_SMDK2443		SMDK2443		1084
++vdavinci		MACH_VDAVINCI		VDAVINCI		1085
++atc6			MACH_ATC6		ATC6			1086
++multmdw			MACH_MULTMDW		MULTMDW			1087
++mba2440			MACH_MBA2440		MBA2440			1088
++ecsd			MACH_ECSD		ECSD			1089
++palmz31			MACH_PALMZ31		PALMZ31			1090
++fsg			MACH_FSG		FSG			1091
++razor101		MACH_RAZOR101		RAZOR101		1092
++opera_tdm		MACH_OPERA_TDM		OPERA_TDM		1093
++comcerto		MACH_COMCERTO		COMCERTO		1094
++tb0319			MACH_TB0319		TB0319			1095
++kws8000			MACH_KWS8000		KWS8000			1096
++b2			MACH_B2			B2			1097
++lcl54			MACH_LCL54		LCL54			1098
++at91sam9260ek		MACH_AT91SAM9260EK	AT91SAM9260EK		1099
++glantank		MACH_GLANTANK		GLANTANK		1100
++n2100			MACH_N2100		N2100			1101
++n4100			MACH_N4100		N4100			1102
++rsc4			MACH_VERTICAL_RSC4	VERTICAL_RSC4		1103
++sg8100			MACH_SG8100		SG8100			1104
++im42xx			MACH_IM42XX		IM42XX			1105
++ftxx			MACH_FTXX		FTXX			1106
++lwfusion		MACH_LWFUSION		LWFUSION		1107
++qt2410			MACH_QT2410		QT2410			1108
++kixrp435		MACH_KIXRP435		KIXRP435		1109
++ccw9c			MACH_CCW9C		CCW9C			1110
++dabhs			MACH_DABHS		DABHS			1111
++gzmx			MACH_GZMX		GZMX			1112
++ipnw100ap		MACH_IPNW100AP		IPNW100AP		1113
++cc9p9360dev		MACH_CC9P9360DEV	CC9P9360DEV		1114
++cc9p9750dev		MACH_CC9P9750DEV	CC9P9750DEV		1115
++cc9p9360val		MACH_CC9P9360VAL	CC9P9360VAL		1116
++cc9p9750val		MACH_CC9P9750VAL	CC9P9750VAL		1117
++nx70v			MACH_NX70V		NX70V			1118
++at91rm9200df		MACH_AT91RM9200DF	AT91RM9200DF		1119
++se_pilot2		MACH_SE_PILOT2		SE_PILOT2		1120
++mtcn_t800		MACH_MTCN_T800		MTCN_T800		1121
++vcmx212			MACH_VCMX212		VCMX212			1122
++lynx			MACH_LYNX		LYNX			1123
++at91sam9260id		MACH_AT91SAM9260ID	AT91SAM9260ID		1124
++hw86052			MACH_HW86052		HW86052			1125
++pilz_pmi3		MACH_PILZ_PMI3		PILZ_PMI3		1126
++edb9302a		MACH_EDB9302A		EDB9302A		1127
++edb9307a		MACH_EDB9307A		EDB9307A		1128
++ct_dfs			MACH_CT_DFS		CT_DFS			1129
++pilz_pmi4		MACH_PILZ_PMI4		PILZ_PMI4		1130
++xceednp_ixp		MACH_XCEEDNP_IXP	XCEEDNP_IXP		1131
++smdk2442b		MACH_SMDK2442B		SMDK2442B		1132
++xnode			MACH_XNODE		XNODE			1133
++aidx270			MACH_AIDX270		AIDX270			1134
++rema			MACH_REMA		REMA			1135
++bps1000			MACH_BPS1000		BPS1000			1136
++hw90350			MACH_HW90350		HW90350			1137
++omap_3430sdp		MACH_OMAP_3430SDP	OMAP_3430SDP		1138
++bluetouch		MACH_BLUETOUCH		BLUETOUCH		1139
++vstms			MACH_VSTMS		VSTMS			1140
++xsbase270		MACH_XSBASE270		XSBASE270		1141
++at91sam9260ek_cn	MACH_AT91SAM9260EK_CN	AT91SAM9260EK_CN	1142
++adsturboxb		MACH_ADSTURBOXB		ADSTURBOXB		1143
++oti4110			MACH_OTI4110		OTI4110			1144
++hme_pxa			MACH_HME_PXA		HME_PXA			1145
++deisterdca		MACH_DEISTERDCA		DEISTERDCA		1146
++ces_ssem2		MACH_CES_SSEM2		CES_SSEM2		1147
++ces_mtr			MACH_CES_MTR		CES_MTR			1148
++tds_avng_sbc		MACH_TDS_AVNG_SBC	TDS_AVNG_SBC		1149
++everest			MACH_EVEREST		EVEREST			1150
++pnx4010			MACH_PNX4010		PNX4010			1151
++oxnas			MACH_OXNAS		OXNAS			1152
++fiori			MACH_FIORI		FIORI			1153
++ml1200			MACH_ML1200		ML1200			1154
++pecos			MACH_PECOS		PECOS			1155
++nb2xxx			MACH_NB2XXX		NB2XXX			1156
++hw6900			MACH_HW6900		HW6900			1157
++cdcs_quoll		MACH_CDCS_QUOLL		CDCS_QUOLL		1158
++quicksilver		MACH_QUICKSILVER	QUICKSILVER		1159
++uplat926		MACH_UPLAT926		UPLAT926		1160
++dep2410_dep2410		MACH_DEP2410_THOMAS	DEP2410_THOMAS		1161
++dtk2410			MACH_DTK2410		DTK2410			1162
++chili			MACH_CHILI		CHILI			1163
++demeter			MACH_DEMETER		DEMETER			1164
++dionysus		MACH_DIONYSUS		DIONYSUS		1165
++as352x			MACH_AS352X		AS352X			1166
++service			MACH_SERVICE		SERVICE			1167
++cs_e9301		MACH_CS_E9301		CS_E9301		1168
++micro9m			MACH_MICRO9M		MICRO9M			1169
++ia_mospck		MACH_IA_MOSPCK		IA_MOSPCK		1170
++ql201b			MACH_QL201B		QL201B			1171
++bbm			MACH_BBM		BBM			1174
++exxx			MACH_EXXX		EXXX			1175
++wma11b			MACH_WMA11B		WMA11B			1176
++pelco_atlas		MACH_PELCO_ATLAS	PELCO_ATLAS		1177
++g500			MACH_G500		G500			1178
++bug			MACH_BUG		BUG			1179
++mx33ads			MACH_MX33ADS		MX33ADS			1180
++chub			MACH_CHUB		CHUB			1181
++neo1973_gta01		MACH_NEO1973_GTA01	NEO1973_GTA01		1182
++w90n740			MACH_W90N740		W90N740			1183
++medallion_sa2410	MACH_MEDALLION_SA2410	MEDALLION_SA2410	1184
++ia_cpu_9200_2		MACH_IA_CPU_9200_2	IA_CPU_9200_2		1185
++dimmrm9200		MACH_DIMMRM9200		DIMMRM9200		1186
++pm9261			MACH_PM9261		PM9261			1187
++ml7304			MACH_ML7304		ML7304			1189
++ucp250			MACH_UCP250		UCP250			1190
++intboard		MACH_INTBOARD		INTBOARD		1191
++gulfstream		MACH_GULFSTREAM		GULFSTREAM		1192
++labquest		MACH_LABQUEST		LABQUEST		1193
++vcmx313			MACH_VCMX313		VCMX313			1194
++urg200			MACH_URG200		URG200			1195
++cpux255lcdnet		MACH_CPUX255LCDNET	CPUX255LCDNET		1196
++netdcu9			MACH_NETDCU9		NETDCU9			1197
++netdcu10		MACH_NETDCU10		NETDCU10		1198
++dspg_dga		MACH_DSPG_DGA		DSPG_DGA		1199
++dspg_dvw		MACH_DSPG_DVW		DSPG_DVW		1200
++solos			MACH_SOLOS		SOLOS			1201
++at91sam9263ek		MACH_AT91SAM9263EK	AT91SAM9263EK		1202
++osstbox			MACH_OSSTBOX		OSSTBOX			1203
++kbat9261		MACH_KBAT9261		KBAT9261		1204
++ct1100			MACH_CT1100		CT1100			1205
++akcppxa			MACH_AKCPPXA		AKCPPXA			1206
++ochaya1020		MACH_OCHAYA1020		OCHAYA1020		1207
++hitrack			MACH_HITRACK		HITRACK			1208
++syme1			MACH_SYME1		SYME1			1209
++syhl1			MACH_SYHL1		SYHL1			1210
++empca400		MACH_EMPCA400		EMPCA400		1211
++em7210			MACH_EM7210		EM7210			1212
++htchermes		MACH_HTCHERMES		HTCHERMES		1213
++eti_c1			MACH_ETI_C1		ETI_C1			1214
++ac100			MACH_AC100		AC100			1216
++sneetch			MACH_SNEETCH		SNEETCH			1217
++studentmate		MACH_STUDENTMATE	STUDENTMATE		1218
++zir2410			MACH_ZIR2410		ZIR2410			1219
++zir2413			MACH_ZIR2413		ZIR2413			1220
++dlonip3			MACH_DLONIP3		DLONIP3			1221
++instream		MACH_INSTREAM		INSTREAM		1222
++ambarella		MACH_AMBARELLA		AMBARELLA		1223
++nevis			MACH_NEVIS		NEVIS			1224
++htc_trinity		MACH_HTC_TRINITY	HTC_TRINITY		1225
++ql202b			MACH_QL202B		QL202B			1226
++vpac270			MACH_VPAC270		VPAC270			1227
++rd129			MACH_RD129		RD129			1228
++htcwizard		MACH_HTCWIZARD		HTCWIZARD		1229
++treo680			MACH_TREO680		TREO680			1230
++tecon_tmezon		MACH_TECON_TMEZON	TECON_TMEZON		1231
++zylonite		MACH_ZYLONITE		ZYLONITE		1233
++gene1270		MACH_GENE1270		GENE1270		1234
++zir2412			MACH_ZIR2412		ZIR2412			1235
++mx31lite		MACH_MX31LITE		MX31LITE		1236
++t700wx			MACH_T700WX		T700WX			1237
++vf100			MACH_VF100		VF100			1238
++nsb2			MACH_NSB2		NSB2			1239
++nxhmi_bb		MACH_NXHMI_BB		NXHMI_BB		1240
++nxhmi_re		MACH_NXHMI_RE		NXHMI_RE		1241
++n4100pro		MACH_N4100PRO		N4100PRO		1242
++sam9260			MACH_SAM9260		SAM9260			1243
++omap_treo600		MACH_OMAP_TREO600	OMAP_TREO600		1244
++indy2410		MACH_INDY2410		INDY2410		1245
++nelt_a			MACH_NELT_A		NELT_A			1246
++n311			MACH_N311		N311			1248
++at91sam9260vgk		MACH_AT91SAM9260VGK	AT91SAM9260VGK		1249
++at91leppe		MACH_AT91LEPPE		AT91LEPPE		1250
++at91lepccn		MACH_AT91LEPCCN		AT91LEPCCN		1251
++apc7100			MACH_APC7100		APC7100			1252
++stargazer		MACH_STARGAZER		STARGAZER		1253
++sonata			MACH_SONATA		SONATA			1254
++schmoogie		MACH_SCHMOOGIE		SCHMOOGIE		1255
++aztool			MACH_AZTOOL		AZTOOL			1256
++mioa701			MACH_MIOA701		MIOA701			1257
++sxni9260		MACH_SXNI9260		SXNI9260		1258
++mxc27520evb		MACH_MXC27520EVB	MXC27520EVB		1259
++armadillo5x0		MACH_ARMADILLO5X0	ARMADILLO5X0		1260
++mb9260			MACH_MB9260		MB9260			1261
++mb9263			MACH_MB9263		MB9263			1262
++ipac9302		MACH_IPAC9302		IPAC9302		1263
++cc9p9360js		MACH_CC9P9360JS		CC9P9360JS		1264
++gallium			MACH_GALLIUM		GALLIUM			1265
++msc2410			MACH_MSC2410		MSC2410			1266
++ghi270			MACH_GHI270		GHI270			1267
++davinci_leonardo	MACH_DAVINCI_LEONARDO	DAVINCI_LEONARDO	1268
++oiab			MACH_OIAB		OIAB			1269
++smdk6400		MACH_SMDK6400		SMDK6400		1270
++nokia_n800		MACH_NOKIA_N800		NOKIA_N800		1271
++greenphone		MACH_GREENPHONE		GREENPHONE		1272
++compex42x		MACH_COMPEXWP18		COMPEXWP18		1273
++xmate			MACH_XMATE		XMATE			1274
++energizer		MACH_ENERGIZER		ENERGIZER		1275
++ime1			MACH_IME1		IME1			1276
++sweda_tms		MACH_SWEDATMS		SWEDATMS		1277
++ntnp435c		MACH_NTNP435C		NTNP435C		1278
++spectro2		MACH_SPECTRO2		SPECTRO2		1279
++h6039			MACH_H6039		H6039			1280
++ep80219			MACH_EP80219		EP80219			1281
++samoa_ii		MACH_SAMOA_II		SAMOA_II		1282
++cwmxl			MACH_CWMXL		CWMXL			1283
++as9200			MACH_AS9200		AS9200			1284
++sfx1149			MACH_SFX1149		SFX1149			1285
++navi010			MACH_NAVI010		NAVI010			1286
++multmdp			MACH_MULTMDP		MULTMDP			1287
++scb9520			MACH_SCB9520		SCB9520			1288
++htcathena		MACH_HTCATHENA		HTCATHENA		1289
++xp179			MACH_XP179		XP179			1290
++h4300			MACH_H4300		H4300			1291
++goramo_mlr		MACH_GORAMO_MLR		GORAMO_MLR		1292
++mxc30020evb		MACH_MXC30020EVB	MXC30020EVB		1293
++adsbitsyg5		MACH_ADSBITSYG5		ADSBITSYG5		1294
++adsportalplus		MACH_ADSPORTALPLUS	ADSPORTALPLUS		1295
++mmsp2plus		MACH_MMSP2PLUS		MMSP2PLUS		1296
++em_x270			MACH_EM_X270		EM_X270			1297
++tpp302			MACH_TPP302		TPP302			1298
++tpp104			MACH_TPM104		TPM104			1299
++tpm102			MACH_TPM102		TPM102			1300
++tpm109			MACH_TPM109		TPM109			1301
++fbxo1			MACH_FBXO1		FBXO1			1302
++hxd8			MACH_HXD8		HXD8			1303
++neo1973_gta02		MACH_NEO1973_GTA02	NEO1973_GTA02		1304
++emtest			MACH_EMTEST		EMTEST			1305
++ad6900			MACH_AD6900		AD6900			1306
++europa			MACH_EUROPA		EUROPA			1307
++metroconnect		MACH_METROCONNECT	METROCONNECT		1308
++ez_s2410		MACH_EZ_S2410		EZ_S2410		1309
++ez_s2440		MACH_EZ_S2440		EZ_S2440		1310
++ez_ep9312		MACH_EZ_EP9312		EZ_EP9312		1311
++ez_ep9315		MACH_EZ_EP9315		EZ_EP9315		1312
++ez_x7			MACH_EZ_X7		EZ_X7			1313
++godotdb			MACH_GODOTDB		GODOTDB			1314
++mistral			MACH_MISTRAL		MISTRAL			1315
++msm			MACH_MSM		MSM			1316
++ct5910			MACH_CT5910		CT5910			1317
++ct5912			MACH_CT5912		CT5912			1318
++hynet_ine		MACH_HYNET_INE		HYNET_INE		1319
++hynet_app		MACH_HYNET_APP		HYNET_APP		1320
++msm7200			MACH_MSM7200		MSM7200			1321
++msm7600			MACH_MSM7600		MSM7600			1322
++ceb255			MACH_CEB255		CEB255			1323
++ciel			MACH_CIEL		CIEL			1324
++slm5650			MACH_SLM5650		SLM5650			1325
++at91sam9rlek		MACH_AT91SAM9RLEK	AT91SAM9RLEK		1326
++comtech_router		MACH_COMTECH_ROUTER	COMTECH_ROUTER		1327
++sbc2410x		MACH_SBC2410X		SBC2410X		1328
++at4x0bd			MACH_AT4X0BD		AT4X0BD			1329
++cbifr			MACH_CBIFR		CBIFR			1330
++arcom_quantum		MACH_ARCOM_QUANTUM	ARCOM_QUANTUM		1331
++matrix520		MACH_MATRIX520		MATRIX520		1332
++matrix510		MACH_MATRIX510		MATRIX510		1333
++matrix500		MACH_MATRIX500		MATRIX500		1334
++m501			MACH_M501		M501			1335
++aaeon1270		MACH_AAEON1270		AAEON1270		1336
++matrix500ev		MACH_MATRIX500EV	MATRIX500EV		1337
++pac500			MACH_PAC500		PAC500			1338
++pnx8181			MACH_PNX8181		PNX8181			1339
++colibri320		MACH_COLIBRI320		COLIBRI320		1340
++aztoolbb		MACH_AZTOOLBB		AZTOOLBB		1341
++aztoolg2		MACH_AZTOOLG2		AZTOOLG2		1342
++dvlhost			MACH_DVLHOST		DVLHOST			1343
++zir9200			MACH_ZIR9200		ZIR9200			1344
++zir9260			MACH_ZIR9260		ZIR9260			1345
++cocopah			MACH_COCOPAH		COCOPAH			1346
++nds			MACH_NDS		NDS			1347
++rosencrantz		MACH_ROSENCRANTZ	ROSENCRANTZ		1348
++fttx_odsc		MACH_FTTX_ODSC		FTTX_ODSC		1349
++classe_r6904		MACH_CLASSE_R6904	CLASSE_R6904		1350
++cam60			MACH_CAM60		CAM60			1351
++mxc30031ads		MACH_MXC30031ADS	MXC30031ADS		1352
++datacall		MACH_DATACALL		DATACALL		1353
++at91eb01		MACH_AT91EB01		AT91EB01		1354
++rty			MACH_RTY		RTY			1355
++dwl2100			MACH_DWL2100		DWL2100			1356
++vinsi			MACH_VINSI		VINSI			1357
++db88f5281		MACH_DB88F5281		DB88F5281		1358
++csb726			MACH_CSB726		CSB726			1359
++tik27			MACH_TIK27		TIK27			1360
++mx_uc7420		MACH_MX_UC7420		MX_UC7420		1361
++rirm3			MACH_RIRM3		RIRM3			1362
++pelco_odyssey		MACH_PELCO_ODYSSEY	PELCO_ODYSSEY		1363
++adx_abox		MACH_ADX_ABOX		ADX_ABOX		1365
++adx_tpid		MACH_ADX_TPID		ADX_TPID		1366
++minicheck		MACH_MINICHECK		MINICHECK		1367
++idam			MACH_IDAM		IDAM			1368
++mario_mx		MACH_MARIO_MX		MARIO_MX		1369
++vi1888			MACH_VI1888		VI1888			1370
++zr4230			MACH_ZR4230		ZR4230			1371
++t1_ix_blue		MACH_T1_IX_BLUE		T1_IX_BLUE		1372
++syhq2			MACH_SYHQ2		SYHQ2			1373
++computime_r3		MACH_COMPUTIME_R3	COMPUTIME_R3		1374
++oratis			MACH_ORATIS		ORATIS			1375
++mikko			MACH_MIKKO		MIKKO			1376
++holon			MACH_HOLON		HOLON			1377
++olip8			MACH_OLIP8		OLIP8			1378
++ghi270hg		MACH_GHI270HG		GHI270HG		1379
++davinci_dm6467_evm	MACH_DAVINCI_DM6467_EVM	DAVINCI_DM6467_EVM	1380
++davinci_dm355_evm	MACH_DAVINCI_DM355_EVM	DAVINCI_DM355_EVM	1381
++blackriver		MACH_BLACKRIVER		BLACKRIVER		1383
++sandgate_wp		MACH_SANDGATEWP		SANDGATEWP		1384
++cdotbwsg		MACH_CDOTBWSG		CDOTBWSG		1385
++quark963		MACH_QUARK963		QUARK963		1386
++csb735			MACH_CSB735		CSB735			1387
++littleton		MACH_LITTLETON		LITTLETON		1388
++mio_p550		MACH_MIO_P550		MIO_P550		1389
++motion2440		MACH_MOTION2440		MOTION2440		1390
++imm500			MACH_IMM500		IMM500			1391
++homematic		MACH_HOMEMATIC		HOMEMATIC		1392
++ermine			MACH_ERMINE		ERMINE			1393
++kb9202b			MACH_KB9202B		KB9202B			1394
++hs1xx			MACH_HS1XX		HS1XX			1395
++studentmate2440		MACH_STUDENTMATE2440	STUDENTMATE2440		1396
++arvoo_l1_z1		MACH_ARVOO_L1_Z1	ARVOO_L1_Z1		1397
++dep2410k		MACH_DEP2410K		DEP2410K		1398
++xxsvideo		MACH_XXSVIDEO		XXSVIDEO		1399
++im4004			MACH_IM4004		IM4004			1400
++ochaya1050		MACH_OCHAYA1050		OCHAYA1050		1401
++lep9261			MACH_LEP9261		LEP9261			1402
++svenmeb			MACH_SVENMEB		SVENMEB			1403
++fortunet2ne		MACH_FORTUNET2NE	FORTUNET2NE		1404
++nxhx			MACH_NXHX		NXHX			1406
++realview_pb11mp		MACH_REALVIEW_PB11MP	REALVIEW_PB11MP		1407
++ids500			MACH_IDS500		IDS500			1408
++ors_n725		MACH_ORS_N725		ORS_N725		1409
++hsdarm			MACH_HSDARM		HSDARM			1410
++sha_pon003		MACH_SHA_PON003		SHA_PON003		1411
++sha_pon004		MACH_SHA_PON004		SHA_PON004		1412
++sha_pon007		MACH_SHA_PON007		SHA_PON007		1413
++sha_pon011		MACH_SHA_PON011		SHA_PON011		1414
++h6042			MACH_H6042		H6042			1415
++h6043			MACH_H6043		H6043			1416
++looxc550		MACH_LOOXC550		LOOXC550		1417
++cnty_titan		MACH_CNTY_TITAN		CNTY_TITAN		1418
++app3xx			MACH_APP3XX		APP3XX			1419
++sideoatsgrama		MACH_SIDEOATSGRAMA	SIDEOATSGRAMA		1420
++treo700p		MACH_TREO700P		TREO700P		1421
++treo700w		MACH_TREO700W		TREO700W		1422
++treo750			MACH_TREO750		TREO750			1423
++treo755p		MACH_TREO755P		TREO755P		1424
++ezreganut9200		MACH_EZREGANUT9200	EZREGANUT9200		1425
++sarge			MACH_SARGE		SARGE			1426
++a696			MACH_A696		A696			1427
++turtle1916		MACH_TURTLE		TURTLE			1428
++mx27_3ds		MACH_MX27_3DS		MX27_3DS		1430
++bishop			MACH_BISHOP		BISHOP			1431
++pxx			MACH_PXX		PXX			1432
++redwood			MACH_REDWOOD		REDWOOD			1433
++omap_2430dlp		MACH_OMAP_2430DLP	OMAP_2430DLP		1436
++omap_2430osk		MACH_OMAP_2430OSK	OMAP_2430OSK		1437
++sardine			MACH_SARDINE		SARDINE			1438
++halibut			MACH_HALIBUT		HALIBUT			1439
++trout			MACH_TROUT		TROUT			1440
++goldfish		MACH_GOLDFISH		GOLDFISH		1441
++gesbc2440		MACH_GESBC2440		GESBC2440		1442
++nomad			MACH_NOMAD		NOMAD			1443
++rosalind		MACH_ROSALIND		ROSALIND		1444
++cc9p9215		MACH_CC9P9215		CC9P9215		1445
++cc9p9210		MACH_CC9P9210		CC9P9210		1446
++cc9p9215js		MACH_CC9P9215JS		CC9P9215JS		1447
++cc9p9210js		MACH_CC9P9210JS		CC9P9210JS		1448
++nasffe			MACH_NASFFE		NASFFE			1449
++tn2x0bd			MACH_TN2X0BD		TN2X0BD			1450
++gwmpxa			MACH_GWMPXA		GWMPXA			1451
++exyplus			MACH_EXYPLUS		EXYPLUS			1452
++jadoo21			MACH_JADOO21		JADOO21			1453
++looxn560		MACH_LOOXN560		LOOXN560		1454
++bonsai			MACH_BONSAI		BONSAI			1455
++adsmilgato		MACH_ADSMILGATO		ADSMILGATO		1456
++gba			MACH_GBA		GBA			1457
++h6044			MACH_H6044		H6044			1458
++app			MACH_APP		APP			1459
++tct_hammer		MACH_TCT_HAMMER		TCT_HAMMER		1460
++herald			MACH_HERALD		HERALD			1461
++artemis			MACH_ARTEMIS		ARTEMIS			1462
++htctitan		MACH_HTCTITAN		HTCTITAN		1463
++qranium			MACH_QRANIUM		QRANIUM			1464
++adx_wsc2		MACH_ADX_WSC2		ADX_WSC2		1465
++adx_medcom		MACH_ADX_MEDCOM		ADX_MEDCOM		1466
++bboard			MACH_BBOARD		BBOARD			1467
++cambria			MACH_CAMBRIA		CAMBRIA			1468
++mt7xxx			MACH_MT7XXX		MT7XXX			1469
++matrix512		MACH_MATRIX512		MATRIX512		1470
++matrix522		MACH_MATRIX522		MATRIX522		1471
++ipac5010		MACH_IPAC5010		IPAC5010		1472
++sakura			MACH_SAKURA		SAKURA			1473
++grocx			MACH_GROCX		GROCX			1474
++pm9263			MACH_PM9263		PM9263			1475
++sim_one			MACH_SIM_ONE		SIM_ONE			1476
++acq132			MACH_ACQ132		ACQ132			1477
++datr			MACH_DATR		DATR			1478
++actux1			MACH_ACTUX1		ACTUX1			1479
++actux2			MACH_ACTUX2		ACTUX2			1480
++actux3			MACH_ACTUX3		ACTUX3			1481
++flexit			MACH_FLEXIT		FLEXIT			1482
++bh2x0bd			MACH_BH2X0BD		BH2X0BD			1483
++atb2002			MACH_ATB2002		ATB2002			1484
++xenon			MACH_XENON		XENON			1485
++fm607			MACH_FM607		FM607			1486
++matrix514		MACH_MATRIX514		MATRIX514		1487
++matrix524		MACH_MATRIX524		MATRIX524		1488
++inpod			MACH_INPOD		INPOD			1489
++jive			MACH_JIVE		JIVE			1490
++tll_mx21		MACH_TLL_MX21		TLL_MX21		1491
++sbc2800			MACH_SBC2800		SBC2800			1492
++cc7ucamry		MACH_CC7UCAMRY		CC7UCAMRY		1493
++ubisys_p9_sc15		MACH_UBISYS_P9_SC15	UBISYS_P9_SC15		1494
++ubisys_p9_ssc2d10	MACH_UBISYS_P9_SSC2D10	UBISYS_P9_SSC2D10	1495
++ubisys_p9_rcu3		MACH_UBISYS_P9_RCU3	UBISYS_P9_RCU3		1496
++aml_m8000		MACH_AML_M8000		AML_M8000		1497
++snapper_270		MACH_SNAPPER_270	SNAPPER_270		1498
++omap_bbx		MACH_OMAP_BBX		OMAP_BBX		1499
++ucn2410			MACH_UCN2410		UCN2410			1500
++sam9_l9260		MACH_SAM9_L9260		SAM9_L9260		1501
++eti_c2			MACH_ETI_C2		ETI_C2			1502
++avalanche		MACH_AVALANCHE		AVALANCHE		1503
++realview_pb1176		MACH_REALVIEW_PB1176	REALVIEW_PB1176		1504
++dp1500			MACH_DP1500		DP1500			1505
++apple_iphone		MACH_APPLE_IPHONE	APPLE_IPHONE		1506
++yl9200			MACH_YL9200		YL9200			1507
++rd88f5182		MACH_RD88F5182		RD88F5182		1508
++kurobox_pro		MACH_KUROBOX_PRO	KUROBOX_PRO		1509
++se_poet			MACH_SE_POET		SE_POET			1510
++mx31_3ds		MACH_MX31_3DS		MX31_3DS		1511
++r270			MACH_R270		R270			1512
++armour21		MACH_ARMOUR21		ARMOUR21		1513
++dt2			MACH_DT2		DT2			1514
++vt4			MACH_VT4		VT4			1515
++tyco320			MACH_TYCO320		TYCO320			1516
++adma			MACH_ADMA		ADMA			1517
++wp188			MACH_WP188		WP188			1518
++corsica			MACH_CORSICA		CORSICA			1519
++bigeye			MACH_BIGEYE		BIGEYE			1520
++tll5000			MACH_TLL5000		TLL5000			1522
++bebot			MACH_BEBOT		BEBOT			1523
++qong			MACH_QONG		QONG			1524
++tcompact		MACH_TCOMPACT		TCOMPACT		1525
++puma5			MACH_PUMA5		PUMA5			1526
++elara			MACH_ELARA		ELARA			1527
++ellington		MACH_ELLINGTON		ELLINGTON		1528
++xda_atom		MACH_XDA_ATOM		XDA_ATOM		1529
++energizer2		MACH_ENERGIZER2		ENERGIZER2		1530
++odin			MACH_ODIN		ODIN			1531
++actux4			MACH_ACTUX4		ACTUX4			1532
++esl_omap		MACH_ESL_OMAP		ESL_OMAP		1533
++omap2evm		MACH_OMAP2EVM		OMAP2EVM		1534
++omap3evm		MACH_OMAP3EVM		OMAP3EVM		1535
++adx_pcu57		MACH_ADX_PCU57		ADX_PCU57		1536
++monaco			MACH_MONACO		MONACO			1537
++levante			MACH_LEVANTE		LEVANTE			1538
++tmxipx425		MACH_TMXIPX425		TMXIPX425		1539
++leep			MACH_LEEP		LEEP			1540
++raad			MACH_RAAD		RAAD			1541
++dns323			MACH_DNS323		DNS323			1542
++ap1000			MACH_AP1000		AP1000			1543
++a9sam6432		MACH_A9SAM6432		A9SAM6432		1544
++shiny			MACH_SHINY		SHINY			1545
++omap3_beagle		MACH_OMAP3_BEAGLE	OMAP3_BEAGLE		1546
++csr_bdb2		MACH_CSR_BDB2		CSR_BDB2		1547
++nokia_n810		MACH_NOKIA_N810		NOKIA_N810		1548
++c270			MACH_C270		C270			1549
++sentry			MACH_SENTRY		SENTRY			1550
++pcm038			MACH_PCM038		PCM038			1551
++anc300			MACH_ANC300		ANC300			1552
++htckaiser		MACH_HTCKAISER		HTCKAISER		1553
++sbat100			MACH_SBAT100		SBAT100			1554
++modunorm		MACH_MODUNORM		MODUNORM		1555
++pelos_twarm		MACH_PELOS_TWARM	PELOS_TWARM		1556
++flank			MACH_FLANK		FLANK			1557
++sirloin			MACH_SIRLOIN		SIRLOIN			1558
++brisket			MACH_BRISKET		BRISKET			1559
++chuck			MACH_CHUCK		CHUCK			1560
++otter			MACH_OTTER		OTTER			1561
++davinci_ldk		MACH_DAVINCI_LDK	DAVINCI_LDK		1562
++phreedom		MACH_PHREEDOM		PHREEDOM		1563
++sg310			MACH_SG310		SG310			1564
++ts_x09			MACH_TS209		TS209			1565
++at91cap9adk		MACH_AT91CAP9ADK	AT91CAP9ADK		1566
++tion9315		MACH_TION9315		TION9315		1567
++mast			MACH_MAST		MAST			1568
++pfw			MACH_PFW		PFW			1569
++yl_p2440		MACH_YL_P2440		YL_P2440		1570
++zsbc32			MACH_ZSBC32		ZSBC32			1571
++omap_pace2		MACH_OMAP_PACE2		OMAP_PACE2		1572
++imx_pace2		MACH_IMX_PACE2		IMX_PACE2		1573
++mx31moboard		MACH_MX31MOBOARD	MX31MOBOARD		1574
++mx37_3ds		MACH_MX37_3DS		MX37_3DS		1575
++rcc			MACH_RCC		RCC			1576
++dmp			MACH_ARM9		ARM9			1577
++vision_ep9307		MACH_VISION_EP9307	VISION_EP9307		1578
++scly1000		MACH_SCLY1000		SCLY1000		1579
++fontel_ep		MACH_FONTEL_EP		FONTEL_EP		1580
++voiceblue3g		MACH_VOICEBLUE3G	VOICEBLUE3G		1581
++tt9200			MACH_TT9200		TT9200			1582
++digi2410		MACH_DIGI2410		DIGI2410		1583
++terastation_pro2	MACH_TERASTATION_PRO2	TERASTATION_PRO2	1584
++linkstation_pro		MACH_LINKSTATION_PRO	LINKSTATION_PRO		1585
++motorola_a780		MACH_MOTOROLA_A780	MOTOROLA_A780		1587
++motorola_e6		MACH_MOTOROLA_E6	MOTOROLA_E6		1588
++motorola_e2		MACH_MOTOROLA_E2	MOTOROLA_E2		1589
++motorola_e680		MACH_MOTOROLA_E680	MOTOROLA_E680		1590
++ur2410			MACH_UR2410		UR2410			1591
++tas9261			MACH_TAS9261		TAS9261			1592
++davinci_hermes_hd	MACH_HERMES_HD		HERMES_HD		1593
++davinci_perseo_hd	MACH_PERSEO_HD		PERSEO_HD		1594
++stargazer2		MACH_STARGAZER2		STARGAZER2		1595
++e350			MACH_E350		E350			1596
++wpcm450			MACH_WPCM450		WPCM450			1597
++cartesio		MACH_CARTESIO		CARTESIO		1598
++toybox			MACH_TOYBOX		TOYBOX			1599
++tx27			MACH_TX27		TX27			1600
++ts409			MACH_TS409		TS409			1601
++p300			MACH_P300		P300			1602
++xdacomet		MACH_XDACOMET		XDACOMET		1603
++dexflex2		MACH_DEXFLEX2		DEXFLEX2		1604
++ow			MACH_OW			OW			1605
++armebs3			MACH_ARMEBS3		ARMEBS3			1606
++u3			MACH_U3			U3			1607
++smdk2450		MACH_SMDK2450		SMDK2450		1608
++rsi_ews			MACH_RSI_EWS		RSI_EWS			1609
++tnb			MACH_TNB		TNB			1610
++toepath			MACH_TOEPATH		TOEPATH			1611
++kb9263			MACH_KB9263		KB9263			1612
++mt7108			MACH_MT7108		MT7108			1613
++smtr2440		MACH_SMTR2440		SMTR2440		1614
++manao			MACH_MANAO		MANAO			1615
++cm_x300			MACH_CM_X300		CM_X300			1616
++gulfstream_kp		MACH_GULFSTREAM_KP	GULFSTREAM_KP		1617
++lanreadyfn522		MACH_LANREADYFN522	LANREADYFN522		1618
++arma37			MACH_ARMA37		ARMA37			1619
++mendel			MACH_MENDEL		MENDEL			1620
++pelco_iliad		MACH_PELCO_ILIAD	PELCO_ILIAD		1621
++unit2p			MACH_UNIT2P		UNIT2P			1622
++inc20otter		MACH_INC20OTTER		INC20OTTER		1623
++at91sam9g20ek		MACH_AT91SAM9G20EK	AT91SAM9G20EK		1624
++sc_ge2			MACH_STORCENTER		STORCENTER		1625
++smdk6410		MACH_SMDK6410		SMDK6410		1626
++u300			MACH_U300		U300			1627
++u500			MACH_U500		U500			1628
++ds9260			MACH_DS9260		DS9260			1629
++riverrock		MACH_RIVERROCK		RIVERROCK		1630
++scibath			MACH_SCIBATH		SCIBATH			1631
++at91sam7se		MACH_AT91SAM7SE512EK	AT91SAM7SE512EK		1632
++wrt350n_v2		MACH_WRT350N_V2		WRT350N_V2		1633
++multimedia		MACH_MULTIMEDIA		MULTIMEDIA		1634
++marvin			MACH_MARVIN		MARVIN			1635
++x500			MACH_X500		X500			1636
++awlug4lcu		MACH_AWLUG4LCU		AWLUG4LCU		1637
++palermoc		MACH_PALERMOC		PALERMOC		1638
++omap_ldp		MACH_OMAP_LDP		OMAP_LDP		1639
++ip500			MACH_IP500		IP500			1640
++ase2			MACH_ASE2		ASE2			1642
++mx35evb			MACH_MX35EVB		MX35EVB			1643
++aml_m8050		MACH_AML_M8050		AML_M8050		1644
++mx35_3ds		MACH_MX35_3DS		MX35_3DS		1645
++mars			MACH_MARS		MARS			1646
++neuros_osd2		MACH_NEUROS_OSD2	NEUROS_OSD2		1647
++badger			MACH_BADGER		BADGER			1648
++trizeps4wl		MACH_TRIZEPS4WL		TRIZEPS4WL		1649
++trizeps5		MACH_TRIZEPS5		TRIZEPS5		1650
++marlin			MACH_MARLIN		MARLIN			1651
++ts78xx			MACH_TS78XX		TS78XX			1652
++hpipaq214		MACH_HPIPAQ214		HPIPAQ214		1653
++at572d940dcm		MACH_AT572D940DCM	AT572D940DCM		1654
++ne1board		MACH_NE1BOARD		NE1BOARD		1655
++zante			MACH_ZANTE		ZANTE			1656
++sffsdr			MACH_SFFSDR		SFFSDR			1657
++tw2662			MACH_TW2662		TW2662			1658
++vf10xx			MACH_VF10XX		VF10XX			1659
++zoran43xx		MACH_ZORAN43XX		ZORAN43XX		1660
++sonix926		MACH_SONIX926		SONIX926		1661
++celestialsemi		MACH_CELESTIALSEMI	CELESTIALSEMI		1662
++cc9m2443js		MACH_CC9M2443JS		CC9M2443JS		1663
++tw5334			MACH_TW5334		TW5334			1664
++omap_htcartemis		MACH_HTCARTEMIS		HTCARTEMIS		1665
++nal_hlite		MACH_NAL_HLITE		NAL_HLITE		1666
++htcvogue		MACH_HTCVOGUE		HTCVOGUE		1667
++smartweb		MACH_SMARTWEB		SMARTWEB		1668
++mv86xx			MACH_MV86XX		MV86XX			1669
++mv87xx			MACH_MV87XX		MV87XX			1670
++songyoungho		MACH_SONGYOUNGHO	SONGYOUNGHO		1671
++younghotema		MACH_YOUNGHOTEMA	YOUNGHOTEMA		1672
++pcm037			MACH_PCM037		PCM037			1673
++mmvp			MACH_MMVP		MMVP			1674
++mmap			MACH_MMAP		MMAP			1675
++ptid2410		MACH_PTID2410		PTID2410		1676
++james_926		MACH_JAMES_926		JAMES_926		1677
++fm6000			MACH_FM6000		FM6000			1678
++db88f6281_bp		MACH_DB88F6281_BP	DB88F6281_BP		1680
++rd88f6192_nas		MACH_RD88F6192_NAS	RD88F6192_NAS		1681
++rd88f6281		MACH_RD88F6281		RD88F6281		1682
++db78x00_bp		MACH_DB78X00_BP		DB78X00_BP		1683
++smdk2416		MACH_SMDK2416		SMDK2416		1685
++oce_spider_si		MACH_OCE_SPIDER_SI	OCE_SPIDER_SI		1686
++oce_spider_sk		MACH_OCE_SPIDER_SK	OCE_SPIDER_SK		1687
++rovern6			MACH_ROVERN6		ROVERN6			1688
++pelco_evolution		MACH_PELCO_EVOLUTION	PELCO_EVOLUTION		1689
++wbd111			MACH_WBD111		WBD111			1690
++elaracpe		MACH_ELARACPE		ELARACPE		1691
++mabv3			MACH_MABV3		MABV3			1692
++mv2120			MACH_MV2120		MV2120			1693
++csb737			MACH_CSB737		CSB737			1695
++mx51_3ds		MACH_MX51_3DS		MX51_3DS		1696
++g900			MACH_G900		G900			1697
++apf27			MACH_APF27		APF27			1698
++ggus2000		MACH_GGUS2000		GGUS2000		1699
++omap_2430_mimic		MACH_OMAP_2430_MIMIC	OMAP_2430_MIMIC		1700
++imx27lite		MACH_IMX27LITE		IMX27LITE		1701
++almex			MACH_ALMEX		ALMEX			1702
++control			MACH_CONTROL		CONTROL			1703
++mba2410			MACH_MBA2410		MBA2410			1704
++volcano			MACH_VOLCANO		VOLCANO			1705
++zenith			MACH_ZENITH		ZENITH			1706
++muchip			MACH_MUCHIP		MUCHIP			1707
++magellan		MACH_MAGELLAN		MAGELLAN		1708
++usb_a9260		MACH_USB_A9260		USB_A9260		1709
++usb_a9263		MACH_USB_A9263		USB_A9263		1710
++qil_a9260		MACH_QIL_A9260		QIL_A9260		1711
++cme9210			MACH_CME9210		CME9210			1712
++hczh4			MACH_HCZH4		HCZH4			1713
++spearbasic		MACH_SPEARBASIC		SPEARBASIC		1714
++dep2440			MACH_DEP2440		DEP2440			1715
++hdl_gxr			MACH_HDL_GXR		HDL_GXR			1716
++hdl_gt			MACH_HDL_GT		HDL_GT			1717
++hdl_4g			MACH_HDL_4G		HDL_4G			1718
++s3c6000			MACH_S3C6000		S3C6000			1719
++mmsp2_mdk		MACH_MMSP2_MDK		MMSP2_MDK		1720
++mpx220			MACH_MPX220		MPX220			1721
++kzm_arm11_01		MACH_KZM_ARM11_01	KZM_ARM11_01		1722
++htc_polaris		MACH_HTC_POLARIS	HTC_POLARIS		1723
++htc_kaiser		MACH_HTC_KAISER		HTC_KAISER		1724
++lg_ks20			MACH_LG_KS20		LG_KS20			1725
++hhgps			MACH_HHGPS		HHGPS			1726
++nokia_n810_wimax	MACH_NOKIA_N810_WIMAX	NOKIA_N810_WIMAX	1727
++insight			MACH_INSIGHT		INSIGHT			1728
++sapphire		MACH_SAPPHIRE		SAPPHIRE		1729
++csb637xo		MACH_CSB637XO		CSB637XO		1730
++evisiong		MACH_EVISIONG		EVISIONG		1731
++stmp37xx		MACH_STMP37XX		STMP37XX		1732
++stmp378x		MACH_STMP378X		STMP378X		1733
++tnt			MACH_TNT		TNT			1734
++tbxt			MACH_TBXT		TBXT			1735
++playmate		MACH_PLAYMATE		PLAYMATE		1736
++pns10			MACH_PNS10		PNS10			1737
++eznavi			MACH_EZNAVI		EZNAVI			1738
++ps4000			MACH_PS4000		PS4000			1739
++ezx_a780		MACH_EZX_A780		EZX_A780		1740
++ezx_e680		MACH_EZX_E680		EZX_E680		1741
++ezx_a1200		MACH_EZX_A1200		EZX_A1200		1742
++ezx_e6			MACH_EZX_E6		EZX_E6			1743
++ezx_e2			MACH_EZX_E2		EZX_E2			1744
++ezx_a910		MACH_EZX_A910		EZX_A910		1745
++cwmx31			MACH_CWMX31		CWMX31			1746
++sl2312			MACH_SL2312		SL2312			1747
++blenny			MACH_BLENNY		BLENNY			1748
++ds107			MACH_DS107		DS107			1749
++dsx07			MACH_DSX07		DSX07			1750
++picocom1		MACH_PICOCOM1		PICOCOM1		1751
++lynx_wolverine		MACH_LYNX_WOLVERINE	LYNX_WOLVERINE		1752
++ubisys_p9_sc19		MACH_UBISYS_P9_SC19	UBISYS_P9_SC19		1753
++kratos_low		MACH_KRATOS_LOW		KRATOS_LOW		1754
++m700			MACH_M700		M700			1755
++edmini_v2		MACH_EDMINI_V2		EDMINI_V2		1756
++zipit2			MACH_ZIPIT2		ZIPIT2			1757
++hslfemtocell		MACH_HSLFEMTOCELL	HSLFEMTOCELL		1758
++daintree_at91		MACH_DAINTREE_AT91	DAINTREE_AT91		1759
++sg560usb		MACH_SG560USB		SG560USB		1760
++omap3_pandora		MACH_OMAP3_PANDORA	OMAP3_PANDORA		1761
++usr8200			MACH_USR8200		USR8200			1762
++s1s65k			MACH_S1S65K		S1S65K			1763
++s2s65a			MACH_S2S65A		S2S65A			1764
++icore			MACH_ICORE		ICORE			1765
++mss2			MACH_MSS2		MSS2			1766
++belmont			MACH_BELMONT		BELMONT			1767
++asusp525		MACH_ASUSP525		ASUSP525		1768
++lb88rc8480		MACH_LB88RC8480		LB88RC8480		1769
++hipxa			MACH_HIPXA		HIPXA			1770
++mx25_3ds		MACH_MX25_3DS		MX25_3DS		1771
++m800			MACH_M800		M800			1772
++omap3530_lv_som		MACH_OMAP3530_LV_SOM	OMAP3530_LV_SOM		1773
++prima_evb		MACH_PRIMA_EVB		PRIMA_EVB		1774
++mx31bt1			MACH_MX31BT1		MX31BT1			1775
++atlas4_evb		MACH_ATLAS4_EVB		ATLAS4_EVB		1776
++mx31cicada		MACH_MX31CICADA		MX31CICADA		1777
++mi424wr			MACH_MI424WR		MI424WR			1778
++axs_ultrax		MACH_AXS_ULTRAX		AXS_ULTRAX		1779
++at572d940deb		MACH_AT572D940DEB	AT572D940DEB		1780
++davinci_da830_evm	MACH_DAVINCI_DA830_EVM	DAVINCI_DA830_EVM	1781
++ep9302			MACH_EP9302		EP9302			1782
++at572d940hfek		MACH_AT572D940HFEB	AT572D940HFEB		1783
++cybook3			MACH_CYBOOK3		CYBOOK3			1784
++wdg002			MACH_WDG002		WDG002			1785
++sg560adsl		MACH_SG560ADSL		SG560ADSL		1786
++nextio_n2800_ica	MACH_NEXTIO_N2800_ICA	NEXTIO_N2800_ICA	1787
++dove_db			MACH_DOVE_DB		DOVE_DB			1788
++marvell_newdb		MACH_MARVELL_NEWDB	MARVELL_NEWDB		1789
++vandihud		MACH_VANDIHUD		VANDIHUD		1790
++magx_e8			MACH_MAGX_E8		MAGX_E8			1791
++magx_z6			MACH_MAGX_Z6		MAGX_Z6			1792
++magx_v8			MACH_MAGX_V8		MAGX_V8			1793
++magx_u9			MACH_MAGX_U9		MAGX_U9			1794
++toughcf08		MACH_TOUGHCF08		TOUGHCF08		1795
++zw4400			MACH_ZW4400		ZW4400			1796
++marat91			MACH_MARAT91		MARAT91			1797
++overo			MACH_OVERO		OVERO			1798
++at2440evb		MACH_AT2440EVB		AT2440EVB		1799
++neocore926		MACH_NEOCORE926		NEOCORE926		1800
++wnr854t			MACH_WNR854T		WNR854T			1801
++imx27			MACH_IMX27		IMX27			1802
++moose_db		MACH_MOOSE_DB		MOOSE_DB		1803
++fab4			MACH_FAB4		FAB4			1804
++htcdiamond		MACH_HTCDIAMOND		HTCDIAMOND		1805
++fiona			MACH_FIONA		FIONA			1806
++mxc30030_x		MACH_MXC30030_X		MXC30030_X		1807
++bmp1000			MACH_BMP1000		BMP1000			1808
++logi9200		MACH_LOGI9200		LOGI9200		1809
++tqma31			MACH_TQMA31		TQMA31			1810
++ccw9p9215js		MACH_CCW9P9215JS	CCW9P9215JS		1811
++rd88f5181l_ge		MACH_RD88F5181L_GE	RD88F5181L_GE		1812
++sifmain			MACH_SIFMAIN		SIFMAIN			1813
++sam9_l9261		MACH_SAM9_L9261		SAM9_L9261		1814
++cc9m2443		MACH_CC9M2443		CC9M2443		1815
++xaria300		MACH_XARIA300		XARIA300		1816
++it9200			MACH_IT9200		IT9200			1817
++rd88f5181l_fxo		MACH_RD88F5181L_FXO	RD88F5181L_FXO		1818
++kriss_sensor		MACH_KRISS_SENSOR	KRISS_SENSOR		1819
++pilz_pmi5		MACH_PILZ_PMI5		PILZ_PMI5		1820
++jade			MACH_JADE		JADE			1821
++ks8695_softplc		MACH_KS8695_SOFTPLC	KS8695_SOFTPLC		1822
++gprisc3			MACH_GPRISC3		GPRISC3			1823
++stamp9g20		MACH_STAMP9G20		STAMP9G20		1824
++smdk6430		MACH_SMDK6430		SMDK6430		1825
++smdkc100		MACH_SMDKC100		SMDKC100		1826
++tavorevb		MACH_TAVOREVB		TAVOREVB		1827
++saar			MACH_SAAR		SAAR			1828
++deister_eyecam		MACH_DEISTER_EYECAM	DEISTER_EYECAM		1829
++at91sam9m10g45ek	MACH_AT91SAM9M10G45EK	AT91SAM9M10G45EK	1830
++linkstation_produo	MACH_LINKSTATION_PRODUO	LINKSTATION_PRODUO	1831
++hit_b0			MACH_HIT_B0		HIT_B0			1832
++adx_rmu			MACH_ADX_RMU		ADX_RMU			1833
++xg_cpe_main		MACH_XG_CPE_MAIN	XG_CPE_MAIN		1834
++edb9407a		MACH_EDB9407A		EDB9407A		1835
++dtb9608			MACH_DTB9608		DTB9608			1836
++em104v1			MACH_EM104V1		EM104V1			1837
++demo			MACH_DEMO		DEMO			1838
++logi9260		MACH_LOGI9260		LOGI9260		1839
++mx31_exm32		MACH_MX31_EXM32		MX31_EXM32		1840
++usb_a9g20		MACH_USB_A9G20		USB_A9G20		1841
++picproje2008		MACH_PICPROJE2008	PICPROJE2008		1842
++cs_e9315		MACH_CS_E9315		CS_E9315		1843
++qil_a9g20		MACH_QIL_A9G20		QIL_A9G20		1844
++sha_pon020		MACH_SHA_PON020		SHA_PON020		1845
++nad			MACH_NAD		NAD			1846
++sbc35_a9260		MACH_SBC35_A9260	SBC35_A9260		1847
++sbc35_a9g20		MACH_SBC35_A9G20	SBC35_A9G20		1848
++davinci_beginning	MACH_DAVINCI_BEGINNING	DAVINCI_BEGINNING	1849
++uwc			MACH_UWC		UWC			1850
++mxlads			MACH_MXLADS		MXLADS			1851
++htcnike			MACH_HTCNIKE		HTCNIKE			1852
++deister_pxa270		MACH_DEISTER_PXA270	DEISTER_PXA270		1853
++cme9210js		MACH_CME9210JS		CME9210JS		1854
++cc9p9360		MACH_CC9P9360		CC9P9360		1855
++mocha			MACH_MOCHA		MOCHA			1856
++wapd170ag		MACH_WAPD170AG		WAPD170AG		1857
++linkstation_mini	MACH_LINKSTATION_MINI	LINKSTATION_MINI	1858
++afeb9260		MACH_AFEB9260		AFEB9260		1859
++w90x900			MACH_W90X900		W90X900			1860
++w90x700			MACH_W90X700		W90X700			1861
++kt300ip			MACH_KT300IP		KT300IP			1862
++kt300ip_g20		MACH_KT300IP_G20	KT300IP_G20		1863
++srcm			MACH_SRCM		SRCM			1864
++wlnx_9260		MACH_WLNX_9260		WLNX_9260		1865
++openmoko_gta03		MACH_OPENMOKO_GTA03	OPENMOKO_GTA03		1866
++osprey2			MACH_OSPREY2		OSPREY2			1867
++kbio9260		MACH_KBIO9260		KBIO9260		1868
++ginza			MACH_GINZA		GINZA			1869
++a636n			MACH_A636N		A636N			1870
++imx27ipcam		MACH_IMX27IPCAM		IMX27IPCAM		1871
++nemoc			MACH_NEMOC		NEMOC			1872
++geneva			MACH_GENEVA		GENEVA			1873
++htcpharos		MACH_HTCPHAROS		HTCPHAROS		1874
++neonc			MACH_NEONC		NEONC			1875
++nas7100			MACH_NAS7100		NAS7100			1876
++teuphone		MACH_TEUPHONE		TEUPHONE		1877
++annax_eth2		MACH_ANNAX_ETH2		ANNAX_ETH2		1878
++csb733			MACH_CSB733		CSB733			1879
++bk3			MACH_BK3		BK3			1880
++omap_em32		MACH_OMAP_EM32		OMAP_EM32		1881
++et9261cp		MACH_ET9261CP		ET9261CP		1882
++jasperc			MACH_JASPERC		JASPERC			1883
++issi_arm9		MACH_ISSI_ARM9		ISSI_ARM9		1884
++ued			MACH_UED		UED			1885
++esiblade		MACH_ESIBLADE		ESIBLADE		1886
++eye02			MACH_EYE02		EYE02			1887
++imx27kbd		MACH_IMX27KBD		IMX27KBD		1888
++sst61vc010_fpga		MACH_SST61VC010_FPGA	SST61VC010_FPGA		1889
++kixvp435		MACH_KIXVP435		KIXVP435		1890
++kixnp435		MACH_KIXNP435		KIXNP435		1891
++africa			MACH_AFRICA		AFRICA			1892
++nh233			MACH_NH233		NH233			1893
++rd88f6183ap_ge		MACH_RD88F6183AP_GE	RD88F6183AP_GE		1894
++bcm4760			MACH_BCM4760		BCM4760			1895
++eddy_v2			MACH_EDDY_V2		EDDY_V2			1896
++realview_pba8		MACH_REALVIEW_PBA8	REALVIEW_PBA8		1897
++hid_a7			MACH_HID_A7		HID_A7			1898
++hero			MACH_HERO		HERO			1899
++omap_poseidon		MACH_OMAP_POSEIDON	OMAP_POSEIDON		1900
++realview_pbx		MACH_REALVIEW_PBX	REALVIEW_PBX		1901
++micro9s			MACH_MICRO9S		MICRO9S			1902
++mako			MACH_MAKO		MAKO			1903
++xdaflame		MACH_XDAFLAME		XDAFLAME		1904
++phidget_sbc2		MACH_PHIDGET_SBC2	PHIDGET_SBC2		1905
++limestone		MACH_LIMESTONE		LIMESTONE		1906
++iprobe_c32		MACH_IPROBE_C32		IPROBE_C32		1907
++rut100			MACH_RUT100		RUT100			1908
++asusp535		MACH_ASUSP535		ASUSP535		1909
++htcraphael		MACH_HTCRAPHAEL		HTCRAPHAEL		1910
++sygdg1			MACH_SYGDG1		SYGDG1			1911
++sygdg2			MACH_SYGDG2		SYGDG2			1912
++seoul			MACH_SEOUL		SEOUL			1913
++salerno			MACH_SALERNO		SALERNO			1914
++ucn_s3c64xx		MACH_UCN_S3C64XX	UCN_S3C64XX		1915
++msm7201a		MACH_MSM7201A		MSM7201A		1916
++lpr1			MACH_LPR1		LPR1			1917
++armadillo500fx		MACH_ARMADILLO500FX	ARMADILLO500FX		1918
++g3evm			MACH_G3EVM		G3EVM			1919
++z3_dm355		MACH_Z3_DM355		Z3_DM355		1920
++w90p910evb		MACH_W90P910EVB		W90P910EVB		1921
++w90p920evb		MACH_W90P920EVB		W90P920EVB		1922
++w90p950evb		MACH_W90P950EVB		W90P950EVB		1923
++w90n960evb		MACH_W90N960EVB		W90N960EVB		1924
++camhd			MACH_CAMHD		CAMHD			1925
++mvc100			MACH_MVC100		MVC100			1926
++electrum_200		MACH_ELECTRUM_200	ELECTRUM_200		1927
++htcjade			MACH_HTCJADE		HTCJADE			1928
++memphis			MACH_MEMPHIS		MEMPHIS			1929
++imx27sbc		MACH_IMX27SBC		IMX27SBC		1930
++lextar			MACH_LEXTAR		LEXTAR			1931
++mv88f6281gtw_ge		MACH_MV88F6281GTW_GE	MV88F6281GTW_GE		1932
++ncp			MACH_NCP		NCP			1933
++z32an_series		MACH_Z32AN		Z32AN			1934
++tmq_capd		MACH_TMQ_CAPD		TMQ_CAPD		1935
++omap3_wl		MACH_OMAP3_WL		OMAP3_WL		1936
++chumby			MACH_CHUMBY		CHUMBY			1937
++atsarm9			MACH_ATSARM9		ATSARM9			1938
++davinci_dm365_evm	MACH_DAVINCI_DM365_EVM	DAVINCI_DM365_EVM	1939
++bahamas			MACH_BAHAMAS		BAHAMAS			1940
++das			MACH_DAS		DAS			1941
++minidas			MACH_MINIDAS		MINIDAS			1942
++vk1000			MACH_VK1000		VK1000			1943
++centro			MACH_CENTRO		CENTRO			1944
++ctera_2bay		MACH_CTERA_2BAY		CTERA_2BAY		1945
++edgeconnect		MACH_EDGECONNECT	EDGECONNECT		1946
++nd27000			MACH_ND27000		ND27000			1947
++cobra			MACH_GEMALTO_COBRA	GEMALTO_COBRA		1948
++ingelabs_comet		MACH_INGELABS_COMET	INGELABS_COMET		1949
++pollux_wiz		MACH_POLLUX_WIZ		POLLUX_WIZ		1950
++blackstone		MACH_BLACKSTONE		BLACKSTONE		1951
++topaz			MACH_TOPAZ		TOPAZ			1952
++aixle			MACH_AIXLE		AIXLE			1953
++mw998			MACH_MW998		MW998			1954
++nokia_rx51		MACH_NOKIA_RX51		NOKIA_RX51		1955
++vsc5605ev		MACH_VSC5605EV		VSC5605EV		1956
++nt98700dk		MACH_NT98700DK		NT98700DK		1957
++icontact		MACH_ICONTACT		ICONTACT		1958
++swarco_frcpu		MACH_SWARCO_FRCPU	SWARCO_FRCPU		1959
++swarco_scpu		MACH_SWARCO_SCPU	SWARCO_SCPU		1960
++bbox_p16		MACH_BBOX_P16		BBOX_P16		1961
++bstd			MACH_BSTD		BSTD			1962
++sbc2440ii		MACH_SBC2440II		SBC2440II		1963
++pcm034			MACH_PCM034		PCM034			1964
++neso			MACH_NESO		NESO			1965
++wlnx_9g20		MACH_WLNX_9G20		WLNX_9G20		1966
++omap_zoom2		MACH_OMAP_ZOOM2		OMAP_ZOOM2		1967
++totemnova		MACH_TOTEMNOVA		TOTEMNOVA		1968
++c5000			MACH_C5000		C5000			1969
++unipo_at91sam9263	MACH_UNIPO_AT91SAM9263	UNIPO_AT91SAM9263	1970
++ethernut5		MACH_ETHERNUT5		ETHERNUT5		1971
++arm11			MACH_ARM11		ARM11			1972
++cpuat9260		MACH_CPUAT9260		CPUAT9260		1973
++cpupxa255		MACH_CPUPXA255		CPUPXA255		1974
++eukrea_cpuimx27		MACH_CPUIMX27		CPUIMX27		1975
++cheflux			MACH_CHEFLUX		CHEFLUX			1976
++eb_cpux9k2		MACH_EB_CPUX9K2		EB_CPUX9K2		1977
++opcotec			MACH_OPCOTEC		OPCOTEC			1978
++yt			MACH_YT			YT			1979
++motoq			MACH_MOTOQ		MOTOQ			1980
++bsb1			MACH_BSB1		BSB1			1981
++acs5k			MACH_ACS5K		ACS5K			1982
++milan			MACH_MILAN		MILAN			1983
++quartzv2		MACH_QUARTZV2		QUARTZV2		1984
++rsvp			MACH_RSVP		RSVP			1985
++rmp200			MACH_RMP200		RMP200			1986
++snapper_9260		MACH_SNAPPER_9260	SNAPPER_9260		1987
++dsm320			MACH_DSM320		DSM320			1988
++adsgcm			MACH_ADSGCM		ADSGCM			1989
++ase2_400		MACH_ASE2_400		ASE2_400		1990
++pizza			MACH_PIZZA		PIZZA			1991
++spot_ngpl		MACH_SPOT_NGPL		SPOT_NGPL		1992
++armata			MACH_ARMATA		ARMATA			1993
++exeda			MACH_EXEDA		EXEDA			1994
++mx31sf005		MACH_MX31SF005		MX31SF005		1995
++f5d8231_4_v2		MACH_F5D8231_4_V2	F5D8231_4_V2		1996
++q2440			MACH_Q2440		Q2440			1997
++qq2440			MACH_QQ2440		QQ2440			1998
++mini2440		MACH_MINI2440		MINI2440		1999
++colibri300		MACH_COLIBRI300		COLIBRI300		2000
++jades			MACH_JADES		JADES			2001
++spark			MACH_SPARK		SPARK			2002
++benzina			MACH_BENZINA		BENZINA			2003
++blaze			MACH_BLAZE		BLAZE			2004
++linkstation_ls_hgl	MACH_LINKSTATION_LS_HGL	LINKSTATION_LS_HGL	2005
++htckovsky		MACH_HTCKOVSKY		HTCKOVSKY		2006
++sony_prs505		MACH_SONY_PRS505	SONY_PRS505		2007
++hanlin_v3		MACH_HANLIN_V3		HANLIN_V3		2008
++sapphira		MACH_SAPPHIRA		SAPPHIRA		2009
++dack_sda_01		MACH_DACK_SDA_01	DACK_SDA_01		2010
++armbox			MACH_ARMBOX		ARMBOX			2011
++harris_rvp		MACH_HARRIS_RVP		HARRIS_RVP		2012
++ribaldo			MACH_RIBALDO		RIBALDO			2013
++agora			MACH_AGORA		AGORA			2014
++omap3_mini		MACH_OMAP3_MINI		OMAP3_MINI		2015
++a9sam6432_b		MACH_A9SAM6432_B	A9SAM6432_B		2016
++usg2410			MACH_USG2410		USG2410			2017
++pc72052_i10_revb	MACH_PC72052_I10_REVB	PC72052_I10_REVB	2018
++mx35_exm32		MACH_MX35_EXM32		MX35_EXM32		2019
++topas910		MACH_TOPAS910		TOPAS910		2020
++hyena			MACH_HYENA		HYENA			2021
++pospax			MACH_POSPAX		POSPAX			2022
++hdl_gx			MACH_HDL_GX		HDL_GX			2023
++ctera_4bay		MACH_CTERA_4BAY		CTERA_4BAY		2024
++ctera_plug_c		MACH_CTERA_PLUG_C	CTERA_PLUG_C		2025
++crwea_plug_i		MACH_CRWEA_PLUG_I	CRWEA_PLUG_I		2026
++egauge2			MACH_EGAUGE2		EGAUGE2			2027
++didj			MACH_DIDJ		DIDJ			2028
++m_s3c2443		MACH_MEISTER		MEISTER			2029
++htcblackstone		MACH_HTCBLACKSTONE	HTCBLACKSTONE		2030
++cpuat9g20		MACH_CPUAT9G20		CPUAT9G20		2031
++smdk6440		MACH_SMDK6440		SMDK6440		2032
++omap_35xx_mvp		MACH_OMAP_35XX_MVP	OMAP_35XX_MVP		2033
++ctera_plug_i		MACH_CTERA_PLUG_I	CTERA_PLUG_I		2034
++pvg610_100		MACH_PVG610		PVG610			2035
++hprw6815		MACH_HPRW6815		HPRW6815		2036
++omap3_oswald		MACH_OMAP3_OSWALD	OMAP3_OSWALD		2037
++nas4220b		MACH_NAS4220B		NAS4220B		2038
++htcraphael_cdma		MACH_HTCRAPHAEL_CDMA	HTCRAPHAEL_CDMA		2039
++htcdiamond_cdma		MACH_HTCDIAMOND_CDMA	HTCDIAMOND_CDMA		2040
++scaler			MACH_SCALER		SCALER			2041
++zylonite2		MACH_ZYLONITE2		ZYLONITE2		2042
++aspenite		MACH_ASPENITE		ASPENITE		2043
++teton			MACH_TETON		TETON			2044
++ttc_dkb			MACH_TTC_DKB		TTC_DKB			2045
++bishop2			MACH_BISHOP2		BISHOP2			2046
++ippv5			MACH_IPPV5		IPPV5			2047
++farm926			MACH_FARM926		FARM926			2048
++mmccpu			MACH_MMCCPU		MMCCPU			2049
++sgmsfl			MACH_SGMSFL		SGMSFL			2050
++tt8000			MACH_TT8000		TT8000			2051
++zrn4300lp		MACH_ZRN4300LP		ZRN4300LP		2052
++mptc			MACH_MPTC		MPTC			2053
++h6051			MACH_H6051		H6051			2054
++pvg610_101		MACH_PVG610_101		PVG610_101		2055
++stamp9261_pc_evb	MACH_STAMP9261_PC_EVB	STAMP9261_PC_EVB	2056
++pelco_odysseus		MACH_PELCO_ODYSSEUS	PELCO_ODYSSEUS		2057
++tny_a9260		MACH_TNY_A9260		TNY_A9260		2058
++tny_a9g20		MACH_TNY_A9G20		TNY_A9G20		2059
++aesop_mp2530f		MACH_AESOP_MP2530F	AESOP_MP2530F		2060
++dx900			MACH_DX900		DX900			2061
++cpodc2			MACH_CPODC2		CPODC2			2062
++tilt_8925		MACH_TILT_8925		TILT_8925		2063
++davinci_dm357_evm	MACH_DAVINCI_DM357_EVM	DAVINCI_DM357_EVM	2064
++swordfish		MACH_SWORDFISH		SWORDFISH		2065
++corvus			MACH_CORVUS		CORVUS			2066
++taurus			MACH_TAURUS		TAURUS			2067
++axm			MACH_AXM		AXM			2068
++axc			MACH_AXC		AXC			2069
++baby			MACH_BABY		BABY			2070
++mp200			MACH_MP200		MP200			2071
++pcm043			MACH_PCM043		PCM043			2072
++hanlin_v3c		MACH_HANLIN_V3C		HANLIN_V3C		2073
++kbk9g20			MACH_KBK9G20		KBK9G20			2074
++adsturbog5		MACH_ADSTURBOG5		ADSTURBOG5		2075
++avenger_lite1		MACH_AVENGER_LITE1	AVENGER_LITE1		2076
++suc82x			MACH_SUC		SUC			2077
++at91sam7s256		MACH_AT91SAM7S256	AT91SAM7S256		2078
++mendoza			MACH_MENDOZA		MENDOZA			2079
++kira			MACH_KIRA		KIRA			2080
++mx1hbm			MACH_MX1HBM		MX1HBM			2081
++quatro43xx		MACH_QUATRO43XX		QUATRO43XX		2082
++quatro4230		MACH_QUATRO4230		QUATRO4230		2083
++nsb400			MACH_NSB400		NSB400			2084
++drp255			MACH_DRP255		DRP255			2085
++thoth			MACH_THOTH		THOTH			2086
++firestone		MACH_FIRESTONE		FIRESTONE		2087
++asusp750		MACH_ASUSP750		ASUSP750		2088
++ctera_dl		MACH_CTERA_DL		CTERA_DL		2089
++socr			MACH_SOCR		SOCR			2090
++htcoxygen		MACH_HTCOXYGEN		HTCOXYGEN		2091
++heroc			MACH_HEROC		HEROC			2092
++zeno6800		MACH_ZENO6800		ZENO6800		2093
++sc2mcs			MACH_SC2MCS		SC2MCS			2094
++gene100			MACH_GENE100		GENE100			2095
++as353x			MACH_AS353X		AS353X			2096
++sheevaplug		MACH_SHEEVAPLUG		SHEEVAPLUG		2097
++at91sam9g20		MACH_AT91SAM9G20	AT91SAM9G20		2098
++mv88f6192gtw_fe		MACH_MV88F6192GTW_FE	MV88F6192GTW_FE		2099
++cc9200			MACH_CC9200		CC9200			2100
++sm9200			MACH_SM9200		SM9200			2101
++tp9200			MACH_TP9200		TP9200			2102
++snapperdv		MACH_SNAPPERDV		SNAPPERDV		2103
++avengers_lite		MACH_AVENGERS_LITE	AVENGERS_LITE		2104
++avengers_lite1		MACH_AVENGERS_LITE1	AVENGERS_LITE1		2105
++omap3axon		MACH_OMAP3AXON		OMAP3AXON		2106
++ma8xx			MACH_MA8XX		MA8XX			2107
++mp201ek			MACH_MP201EK		MP201EK			2108
++davinci_tux		MACH_DAVINCI_TUX	DAVINCI_TUX		2109
++mpa1600			MACH_MPA1600		MPA1600			2110
++pelco_troy		MACH_PELCO_TROY		PELCO_TROY		2111
++nsb667			MACH_NSB667		NSB667			2112
++rovers5_4mpix		MACH_ROVERS5_4MPIX	ROVERS5_4MPIX		2113
++twocom			MACH_TWOCOM		TWOCOM			2114
++ubisys_p9_rcu3r2	MACH_UBISYS_P9_RCU3R2	UBISYS_P9_RCU3R2	2115
++hero_espresso		MACH_HERO_ESPRESSO	HERO_ESPRESSO		2116
++afeusb			MACH_AFEUSB		AFEUSB			2117
++t830			MACH_T830		T830			2118
++spd8020_cc		MACH_SPD8020_CC		SPD8020_CC		2119
++om_3d7k			MACH_OM_3D7K		OM_3D7K			2120
++picocom2		MACH_PICOCOM2		PICOCOM2		2121
++uwg4mx27		MACH_UWG4MX27		UWG4MX27		2122
++uwg4mx31		MACH_UWG4MX31		UWG4MX31		2123
++cherry			MACH_CHERRY		CHERRY			2124
++mx51_babbage		MACH_MX51_BABBAGE	MX51_BABBAGE		2125
++s3c2440turkiye		MACH_S3C2440TURKIYE	S3C2440TURKIYE		2126
++tx37			MACH_TX37		TX37			2127
++sbc2800_9g20		MACH_SBC2800_9G20	SBC2800_9G20		2128
++benzglb			MACH_BENZGLB		BENZGLB			2129
++benztd			MACH_BENZTD		BENZTD			2130
++cartesio_plus		MACH_CARTESIO_PLUS	CARTESIO_PLUS		2131
++solrad_g20		MACH_SOLRAD_G20		SOLRAD_G20		2132
++mx27wallace		MACH_MX27WALLACE	MX27WALLACE		2133
++fmzwebmodul		MACH_FMZWEBMODUL	FMZWEBMODUL		2134
++rd78x00_masa		MACH_RD78X00_MASA	RD78X00_MASA		2135
++smallogger		MACH_SMALLOGGER		SMALLOGGER		2136
++ccw9p9215		MACH_CCW9P9215		CCW9P9215		2137
++dm355_leopard		MACH_DM355_LEOPARD	DM355_LEOPARD		2138
++ts219			MACH_TS219		TS219			2139
++tny_a9263		MACH_TNY_A9263		TNY_A9263		2140
++apollo			MACH_APOLLO		APOLLO			2141
++at91cap9stk		MACH_AT91CAP9STK	AT91CAP9STK		2142
++spc300			MACH_SPC300		SPC300			2143
++eko			MACH_EKO		EKO			2144
++ccw9m2443		MACH_CCW9M2443		CCW9M2443		2145
++ccw9m2443js		MACH_CCW9M2443JS	CCW9M2443JS		2146
++m2m_router_device	MACH_M2M_ROUTER_DEVICE	M2M_ROUTER_DEVICE	2147
++str9104nas		MACH_STAR9104NAS	STAR9104NAS		2148
++pca100			MACH_PCA100		PCA100			2149
++z3_dm365_mod_01		MACH_Z3_DM365_MOD_01	Z3_DM365_MOD_01		2150
++hipox			MACH_HIPOX		HIPOX			2151
++omap3_piteds		MACH_OMAP3_PITEDS	OMAP3_PITEDS		2152
++bm150r			MACH_BM150R		BM150R			2153
++tbone			MACH_TBONE		TBONE			2154
++merlin			MACH_MERLIN		MERLIN			2155
++falcon			MACH_FALCON		FALCON			2156
++davinci_da850_evm	MACH_DAVINCI_DA850_EVM	DAVINCI_DA850_EVM	2157
++s5p6440			MACH_S5P6440		S5P6440			2158
++at91sam9g10ek		MACH_AT91SAM9G10EK	AT91SAM9G10EK		2159
++omap_4430sdp		MACH_OMAP_4430SDP	OMAP_4430SDP		2160
++lpc313x			MACH_LPC313X		LPC313X			2161
++magx_zn5		MACH_MAGX_ZN5		MAGX_ZN5		2162
++magx_em30		MACH_MAGX_EM30		MAGX_EM30		2163
++magx_ve66		MACH_MAGX_VE66		MAGX_VE66		2164
++meesc			MACH_MEESC		MEESC			2165
++otc570			MACH_OTC570		OTC570			2166
++bcu2412			MACH_BCU2412		BCU2412			2167
++beacon			MACH_BEACON		BEACON			2168
++actia_tgw		MACH_ACTIA_TGW		ACTIA_TGW		2169
++e4430			MACH_E4430		E4430			2170
++ql300			MACH_QL300		QL300			2171
++btmavb101		MACH_BTMAVB101		BTMAVB101		2172
++btmawb101		MACH_BTMAWB101		BTMAWB101		2173
++sq201			MACH_SQ201		SQ201			2174
++quatro45xx		MACH_QUATRO45XX		QUATRO45XX		2175
++openpad			MACH_OPENPAD		OPENPAD			2176
++tx25			MACH_TX25		TX25			2177
++omap3_torpedo		MACH_OMAP3_TORPEDO	OMAP3_TORPEDO		2178
++htcraphael_k		MACH_HTCRAPHAEL_K	HTCRAPHAEL_K		2179
++lal43			MACH_LAL43		LAL43			2181
++htcraphael_cdma500	MACH_HTCRAPHAEL_CDMA500	HTCRAPHAEL_CDMA500	2182
++anw6410			MACH_ANW6410		ANW6410			2183
++htcprophet		MACH_HTCPROPHET		HTCPROPHET		2185
++cfa_10022		MACH_CFA_10022		CFA_10022		2186
++imx27_visstrim_m10	MACH_IMX27_VISSTRIM_M10	IMX27_VISSTRIM_M10	2187
++px2imx27		MACH_PX2IMX27		PX2IMX27		2188
++stm3210e_eval		MACH_STM3210E_EVAL	STM3210E_EVAL		2189
++dvs10			MACH_DVS10		DVS10			2190
++portuxg20		MACH_PORTUXG20		PORTUXG20		2191
++arm_spv			MACH_ARM_SPV		ARM_SPV			2192
++smdkc110		MACH_SMDKC110		SMDKC110		2193
++cabespresso		MACH_CABESPRESSO	CABESPRESSO		2194
++hmc800			MACH_HMC800		HMC800			2195
++sholes			MACH_SHOLES		SHOLES			2196
++btmxc31			MACH_BTMXC31		BTMXC31			2197
++dt501			MACH_DT501		DT501			2198
++ktx			MACH_KTX		KTX			2199
++omap3517evm		MACH_OMAP3517EVM	OMAP3517EVM		2200
++netspace_v2		MACH_NETSPACE_V2	NETSPACE_V2		2201
++netspace_max_v2		MACH_NETSPACE_MAX_V2	NETSPACE_MAX_V2		2202
++d2net_v2		MACH_D2NET_V2		D2NET_V2		2203
++net2big_v2		MACH_NET2BIG_V2		NET2BIG_V2		2204
++net4big_v2		MACH_NET4BIG_V2		NET4BIG_V2		2205
++net5big_v2		MACH_NET5BIG_V2		NET5BIG_V2		2206
++endb2443		MACH_ENDB2443		ENDB2443		2207
++inetspace_v2		MACH_INETSPACE_V2	INETSPACE_V2		2208
++tros			MACH_TROS		TROS			2209
++pelco_homer		MACH_PELCO_HOMER	PELCO_HOMER		2210
++ofsp8			MACH_OFSP8		OFSP8			2211
++at91sam9g45ekes		MACH_AT91SAM9G45EKES	AT91SAM9G45EKES		2212
++guf_cupid		MACH_GUF_CUPID		GUF_CUPID		2213
++eab1r			MACH_EAB1R		EAB1R			2214
++desirec			MACH_DESIREC		DESIREC			2215
++cordoba			MACH_CORDOBA		CORDOBA			2216
++irvine			MACH_IRVINE		IRVINE			2217
++sff772			MACH_SFF772		SFF772			2218
++pelco_milano		MACH_PELCO_MILANO	PELCO_MILANO		2219
++pc7302			MACH_PC7302		PC7302			2220
++bip6000			MACH_BIP6000		BIP6000			2221
++silvermoon		MACH_SILVERMOON		SILVERMOON		2222
++vc0830			MACH_VC0830		VC0830			2223
++dt430			MACH_DT430		DT430			2224
++ji42pf			MACH_JI42PF		JI42PF			2225
++gnet_ksm		MACH_GNET_KSM		GNET_KSM		2226
++gnet_sgm		MACH_GNET_SGM		GNET_SGM		2227
++gnet_sgr		MACH_GNET_SGR		GNET_SGR		2228
++omap3_icetekevm		MACH_OMAP3_ICETEKEVM	OMAP3_ICETEKEVM		2229
++pnp			MACH_PNP		PNP			2230
++ctera_2bay_k		MACH_CTERA_2BAY_K	CTERA_2BAY_K		2231
++ctera_2bay_u		MACH_CTERA_2BAY_U	CTERA_2BAY_U		2232
++sas_c			MACH_SAS_C		SAS_C			2233
++vma2315			MACH_VMA2315		VMA2315			2234
++vcs			MACH_VCS		VCS			2235
++spear600		MACH_SPEAR600		SPEAR600		2236
++spear300		MACH_SPEAR300		SPEAR300		2237
++spear1300		MACH_SPEAR1300		SPEAR1300		2238
++lilly1131		MACH_LILLY1131		LILLY1131		2239
++arvoo_ax301		MACH_ARVOO_AX301	ARVOO_AX301		2240
++mapphone		MACH_MAPPHONE		MAPPHONE		2241
++legend			MACH_LEGEND		LEGEND			2242
++salsa			MACH_SALSA		SALSA			2243
++lounge			MACH_LOUNGE		LOUNGE			2244
++vision			MACH_VISION		VISION			2245
++vmb20			MACH_VMB20		VMB20			2246
++hy2410			MACH_HY2410		HY2410			2247
++hy9315			MACH_HY9315		HY9315			2248
++bullwinkle		MACH_BULLWINKLE		BULLWINKLE		2249
++arm_ultimator2		MACH_ARM_ULTIMATOR2	ARM_ULTIMATOR2		2250
++vs_v210			MACH_VS_V210		VS_V210			2252
++vs_v212			MACH_VS_V212		VS_V212			2253
++hmt			MACH_HMT		HMT			2254
++suen3			MACH_SUEN3		SUEN3			2255
++vesper			MACH_VESPER		VESPER			2256
++str9			MACH_STR9		STR9			2257
++omap3_wl_ff		MACH_OMAP3_WL_FF	OMAP3_WL_FF		2258
++simcom			MACH_SIMCOM		SIMCOM			2259
++mcwebio			MACH_MCWEBIO		MCWEBIO			2260
++omap3_phrazer		MACH_OMAP3_PHRAZER	OMAP3_PHRAZER		2261
++darwin			MACH_DARWIN		DARWIN			2262
++oratiscomu		MACH_ORATISCOMU		ORATISCOMU		2263
++rtsbc20			MACH_RTSBC20		RTSBC20			2264
++sgh_i780		MACH_I780		I780			2265
++gemini324		MACH_GEMINI324		GEMINI324		2266
++oratislan		MACH_ORATISLAN		ORATISLAN		2267
++oratisalog		MACH_ORATISALOG		ORATISALOG		2268
++oratismadi		MACH_ORATISMADI		ORATISMADI		2269
++oratisot16		MACH_ORATISOT16		ORATISOT16		2270
++oratisdesk		MACH_ORATISDESK		ORATISDESK		2271
++vexpress		MACH_VEXPRESS		VEXPRESS		2272
++sintexo			MACH_SINTEXO		SINTEXO			2273
++cm3389			MACH_CM3389		CM3389			2274
++omap3_cio		MACH_OMAP3_CIO		OMAP3_CIO		2275
++sgh_i900		MACH_SGH_I900		SGH_I900		2276
++bst100			MACH_BST100		BST100			2277
++passion			MACH_PASSION		PASSION			2278
++indesign_at91sam	MACH_INDESIGN_AT91SAM	INDESIGN_AT91SAM	2279
++c4_badger		MACH_C4_BADGER		C4_BADGER		2280
++c4_viper		MACH_C4_VIPER		C4_VIPER		2281
++d2net			MACH_D2NET		D2NET			2282
++bigdisk			MACH_BIGDISK		BIGDISK			2283
++notalvision		MACH_NOTALVISION	NOTALVISION		2284
++omap3_kboc		MACH_OMAP3_KBOC		OMAP3_KBOC		2285
++cyclone			MACH_CYCLONE		CYCLONE			2286
++ninja			MACH_NINJA		NINJA			2287
++at91sam9g20ek_2mmc	MACH_AT91SAM9G20EK_2MMC	AT91SAM9G20EK_2MMC	2288
++bcmring			MACH_BCMRING		BCMRING			2289
++resol_dl2		MACH_RESOL_DL2		RESOL_DL2		2290
++ifosw			MACH_IFOSW		IFOSW			2291
++htcrhodium		MACH_HTCRHODIUM		HTCRHODIUM		2292
++htctopaz		MACH_HTCTOPAZ		HTCTOPAZ		2293
++matrix504		MACH_MATRIX504		MATRIX504		2294
++mrfsa			MACH_MRFSA		MRFSA			2295
++sc_p270			MACH_SC_P270		SC_P270			2296
++atlas5_evb		MACH_ATLAS5_EVB		ATLAS5_EVB		2297
++pelco_lobox		MACH_PELCO_LOBOX	PELCO_LOBOX		2298
++dilax_pcu200		MACH_DILAX_PCU200	DILAX_PCU200		2299
++leonardo		MACH_LEONARDO		LEONARDO		2300
++zoran_approach7		MACH_ZORAN_APPROACH7	ZORAN_APPROACH7		2301
++dp6xx			MACH_DP6XX		DP6XX			2302
++bcm2153_vesper		MACH_BCM2153_VESPER	BCM2153_VESPER		2303
++mahimahi		MACH_MAHIMAHI		MAHIMAHI		2304
++clickc			MACH_CLICKC		CLICKC			2305
++zb_gateway		MACH_ZB_GATEWAY		ZB_GATEWAY		2306
++tazcard			MACH_TAZCARD		TAZCARD			2307
++tazdev			MACH_TAZDEV		TAZDEV			2308
++annax_cb_arm		MACH_ANNAX_CB_ARM	ANNAX_CB_ARM		2309
++annax_dm3		MACH_ANNAX_DM3		ANNAX_DM3		2310
++cerebric		MACH_CEREBRIC		CEREBRIC		2311
++orca			MACH_ORCA		ORCA			2312
++pc9260			MACH_PC9260		PC9260			2313
++ems285a			MACH_EMS285A		EMS285A			2314
++gec2410			MACH_GEC2410		GEC2410			2315
++gec2440			MACH_GEC2440		GEC2440			2316
++mw903			MACH_ARCH_MW903		ARCH_MW903		2317
++mw2440			MACH_MW2440		MW2440			2318
++ecac2378		MACH_ECAC2378		ECAC2378		2319
++tazkiosk		MACH_TAZKIOSK		TAZKIOSK		2320
++whiterabbit_mch		MACH_WHITERABBIT_MCH	WHITERABBIT_MCH		2321
++sbox9263		MACH_SBOX9263		SBOX9263		2322
++oreo			MACH_OREO		OREO			2323
++smdk6442		MACH_SMDK6442		SMDK6442		2324
++openrd_base		MACH_OPENRD_BASE	OPENRD_BASE		2325
++incredible		MACH_INCREDIBLE		INCREDIBLE		2326
++incrediblec		MACH_INCREDIBLEC	INCREDIBLEC		2327
++heroct			MACH_HEROCT		HEROCT			2328
++mmnet1000		MACH_MMNET1000		MMNET1000		2329
++devkit8000		MACH_DEVKIT8000		DEVKIT8000		2330
++devkit9000		MACH_DEVKIT9000		DEVKIT9000		2331
++mx31txtr		MACH_MX31TXTR		MX31TXTR		2332
++u380			MACH_U380		U380			2333
++oamp3_hualu		MACH_HUALU_BOARD	HUALU_BOARD		2334
++npcmx50			MACH_NPCMX50		NPCMX50			2335
++mx51_lange51		MACH_MX51_LANGE51	MX51_LANGE51		2336
++mx51_lange52		MACH_MX51_LANGE52	MX51_LANGE52		2337
++riom			MACH_RIOM		RIOM			2338
++comcas			MACH_COMCAS		COMCAS			2339
++wsi_mx27		MACH_WSI_MX27		WSI_MX27		2340
++cm_t35			MACH_CM_T35		CM_T35			2341
++net2big			MACH_NET2BIG		NET2BIG			2342
++motorola_a1600		MACH_MOTOROLA_A1600	MOTOROLA_A1600		2343
++igep0020		MACH_IGEP0020		IGEP0020		2344
++igep0010		MACH_IGEP0010		IGEP0010		2345
++mv6281gtwge2		MACH_MV6281GTWGE2	MV6281GTWGE2		2346
++scat100			MACH_SCAT100		SCAT100			2347
++sanmina			MACH_SANMINA		SANMINA			2348
++momento			MACH_MOMENTO		MOMENTO			2349
++nuc9xx			MACH_NUC9XX		NUC9XX			2350
++nuc910evb		MACH_NUC910EVB		NUC910EVB		2351
++nuc920evb		MACH_NUC920EVB		NUC920EVB		2352
++nuc950evb		MACH_NUC950EVB		NUC950EVB		2353
++nuc945evb		MACH_NUC945EVB		NUC945EVB		2354
++nuc960evb		MACH_NUC960EVB		NUC960EVB		2355
++nuc932evb		MACH_NUC932EVB		NUC932EVB		2356
++nuc900			MACH_NUC900		NUC900			2357
++sd1soc			MACH_SD1SOC		SD1SOC			2358
++ln2440bc		MACH_LN2440BC		LN2440BC		2359
++rsbc			MACH_RSBC		RSBC			2360
++openrd_client		MACH_OPENRD_CLIENT	OPENRD_CLIENT		2361
++hpipaq11x		MACH_HPIPAQ11X		HPIPAQ11X		2362
++wayland			MACH_WAYLAND		WAYLAND			2363
++acnbsx102		MACH_ACNBSX102		ACNBSX102		2364
++hwat91			MACH_HWAT91		HWAT91			2365
++at91sam9263cs		MACH_AT91SAM9263CS	AT91SAM9263CS		2366
++csb732			MACH_CSB732		CSB732			2367
++u8500			MACH_U8500		U8500			2368
++huqiu			MACH_HUQIU		HUQIU			2369
++mx51_kunlun		MACH_MX51_KUNLUN	MX51_KUNLUN		2370
++pmt1g			MACH_PMT1G		PMT1G			2371
++htcelf			MACH_HTCELF		HTCELF			2372
++armadillo420		MACH_ARMADILLO420	ARMADILLO420		2373
++armadillo440		MACH_ARMADILLO440	ARMADILLO440		2374
++u_chip_dual_arm		MACH_U_CHIP_DUAL_ARM	U_CHIP_DUAL_ARM		2375
++csr_bdb3		MACH_CSR_BDB3		CSR_BDB3		2376
++dolby_cat1018		MACH_DOLBY_CAT1018	DOLBY_CAT1018		2377
++hy9307			MACH_HY9307		HY9307			2378
++aspire_easystore	MACH_A_ES		A_ES			2379
++davinci_irif		MACH_DAVINCI_IRIF	DAVINCI_IRIF		2380
++agama9263		MACH_AGAMA9263		AGAMA9263		2381
++marvell_jasper		MACH_MARVELL_JASPER	MARVELL_JASPER		2382
++flint			MACH_FLINT		FLINT			2383
++tavorevb3		MACH_TAVOREVB3		TAVOREVB3		2384
++sch_m490		MACH_SCH_M490		SCH_M490		2386
++rbl01			MACH_RBL01		RBL01			2387
++omnifi			MACH_OMNIFI		OMNIFI			2388
++otavalo			MACH_OTAVALO		OTAVALO			2389
++sienna			MACH_SIENNA		SIENNA			2390
++htc_excalibur_s620	MACH_HTC_EXCALIBUR_S620	HTC_EXCALIBUR_S620	2391
++htc_opal		MACH_HTC_OPAL		HTC_OPAL		2392
++touchbook		MACH_TOUCHBOOK		TOUCHBOOK		2393
++latte			MACH_LATTE		LATTE			2394
++xa200			MACH_XA200		XA200			2395
++nimrod			MACH_NIMROD		NIMROD			2396
++cc9p9215_3g		MACH_CC9P9215_3G	CC9P9215_3G		2397
++cc9p9215_3gjs		MACH_CC9P9215_3GJS	CC9P9215_3GJS		2398
++tk71			MACH_TK71		TK71			2399
++comham3525		MACH_COMHAM3525		COMHAM3525		2400
++mx31erebus		MACH_MX31EREBUS		MX31EREBUS		2401
++mcardmx27		MACH_MCARDMX27		MCARDMX27		2402
++paradise		MACH_PARADISE		PARADISE		2403
++tide			MACH_TIDE		TIDE			2404
++wzl2440			MACH_WZL2440		WZL2440			2405
++sdrdemo			MACH_SDRDEMO		SDRDEMO			2406
++ethercan2		MACH_ETHERCAN2		ETHERCAN2		2407
++ecmimg20		MACH_ECMIMG20		ECMIMG20		2408
++omap_dragon		MACH_OMAP_DRAGON	OMAP_DRAGON		2409
++halo			MACH_HALO		HALO			2410
++huangshan		MACH_HUANGSHAN		HUANGSHAN		2411
++vl_ma2sc		MACH_VL_MA2SC		VL_MA2SC		2412
++raumfeld_rc		MACH_RAUMFELD_RC	RAUMFELD_RC		2413
++raumfeld_connector	MACH_RAUMFELD_CONNECTOR	RAUMFELD_CONNECTOR	2414
++raumfeld_speaker	MACH_RAUMFELD_SPEAKER	RAUMFELD_SPEAKER	2415
++multibus_master		MACH_MULTIBUS_MASTER	MULTIBUS_MASTER		2416
++multibus_pbk		MACH_MULTIBUS_PBK	MULTIBUS_PBK		2417
++tnetv107x		MACH_TNETV107X		TNETV107X		2418
++snake			MACH_SNAKE		SNAKE			2419
++cwmx27			MACH_CWMX27		CWMX27			2420
++sch_m480		MACH_SCH_M480		SCH_M480		2421
++platypus		MACH_PLATYPUS		PLATYPUS		2422
++pss2			MACH_PSS2		PSS2			2423
++davinci_apm150		MACH_DAVINCI_APM150	DAVINCI_APM150		2424
++str9100			MACH_STR9100		STR9100			2425
++net5big			MACH_NET5BIG		NET5BIG			2426
++seabed9263		MACH_SEABED9263		SEABED9263		2427
++mx51_m2id		MACH_MX51_M2ID		MX51_M2ID		2428
++octvocplus_eb		MACH_OCTVOCPLUS_EB	OCTVOCPLUS_EB		2429
++klk_firefox		MACH_KLK_FIREFOX	KLK_FIREFOX		2430
++klk_wirma_module	MACH_KLK_WIRMA_MODULE	KLK_WIRMA_MODULE	2431
++klk_wirma_mmi		MACH_KLK_WIRMA_MMI	KLK_WIRMA_MMI		2432
++supersonic		MACH_SUPERSONIC		SUPERSONIC		2433
++liberty			MACH_LIBERTY		LIBERTY			2434
++mh355			MACH_MH355		MH355			2435
++pc7802			MACH_PC7802		PC7802			2436
++gnet_sgc		MACH_GNET_SGC		GNET_SGC		2437
++einstein15		MACH_EINSTEIN15		EINSTEIN15		2438
++cmpd			MACH_CMPD		CMPD			2439
++davinci_hase1		MACH_DAVINCI_HASE1	DAVINCI_HASE1		2440
++lgeincitephone		MACH_LGEINCITEPHONE	LGEINCITEPHONE		2441
++ea313x			MACH_EA313X		EA313X			2442
++fwbd_39064		MACH_FWBD_39064		FWBD_39064		2443
++fwbd_390128		MACH_FWBD_390128	FWBD_390128		2444
++pelco_moe		MACH_PELCO_MOE		PELCO_MOE		2445
++minimix27		MACH_MINIMIX27		MINIMIX27		2446
++omap3_thunder		MACH_OMAP3_THUNDER	OMAP3_THUNDER		2447
++passionc		MACH_PASSIONC		PASSIONC		2448
++mx27amata		MACH_MX27AMATA		MX27AMATA		2449
++bgat1			MACH_BGAT1		BGAT1			2450
++buzz			MACH_BUZZ		BUZZ			2451
++mb9g20			MACH_MB9G20		MB9G20			2452
++yushan			MACH_YUSHAN		YUSHAN			2453
++lizard			MACH_LIZARD		LIZARD			2454
++omap3polycom		MACH_OMAP3POLYCOM	OMAP3POLYCOM		2455
++smdkv210		MACH_SMDKV210		SMDKV210		2456
++bravo			MACH_BRAVO		BRAVO			2457
++siogentoo1		MACH_SIOGENTOO1		SIOGENTOO1		2458
++siogentoo2		MACH_SIOGENTOO2		SIOGENTOO2		2459
++sm3k			MACH_SM3K		SM3K			2460
++acer_tempo_f900		MACH_ACER_TEMPO_F900	ACER_TEMPO_F900		2461
++sst61vc010_dev		MACH_SST61VC010_DEV	SST61VC010_DEV		2462
++glittertind		MACH_GLITTERTIND	GLITTERTIND		2463
++omap_zoom3		MACH_OMAP_ZOOM3		OMAP_ZOOM3		2464
++omap_3630sdp		MACH_OMAP_3630SDP	OMAP_3630SDP		2465
++cybook2440		MACH_CYBOOK2440		CYBOOK2440		2466
++torino_s		MACH_TORINO_S		TORINO_S		2467
++havana			MACH_HAVANA		HAVANA			2468
++beaumont_11		MACH_BEAUMONT_11	BEAUMONT_11		2469
++vanguard		MACH_VANGUARD		VANGUARD		2470
++s5pc110_draco		MACH_S5PC110_DRACO	S5PC110_DRACO		2471
++cartesio_two		MACH_CARTESIO_TWO	CARTESIO_TWO		2472
++aster			MACH_ASTER		ASTER			2473
++voguesv210		MACH_VOGUESV210		VOGUESV210		2474
++acm500x			MACH_ACM500X		ACM500X			2475
++km9260			MACH_KM9260		KM9260			2476
++nideflexg1		MACH_NIDEFLEXG1		NIDEFLEXG1		2477
++ctera_plug_io		MACH_CTERA_PLUG_IO	CTERA_PLUG_IO		2478
++smartq7			MACH_SMARTQ7		SMARTQ7			2479
++at91sam9g10ek2		MACH_AT91SAM9G10EK2	AT91SAM9G10EK2		2480
++asusp527		MACH_ASUSP527		ASUSP527		2481
++at91sam9g20mpm2		MACH_AT91SAM9G20MPM2	AT91SAM9G20MPM2		2482
++topasa900		MACH_TOPASA900		TOPASA900		2483
++electrum_100		MACH_ELECTRUM_100	ELECTRUM_100		2484
++mx51grb			MACH_MX51GRB		MX51GRB			2485
++xea300			MACH_XEA300		XEA300			2486
++htcstartrek		MACH_HTCSTARTREK	HTCSTARTREK		2487
++lima			MACH_LIMA		LIMA			2488
++csb740			MACH_CSB740		CSB740			2489
++usb_s8815		MACH_USB_S8815		USB_S8815		2490
++watson_efm_plugin	MACH_WATSON_EFM_PLUGIN	WATSON_EFM_PLUGIN	2491
++milkyway		MACH_MILKYWAY		MILKYWAY		2492
++g4evm			MACH_G4EVM		G4EVM			2493
++picomod6		MACH_PICOMOD6		PICOMOD6		2494
++omapl138_hawkboard	MACH_OMAPL138_HAWKBOARD	OMAPL138_HAWKBOARD	2495
++ip6000			MACH_IP6000		IP6000			2496
++ip6010			MACH_IP6010		IP6010			2497
++utm400			MACH_UTM400		UTM400			2498
++omap3_zybex		MACH_OMAP3_ZYBEX	OMAP3_ZYBEX		2499
++wireless_space		MACH_WIRELESS_SPACE	WIRELESS_SPACE		2500
++sx560			MACH_SX560		SX560			2501
++ts41x			MACH_TS41X		TS41X			2502
++elphel10373		MACH_ELPHEL10373	ELPHEL10373		2503
++rhobot			MACH_RHOBOT		RHOBOT			2504
++mx51_refresh		MACH_MX51_REFRESH	MX51_REFRESH		2505
++ls9260			MACH_LS9260		LS9260			2506
++shank			MACH_SHANK		SHANK			2507
++qsd8x50_st1		MACH_QSD8X50_ST1	QSD8X50_ST1		2508
++at91sam9m10ekes		MACH_AT91SAM9M10EKES	AT91SAM9M10EKES		2509
++hiram			MACH_HIRAM		HIRAM			2510
++phy3250			MACH_PHY3250		PHY3250			2511
++ea3250			MACH_EA3250		EA3250			2512
++fdi3250			MACH_FDI3250		FDI3250			2513
++whitestone		MACH_WHITESTONE		WHITESTONE		2514
++at91sam9263nit		MACH_AT91SAM9263NIT	AT91SAM9263NIT		2515
++ccmx51			MACH_CCMX51		CCMX51			2516
++ccmx51js		MACH_CCMX51JS		CCMX51JS		2517
++ccwmx51			MACH_CCWMX51		CCWMX51			2518
++ccwmx51js		MACH_CCWMX51JS		CCWMX51JS		2519
++mini6410		MACH_MINI6410		MINI6410		2520
++tiny6410		MACH_TINY6410		TINY6410		2521
++nano6410		MACH_NANO6410		NANO6410		2522
++at572d940hfnldb		MACH_AT572D940HFNLDB	AT572D940HFNLDB		2523
++htcleo			MACH_HTCLEO		HTCLEO			2524
++avp13			MACH_AVP13		AVP13			2525
++xxsvideod		MACH_XXSVIDEOD		XXSVIDEOD		2526
++vpnext			MACH_VPNEXT		VPNEXT			2527
++swarco_itc3		MACH_SWARCO_ITC3	SWARCO_ITC3		2528
++tx51			MACH_TX51		TX51			2529
++dolby_cat1021		MACH_DOLBY_CAT1021	DOLBY_CAT1021		2530
++mx28evk			MACH_MX28EVK		MX28EVK			2531
++phoenix260		MACH_PHOENIX260		PHOENIX260		2532
++uvaca_stork		MACH_UVACA_STORK	UVACA_STORK		2533
++smartq5			MACH_SMARTQ5		SMARTQ5			2534
++all3078			MACH_ALL3078		ALL3078			2535
++ctera_2bay_ds		MACH_CTERA_2BAY_DS	CTERA_2BAY_DS		2536
++siogentoo3		MACH_SIOGENTOO3		SIOGENTOO3		2537
++epb5000			MACH_EPB5000		EPB5000			2538
++hy9263			MACH_HY9263		HY9263			2539
++acer_tempo_m900		MACH_ACER_TEMPO_M900	ACER_TEMPO_M900		2540
++acer_tempo_dx650	MACH_ACER_TEMPO_DX900	ACER_TEMPO_DX900	2541
++acer_tempo_x960		MACH_ACER_TEMPO_X960	ACER_TEMPO_X960		2542
++acer_eten_v900		MACH_ACER_ETEN_V900	ACER_ETEN_V900		2543
++acer_eten_x900		MACH_ACER_ETEN_X900	ACER_ETEN_X900		2544
++bonnell			MACH_BONNELL		BONNELL			2545
++oht_mx27		MACH_OHT_MX27		OHT_MX27		2546
++htcquartz		MACH_HTCQUARTZ		HTCQUARTZ		2547
++davinci_dm6467tevm	MACH_DAVINCI_DM6467TEVM	DAVINCI_DM6467TEVM	2548
++c3ax03			MACH_C3AX03		C3AX03			2549
++mxt_td60		MACH_MXT_TD60		MXT_TD60		2550
++esyx			MACH_ESYX		ESYX			2551
++dove_db2		MACH_DOVE_DB2		DOVE_DB2		2552
++bulldog			MACH_BULLDOG		BULLDOG			2553
++derell_me2000		MACH_DERELL_ME2000	DERELL_ME2000		2554
++bcmring_base		MACH_BCMRING_BASE	BCMRING_BASE		2555
++bcmring_evm		MACH_BCMRING_EVM	BCMRING_EVM		2556
++bcmring_evm_jazz	MACH_BCMRING_EVM_JAZZ	BCMRING_EVM_JAZZ	2557
++bcmring_sp		MACH_BCMRING_SP		BCMRING_SP		2558
++bcmring_sv		MACH_BCMRING_SV		BCMRING_SV		2559
++bcmring_sv_jazz		MACH_BCMRING_SV_JAZZ	BCMRING_SV_JAZZ		2560
++bcmring_tablet		MACH_BCMRING_TABLET	BCMRING_TABLET		2561
++bcmring_vp		MACH_BCMRING_VP		BCMRING_VP		2562
++bcmring_evm_seikor	MACH_BCMRING_EVM_SEIKOR	BCMRING_EVM_SEIKOR	2563
++bcmring_sp_wqvga	MACH_BCMRING_SP_WQVGA	BCMRING_SP_WQVGA	2564
++bcmring_custom		MACH_BCMRING_CUSTOM	BCMRING_CUSTOM		2565
++acer_s200		MACH_ACER_S200		ACER_S200		2566
++bt270			MACH_BT270		BT270			2567
++iseo			MACH_ISEO		ISEO			2568
++cezanne			MACH_CEZANNE		CEZANNE			2569
++lucca			MACH_LUCCA		LUCCA			2570
++supersmart		MACH_SUPERSMART		SUPERSMART		2571
++arm11_board		MACH_CS_MISANO		CS_MISANO		2572
++magnolia2		MACH_MAGNOLIA2		MAGNOLIA2		2573
++emxx			MACH_EMXX		EMXX			2574
++outlaw			MACH_OUTLAW		OUTLAW			2575
++riot_bei2		MACH_RIOT_BEI2		RIOT_BEI2		2576
++riot_vox		MACH_RIOT_VOX		RIOT_VOX		2577
++riot_x37		MACH_RIOT_X37		RIOT_X37		2578
++mega25mx		MACH_MEGA25MX		MEGA25MX		2579
++benzina2		MACH_BENZINA2		BENZINA2		2580
++ignite			MACH_IGNITE		IGNITE			2581
++foggia			MACH_FOGGIA		FOGGIA			2582
++arezzo			MACH_AREZZO		AREZZO			2583
++leica_skywalker		MACH_LEICA_SKYWALKER	LEICA_SKYWALKER		2584
++jacinto2_jamr		MACH_JACINTO2_JAMR	JACINTO2_JAMR		2585
++gts_nova		MACH_GTS_NOVA		GTS_NOVA		2586
++p3600			MACH_P3600		P3600			2587
++dlt2			MACH_DLT2		DLT2			2588
++df3120			MACH_DF3120		DF3120			2589
++ecucore_9g20		MACH_ECUCORE_9G20	ECUCORE_9G20		2590
++nautel_lpc3240		MACH_NAUTEL_LPC3240	NAUTEL_LPC3240		2591
++glacier			MACH_GLACIER		GLACIER			2592
++phrazer_bulldog		MACH_PHRAZER_BULLDOG	PHRAZER_BULLDOG		2593
++omap3_bulldog		MACH_OMAP3_BULLDOG	OMAP3_BULLDOG		2594
++pca101			MACH_PCA101		PCA101			2595
++buzzc			MACH_BUZZC		BUZZC			2596
++sasie2			MACH_SASIE2		SASIE2			2597
++davinci_cio		MACH_DAVINCI_CIO	DAVINCI_CIO		2598
++smartmeter_dl		MACH_SMARTMETER_DL	SMARTMETER_DL		2599
++wzl6410			MACH_WZL6410		WZL6410			2600
++wzl6410m		MACH_WZL6410M		WZL6410M		2601
++wzl6410f		MACH_WZL6410F		WZL6410F		2602
++wzl6410i		MACH_WZL6410I		WZL6410I		2603
++spacecom1		MACH_SPACECOM1		SPACECOM1		2604
++pingu920		MACH_PINGU920		PINGU920		2605
++bravoc			MACH_BRAVOC		BRAVOC			2606
++cybo2440		MACH_CYBO2440		CYBO2440		2607
++vdssw			MACH_VDSSW		VDSSW			2608
++romulus			MACH_ROMULUS		ROMULUS			2609
++omap_magic		MACH_OMAP_MAGIC		OMAP_MAGIC		2610
++eltd100			MACH_ELTD100		ELTD100			2611
++capc7117		MACH_CAPC7117		CAPC7117		2612
++swan			MACH_SWAN		SWAN			2613
++veu			MACH_VEU		VEU			2614
++rm2			MACH_RM2		RM2			2615
++tt2100			MACH_TT2100		TT2100			2616
++venice			MACH_VENICE		VENICE			2617
++pc7323			MACH_PC7323		PC7323			2618
++masp			MACH_MASP		MASP			2619
++fujitsu_tvstbsoc0	MACH_FUJITSU_TVSTBSOC	FUJITSU_TVSTBSOC	2620
++fujitsu_tvstbsoc1	MACH_FUJITSU_TVSTBSOC1	FUJITSU_TVSTBSOC1	2621
++lexikon			MACH_LEXIKON		LEXIKON			2622
++mini2440v2		MACH_MINI2440V2		MINI2440V2		2623
++icontrol		MACH_ICONTROL		ICONTROL		2624
++gplugd			MACH_SHEEVAD		SHEEVAD			2625
++qsd8x50a_st1_1		MACH_QSD8X50A_ST1_1	QSD8X50A_ST1_1		2626
++qsd8x50a_st1_5		MACH_QSD8X50A_ST1_5	QSD8X50A_ST1_5		2627
++bee			MACH_BEE		BEE			2628
++mx23evk			MACH_MX23EVK		MX23EVK			2629
++ap4evb			MACH_AP4EVB		AP4EVB			2630
++stockholm		MACH_STOCKHOLM		STOCKHOLM		2631
++lpc_h3131		MACH_LPC_H3131		LPC_H3131		2632
++stingray		MACH_STINGRAY		STINGRAY		2633
++kraken			MACH_KRAKEN		KRAKEN			2634
++gw2388			MACH_GW2388		GW2388			2635
++jadecpu			MACH_JADECPU		JADECPU			2636
++carlisle		MACH_CARLISLE		CARLISLE		2637
++lux_sf9			MACH_LUX_SFT9		LUX_SFT9		2638
++nemid_tb		MACH_NEMID_TB		NEMID_TB		2639
++terrier			MACH_TERRIER		TERRIER			2640
++turbot			MACH_TURBOT		TURBOT			2641
++sanddab			MACH_SANDDAB		SANDDAB			2642
++mx35_cicada		MACH_MX35_CICADA	MX35_CICADA		2643
++ghi2703d		MACH_GHI2703D		GHI2703D		2644
++lux_sfx9		MACH_LUX_SFX9		LUX_SFX9		2645
++lux_sf9g		MACH_LUX_SF9G		LUX_SF9G		2646
++lux_edk9		MACH_LUX_EDK9		LUX_EDK9		2647
++hw90240			MACH_HW90240		HW90240			2648
++dm365_leopard		MACH_DM365_LEOPARD	DM365_LEOPARD		2649
++mityomapl138		MACH_MITYOMAPL138	MITYOMAPL138		2650
++scat110			MACH_SCAT110		SCAT110			2651
++acer_a1			MACH_ACER_A1		ACER_A1			2652
++cmcontrol		MACH_CMCONTROL		CMCONTROL		2653
++pelco_lamar		MACH_PELCO_LAMAR	PELCO_LAMAR		2654
++rfp43			MACH_RFP43		RFP43			2655
++sk86r0301		MACH_SK86R0301		SK86R0301		2656
++ctpxa			MACH_CTPXA		CTPXA			2657
++epb_arm9_a		MACH_EPB_ARM9_A		EPB_ARM9_A		2658
++guruplug		MACH_GURUPLUG		GURUPLUG		2659
++spear310		MACH_SPEAR310		SPEAR310		2660
++spear320		MACH_SPEAR320		SPEAR320		2661
++robotx			MACH_ROBOTX		ROBOTX			2662
++lsxhl			MACH_LSXHL		LSXHL			2663
++smartlite		MACH_SMARTLITE		SMARTLITE		2664
++cws2			MACH_CWS2		CWS2			2665
++m619			MACH_M619		M619			2666
++smartview		MACH_SMARTVIEW		SMARTVIEW		2667
++lsa_salsa		MACH_LSA_SALSA		LSA_SALSA		2668
++kizbox			MACH_KIZBOX		KIZBOX			2669
++htccharmer		MACH_HTCCHARMER		HTCCHARMER		2670
++guf_neso_lt		MACH_GUF_NESO_LT	GUF_NESO_LT		2671
++pm9g45			MACH_PM9G45		PM9G45			2672
++htcpanther		MACH_HTCPANTHER		HTCPANTHER		2673
++htcpanther_cdma		MACH_HTCPANTHER_CDMA	HTCPANTHER_CDMA		2674
++reb01			MACH_REB01		REB01			2675
++aquila			MACH_AQUILA		AQUILA			2676
++spark_sls_hw2		MACH_SPARK_SLS_HW2	SPARK_SLS_HW2		2677
++sheeva_esata		MACH_ESATA_SHEEVAPLUG	ESATA_SHEEVAPLUG	2678
++msm7x30_surf		MACH_MSM7X30_SURF	MSM7X30_SURF		2679
++micro2440		MACH_MICRO2440		MICRO2440		2680
++am2440			MACH_AM2440		AM2440			2681
++tq2440			MACH_TQ2440		TQ2440			2682
++lpc2478oem		MACH_LPC2478OEM		LPC2478OEM		2683
++ak880x			MACH_AK880X		AK880X			2684
++cobra3530		MACH_COBRA3530		COBRA3530		2685
++pmppb			MACH_PMPPB		PMPPB			2686
++u6715			MACH_U6715		U6715			2687
++axar1500_sender		MACH_AXAR1500_SENDER	AXAR1500_SENDER		2688
++g30_dvb			MACH_G30_DVB		G30_DVB			2689
++vc088x			MACH_VC088X		VC088X			2690
++mioa702			MACH_MIOA702		MIOA702			2691
++hpmin			MACH_HPMIN		HPMIN			2692
++ak880xak		MACH_AK880XAK		AK880XAK		2693
++arm926tomap850		MACH_ARM926TOMAP850	ARM926TOMAP850		2694
++lkevm			MACH_LKEVM		LKEVM			2695
++mw6410			MACH_MW6410		MW6410			2696
++terastation_wxl		MACH_TERASTATION_WXL	TERASTATION_WXL		2697
++cpu8000e		MACH_CPU8000E		CPU8000E		2698
++catania			MACH_CATANIA		CATANIA			2699
++tokyo			MACH_TOKYO		TOKYO			2700
++msm7201a_surf		MACH_MSM7201A_SURF	MSM7201A_SURF		2701
++msm7201a_ffa		MACH_MSM7201A_FFA	MSM7201A_FFA		2702
++msm7x25_surf		MACH_MSM7X25_SURF	MSM7X25_SURF		2703
++msm7x25_ffa		MACH_MSM7X25_FFA	MSM7X25_FFA		2704
++msm7x27_surf		MACH_MSM7X27_SURF	MSM7X27_SURF		2705
++msm7x27_ffa		MACH_MSM7X27_FFA	MSM7X27_FFA		2706
++msm7x30_ffa		MACH_MSM7X30_FFA	MSM7X30_FFA		2707
++qsd8x50_surf		MACH_QSD8X50_SURF	QSD8X50_SURF		2708
++qsd8x50_comet		MACH_QSD8X50_COMET	QSD8X50_COMET		2709
++qsd8x50_ffa		MACH_QSD8X50_FFA	QSD8X50_FFA		2710
++qsd8x50a_surf		MACH_QSD8X50A_SURF	QSD8X50A_SURF		2711
++qsd8x50a_ffa		MACH_QSD8X50A_FFA	QSD8X50A_FFA		2712
++adx_xgcp10		MACH_ADX_XGCP10		ADX_XGCP10		2713
++mcgwumts2a		MACH_MCGWUMTS2A		MCGWUMTS2A		2714
++mobikt			MACH_MOBIKT		MOBIKT			2715
++mx53_evk		MACH_MX53_EVK		MX53_EVK		2716
++igep0030		MACH_IGEP0030		IGEP0030		2717
++axell_h40_h50_ctrl	MACH_AXELL_H40_H50_CTRL	AXELL_H40_H50_CTRL	2718
++dtcommod		MACH_DTCOMMOD		DTCOMMOD		2719
++gould			MACH_GOULD		GOULD			2720
++siberia			MACH_SIBERIA		SIBERIA			2721
++sbc3530			MACH_SBC3530		SBC3530			2722
++qarm			MACH_QARM		QARM			2723
++mips			MACH_MIPS		MIPS			2724
++mx27grb			MACH_MX27GRB		MX27GRB			2725
++sbc8100			MACH_SBC8100		SBC8100			2726
++saarb			MACH_SAARB		SAARB			2727
++omap3mini		MACH_OMAP3MINI		OMAP3MINI		2728
++cnmbook7se		MACH_CNMBOOK7SE		CNMBOOK7SE		2729
++catan			MACH_CATAN		CATAN			2730
++harmony			MACH_HARMONY		HARMONY			2731
++tonga			MACH_TONGA		TONGA			2732
++cybook_orizon		MACH_CYBOOK_ORIZON	CYBOOK_ORIZON		2733
++htcrhodiumcdma		MACH_HTCRHODIUMCDMA	HTCRHODIUMCDMA		2734
++epc_g45			MACH_EPC_G45		EPC_G45			2735
++epc_lpc3250		MACH_EPC_LPC3250	EPC_LPC3250		2736
++mxc91341evb		MACH_MXC91341EVB	MXC91341EVB		2737
++rtw1000			MACH_RTW1000		RTW1000			2738
++bobcat			MACH_BOBCAT		BOBCAT			2739
++trizeps6		MACH_TRIZEPS6		TRIZEPS6		2740
++msm7x30_fluid		MACH_MSM7X30_FLUID	MSM7X30_FLUID		2741
++nedap9263		MACH_NEDAP9263		NEDAP9263		2742
++netgear_ms2110		MACH_NETGEAR_MS2110	NETGEAR_MS2110		2743
++bmx			MACH_BMX		BMX			2744
++netstream		MACH_NETSTREAM		NETSTREAM		2745
++vpnext_rcu		MACH_VPNEXT_RCU		VPNEXT_RCU		2746
++vpnext_mpu		MACH_VPNEXT_MPU		VPNEXT_MPU		2747
++bcmring_tablet_v1	MACH_BCMRING_TABLET_V1	BCMRING_TABLET_V1	2748
++sgarm10			MACH_SGARM10		SGARM10			2749
++cm_t3517		MACH_CM_T3517		CM_T3517		2750
++omap3_cps		MACH_OMAP3_CPS		OMAP3_CPS		2751
++axar1500_receiver	MACH_AXAR1500_RECEIVER	AXAR1500_RECEIVER	2752
++wbd222			MACH_WBD222		WBD222			2753
++mt65xx			MACH_MT65XX		MT65XX			2754
++msm8x60_surf		MACH_MSM8X60_SURF	MSM8X60_SURF		2755
++msm8x60_sim		MACH_MSM8X60_SIM	MSM8X60_SIM		2756
++vmc300			MACH_VMC300		VMC300			2757
++tcc8000_sdk		MACH_TCC8000_SDK	TCC8000_SDK		2758
++nanos			MACH_NANOS		NANOS			2759
++stamp9g10		MACH_STAMP9G10		STAMP9G10		2760
++stamp9g45		MACH_STAMP9G45		STAMP9G45		2761
++h6053			MACH_H6053		H6053			2762
++smint01			MACH_SMINT01		SMINT01			2763
++prtlvt2			MACH_PRTLVT2		PRTLVT2			2764
++ap420			MACH_AP420		AP420			2765
++htcshift		MACH_HTCSHIFT		HTCSHIFT		2766
++davinci_dm365_fc	MACH_DAVINCI_DM365_FC	DAVINCI_DM365_FC	2767
++msm8x55_surf		MACH_MSM8X55_SURF	MSM8X55_SURF		2768
++msm8x55_ffa		MACH_MSM8X55_FFA	MSM8X55_FFA		2769
++esl_vamana		MACH_ESL_VAMANA		ESL_VAMANA		2770
++sbc35			MACH_SBC35		SBC35			2771
++mpx6446			MACH_MPX6446		MPX6446			2772
++oreo_controller		MACH_OREO_CONTROLLER	OREO_CONTROLLER		2773
++kopin_models		MACH_KOPIN_MODELS	KOPIN_MODELS		2774
++ttc_vision2		MACH_TTC_VISION2	TTC_VISION2		2775
++cns3420vb		MACH_CNS3420VB		CNS3420VB		2776
++lpc2			MACH_LPC2		LPC2			2777
++olympus			MACH_OLYMPUS		OLYMPUS			2778
++vortex			MACH_VORTEX		VORTEX			2779
++s5pc200			MACH_S5PC200		S5PC200			2780
++ecucore_9263		MACH_ECUCORE_9263	ECUCORE_9263		2781
++smdkc200		MACH_SMDKC200		SMDKC200		2782
++emsiso_sx27		MACH_EMSISO_SX27	EMSISO_SX27		2783
++apx_som9g45_ek		MACH_APX_SOM9G45_EK	APX_SOM9G45_EK		2784
++songshan		MACH_SONGSHAN		SONGSHAN		2785
++tianshan		MACH_TIANSHAN		TIANSHAN		2786
++vpx500			MACH_VPX500		VPX500			2787
++am3517sam		MACH_AM3517SAM		AM3517SAM		2788
++skat91_sim508		MACH_SKAT91_SIM508	SKAT91_SIM508		2789
++skat91_s3e		MACH_SKAT91_S3E		SKAT91_S3E		2790
++omap4_panda		MACH_OMAP4_PANDA	OMAP4_PANDA		2791
++df7220			MACH_DF7220		DF7220			2792
++nemini			MACH_NEMINI		NEMINI			2793
++t8200			MACH_T8200		T8200			2794
++apf51			MACH_APF51		APF51			2795
++dr_rc_unit		MACH_DR_RC_UNIT		DR_RC_UNIT		2796
++bordeaux		MACH_BORDEAUX		BORDEAUX		2797
++catania_b		MACH_CATANIA_B		CATANIA_B		2798
++mx51_ocean		MACH_MX51_OCEAN		MX51_OCEAN		2799
++ti8168evm		MACH_TI8168EVM		TI8168EVM		2800
++neocoreomap		MACH_NEOCOREOMAP	NEOCOREOMAP		2801
++withings_wbp		MACH_WITHINGS_WBP	WITHINGS_WBP		2802
++dbps			MACH_DBPS		DBPS			2803
++sbc9261			MACH_SBC9261		SBC9261			2804
++pcbfp0001		MACH_PCBFP0001		PCBFP0001		2805
++speedy			MACH_SPEEDY		SPEEDY			2806
++chrysaor		MACH_CHRYSAOR		CHRYSAOR		2807
++tango			MACH_TANGO		TANGO			2808
++synology_dsx11		MACH_SYNOLOGY_DSX11	SYNOLOGY_DSX11		2809
++hanlin_v3ext		MACH_HANLIN_V3EXT	HANLIN_V3EXT		2810
++hanlin_v5		MACH_HANLIN_V5		HANLIN_V5		2811
++hanlin_v3plus		MACH_HANLIN_V3PLUS	HANLIN_V3PLUS		2812
++iriver_story		MACH_IRIVER_STORY	IRIVER_STORY		2813
++irex_iliad		MACH_IREX_ILIAD		IREX_ILIAD		2814
++irex_dr1000		MACH_IREX_DR1000	IREX_DR1000		2815
++teton_bga		MACH_TETON_BGA		TETON_BGA		2816
++snapper9g45		MACH_SNAPPER9G45	SNAPPER9G45		2817
++tam3517			MACH_TAM3517		TAM3517			2818
++pdc100			MACH_PDC100		PDC100			2819
++eukrea_cpuimx25sd	MACH_EUKREA_CPUIMX25	EUKREA_CPUIMX25		2820
++eukrea_cpuimx35sd	MACH_EUKREA_CPUIMX35	EUKREA_CPUIMX35		2821
++eukrea_cpuimx51sd	MACH_EUKREA_CPUIMX51SD	EUKREA_CPUIMX51SD	2822
++eukrea_cpuimx51		MACH_EUKREA_CPUIMX51	EUKREA_CPUIMX51		2823
++p565			MACH_P565		P565			2824
++acer_a4			MACH_ACER_A4		ACER_A4			2825
++davinci_dm368_bip	MACH_DAVINCI_DM368_BIP	DAVINCI_DM368_BIP	2826
++eshare			MACH_ESHARE		ESHARE			2827
++hw_omapl138_europa	MACH_HW_OMAPL138_EUROPA	HW_OMAPL138_EUROPA	2828
++wlbargn			MACH_WLBARGN		WLBARGN			2829
++bm170			MACH_BM170		BM170			2830
++netspace_mini_v2	MACH_NETSPACE_MINI_V2	NETSPACE_MINI_V2	2831
++netspace_plug_v2	MACH_NETSPACE_PLUG_V2	NETSPACE_PLUG_V2	2832
++siemens_l1		MACH_SIEMENS_L1		SIEMENS_L1		2833
++elv_lcu1		MACH_ELV_LCU1		ELV_LCU1		2834
++mcu1			MACH_MCU1		MCU1			2835
++omap3_tao3530		MACH_OMAP3_TAO3530	OMAP3_TAO3530		2836
++omap3_pcutouch		MACH_OMAP3_PCUTOUCH	OMAP3_PCUTOUCH		2837
++smdkc210		MACH_SMDKC210		SMDKC210		2838
++omap3_braillo		MACH_OMAP3_BRAILLO	OMAP3_BRAILLO		2839
++spyplug			MACH_SPYPLUG		SPYPLUG			2840
++ginger			MACH_GINGER		GINGER			2841
++tny_t3530		MACH_TNY_T3530		TNY_T3530		2842
++pca102			MACH_PCA102		PCA102			2843
++spade			MACH_SPADE		SPADE			2844
++mxc25_topaz		MACH_MXC25_TOPAZ	MXC25_TOPAZ		2845
++t5325			MACH_T5325		T5325			2846
++gw2361			MACH_GW2361		GW2361			2847
++elog			MACH_ELOG		ELOG			2848
++income			MACH_INCOME		INCOME			2849
++bcm589x			MACH_BCM589X		BCM589X			2850
++etna			MACH_ETNA		ETNA			2851
++hawks			MACH_HAWKS		HAWKS			2852
++meson			MACH_MESON		MESON			2853
++xsbase255		MACH_XSBASE255		XSBASE255		2854
++pvm2030			MACH_PVM2030		PVM2030			2855
++mioa502			MACH_MIOA502		MIOA502			2856
++vvbox_sdorig2		MACH_VVBOX_SDORIG2	VVBOX_SDORIG2		2857
++vvbox_sdlite2		MACH_VVBOX_SDLITE2	VVBOX_SDLITE2		2858
++vvbox_sdpro4		MACH_VVBOX_SDPRO4	VVBOX_SDPRO4		2859
++htc_spv_m700		MACH_HTC_SPV_M700	HTC_SPV_M700		2860
++mx257sx			MACH_MX257SX		MX257SX			2861
++goni			MACH_GONI		GONI			2862
++msm8x55_svlte_ffa	MACH_MSM8X55_SVLTE_FFA	MSM8X55_SVLTE_FFA	2863
++msm8x55_svlte_surf	MACH_MSM8X55_SVLTE_SURF	MSM8X55_SVLTE_SURF	2864
++quickstep		MACH_QUICKSTEP		QUICKSTEP		2865
++dmw96			MACH_DMW96		DMW96			2866
++hammerhead		MACH_HAMMERHEAD		HAMMERHEAD		2867
++trident			MACH_TRIDENT		TRIDENT			2868
++lightning		MACH_LIGHTNING		LIGHTNING		2869
++iconnect		MACH_ICONNECT		ICONNECT		2870
++autobot			MACH_AUTOBOT		AUTOBOT			2871
++coconut			MACH_COCONUT		COCONUT			2872
++durian			MACH_DURIAN		DURIAN			2873
++cayenne			MACH_CAYENNE		CAYENNE			2874
++fuji			MACH_FUJI		FUJI			2875
++synology_6282		MACH_SYNOLOGY_6282	SYNOLOGY_6282		2876
++em1sy			MACH_EM1SY		EM1SY			2877
++m502			MACH_M502		M502			2878
++matrix518		MACH_MATRIX518		MATRIX518		2879
++tiny_gurnard		MACH_TINY_GURNARD	TINY_GURNARD		2880
++spear1310		MACH_SPEAR1310		SPEAR1310		2881
++bv07			MACH_BV07		BV07			2882
++mxt_td61		MACH_MXT_TD61		MXT_TD61		2883
++openrd_ultimate		MACH_OPENRD_ULTIMATE	OPENRD_ULTIMATE		2884
++devixp			MACH_DEVIXP		DEVIXP			2885
++miccpt			MACH_MICCPT		MICCPT			2886
++mic256			MACH_MIC256		MIC256			2887
++as1167			MACH_AS1167		AS1167			2888
++omap3_ibiza		MACH_OMAP3_IBIZA	OMAP3_IBIZA		2889
++u5500			MACH_U5500		U5500			2890
++davinci_picto		MACH_DAVINCI_PICTO	DAVINCI_PICTO		2891
++mecha			MACH_MECHA		MECHA			2892
++bubba3			MACH_BUBBA3		BUBBA3			2893
++pupitre			MACH_PUPITRE		PUPITRE			2894
++tegra_harmony		MACH_TEGRA_HARMONY	TEGRA_HARMONY		2895
++tegra_vogue		MACH_TEGRA_VOGUE	TEGRA_VOGUE		2896
++tegra_e1165		MACH_TEGRA_E1165	TEGRA_E1165		2897
++simplenet		MACH_SIMPLENET		SIMPLENET		2898
++ec4350tbm		MACH_EC4350TBM		EC4350TBM		2899
++pec_tc			MACH_PEC_TC		PEC_TC			2900
++pec_hc2			MACH_PEC_HC2		PEC_HC2			2901
++esl_mobilis_a		MACH_ESL_MOBILIS_A	ESL_MOBILIS_A		2902
++esl_mobilis_b		MACH_ESL_MOBILIS_B	ESL_MOBILIS_B		2903
++esl_wave_a		MACH_ESL_WAVE_A		ESL_WAVE_A		2904
++esl_wave_b		MACH_ESL_WAVE_B		ESL_WAVE_B		2905
++unisense_mmm		MACH_UNISENSE_MMM	UNISENSE_MMM		2906
++blueshark		MACH_BLUESHARK		BLUESHARK		2907
++e10			MACH_E10		E10			2908
++app3k_robin		MACH_APP3K_ROBIN	APP3K_ROBIN		2909
++pov15hd			MACH_POV15HD		POV15HD			2910
++stella			MACH_STELLA		STELLA			2911
++linkstation_lschl	MACH_LINKSTATION_LSCHL	LINKSTATION_LSCHL	2913
++netwalker		MACH_NETWALKER		NETWALKER		2914
++acsx106			MACH_ACSX106		ACSX106			2915
++atlas5_c1		MACH_ATLAS5_C1		ATLAS5_C1		2916
++nsb3ast			MACH_NSB3AST		NSB3AST			2917
++gnet_slc		MACH_GNET_SLC		GNET_SLC		2918
++af4000			MACH_AF4000		AF4000			2919
++ark9431			MACH_ARK9431		ARK9431			2920
++fs_s5pc100		MACH_FS_S5PC100		FS_S5PC100		2921
++omap3505nova8		MACH_OMAP3505NOVA8	OMAP3505NOVA8		2922
++omap3621_edp1		MACH_OMAP3621_EDP1	OMAP3621_EDP1		2923
++oratisaes		MACH_ORATISAES		ORATISAES		2924
++smdkv310		MACH_SMDKV310		SMDKV310		2925
++siemens_l0		MACH_SIEMENS_L0		SIEMENS_L0		2926
++ventana			MACH_VENTANA		VENTANA			2927
++wm8505_7in_netbook	MACH_WM8505_7IN_NETBOOK	WM8505_7IN_NETBOOK	2928
++ec4350sdb		MACH_EC4350SDB		EC4350SDB		2929
++mimas			MACH_MIMAS		MIMAS			2930
++titan			MACH_TITAN		TITAN			2931
++craneboard		MACH_CRANEBOARD		CRANEBOARD		2932
++es2440			MACH_ES2440		ES2440			2933
++najay_a9263		MACH_NAJAY_A9263	NAJAY_A9263		2934
++htctornado		MACH_HTCTORNADO		HTCTORNADO		2935
++dimm_mx257		MACH_DIMM_MX257		DIMM_MX257		2936
++jigen301		MACH_JIGEN		JIGEN			2937
++smdk6450		MACH_SMDK6450		SMDK6450		2938
++meno_qng		MACH_MENO_QNG		MENO_QNG		2939
++ns2416			MACH_NS2416		NS2416			2940
++rpc353			MACH_RPC353		RPC353			2941
++tq6410			MACH_TQ6410		TQ6410			2942
++sky6410			MACH_SKY6410		SKY6410			2943
++dynasty			MACH_DYNASTY		DYNASTY			2944
++vivo			MACH_VIVO		VIVO			2945
++bury_bl7582		MACH_BURY_BL7582	BURY_BL7582		2946
++bury_bps5270		MACH_BURY_BPS5270	BURY_BPS5270		2947
++basi			MACH_BASI		BASI			2948
++tn200			MACH_TN200		TN200			2949
++c2mmi			MACH_C2MMI		C2MMI			2950
++meson_6236m		MACH_MESON_6236M	MESON_6236M		2951
++meson_8626m		MACH_MESON_8626M	MESON_8626M		2952
++tube			MACH_TUBE		TUBE			2953
++messina			MACH_MESSINA		MESSINA			2954
++mx50_arm2		MACH_MX50_ARM2		MX50_ARM2		2955
++cetus9263		MACH_CETUS9263		CETUS9263		2956
++brownstone		MACH_BROWNSTONE		BROWNSTONE		2957
++vmx25			MACH_VMX25		VMX25			2958
++vmx51			MACH_VMX51		VMX51			2959
++abacus			MACH_ABACUS		ABACUS			2960
++cm4745			MACH_CM4745		CM4745			2961
++oratislink		MACH_ORATISLINK		ORATISLINK		2962
++davinci_dm365_dvr	MACH_DAVINCI_DM365_DVR	DAVINCI_DM365_DVR	2963
++netviz			MACH_NETVIZ		NETVIZ			2964
++flexibity		MACH_FLEXIBITY		FLEXIBITY		2965
++wlan_computer		MACH_WLAN_COMPUTER	WLAN_COMPUTER		2966
+diff -rupN linux-2.6.35.11/arch/arm/tools/mach-types.orig linux-2.6.35.11-ts7500/arch/arm/tools/mach-types.orig
+--- linux-2.6.35.11/arch/arm/tools/mach-types.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/arch/arm/tools/mach-types.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,2952 @@
++# Database of machine macros and numbers
++#
++# This file is linux/arch/arm/tools/mach-types
++#
++# Up to date versions of this file can be obtained from:
++#
++#   http://www.arm.linux.org.uk/developer/machines/download.php
++#
++# Please do not send patches to this file; it is automatically generated!
++# To add an entry into this database, please see Documentation/arm/README,
++# or visit:
++#
++#   http://www.arm.linux.org.uk/developer/machines/?action=new
++#
++# Last update: Mon Jul 12 21:10:14 2010
++#
++# machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
++#
++ebsa110			ARCH_EBSA110		EBSA110			0
++riscpc			ARCH_RPC		RISCPC			1
++nexuspci		ARCH_NEXUSPCI		NEXUSPCI		3
++ebsa285			ARCH_EBSA285		EBSA285			4
++netwinder		ARCH_NETWINDER		NETWINDER		5
++cats			ARCH_CATS		CATS			6
++tbox			ARCH_TBOX		TBOX			7
++co285			ARCH_CO285		CO285			8
++clps7110		ARCH_CLPS7110		CLPS7110		9
++archimedes		ARCH_ARC		ARCHIMEDES		10
++a5k			ARCH_A5K		A5K			11
++etoile			ARCH_ETOILE		ETOILE			12
++lacie_nas		ARCH_LACIE_NAS		LACIE_NAS		13
++clps7500		ARCH_CLPS7500		CLPS7500		14
++shark			ARCH_SHARK		SHARK			15
++brutus			SA1100_BRUTUS		BRUTUS			16
++personal_server		ARCH_PERSONAL_SERVER	PERSONAL_SERVER		17
++itsy			SA1100_ITSY		ITSY			18
++l7200			ARCH_L7200		L7200			19
++pleb			SA1100_PLEB		PLEB			20
++integrator		ARCH_INTEGRATOR		INTEGRATOR		21
++h3600			SA1100_H3600		H3600			22
++ixp1200			ARCH_IXP1200		IXP1200			23
++p720t			ARCH_P720T		P720T			24
++assabet			SA1100_ASSABET		ASSABET			25
++victor			SA1100_VICTOR		VICTOR			26
++lart			SA1100_LART		LART			27
++ranger			SA1100_RANGER		RANGER			28
++graphicsclient		SA1100_GRAPHICSCLIENT	GRAPHICSCLIENT		29
++xp860			SA1100_XP860		XP860			30
++cerf			SA1100_CERF		CERF			31
++nanoengine		SA1100_NANOENGINE	NANOENGINE		32
++fpic			SA1100_FPIC		FPIC			33
++extenex1		SA1100_EXTENEX1		EXTENEX1		34
++sherman			SA1100_SHERMAN		SHERMAN			35
++accelent_sa		SA1100_ACCELENT		ACCELENT_SA		36
++accelent_l7200		ARCH_L7200_ACCELENT	ACCELENT_L7200		37
++netport			SA1100_NETPORT		NETPORT			38
++pangolin		SA1100_PANGOLIN		PANGOLIN		39
++yopy			SA1100_YOPY		YOPY			40
++coolidge		SA1100_COOLIDGE		COOLIDGE		41
++huw_webpanel		SA1100_HUW_WEBPANEL	HUW_WEBPANEL		42
++spotme			ARCH_SPOTME		SPOTME			43
++freebird		ARCH_FREEBIRD		FREEBIRD		44
++ti925			ARCH_TI925		TI925			45
++riscstation		ARCH_RISCSTATION	RISCSTATION		46
++cavy			SA1100_CAVY		CAVY			47
++jornada720		SA1100_JORNADA720	JORNADA720		48
++omnimeter		SA1100_OMNIMETER	OMNIMETER		49
++edb7211			ARCH_EDB7211		EDB7211			50
++citygo			SA1100_CITYGO		CITYGO			51
++pfs168			SA1100_PFS168		PFS168			52
++spot			SA1100_SPOT		SPOT			53
++flexanet		SA1100_FLEXANET		FLEXANET		54
++webpal			ARCH_WEBPAL		WEBPAL			55
++linpda			SA1100_LINPDA		LINPDA			56
++anakin			ARCH_ANAKIN		ANAKIN			57
++mvi			SA1100_MVI		MVI			58
++jupiter			SA1100_JUPITER		JUPITER			59
++psionw			ARCH_PSIONW		PSIONW			60
++aln			SA1100_ALN		ALN			61
++epxa			ARCH_CAMELOT		CAMELOT			62
++gds2200			SA1100_GDS2200		GDS2200			63
++netbook			SA1100_PSION_SERIES7	PSION_SERIES7		64
++xfile			SA1100_XFILE		XFILE			65
++accelent_ep9312		ARCH_ACCELENT_EP9312	ACCELENT_EP9312		66
++ic200			ARCH_IC200		IC200			67
++creditlart		SA1100_CREDITLART	CREDITLART		68
++htm			SA1100_HTM		HTM			69
++iq80310			ARCH_IQ80310		IQ80310			70
++freebot			SA1100_FREEBOT		FREEBOT			71
++entel			ARCH_ENTEL		ENTEL			72
++enp3510			ARCH_ENP3510		ENP3510			73
++trizeps			SA1100_TRIZEPS		TRIZEPS			74
++nesa			SA1100_NESA		NESA			75
++venus			ARCH_VENUS		VENUS			76
++tardis			ARCH_TARDIS		TARDIS			77
++mercury			ARCH_MERCURY		MERCURY			78
++empeg			SA1100_EMPEG		EMPEG			79
++adi_evb			ARCH_I80200FCC		I80200FCC		80
++itt_cpb			SA1100_ITT_CPB		ITT_CPB			81
++svc			SA1100_SVC		SVC			82
++alpha2			SA1100_ALPHA2		ALPHA2			84
++alpha1			SA1100_ALPHA1		ALPHA1			85
++netarm			ARCH_NETARM		NETARM			86
++simpad			SA1100_SIMPAD		SIMPAD			87
++pda1			ARCH_PDA1		PDA1			88
++lubbock			ARCH_LUBBOCK		LUBBOCK			89
++aniko			ARCH_ANIKO		ANIKO			90
++clep7212		ARCH_CLEP7212		CLEP7212		91
++cs89712			ARCH_CS89712		CS89712			92
++weararm			SA1100_WEARARM		WEARARM			93
++possio_px		SA1100_POSSIO_PX	POSSIO_PX		94
++sidearm			SA1100_SIDEARM		SIDEARM			95
++stork			SA1100_STORK		STORK			96
++shannon			SA1100_SHANNON		SHANNON			97
++ace			ARCH_ACE		ACE			98
++ballyarm		SA1100_BALLYARM		BALLYARM		99
++simputer		SA1100_SIMPUTER		SIMPUTER		100
++nexterm			SA1100_NEXTERM		NEXTERM			101
++sa1100_elf		SA1100_SA1100_ELF	SA1100_ELF		102
++gator			SA1100_GATOR		GATOR			103
++granite			ARCH_GRANITE		GRANITE			104
++consus			SA1100_CONSUS		CONSUS			105
++aaed2000		ARCH_AAED2000		AAED2000		106
++cdb89712		ARCH_CDB89712		CDB89712		107
++graphicsmaster		SA1100_GRAPHICSMASTER	GRAPHICSMASTER		108
++adsbitsy		SA1100_ADSBITSY		ADSBITSY		109
++pxa_idp			ARCH_PXA_IDP		PXA_IDP			110
++plce			ARCH_PLCE		PLCE			111
++pt_system3		SA1100_PT_SYSTEM3	PT_SYSTEM3		112
++murphy			ARCH_MEDALB		MEDALB			113
++eagle			ARCH_EAGLE		EAGLE			114
++dsc21			ARCH_DSC21		DSC21			115
++dsc24			ARCH_DSC24		DSC24			116
++ti5472			ARCH_TI5472		TI5472			117
++autcpu12		ARCH_AUTCPU12		AUTCPU12		118
++uengine			ARCH_UENGINE		UENGINE			119
++bluestem		SA1100_BLUESTEM		BLUESTEM		120
++xingu8			ARCH_XINGU8		XINGU8			121
++bushstb			ARCH_BUSHSTB		BUSHSTB			122
++epsilon1		SA1100_EPSILON1		EPSILON1		123
++balloon			SA1100_BALLOON		BALLOON			124
++puppy			ARCH_PUPPY		PUPPY			125
++elroy			SA1100_ELROY		ELROY			126
++gms720			ARCH_GMS720		GMS720			127
++s24x			ARCH_S24X		S24X			128
++jtel_clep7312		ARCH_JTEL_CLEP7312	JTEL_CLEP7312		129
++cx821xx			ARCH_CX821XX		CX821XX			130
++edb7312			ARCH_EDB7312		EDB7312			131
++bsa1110			SA1100_BSA1110		BSA1110			132
++powerpin		ARCH_POWERPIN		POWERPIN		133
++openarm			ARCH_OPENARM		OPENARM			134
++whitechapel		SA1100_WHITECHAPEL	WHITECHAPEL		135
++h3100			SA1100_H3100		H3100			136
++h3800			SA1100_H3800		H3800			137
++blue_v1			ARCH_BLUE_V1		BLUE_V1			138
++pxa_cerf		ARCH_PXA_CERF		PXA_CERF		139
++arm7tevb		ARCH_ARM7TEVB		ARM7TEVB		140
++d7400			SA1100_D7400		D7400			141
++piranha			ARCH_PIRANHA		PIRANHA			142
++sbcamelot		SA1100_SBCAMELOT	SBCAMELOT		143
++kings			SA1100_KINGS		KINGS			144
++smdk2400		ARCH_SMDK2400		SMDK2400		145
++collie			SA1100_COLLIE		COLLIE			146
++idr			ARCH_IDR		IDR			147
++badge4			SA1100_BADGE4		BADGE4			148
++webnet			ARCH_WEBNET		WEBNET			149
++d7300			SA1100_D7300		D7300			150
++cep			SA1100_CEP		CEP			151
++fortunet		ARCH_FORTUNET		FORTUNET		152
++vc547x			ARCH_VC547X		VC547X			153
++filewalker		SA1100_FILEWALKER	FILEWALKER		154
++netgateway		SA1100_NETGATEWAY	NETGATEWAY		155
++symbol2800		SA1100_SYMBOL2800	SYMBOL2800		156
++suns			SA1100_SUNS		SUNS			157
++frodo			SA1100_FRODO		FRODO			158
++ms301			SA1100_MACH_TYTE_MS301	MACH_TYTE_MS301		159
++mx1ads			ARCH_MX1ADS		MX1ADS			160
++h7201			ARCH_H7201		H7201			161
++h7202			ARCH_H7202		H7202			162
++amico			ARCH_AMICO		AMICO			163
++iam			SA1100_IAM		IAM			164
++tt530			SA1100_TT530		TT530			165
++sam2400			ARCH_SAM2400		SAM2400			166
++jornada56x		SA1100_JORNADA56X	JORNADA56X		167
++active			SA1100_ACTIVE		ACTIVE			168
++iq80321			ARCH_IQ80321		IQ80321			169
++wid			SA1100_WID		WID			170
++sabinal			ARCH_SABINAL		SABINAL			171
++ixp425_matacumbe	ARCH_IXP425_MATACUMBE	IXP425_MATACUMBE	172
++miniprint		SA1100_MINIPRINT	MINIPRINT		173
++adm510x			ARCH_ADM510X		ADM510X			174
++svs200			SA1100_SVS200		SVS200			175
++atg_tcu			ARCH_ATG_TCU		ATG_TCU			176
++jornada820		SA1100_JORNADA820	JORNADA820		177
++s3c44b0			ARCH_S3C44B0		S3C44B0			178
++margis2			ARCH_MARGIS2		MARGIS2			179
++ks8695			ARCH_KS8695		KS8695			180
++brh			ARCH_BRH		BRH			181
++s3c2410			ARCH_S3C2410		S3C2410			182
++possio_px30		ARCH_POSSIO_PX30	POSSIO_PX30		183
++s3c2800			ARCH_S3C2800		S3C2800			184
++fleetwood		SA1100_FLEETWOOD	FLEETWOOD		185
++omaha			ARCH_OMAHA		OMAHA			186
++ta7			ARCH_TA7		TA7			187
++nova			SA1100_NOVA		NOVA			188
++hmk			ARCH_HMK		HMK			189
++karo			ARCH_KARO		KARO			190
++fester			SA1100_FESTER		FESTER			191
++gpi			ARCH_GPI		GPI			192
++smdk2410		ARCH_SMDK2410		SMDK2410		193
++i519			ARCH_I519		I519			194
++nexio			SA1100_NEXIO		NEXIO			195
++bitbox			SA1100_BITBOX		BITBOX			196
++g200			SA1100_G200		G200			197
++gill			SA1100_GILL		GILL			198
++pxa_mercury		ARCH_PXA_MERCURY	PXA_MERCURY		199
++ceiva			ARCH_CEIVA		CEIVA			200
++fret			SA1100_FRET		FRET			201
++emailphone		SA1100_EMAILPHONE	EMAILPHONE		202
++h3900			ARCH_H3900		H3900			203
++pxa1			ARCH_PXA1		PXA1			204
++koan369			SA1100_KOAN369		KOAN369			205
++cogent			ARCH_COGENT		COGENT			206
++esl_simputer		ARCH_ESL_SIMPUTER	ESL_SIMPUTER		207
++esl_simputer_clr	ARCH_ESL_SIMPUTER_CLR	ESL_SIMPUTER_CLR	208
++esl_simputer_bw		ARCH_ESL_SIMPUTER_BW	ESL_SIMPUTER_BW		209
++hhp_cradle		ARCH_HHP_CRADLE		HHP_CRADLE		210
++he500			ARCH_HE500		HE500			211
++inhandelf2		SA1100_INHANDELF2	INHANDELF2		212
++inhandftip		SA1100_INHANDFTIP	INHANDFTIP		213
++dnp1110			SA1100_DNP1110		DNP1110			214
++pnp1110			SA1100_PNP1110		PNP1110			215
++csb226			ARCH_CSB226		CSB226			216
++arnold			SA1100_ARNOLD		ARNOLD			217
++voiceblue		MACH_VOICEBLUE		VOICEBLUE		218
++jz8028			ARCH_JZ8028		JZ8028			219
++h5400			ARCH_H5400		H5400			220
++forte			SA1100_FORTE		FORTE			221
++acam			SA1100_ACAM		ACAM			222
++abox			SA1100_ABOX		ABOX			223
++atmel			ARCH_ATMEL		ATMEL			224
++sitsang			ARCH_SITSANG		SITSANG			225
++cpu1110lcdnet		SA1100_CPU1110LCDNET	CPU1110LCDNET		226
++mpl_vcma9		ARCH_MPL_VCMA9		MPL_VCMA9		227
++opus_a1			ARCH_OPUS_A1		OPUS_A1			228
++daytona			ARCH_DAYTONA		DAYTONA			229
++killbear		SA1100_KILLBEAR		KILLBEAR		230
++yoho			ARCH_YOHO		YOHO			231
++jasper			ARCH_JASPER		JASPER			232
++dsc25			ARCH_DSC25		DSC25			233
++omap_innovator		MACH_OMAP_INNOVATOR	OMAP_INNOVATOR		234
++mnci			ARCH_RAMSES		RAMSES			235
++s28x			ARCH_S28X		S28X			236
++mport3			ARCH_MPORT3		MPORT3			237
++pxa_eagle250		ARCH_PXA_EAGLE250	PXA_EAGLE250		238
++pdb			ARCH_PDB		PDB			239
++blue_2g			SA1100_BLUE_2G		BLUE_2G			240
++bluearch		SA1100_BLUEARCH		BLUEARCH		241
++ixdp2400		ARCH_IXDP2400		IXDP2400		242
++ixdp2800		ARCH_IXDP2800		IXDP2800		243
++explorer		SA1100_EXPLORER		EXPLORER		244
++ixdp425			ARCH_IXDP425		IXDP425			245
++chimp			ARCH_CHIMP		CHIMP			246
++stork_nest		ARCH_STORK_NEST		STORK_NEST		247
++stork_egg		ARCH_STORK_EGG		STORK_EGG		248
++wismo			SA1100_WISMO		WISMO			249
++ezlinx			ARCH_EZLINX		EZLINX			250
++at91rm9200		ARCH_AT91RM9200		AT91RM9200		251
++adtech_orion		ARCH_ADTECH_ORION	ADTECH_ORION		252
++neptune			ARCH_NEPTUNE		NEPTUNE			253
++hackkit			SA1100_HACKKIT		HACKKIT			254
++pxa_wins30		ARCH_PXA_WINS30		PXA_WINS30		255
++lavinna			SA1100_LAVINNA		LAVINNA			256
++pxa_uengine		ARCH_PXA_UENGINE	PXA_UENGINE		257
++innokom			ARCH_INNOKOM		INNOKOM			258
++bms			ARCH_BMS		BMS			259
++ixcdp1100		ARCH_IXCDP1100		IXCDP1100		260
++prpmc1100		ARCH_PRPMC1100		PRPMC1100		261
++at91rm9200dk		ARCH_AT91RM9200DK	AT91RM9200DK		262
++armstick		ARCH_ARMSTICK		ARMSTICK		263
++armonie			ARCH_ARMONIE		ARMONIE			264
++mport1			ARCH_MPORT1		MPORT1			265
++s3c5410			ARCH_S3C5410		S3C5410			266
++zcp320a			ARCH_ZCP320A		ZCP320A			267
++i_box			ARCH_I_BOX		I_BOX			268
++stlc1502		ARCH_STLC1502		STLC1502		269
++siren			ARCH_SIREN		SIREN			270
++greenlake		ARCH_GREENLAKE		GREENLAKE		271
++argus			ARCH_ARGUS		ARGUS			272
++combadge		SA1100_COMBADGE		COMBADGE		273
++rokepxa			ARCH_ROKEPXA		ROKEPXA			274
++cintegrator		ARCH_CINTEGRATOR	CINTEGRATOR		275
++guidea07		ARCH_GUIDEA07		GUIDEA07		276
++tat257			ARCH_TAT257		TAT257			277
++igp2425			ARCH_IGP2425		IGP2425			278
++bluegrama		ARCH_BLUEGRAMMA		BLUEGRAMMA		279
++ipod			ARCH_IPOD		IPOD			280
++adsbitsyx		ARCH_ADSBITSYX		ADSBITSYX		281
++trizeps2		ARCH_TRIZEPS2		TRIZEPS2		282
++viper			ARCH_VIPER		VIPER			283
++adsbitsyplus		SA1100_ADSBITSYPLUS	ADSBITSYPLUS		284
++adsagc			SA1100_ADSAGC		ADSAGC			285
++stp7312			ARCH_STP7312		STP7312			286
++nx_phnx			MACH_NX_PHNX		NX_PHNX			287
++wep_ep250		ARCH_WEP_EP250		WEP_EP250		288
++inhandelf3		ARCH_INHANDELF3		INHANDELF3		289
++adi_coyote		ARCH_ADI_COYOTE		ADI_COYOTE		290
++iyonix			ARCH_IYONIX		IYONIX			291
++damicam1		ARCH_DAMICAM_SA1110	DAMICAM_SA1110		292
++meg03			ARCH_MEG03		MEG03			293
++pxa_whitechapel		ARCH_PXA_WHITECHAPEL	PXA_WHITECHAPEL		294
++nwsc			ARCH_NWSC		NWSC			295
++nwlarm			ARCH_NWLARM		NWLARM			296
++ixp425_mguard		ARCH_IXP425_MGUARD	IXP425_MGUARD		297
++pxa_netdcu4		ARCH_PXA_NETDCU4	PXA_NETDCU4		298
++ixdp2401		ARCH_IXDP2401		IXDP2401		299
++ixdp2801		ARCH_IXDP2801		IXDP2801		300
++zodiac			ARCH_ZODIAC		ZODIAC			301
++armmodul		ARCH_ARMMODUL		ARMMODUL		302
++ketop			SA1100_KETOP		KETOP			303
++av7200			ARCH_AV7200		AV7200			304
++arch_ti925		ARCH_ARCH_TI925		ARCH_TI925		305
++acq200			ARCH_ACQ200		ACQ200			306
++pt_dafit		SA1100_PT_DAFIT		PT_DAFIT		307
++ihba			ARCH_IHBA		IHBA			308
++quinque			ARCH_QUINQUE		QUINQUE			309
++nimbraone		ARCH_NIMBRAONE		NIMBRAONE		310
++nimbra29x		ARCH_NIMBRA29X		NIMBRA29X		311
++nimbra210		ARCH_NIMBRA210		NIMBRA210		312
++hhp_d95xx		ARCH_HHP_D95XX		HHP_D95XX		313
++labarm			ARCH_LABARM		LABARM			314
++m825xx			ARCH_M825XX		M825XX			315
++m7100			SA1100_M7100		M7100			316
++nipc2			ARCH_NIPC2		NIPC2			317
++fu7202			ARCH_FU7202		FU7202			318
++adsagx			ARCH_ADSAGX		ADSAGX			319
++pxa_pooh		ARCH_PXA_POOH		PXA_POOH		320
++bandon			ARCH_BANDON		BANDON			321
++pcm7210			ARCH_PCM7210		PCM7210			322
++nms9200			ARCH_NMS9200		NMS9200			323
++logodl			ARCH_LOGODL		LOGODL			324
++m7140			SA1100_M7140		M7140			325
++korebot			ARCH_KOREBOT		KOREBOT			326
++iq31244			ARCH_IQ31244		IQ31244			327
++koan393			SA1100_KOAN393		KOAN393			328
++inhandftip3		ARCH_INHANDFTIP3	INHANDFTIP3		329
++gonzo			ARCH_GONZO		GONZO			330
++bast			ARCH_BAST		BAST			331
++scanpass		ARCH_SCANPASS		SCANPASS		332
++ep7312_pooh		ARCH_EP7312_POOH	EP7312_POOH		333
++ta7s			ARCH_TA7S		TA7S			334
++ta7v			ARCH_TA7V		TA7V			335
++icarus			SA1100_ICARUS		ICARUS			336
++h1900			ARCH_H1900		H1900			337
++gemini			SA1100_GEMINI		GEMINI			338
++axim			ARCH_AXIM		AXIM			339
++audiotron		ARCH_AUDIOTRON		AUDIOTRON		340
++h2200			ARCH_H2200		H2200			341
++loox600			ARCH_LOOX600		LOOX600			342
++niop			ARCH_NIOP		NIOP			343
++dm310			ARCH_DM310		DM310			344
++seedpxa_c2		ARCH_SEEDPXA_C2		SEEDPXA_C2		345
++ixp4xx_mguardpci	ARCH_IXP4XX_MGUARD_PCI	IXP4XX_MGUARD_PCI	346
++h1940			ARCH_H1940		H1940			347
++scorpio			ARCH_SCORPIO		SCORPIO			348
++viva			ARCH_VIVA		VIVA			349
++pxa_xcard		ARCH_PXA_XCARD		PXA_XCARD		350
++csb335			ARCH_CSB335		CSB335			351
++ixrd425			ARCH_IXRD425		IXRD425			352
++iq80315			ARCH_IQ80315		IQ80315			353
++nmp7312			ARCH_NMP7312		NMP7312			354
++cx861xx			ARCH_CX861XX		CX861XX			355
++enp2611			ARCH_ENP2611		ENP2611			356
++xda			SA1100_XDA		XDA			357
++csir_ims		ARCH_CSIR_IMS		CSIR_IMS		358
++ixp421_dnaeeth		ARCH_IXP421_DNAEETH	IXP421_DNAEETH		359
++pocketserv9200		ARCH_POCKETSERV9200	POCKETSERV9200		360
++toto			ARCH_TOTO		TOTO			361
++s3c2440			ARCH_S3C2440		S3C2440			362
++ks8695p			ARCH_KS8695P		KS8695P			363
++se4000			ARCH_SE4000		SE4000			364
++quadriceps		ARCH_QUADRICEPS		QUADRICEPS		365
++bronco			ARCH_BRONCO		BRONCO			366
++esl_wireless_tab	ARCH_ESL_WIRELESS_TAB	ESL_WIRELESS_TAB	367
++esl_sofcomp		ARCH_ESL_SOFCOMP	ESL_SOFCOMP		368
++s5c7375			ARCH_S5C7375		S5C7375			369
++spearhead		ARCH_SPEARHEAD		SPEARHEAD		370
++pantera			ARCH_PANTERA		PANTERA			371
++prayoglite		ARCH_PRAYOGLITE		PRAYOGLITE		372
++gumstix			ARCH_GUMSTIX		GUMSTIX			373
++rcube			ARCH_RCUBE		RCUBE			374
++rea_olv			ARCH_REA_OLV		REA_OLV			375
++pxa_iphone		ARCH_PXA_IPHONE		PXA_IPHONE		376
++s3c3410			ARCH_S3C3410		S3C3410			377
++espd_4510b		ARCH_ESPD_4510B		ESPD_4510B		378
++mp1x			ARCH_MP1X		MP1X			379
++at91rm9200tb		ARCH_AT91RM9200TB	AT91RM9200TB		380
++adsvgx			ARCH_ADSVGX		ADSVGX			381
++omap_h2			MACH_OMAP_H2		OMAP_H2			382
++pelee			ARCH_PELEE		PELEE			383
++e740			MACH_E740		E740			384
++iq80331			ARCH_IQ80331		IQ80331			385
++versatile_pb		ARCH_VERSATILE_PB	VERSATILE_PB		387
++kev7a400		MACH_KEV7A400		KEV7A400		388
++lpd7a400		MACH_LPD7A400		LPD7A400		389
++lpd7a404		MACH_LPD7A404		LPD7A404		390
++fujitsu_camelot		ARCH_FUJITSU_CAMELOT	FUJITSU_CAMELOT		391
++janus2m			ARCH_JANUS2M		JANUS2M			392
++embtf			MACH_EMBTF		EMBTF			393
++hpm			MACH_HPM		HPM			394
++smdk2410tk		MACH_SMDK2410TK		SMDK2410TK		395
++smdk2410aj		MACH_SMDK2410AJ		SMDK2410AJ		396
++streetracer		MACH_STREETRACER	STREETRACER		397
++eframe			MACH_EFRAME		EFRAME			398
++csb337			MACH_CSB337		CSB337			399
++pxa_lark		MACH_PXA_LARK		PXA_LARK		400
++pxa_pnp2110		MACH_PNP2110		PNP2110			401
++tcc72x			MACH_TCC72X		TCC72X			402
++altair			MACH_ALTAIR		ALTAIR			403
++kc3			MACH_KC3		KC3			404
++sinteftd		MACH_SINTEFTD		SINTEFTD		405
++mainstone		MACH_MAINSTONE		MAINSTONE		406
++aday4x			MACH_ADAY4X		ADAY4X			407
++lite300			MACH_LITE300		LITE300			408
++s5c7376			MACH_S5C7376		S5C7376			409
++mt02			MACH_MT02		MT02			410
++mport3s			MACH_MPORT3S		MPORT3S			411
++ra_alpha		MACH_RA_ALPHA		RA_ALPHA		412
++xcep			MACH_XCEP		XCEP			413
++arcom_vulcan		MACH_ARCOM_VULCAN	ARCOM_VULCAN		414
++stargate		MACH_STARGATE		STARGATE		415
++armadilloj		MACH_ARMADILLOJ		ARMADILLOJ		416
++elroy_jack		MACH_ELROY_JACK		ELROY_JACK		417
++backend			MACH_BACKEND		BACKEND			418
++s5linbox		MACH_S5LINBOX		S5LINBOX		419
++nomadik			MACH_NOMADIK		NOMADIK			420
++ia_cpu_9200		MACH_IA_CPU_9200	IA_CPU_9200		421
++at91_bja1		MACH_AT91_BJA1		AT91_BJA1		422
++corgi			MACH_CORGI		CORGI			423
++poodle			MACH_POODLE		POODLE			424
++ten			MACH_TEN		TEN			425
++roverp5p		MACH_ROVERP5P		ROVERP5P		426
++sc2700			MACH_SC2700		SC2700			427
++ex_eagle		MACH_EX_EAGLE		EX_EAGLE		428
++nx_pxa12		MACH_NX_PXA12		NX_PXA12		429
++nx_pxa5			MACH_NX_PXA5		NX_PXA5			430
++blackboard2		MACH_BLACKBOARD2	BLACKBOARD2		431
++i819			MACH_I819		I819			432
++ixmb995e		MACH_IXMB995E		IXMB995E		433
++skyrider		MACH_SKYRIDER		SKYRIDER		434
++skyhawk			MACH_SKYHAWK		SKYHAWK			435
++enterprise		MACH_ENTERPRISE		ENTERPRISE		436
++dep2410			MACH_DEP2410		DEP2410			437
++armcore			MACH_ARMCORE		ARMCORE			438
++hobbit			MACH_HOBBIT		HOBBIT			439
++h7210			MACH_H7210		H7210			440
++pxa_netdcu5		MACH_PXA_NETDCU5	PXA_NETDCU5		441
++acc			MACH_ACC		ACC			442
++esl_sarva		MACH_ESL_SARVA		ESL_SARVA		443
++xm250			MACH_XM250		XM250			444
++t6tc1xb			MACH_T6TC1XB		T6TC1XB			445
++ess710			MACH_ESS710		ESS710			446
++mx31ads			MACH_MX31ADS		MX31ADS			447
++himalaya		MACH_HIMALAYA		HIMALAYA		448
++bolfenk			MACH_BOLFENK		BOLFENK			449
++at91rm9200kr		MACH_AT91RM9200KR	AT91RM9200KR		450
++edb9312			MACH_EDB9312		EDB9312			451
++omap_generic		MACH_OMAP_GENERIC	OMAP_GENERIC		452
++aximx3			MACH_AXIMX3		AXIMX3			453
++eb67xdip		MACH_EB67XDIP		EB67XDIP		454
++webtxs			MACH_WEBTXS		WEBTXS			455
++hawk			MACH_HAWK		HAWK			456
++ccat91sbc001		MACH_CCAT91SBC001	CCAT91SBC001		457
++expresso		MACH_EXPRESSO		EXPRESSO		458
++h4000			MACH_H4000		H4000			459
++dino			MACH_DINO		DINO			460
++ml675k			MACH_ML675K		ML675K			461
++edb9301			MACH_EDB9301		EDB9301			462
++edb9315			MACH_EDB9315		EDB9315			463
++reciva_tt		MACH_RECIVA_TT		RECIVA_TT		464
++cstcb01			MACH_CSTCB01		CSTCB01			465
++cstcb1			MACH_CSTCB1		CSTCB1			466
++shadwell		MACH_SHADWELL		SHADWELL		467
++goepel263		MACH_GOEPEL263		GOEPEL263		468
++acq100			MACH_ACQ100		ACQ100			469
++mx1fs2			MACH_MX1FS2		MX1FS2			470
++hiptop_g1		MACH_HIPTOP_G1		HIPTOP_G1		471
++sparky			MACH_SPARKY		SPARKY			472
++ns9750			MACH_NS9750		NS9750			473
++phoenix			MACH_PHOENIX		PHOENIX			474
++vr1000			MACH_VR1000		VR1000			475
++deisterpxa		MACH_DEISTERPXA		DEISTERPXA		476
++bcm1160			MACH_BCM1160		BCM1160			477
++pcm022			MACH_PCM022		PCM022			478
++adsgcx			MACH_ADSGCX		ADSGCX			479
++dreadnaught		MACH_DREADNAUGHT	DREADNAUGHT		480
++dm320			MACH_DM320		DM320			481
++markov			MACH_MARKOV		MARKOV			482
++cos7a400		MACH_COS7A400		COS7A400		483
++milano			MACH_MILANO		MILANO			484
++ue9328			MACH_UE9328		UE9328			485
++uex255			MACH_UEX255		UEX255			486
++ue2410			MACH_UE2410		UE2410			487
++a620			MACH_A620		A620			488
++ocelot			MACH_OCELOT		OCELOT			489
++cheetah			MACH_CHEETAH		CHEETAH			490
++omap_perseus2		MACH_OMAP_PERSEUS2	OMAP_PERSEUS2		491
++zvue			MACH_ZVUE		ZVUE			492
++roverp1			MACH_ROVERP1		ROVERP1			493
++asidial2		MACH_ASIDIAL2		ASIDIAL2		494
++s3c24a0			MACH_S3C24A0		S3C24A0			495
++e800			MACH_E800		E800			496
++e750			MACH_E750		E750			497
++s3c5500			MACH_S3C5500		S3C5500			498
++smdk5500		MACH_SMDK5500		SMDK5500		499
++signalsync		MACH_SIGNALSYNC		SIGNALSYNC		500
++nbc			MACH_NBC		NBC			501
++kodiak			MACH_KODIAK		KODIAK			502
++netbookpro		MACH_NETBOOKPRO		NETBOOKPRO		503
++hw90200			MACH_HW90200		HW90200			504
++condor			MACH_CONDOR		CONDOR			505
++cup			MACH_CUP		CUP			506
++kite			MACH_KITE		KITE			507
++scb9328			MACH_SCB9328		SCB9328			508
++omap_h3			MACH_OMAP_H3		OMAP_H3			509
++omap_h4			MACH_OMAP_H4		OMAP_H4			510
++n10			MACH_N10		N10			511
++montejade		MACH_MONTAJADE		MONTAJADE		512
++sg560			MACH_SG560		SG560			513
++dp1000			MACH_DP1000		DP1000			514
++omap_osk		MACH_OMAP_OSK		OMAP_OSK		515
++rg100v3			MACH_RG100V3		RG100V3			516
++mx2ads			MACH_MX2ADS		MX2ADS			517
++pxa_kilo		MACH_PXA_KILO		PXA_KILO		518
++ixp4xx_eagle		MACH_IXP4XX_EAGLE	IXP4XX_EAGLE		519
++tosa			MACH_TOSA		TOSA			520
++mb2520f			MACH_MB2520F		MB2520F			521
++emc1000			MACH_EMC1000		EMC1000			522
++tidsc25			MACH_TIDSC25		TIDSC25			523
++akcpmxl			MACH_AKCPMXL		AKCPMXL			524
++av3xx			MACH_AV3XX		AV3XX			525
++avila			MACH_AVILA		AVILA			526
++pxa_mpm10		MACH_PXA_MPM10		PXA_MPM10		527
++pxa_kyanite		MACH_PXA_KYANITE	PXA_KYANITE		528
++sgold			MACH_SGOLD		SGOLD			529
++oscar			MACH_OSCAR		OSCAR			530
++epxa4usb2		MACH_EPXA4USB2		EPXA4USB2		531
++xsengine		MACH_XSENGINE		XSENGINE		532
++ip600			MACH_IP600		IP600			533
++mcan2			MACH_MCAN2		MCAN2			534
++ddi_blueridge		MACH_DDI_BLUERIDGE	DDI_BLUERIDGE		535
++skyminder		MACH_SKYMINDER		SKYMINDER		536
++lpd79520		MACH_LPD79520		LPD79520		537
++edb9302			MACH_EDB9302		EDB9302			538
++hw90340			MACH_HW90340		HW90340			539
++cip_box			MACH_CIP_BOX		CIP_BOX			540
++ivpn			MACH_IVPN		IVPN			541
++rsoc2			MACH_RSOC2		RSOC2			542
++husky			MACH_HUSKY		HUSKY			543
++boxer			MACH_BOXER		BOXER			544
++shepherd		MACH_SHEPHERD		SHEPHERD		545
++aml42800aa		MACH_AML42800AA		AML42800AA		546
++lpc2294			MACH_LPC2294		LPC2294			548
++switchgrass		MACH_SWITCHGRASS	SWITCHGRASS		549
++ens_cmu			MACH_ENS_CMU		ENS_CMU			550
++mm6_sdb			MACH_MM6_SDB		MM6_SDB			551
++saturn			MACH_SATURN		SATURN			552
++i30030evb		MACH_I30030EVB		I30030EVB		553
++mxc27530evb		MACH_MXC27530EVB	MXC27530EVB		554
++smdk2800		MACH_SMDK2800		SMDK2800		555
++mtwilson		MACH_MTWILSON		MTWILSON		556
++ziti			MACH_ZITI		ZITI			557
++grandfather		MACH_GRANDFATHER	GRANDFATHER		558
++tengine			MACH_TENGINE		TENGINE			559
++s3c2460			MACH_S3C2460		S3C2460			560
++pdm			MACH_PDM		PDM			561
++h4700			MACH_H4700		H4700			562
++h6300			MACH_H6300		H6300			563
++rz1700			MACH_RZ1700		RZ1700			564
++a716			MACH_A716		A716			565
++estk2440a		MACH_ESTK2440A		ESTK2440A		566
++atwixp425		MACH_ATWIXP425		ATWIXP425		567
++csb336			MACH_CSB336		CSB336			568
++rirm2			MACH_RIRM2		RIRM2			569
++cx23518			MACH_CX23518		CX23518			570
++cx2351x			MACH_CX2351X		CX2351X			571
++computime		MACH_COMPUTIME		COMPUTIME		572
++izarus			MACH_IZARUS		IZARUS			573
++pxa_rts			MACH_RTS		RTS			574
++se5100			MACH_SE5100		SE5100			575
++s3c2510			MACH_S3C2510		S3C2510			576
++csb437tl		MACH_CSB437TL		CSB437TL		577
++slauson			MACH_SLAUSON		SLAUSON			578
++pearlriver		MACH_PEARLRIVER		PEARLRIVER		579
++tdc_p210		MACH_TDC_P210		TDC_P210		580
++sg580			MACH_SG580		SG580			581
++wrsbcarm7		MACH_WRSBCARM7		WRSBCARM7		582
++ipd			MACH_IPD		IPD			583
++pxa_dnp2110		MACH_PXA_DNP2110	PXA_DNP2110		584
++xaeniax			MACH_XAENIAX		XAENIAX			585
++somn4250		MACH_SOMN4250		SOMN4250		586
++pleb2			MACH_PLEB2		PLEB2			587
++cornwallis		MACH_CORNWALLIS		CORNWALLIS		588
++gurney_drv		MACH_GURNEY_DRV		GURNEY_DRV		589
++chaffee			MACH_CHAFFEE		CHAFFEE			590
++rms101			MACH_RMS101		RMS101			591
++rx3715			MACH_RX3715		RX3715			592
++swift			MACH_SWIFT		SWIFT			593
++roverp7			MACH_ROVERP7		ROVERP7			594
++pr818s			MACH_PR818S		PR818S			595
++trxpro			MACH_TRXPRO		TRXPRO			596
++nslu2			MACH_NSLU2		NSLU2			597
++e400			MACH_E400		E400			598
++trab			MACH_TRAB		TRAB			599
++cmc_pu2			MACH_CMC_PU2		CMC_PU2			600
++fulcrum			MACH_FULCRUM		FULCRUM			601
++netgate42x		MACH_NETGATE42X		NETGATE42X		602
++str710			MACH_STR710		STR710			603
++ixdpg425		MACH_IXDPG425		IXDPG425		604
++tomtomgo		MACH_TOMTOMGO		TOMTOMGO		605
++versatile_ab		MACH_VERSATILE_AB	VERSATILE_AB		606
++edb9307			MACH_EDB9307		EDB9307			607
++sg565			MACH_SG565		SG565			608
++lpd79524		MACH_LPD79524		LPD79524		609
++lpd79525		MACH_LPD79525		LPD79525		610
++rms100			MACH_RMS100		RMS100			611
++kb9200			MACH_KB9200		KB9200			612
++sx1			MACH_SX1		SX1			613
++hms39c7092		MACH_HMS39C7092		HMS39C7092		614
++armadillo		MACH_ARMADILLO		ARMADILLO		615
++ipcu			MACH_IPCU		IPCU			616
++loox720			MACH_LOOX720		LOOX720			617
++ixdp465			MACH_IXDP465		IXDP465			618
++ixdp2351		MACH_IXDP2351		IXDP2351		619
++adsvix			MACH_ADSVIX		ADSVIX			620
++dm270			MACH_DM270		DM270			621
++socltplus		MACH_SOCLTPLUS		SOCLTPLUS		622
++ecia			MACH_ECIA		ECIA			623
++cm4008			MACH_CM4008		CM4008			624
++p2001			MACH_P2001		P2001			625
++twister			MACH_TWISTER		TWISTER			626
++mudshark		MACH_MUDSHARK		MUDSHARK		627
++hb2			MACH_HB2		HB2			628
++iq80332			MACH_IQ80332		IQ80332			629
++sendt			MACH_SENDT		SENDT			630
++mx2jazz			MACH_MX2JAZZ		MX2JAZZ			631
++multiio			MACH_MULTIIO		MULTIIO			632
++hrdisplay		MACH_HRDISPLAY		HRDISPLAY		633
++mxc27530ads		MACH_MXC27530ADS	MXC27530ADS		634
++trizeps3		MACH_TRIZEPS3		TRIZEPS3		635
++zefeerdza		MACH_ZEFEERDZA		ZEFEERDZA		636
++zefeerdzb		MACH_ZEFEERDZB		ZEFEERDZB		637
++zefeerdzg		MACH_ZEFEERDZG		ZEFEERDZG		638
++zefeerdzn		MACH_ZEFEERDZN		ZEFEERDZN		639
++zefeerdzq		MACH_ZEFEERDZQ		ZEFEERDZQ		640
++gtwx5715		MACH_GTWX5715		GTWX5715		641
++astro_jack		MACH_ASTRO_JACK		ASTRO_JACK		643
++tip03			MACH_TIP03		TIP03			644
++a9200ec			MACH_A9200EC		A9200EC			645
++pnx0105			MACH_PNX0105		PNX0105			646
++adcpoecpu		MACH_ADCPOECPU		ADCPOECPU		647
++csb637			MACH_CSB637		CSB637			648
++mb9200			MACH_MB9200		MB9200			650
++kulun			MACH_KULUN		KULUN			651
++snapper			MACH_SNAPPER		SNAPPER			652
++optima			MACH_OPTIMA		OPTIMA			653
++dlhsbc			MACH_DLHSBC		DLHSBC			654
++x30			MACH_X30		X30			655
++n30			MACH_N30		N30			656
++manga_ks8695		MACH_MANGA_KS8695	MANGA_KS8695		657
++ajax			MACH_AJAX		AJAX			658
++nec_mp900		MACH_NEC_MP900		NEC_MP900		659
++vvtk1000		MACH_VVTK1000		VVTK1000		661
++kafa			MACH_KAFA		KAFA			662
++vvtk3000		MACH_VVTK3000		VVTK3000		663
++pimx1			MACH_PIMX1		PIMX1			664
++ollie			MACH_OLLIE		OLLIE			665
++skymax			MACH_SKYMAX		SKYMAX			666
++jazz			MACH_JAZZ		JAZZ			667
++tel_t3			MACH_TEL_T3		TEL_T3			668
++aisino_fcr255		MACH_AISINO_FCR255	AISINO_FCR255		669
++btweb			MACH_BTWEB		BTWEB			670
++dbg_lh79520		MACH_DBG_LH79520	DBG_LH79520		671
++cm41xx			MACH_CM41XX		CM41XX			672
++ts72xx			MACH_TS72XX		TS72XX			673
++nggpxa			MACH_NGGPXA		NGGPXA			674
++csb535			MACH_CSB535		CSB535			675
++csb536			MACH_CSB536		CSB536			676
++pxa_trakpod		MACH_PXA_TRAKPOD	PXA_TRAKPOD		677
++praxis			MACH_PRAXIS		PRAXIS			678
++lh75411			MACH_LH75411		LH75411			679
++otom			MACH_OTOM		OTOM			680
++nexcoder_2440		MACH_NEXCODER_2440	NEXCODER_2440		681
++loox410			MACH_LOOX410		LOOX410			682
++westlake		MACH_WESTLAKE		WESTLAKE		683
++nsb			MACH_NSB		NSB			684
++esl_sarva_stn		MACH_ESL_SARVA_STN	ESL_SARVA_STN		685
++esl_sarva_tft		MACH_ESL_SARVA_TFT	ESL_SARVA_TFT		686
++esl_sarva_iad		MACH_ESL_SARVA_IAD	ESL_SARVA_IAD		687
++esl_sarva_acc		MACH_ESL_SARVA_ACC	ESL_SARVA_ACC		688
++typhoon			MACH_TYPHOON		TYPHOON			689
++cnav			MACH_CNAV		CNAV			690
++a730			MACH_A730		A730			691
++netstar			MACH_NETSTAR		NETSTAR			692
++supercon		MACH_PHASEFALE_SUPERCON	PHASEFALE_SUPERCON	693
++shiva1100		MACH_SHIVA1100		SHIVA1100		694
++etexsc			MACH_ETEXSC		ETEXSC			695
++ixdpg465		MACH_IXDPG465		IXDPG465		696
++a9m2410			MACH_A9M2410		A9M2410			697
++a9m2440			MACH_A9M2440		A9M2440			698
++a9m9750			MACH_A9M9750		A9M9750			699
++a9m9360			MACH_A9M9360		A9M9360			700
++unc90			MACH_UNC90		UNC90			701
++eco920			MACH_ECO920		ECO920			702
++satview			MACH_SATVIEW		SATVIEW			703
++roadrunner		MACH_ROADRUNNER		ROADRUNNER		704
++at91rm9200ek		MACH_AT91RM9200EK	AT91RM9200EK		705
++gp32			MACH_GP32		GP32			706
++gem			MACH_GEM		GEM			707
++i858			MACH_I858		I858			708
++hx2750			MACH_HX2750		HX2750			709
++mxc91131evb		MACH_MXC91131EVB	MXC91131EVB		710
++p700			MACH_P700		P700			711
++cpe			MACH_CPE		CPE			712
++spitz			MACH_SPITZ		SPITZ			713
++nimbra340		MACH_NIMBRA340		NIMBRA340		714
++lpc22xx			MACH_LPC22XX		LPC22XX			715
++omap_comet3		MACH_COMET3		COMET3			716
++omap_comet4		MACH_COMET4		COMET4			717
++csb625			MACH_CSB625		CSB625			718
++fortunet2		MACH_FORTUNET2		FORTUNET2		719
++s5h2200			MACH_S5H2200		S5H2200			720
++optorm920		MACH_OPTORM920		OPTORM920		721
++adsbitsyxb		MACH_ADSBITSYXB		ADSBITSYXB		722
++adssphere		MACH_ADSSPHERE		ADSSPHERE		723
++adsportal		MACH_ADSPORTAL		ADSPORTAL		724
++ln2410sbc		MACH_LN2410SBC		LN2410SBC		725
++cb3rufc			MACH_CB3RUFC		CB3RUFC			726
++mp2usb			MACH_MP2USB		MP2USB			727
++ntnp425c		MACH_NTNP425C		NTNP425C		728
++colibri			MACH_COLIBRI		COLIBRI			729
++pcm7220			MACH_PCM7220		PCM7220			730
++gateway7001		MACH_GATEWAY7001	GATEWAY7001		731
++pcm027			MACH_PCM027		PCM027			732
++cmpxa			MACH_CMPXA		CMPXA			733
++anubis			MACH_ANUBIS		ANUBIS			734
++ite8152			MACH_ITE8152		ITE8152			735
++lpc3xxx			MACH_LPC3XXX		LPC3XXX			736
++puppeteer		MACH_PUPPETEER		PUPPETEER		737
++e570			MACH_E570		E570			739
++x50			MACH_X50		X50			740
++recon			MACH_RECON		RECON			741
++xboardgp8		MACH_XBOARDGP8		XBOARDGP8		742
++fpic2			MACH_FPIC2		FPIC2			743
++akita			MACH_AKITA		AKITA			744
++a81			MACH_A81		A81			745
++svm_sc25x		MACH_SVM_SC25X		SVM_SC25X		746
++vt020			MACH_VADATECH020	VADATECH020		747
++tli			MACH_TLI		TLI			748
++edb9315lc		MACH_EDB9315LC		EDB9315LC		749
++passec			MACH_PASSEC		PASSEC			750
++ds_tiger		MACH_DS_TIGER		DS_TIGER		751
++e310			MACH_E310		E310			752
++e330			MACH_E330		E330			753
++rt3000			MACH_RT3000		RT3000			754
++nokia770		MACH_NOKIA770		NOKIA770		755
++pnx0106			MACH_PNX0106		PNX0106			756
++hx21xx			MACH_HX21XX		HX21XX			757
++faraday			MACH_FARADAY		FARADAY			758
++sbc9312			MACH_SBC9312		SBC9312			759
++batman			MACH_BATMAN		BATMAN			760
++jpd201			MACH_JPD201		JPD201			761
++mipsa			MACH_MIPSA		MIPSA			762
++kacom			MACH_KACOM		KACOM			763
++swarcocpu		MACH_SWARCOCPU		SWARCOCPU		764
++swarcodsl		MACH_SWARCODSL		SWARCODSL		765
++blueangel		MACH_BLUEANGEL		BLUEANGEL		766
++hairygrama		MACH_HAIRYGRAMA		HAIRYGRAMA		767
++banff			MACH_BANFF		BANFF			768
++carmeva			MACH_CARMEVA		CARMEVA			769
++sam255			MACH_SAM255		SAM255			770
++ppm10			MACH_PPM10		PPM10			771
++edb9315a		MACH_EDB9315A		EDB9315A		772
++sunset			MACH_SUNSET		SUNSET			773
++stargate2		MACH_STARGATE2		STARGATE2		774
++intelmote2		MACH_INTELMOTE2		INTELMOTE2		775
++trizeps4		MACH_TRIZEPS4		TRIZEPS4		776
++mainstone2		MACH_MAINSTONE2		MAINSTONE2		777
++ez_ixp42x		MACH_EZ_IXP42X		EZ_IXP42X		778
++tapwave_zodiac		MACH_TAPWAVE_ZODIAC	TAPWAVE_ZODIAC		779
++universalmeter		MACH_UNIVERSALMETER	UNIVERSALMETER		780
++hicoarm9		MACH_HICOARM9		HICOARM9		781
++pnx4008			MACH_PNX4008		PNX4008			782
++kws6000			MACH_KWS6000		KWS6000			783
++portux920t		MACH_PORTUX920T		PORTUX920T		784
++ez_x5			MACH_EZ_X5		EZ_X5			785
++omap_rudolph		MACH_OMAP_RUDOLPH	OMAP_RUDOLPH		786
++cpuat91			MACH_CPUAT91		CPUAT91			787
++rea9200			MACH_REA9200		REA9200			788
++acts_pune_sa1110	MACH_ACTS_PUNE_SA1110	ACTS_PUNE_SA1110	789
++ixp425			MACH_IXP425		IXP425			790
++i30030ads		MACH_I30030ADS		I30030ADS		791
++perch			MACH_PERCH		PERCH			792
++eis05r1			MACH_EIS05R1		EIS05R1			793
++pepperpad		MACH_PEPPERPAD		PEPPERPAD		794
++sb3010			MACH_SB3010		SB3010			795
++rm9200			MACH_RM9200		RM9200			796
++dma03			MACH_DMA03		DMA03			797
++road_s101		MACH_ROAD_S101		ROAD_S101		798
++iq81340sc		MACH_IQ81340SC		IQ81340SC		799
++iq_nextgen_b		MACH_IQ_NEXTGEN_B	IQ_NEXTGEN_B		800
++iq81340mc		MACH_IQ81340MC		IQ81340MC		801
++iq_nextgen_d		MACH_IQ_NEXTGEN_D	IQ_NEXTGEN_D		802
++iq_nextgen_e		MACH_IQ_NEXTGEN_E	IQ_NEXTGEN_E		803
++mallow_at91		MACH_MALLOW_AT91	MALLOW_AT91		804
++cybertracker_i		MACH_CYBERTRACKER_I	CYBERTRACKER_I		805
++gesbc931x		MACH_GESBC931X		GESBC931X		806
++centipad		MACH_CENTIPAD		CENTIPAD		807
++armsoc			MACH_ARMSOC		ARMSOC			808
++se4200			MACH_SE4200		SE4200			809
++ems197a			MACH_EMS197A		EMS197A			810
++micro9			MACH_MICRO9		MICRO9			811
++micro9l			MACH_MICRO9L		MICRO9L			812
++uc5471dsp		MACH_UC5471DSP		UC5471DSP		813
++sj5471eng		MACH_SJ5471ENG		SJ5471ENG		814
++none			MACH_CMPXA26X		CMPXA26X		815
++nc1			MACH_NC			NC			816
++omap_palmte		MACH_OMAP_PALMTE	OMAP_PALMTE		817
++ajax52x			MACH_AJAX52X		AJAX52X			818
++siriustar		MACH_SIRIUSTAR		SIRIUSTAR		819
++iodata_hdlg		MACH_IODATA_HDLG	IODATA_HDLG		820
++at91rm9200utl		MACH_AT91RM9200UTL	AT91RM9200UTL		821
++biosafe			MACH_BIOSAFE		BIOSAFE			822
++mp1000			MACH_MP1000		MP1000			823
++parsy			MACH_PARSY		PARSY			824
++ccxp270			MACH_CCXP		CCXP			825
++omap_gsample		MACH_OMAP_GSAMPLE	OMAP_GSAMPLE		826
++realview_eb		MACH_REALVIEW_EB	REALVIEW_EB		827
++samoa			MACH_SAMOA		SAMOA			828
++palmt3			MACH_PALMT3		PALMT3			829
++i878			MACH_I878		I878			830
++borzoi			MACH_BORZOI		BORZOI			831
++gecko			MACH_GECKO		GECKO			832
++ds101			MACH_DS101		DS101			833
++omap_palmtt2		MACH_OMAP_PALMTT2	OMAP_PALMTT2		834
++palmld			MACH_PALMLD		PALMLD			835
++cc9c			MACH_CC9C		CC9C			836
++sbc1670			MACH_SBC1670		SBC1670			837
++ixdp28x5		MACH_IXDP28X5		IXDP28X5		838
++omap_palmtt		MACH_OMAP_PALMTT	OMAP_PALMTT		839
++ml696k			MACH_ML696K		ML696K			840
++arcom_zeus		MACH_ARCOM_ZEUS		ARCOM_ZEUS		841
++osiris			MACH_OSIRIS		OSIRIS			842
++maestro			MACH_MAESTRO		MAESTRO			843
++palmte2			MACH_PALMTE2		PALMTE2			844
++ixbbm			MACH_IXBBM		IXBBM			845
++mx27ads			MACH_MX27ADS		MX27ADS			846
++ax8004			MACH_AX8004		AX8004			847
++at91sam9261ek		MACH_AT91SAM9261EK	AT91SAM9261EK		848
++loft			MACH_LOFT		LOFT			849
++magpie			MACH_MAGPIE		MAGPIE			850
++mx21ads			MACH_MX21ADS		MX21ADS			851
++mb87m3400		MACH_MB87M3400		MB87M3400		852
++mguard_delta		MACH_MGUARD_DELTA	MGUARD_DELTA		853
++davinci_dvdp		MACH_DAVINCI_DVDP	DAVINCI_DVDP		854
++htcuniversal		MACH_HTCUNIVERSAL	HTCUNIVERSAL		855
++tpad			MACH_TPAD		TPAD			856
++roverp3			MACH_ROVERP3		ROVERP3			857
++jornada928		MACH_JORNADA928		JORNADA928		858
++mv88fxx81		MACH_MV88FXX81		MV88FXX81		859
++stmp36xx		MACH_STMP36XX		STMP36XX		860
++sxni79524		MACH_SXNI79524		SXNI79524		861
++ams_delta		MACH_AMS_DELTA		AMS_DELTA		862
++uranium			MACH_URANIUM		URANIUM			863
++ucon			MACH_UCON		UCON			864
++nas100d			MACH_NAS100D		NAS100D			865
++l083			MACH_L083_1000		L083_1000		866
++ezx			MACH_EZX		EZX			867
++pnx5220			MACH_PNX5220		PNX5220			868
++butte			MACH_BUTTE		BUTTE			869
++srm2			MACH_SRM2		SRM2			870
++dsbr			MACH_DSBR		DSBR			871
++crystalball		MACH_CRYSTALBALL	CRYSTALBALL		872
++tinypxa27x		MACH_TINYPXA27X		TINYPXA27X		873
++herbie			MACH_HERBIE		HERBIE			874
++magician		MACH_MAGICIAN		MAGICIAN		875
++cm4002			MACH_CM4002		CM4002			876
++b4			MACH_B4			B4			877
++maui			MACH_MAUI		MAUI			878
++cybertracker_g		MACH_CYBERTRACKER_G	CYBERTRACKER_G		879
++nxdkn			MACH_NXDKN		NXDKN			880
++mio8390			MACH_MIO8390		MIO8390			881
++omi_board		MACH_OMI_BOARD		OMI_BOARD		882
++mx21civ			MACH_MX21CIV		MX21CIV			883
++mahi_cdac		MACH_MAHI_CDAC		MAHI_CDAC		884
++palmtx			MACH_PALMTX		PALMTX			885
++s3c2413			MACH_S3C2413		S3C2413			887
++samsys_ep0		MACH_SAMSYS_EP0		SAMSYS_EP0		888
++wg302v1			MACH_WG302V1		WG302V1			889
++wg302v2			MACH_WG302V2		WG302V2			890
++eb42x			MACH_EB42X		EB42X			891
++iq331es			MACH_IQ331ES		IQ331ES			892
++cosydsp			MACH_COSYDSP		COSYDSP			893
++uplat7d_proto		MACH_UPLAT7D		UPLAT7D			894
++ptdavinci		MACH_PTDAVINCI		PTDAVINCI		895
++mbus			MACH_MBUS		MBUS			896
++nadia2vb		MACH_NADIA2VB		NADIA2VB		897
++r1000			MACH_R1000		R1000			898
++hw90250			MACH_HW90250		HW90250			899
++omap_2430sdp		MACH_OMAP_2430SDP	OMAP_2430SDP		900
++davinci_evm		MACH_DAVINCI_EVM	DAVINCI_EVM		901
++omap_tornado		MACH_OMAP_TORNADO	OMAP_TORNADO		902
++olocreek		MACH_OLOCREEK		OLOCREEK		903
++palmz72			MACH_PALMZ72		PALMZ72			904
++nxdb500			MACH_NXDB500		NXDB500			905
++apf9328			MACH_APF9328		APF9328			906
++omap_wipoq		MACH_OMAP_WIPOQ		OMAP_WIPOQ		907
++omap_twip		MACH_OMAP_TWIP		OMAP_TWIP		908
++treo650			MACH_TREO650		TREO650			909
++acumen			MACH_ACUMEN		ACUMEN			910
++xp100			MACH_XP100		XP100			911
++fs2410			MACH_FS2410		FS2410			912
++pxa270_cerf		MACH_PXA270_CERF	PXA270_CERF		913
++sq2ftlpalm		MACH_SQ2FTLPALM		SQ2FTLPALM		914
++bsemserver		MACH_BSEMSERVER		BSEMSERVER		915
++netclient		MACH_NETCLIENT		NETCLIENT		916
++palmt5			MACH_PALMT5		PALMT5			917
++palmtc			MACH_PALMTC		PALMTC			918
++omap_apollon		MACH_OMAP_APOLLON	OMAP_APOLLON		919
++mxc30030evb		MACH_MXC30030EVB	MXC30030EVB		920
++rea_cpu2		MACH_REA_2D		REA_2D			921
++eti3e524		MACH_TI3E524		TI3E524			922
++ateb9200		MACH_ATEB9200		ATEB9200		923
++auckland		MACH_AUCKLAND		AUCKLAND		924
++ak3220m			MACH_AK3320M		AK3320M			925
++duramax			MACH_DURAMAX		DURAMAX			926
++n35			MACH_N35		N35			927
++pronghorn		MACH_PRONGHORN		PRONGHORN		928
++fundy			MACH_FUNDY		FUNDY			929
++logicpd_pxa270		MACH_LOGICPD_PXA270	LOGICPD_PXA270		930
++cpu777			MACH_CPU777		CPU777			931
++simicon9201		MACH_SIMICON9201	SIMICON9201		932
++leap2_hpm		MACH_LEAP2_HPM		LEAP2_HPM		933
++cm922txa10		MACH_CM922TXA10		CM922TXA10		934
++sandgate		MACH_PXA		PXA			935
++sandgate2		MACH_SANDGATE2		SANDGATE2		936
++sandgate2g		MACH_SANDGATE2G		SANDGATE2G		937
++sandgate2p		MACH_SANDGATE2P		SANDGATE2P		938
++fred_jack		MACH_FRED_JACK		FRED_JACK		939
++ttg_color1		MACH_TTG_COLOR1		TTG_COLOR1		940
++nxeb500hmi		MACH_NXEB500HMI		NXEB500HMI		941
++netdcu8			MACH_NETDCU8		NETDCU8			942
++ng_fvx538		MACH_NG_FVX538		NG_FVX538		944
++ng_fvs338		MACH_NG_FVS338		NG_FVS338		945
++pnx4103			MACH_PNX4103		PNX4103			946
++hesdb			MACH_HESDB		HESDB			947
++xsilo			MACH_XSILO		XSILO			948
++espresso		MACH_ESPRESSO		ESPRESSO		949
++emlc			MACH_EMLC		EMLC			950
++sisteron		MACH_SISTERON		SISTERON		951
++rx1950			MACH_RX1950		RX1950			952
++tsc_venus		MACH_TSC_VENUS		TSC_VENUS		953
++ds101j			MACH_DS101J		DS101J			954
++mxc30030ads		MACH_MXC30030ADS	MXC30030ADS		955
++fujitsu_wimaxsoc	MACH_FUJITSU_WIMAXSOC	FUJITSU_WIMAXSOC	956
++dualpcmodem		MACH_DUALPCMODEM	DUALPCMODEM		957
++gesbc9312		MACH_GESBC9312		GESBC9312		958
++htcapache		MACH_HTCAPACHE		HTCAPACHE		959
++ixdp435			MACH_IXDP435		IXDP435			960
++catprovt100		MACH_CATPROVT100	CATPROVT100		961
++picotux1xx		MACH_PICOTUX1XX		PICOTUX1XX		962
++picotux2xx		MACH_PICOTUX2XX		PICOTUX2XX		963
++dsmg600			MACH_DSMG600		DSMG600			964
++empc2			MACH_EMPC2		EMPC2			965
++ventura			MACH_VENTURA		VENTURA			966
++phidget_sbc		MACH_PHIDGET_SBC	PHIDGET_SBC		967
++ij3k			MACH_IJ3K		IJ3K			968
++pisgah			MACH_PISGAH		PISGAH			969
++omap_fsample		MACH_OMAP_FSAMPLE	OMAP_FSAMPLE		970
++sg720			MACH_SG720		SG720			971
++redfox			MACH_REDFOX		REDFOX			972
++mysh_ep9315_1		MACH_MYSH_EP9315_1	MYSH_EP9315_1		973
++tpf106			MACH_TPF106		TPF106			974
++at91rm9200kg		MACH_AT91RM9200KG	AT91RM9200KG		975
++rcmt2			MACH_SLEDB		SLEDB			976
++ontrack			MACH_ONTRACK		ONTRACK			977
++pm1200			MACH_PM1200		PM1200			978
++ess24562		MACH_ESS24XXX		ESS24XXX		979
++coremp7			MACH_COREMP7		COREMP7			980
++nexcoder_6446		MACH_NEXCODER_6446	NEXCODER_6446		981
++stvc8380		MACH_STVC8380		STVC8380		982
++teklynx			MACH_TEKLYNX		TEKLYNX			983
++carbonado		MACH_CARBONADO		CARBONADO		984
++sysmos_mp730		MACH_SYSMOS_MP730	SYSMOS_MP730		985
++snapper_cl15		MACH_SNAPPER_CL15	SNAPPER_CL15		986
++pgigim			MACH_PGIGIM		PGIGIM			987
++ptx9160p2		MACH_PTX9160P2		PTX9160P2		988
++dcore1			MACH_DCORE1		DCORE1			989
++victorpxa		MACH_VICTORPXA		VICTORPXA		990
++mx2dtb			MACH_MX2DTB		MX2DTB			991
++pxa_irex_er0100		MACH_PXA_IREX_ER0100	PXA_IREX_ER0100		992
++omap_palmz71		MACH_OMAP_PALMZ71	OMAP_PALMZ71		993
++bartec_deg		MACH_BARTEC_DEG		BARTEC_DEG		994
++hw50251			MACH_HW50251		HW50251			995
++ibox			MACH_IBOX		IBOX			996
++atlaslh7a404		MACH_ATLASLH7A404	ATLASLH7A404		997
++pt2026			MACH_PT2026		PT2026			998
++htcalpine		MACH_HTCALPINE		HTCALPINE		999
++bartec_vtu		MACH_BARTEC_VTU		BARTEC_VTU		1000
++vcoreii			MACH_VCOREII		VCOREII			1001
++pdnb3			MACH_PDNB3		PDNB3			1002
++htcbeetles		MACH_HTCBEETLES		HTCBEETLES		1003
++s3c6400			MACH_S3C6400		S3C6400			1004
++s3c2443			MACH_S3C2443		S3C2443			1005
++omap_ldk		MACH_OMAP_LDK		OMAP_LDK		1006
++smdk2460		MACH_SMDK2460		SMDK2460		1007
++smdk2440		MACH_SMDK2440		SMDK2440		1008
++smdk2412		MACH_SMDK2412		SMDK2412		1009
++webbox			MACH_WEBBOX		WEBBOX			1010
++cwwndp			MACH_CWWNDP		CWWNDP			1011
++i839			MACH_DRAGON		DRAGON			1012
++opendo_cpu_board	MACH_OPENDO_CPU_BOARD	OPENDO_CPU_BOARD	1013
++ccm2200			MACH_CCM2200		CCM2200			1014
++etwarm			MACH_ETWARM		ETWARM			1015
++m93030			MACH_M93030		M93030			1016
++cc7u			MACH_CC7U		CC7U			1017
++mtt_ranger		MACH_MTT_RANGER		MTT_RANGER		1018
++nexus			MACH_NEXUS		NEXUS			1019
++desman			MACH_DESMAN		DESMAN			1020
++bkde303			MACH_BKDE303		BKDE303			1021
++smdk2413		MACH_SMDK2413		SMDK2413		1022
++aml_m7200		MACH_AML_M7200		AML_M7200		1023
++aml_m5900		MACH_AML_M5900		AML_M5900		1024
++sg640			MACH_SG640		SG640			1025
++edg79524		MACH_EDG79524		EDG79524		1026
++ai2410			MACH_AI2410		AI2410			1027
++ixp465			MACH_IXP465		IXP465			1028
++balloon3		MACH_BALLOON3		BALLOON3		1029
++heins			MACH_HEINS		HEINS			1030
++mpluseva		MACH_MPLUSEVA		MPLUSEVA		1031
++rt042			MACH_RT042		RT042			1032
++cwiem			MACH_CWIEM		CWIEM			1033
++cm_x270			MACH_CM_X270		CM_X270			1034
++cm_x255			MACH_CM_X255		CM_X255			1035
++esh_at91		MACH_ESH_AT91		ESH_AT91		1036
++sandgate3		MACH_SANDGATE3		SANDGATE3		1037
++primo			MACH_PRIMO		PRIMO			1038
++gemstone		MACH_GEMSTONE		GEMSTONE		1039
++pronghorn_metro		MACH_PRONGHORNMETRO	PRONGHORNMETRO		1040
++sidewinder		MACH_SIDEWINDER		SIDEWINDER		1041
++picomod1		MACH_PICOMOD1		PICOMOD1		1042
++sg590			MACH_SG590		SG590			1043
++akai9307		MACH_AKAI9307		AKAI9307		1044
++fontaine		MACH_FONTAINE		FONTAINE		1045
++wombat			MACH_WOMBAT		WOMBAT			1046
++acq300			MACH_ACQ300		ACQ300			1047
++mod272			MACH_MOD_270		MOD_270			1048
++vmc_vc0820		MACH_VC0820		VC0820			1049
++ani_aim			MACH_ANI_AIM		ANI_AIM			1050
++jellyfish		MACH_JELLYFISH		JELLYFISH		1051
++amanita			MACH_AMANITA		AMANITA			1052
++vlink			MACH_VLINK		VLINK			1053
++dexflex			MACH_DEXFLEX		DEXFLEX			1054
++eigen_ttq		MACH_EIGEN_TTQ		EIGEN_TTQ		1055
++arcom_titan		MACH_ARCOM_TITAN	ARCOM_TITAN		1056
++tabla			MACH_TABLA		TABLA			1057
++mdirac3			MACH_MDIRAC3		MDIRAC3			1058
++mrhfbp2			MACH_MRHFBP2		MRHFBP2			1059
++at91rm9200rb		MACH_AT91RM9200RB	AT91RM9200RB		1060
++ani_apm			MACH_ANI_APM		ANI_APM			1061
++ella1			MACH_ELLA1		ELLA1			1062
++inhand_pxa27x		MACH_INHAND_PXA27X	INHAND_PXA27X		1063
++inhand_pxa25x		MACH_INHAND_PXA25X	INHAND_PXA25X		1064
++empos_xm		MACH_EMPOS_XM		EMPOS_XM		1065
++empos			MACH_EMPOS		EMPOS			1066
++empos_tiny		MACH_EMPOS_TINY		EMPOS_TINY		1067
++empos_sm		MACH_EMPOS_SM		EMPOS_SM		1068
++egret			MACH_EGRET		EGRET			1069
++ostrich			MACH_OSTRICH		OSTRICH			1070
++n50			MACH_N50		N50			1071
++ecbat91			MACH_ECBAT91		ECBAT91			1072
++stareast		MACH_STAREAST		STAREAST		1073
++dspg_dw			MACH_DSPG_DW		DSPG_DW			1074
++onearm			MACH_ONEARM		ONEARM			1075
++mrg110_6		MACH_MRG110_6		MRG110_6		1076
++wrt300nv2		MACH_WRT300NV2		WRT300NV2		1077
++xm_bulverde		MACH_XM_BULVERDE	XM_BULVERDE		1078
++msm6100			MACH_MSM6100		MSM6100			1079
++eti_b1			MACH_ETI_B1		ETI_B1			1080
++za9l_series		MACH_ZILOG_ZA9L		ZILOG_ZA9L		1081
++bit2440			MACH_BIT2440		BIT2440			1082
++nbi			MACH_NBI		NBI			1083
++smdk2443		MACH_SMDK2443		SMDK2443		1084
++vdavinci		MACH_VDAVINCI		VDAVINCI		1085
++atc6			MACH_ATC6		ATC6			1086
++multmdw			MACH_MULTMDW		MULTMDW			1087
++mba2440			MACH_MBA2440		MBA2440			1088
++ecsd			MACH_ECSD		ECSD			1089
++palmz31			MACH_PALMZ31		PALMZ31			1090
++fsg			MACH_FSG		FSG			1091
++razor101		MACH_RAZOR101		RAZOR101		1092
++opera_tdm		MACH_OPERA_TDM		OPERA_TDM		1093
++comcerto		MACH_COMCERTO		COMCERTO		1094
++tb0319			MACH_TB0319		TB0319			1095
++kws8000			MACH_KWS8000		KWS8000			1096
++b2			MACH_B2			B2			1097
++lcl54			MACH_LCL54		LCL54			1098
++at91sam9260ek		MACH_AT91SAM9260EK	AT91SAM9260EK		1099
++glantank		MACH_GLANTANK		GLANTANK		1100
++n2100			MACH_N2100		N2100			1101
++n4100			MACH_N4100		N4100			1102
++rsc4			MACH_VERTICAL_RSC4	VERTICAL_RSC4		1103
++sg8100			MACH_SG8100		SG8100			1104
++im42xx			MACH_IM42XX		IM42XX			1105
++ftxx			MACH_FTXX		FTXX			1106
++lwfusion		MACH_LWFUSION		LWFUSION		1107
++qt2410			MACH_QT2410		QT2410			1108
++kixrp435		MACH_KIXRP435		KIXRP435		1109
++ccw9c			MACH_CCW9C		CCW9C			1110
++dabhs			MACH_DABHS		DABHS			1111
++gzmx			MACH_GZMX		GZMX			1112
++ipnw100ap		MACH_IPNW100AP		IPNW100AP		1113
++cc9p9360dev		MACH_CC9P9360DEV	CC9P9360DEV		1114
++cc9p9750dev		MACH_CC9P9750DEV	CC9P9750DEV		1115
++cc9p9360val		MACH_CC9P9360VAL	CC9P9360VAL		1116
++cc9p9750val		MACH_CC9P9750VAL	CC9P9750VAL		1117
++nx70v			MACH_NX70V		NX70V			1118
++at91rm9200df		MACH_AT91RM9200DF	AT91RM9200DF		1119
++se_pilot2		MACH_SE_PILOT2		SE_PILOT2		1120
++mtcn_t800		MACH_MTCN_T800		MTCN_T800		1121
++vcmx212			MACH_VCMX212		VCMX212			1122
++lynx			MACH_LYNX		LYNX			1123
++at91sam9260id		MACH_AT91SAM9260ID	AT91SAM9260ID		1124
++hw86052			MACH_HW86052		HW86052			1125
++pilz_pmi3		MACH_PILZ_PMI3		PILZ_PMI3		1126
++edb9302a		MACH_EDB9302A		EDB9302A		1127
++edb9307a		MACH_EDB9307A		EDB9307A		1128
++ct_dfs			MACH_CT_DFS		CT_DFS			1129
++pilz_pmi4		MACH_PILZ_PMI4		PILZ_PMI4		1130
++xceednp_ixp		MACH_XCEEDNP_IXP	XCEEDNP_IXP		1131
++smdk2442b		MACH_SMDK2442B		SMDK2442B		1132
++xnode			MACH_XNODE		XNODE			1133
++aidx270			MACH_AIDX270		AIDX270			1134
++rema			MACH_REMA		REMA			1135
++bps1000			MACH_BPS1000		BPS1000			1136
++hw90350			MACH_HW90350		HW90350			1137
++omap_3430sdp		MACH_OMAP_3430SDP	OMAP_3430SDP		1138
++bluetouch		MACH_BLUETOUCH		BLUETOUCH		1139
++vstms			MACH_VSTMS		VSTMS			1140
++xsbase270		MACH_XSBASE270		XSBASE270		1141
++at91sam9260ek_cn	MACH_AT91SAM9260EK_CN	AT91SAM9260EK_CN	1142
++adsturboxb		MACH_ADSTURBOXB		ADSTURBOXB		1143
++oti4110			MACH_OTI4110		OTI4110			1144
++hme_pxa			MACH_HME_PXA		HME_PXA			1145
++deisterdca		MACH_DEISTERDCA		DEISTERDCA		1146
++ces_ssem2		MACH_CES_SSEM2		CES_SSEM2		1147
++ces_mtr			MACH_CES_MTR		CES_MTR			1148
++tds_avng_sbc		MACH_TDS_AVNG_SBC	TDS_AVNG_SBC		1149
++everest			MACH_EVEREST		EVEREST			1150
++pnx4010			MACH_PNX4010		PNX4010			1151
++oxnas			MACH_OXNAS		OXNAS			1152
++fiori			MACH_FIORI		FIORI			1153
++ml1200			MACH_ML1200		ML1200			1154
++pecos			MACH_PECOS		PECOS			1155
++nb2xxx			MACH_NB2XXX		NB2XXX			1156
++hw6900			MACH_HW6900		HW6900			1157
++cdcs_quoll		MACH_CDCS_QUOLL		CDCS_QUOLL		1158
++quicksilver		MACH_QUICKSILVER	QUICKSILVER		1159
++uplat926		MACH_UPLAT926		UPLAT926		1160
++dep2410_dep2410		MACH_DEP2410_THOMAS	DEP2410_THOMAS		1161
++dtk2410			MACH_DTK2410		DTK2410			1162
++chili			MACH_CHILI		CHILI			1163
++demeter			MACH_DEMETER		DEMETER			1164
++dionysus		MACH_DIONYSUS		DIONYSUS		1165
++as352x			MACH_AS352X		AS352X			1166
++service			MACH_SERVICE		SERVICE			1167
++cs_e9301		MACH_CS_E9301		CS_E9301		1168
++micro9m			MACH_MICRO9M		MICRO9M			1169
++ia_mospck		MACH_IA_MOSPCK		IA_MOSPCK		1170
++ql201b			MACH_QL201B		QL201B			1171
++bbm			MACH_BBM		BBM			1174
++exxx			MACH_EXXX		EXXX			1175
++wma11b			MACH_WMA11B		WMA11B			1176
++pelco_atlas		MACH_PELCO_ATLAS	PELCO_ATLAS		1177
++g500			MACH_G500		G500			1178
++bug			MACH_BUG		BUG			1179
++mx33ads			MACH_MX33ADS		MX33ADS			1180
++chub			MACH_CHUB		CHUB			1181
++neo1973_gta01		MACH_NEO1973_GTA01	NEO1973_GTA01		1182
++w90n740			MACH_W90N740		W90N740			1183
++medallion_sa2410	MACH_MEDALLION_SA2410	MEDALLION_SA2410	1184
++ia_cpu_9200_2		MACH_IA_CPU_9200_2	IA_CPU_9200_2		1185
++dimmrm9200		MACH_DIMMRM9200		DIMMRM9200		1186
++pm9261			MACH_PM9261		PM9261			1187
++ml7304			MACH_ML7304		ML7304			1189
++ucp250			MACH_UCP250		UCP250			1190
++intboard		MACH_INTBOARD		INTBOARD		1191
++gulfstream		MACH_GULFSTREAM		GULFSTREAM		1192
++labquest		MACH_LABQUEST		LABQUEST		1193
++vcmx313			MACH_VCMX313		VCMX313			1194
++urg200			MACH_URG200		URG200			1195
++cpux255lcdnet		MACH_CPUX255LCDNET	CPUX255LCDNET		1196
++netdcu9			MACH_NETDCU9		NETDCU9			1197
++netdcu10		MACH_NETDCU10		NETDCU10		1198
++dspg_dga		MACH_DSPG_DGA		DSPG_DGA		1199
++dspg_dvw		MACH_DSPG_DVW		DSPG_DVW		1200
++solos			MACH_SOLOS		SOLOS			1201
++at91sam9263ek		MACH_AT91SAM9263EK	AT91SAM9263EK		1202
++osstbox			MACH_OSSTBOX		OSSTBOX			1203
++kbat9261		MACH_KBAT9261		KBAT9261		1204
++ct1100			MACH_CT1100		CT1100			1205
++akcppxa			MACH_AKCPPXA		AKCPPXA			1206
++ochaya1020		MACH_OCHAYA1020		OCHAYA1020		1207
++hitrack			MACH_HITRACK		HITRACK			1208
++syme1			MACH_SYME1		SYME1			1209
++syhl1			MACH_SYHL1		SYHL1			1210
++empca400		MACH_EMPCA400		EMPCA400		1211
++em7210			MACH_EM7210		EM7210			1212
++htchermes		MACH_HTCHERMES		HTCHERMES		1213
++eti_c1			MACH_ETI_C1		ETI_C1			1214
++ac100			MACH_AC100		AC100			1216
++sneetch			MACH_SNEETCH		SNEETCH			1217
++studentmate		MACH_STUDENTMATE	STUDENTMATE		1218
++zir2410			MACH_ZIR2410		ZIR2410			1219
++zir2413			MACH_ZIR2413		ZIR2413			1220
++dlonip3			MACH_DLONIP3		DLONIP3			1221
++instream		MACH_INSTREAM		INSTREAM		1222
++ambarella		MACH_AMBARELLA		AMBARELLA		1223
++nevis			MACH_NEVIS		NEVIS			1224
++htc_trinity		MACH_HTC_TRINITY	HTC_TRINITY		1225
++ql202b			MACH_QL202B		QL202B			1226
++vpac270			MACH_VPAC270		VPAC270			1227
++rd129			MACH_RD129		RD129			1228
++htcwizard		MACH_HTCWIZARD		HTCWIZARD		1229
++treo680			MACH_TREO680		TREO680			1230
++tecon_tmezon		MACH_TECON_TMEZON	TECON_TMEZON		1231
++zylonite		MACH_ZYLONITE		ZYLONITE		1233
++gene1270		MACH_GENE1270		GENE1270		1234
++zir2412			MACH_ZIR2412		ZIR2412			1235
++mx31lite		MACH_MX31LITE		MX31LITE		1236
++t700wx			MACH_T700WX		T700WX			1237
++vf100			MACH_VF100		VF100			1238
++nsb2			MACH_NSB2		NSB2			1239
++nxhmi_bb		MACH_NXHMI_BB		NXHMI_BB		1240
++nxhmi_re		MACH_NXHMI_RE		NXHMI_RE		1241
++n4100pro		MACH_N4100PRO		N4100PRO		1242
++sam9260			MACH_SAM9260		SAM9260			1243
++omap_treo600		MACH_OMAP_TREO600	OMAP_TREO600		1244
++indy2410		MACH_INDY2410		INDY2410		1245
++nelt_a			MACH_NELT_A		NELT_A			1246
++n311			MACH_N311		N311			1248
++at91sam9260vgk		MACH_AT91SAM9260VGK	AT91SAM9260VGK		1249
++at91leppe		MACH_AT91LEPPE		AT91LEPPE		1250
++at91lepccn		MACH_AT91LEPCCN		AT91LEPCCN		1251
++apc7100			MACH_APC7100		APC7100			1252
++stargazer		MACH_STARGAZER		STARGAZER		1253
++sonata			MACH_SONATA		SONATA			1254
++schmoogie		MACH_SCHMOOGIE		SCHMOOGIE		1255
++aztool			MACH_AZTOOL		AZTOOL			1256
++mioa701			MACH_MIOA701		MIOA701			1257
++sxni9260		MACH_SXNI9260		SXNI9260		1258
++mxc27520evb		MACH_MXC27520EVB	MXC27520EVB		1259
++armadillo5x0		MACH_ARMADILLO5X0	ARMADILLO5X0		1260
++mb9260			MACH_MB9260		MB9260			1261
++mb9263			MACH_MB9263		MB9263			1262
++ipac9302		MACH_IPAC9302		IPAC9302		1263
++cc9p9360js		MACH_CC9P9360JS		CC9P9360JS		1264
++gallium			MACH_GALLIUM		GALLIUM			1265
++msc2410			MACH_MSC2410		MSC2410			1266
++ghi270			MACH_GHI270		GHI270			1267
++davinci_leonardo	MACH_DAVINCI_LEONARDO	DAVINCI_LEONARDO	1268
++oiab			MACH_OIAB		OIAB			1269
++smdk6400		MACH_SMDK6400		SMDK6400		1270
++nokia_n800		MACH_NOKIA_N800		NOKIA_N800		1271
++greenphone		MACH_GREENPHONE		GREENPHONE		1272
++compex42x		MACH_COMPEXWP18		COMPEXWP18		1273
++xmate			MACH_XMATE		XMATE			1274
++energizer		MACH_ENERGIZER		ENERGIZER		1275
++ime1			MACH_IME1		IME1			1276
++sweda_tms		MACH_SWEDATMS		SWEDATMS		1277
++ntnp435c		MACH_NTNP435C		NTNP435C		1278
++spectro2		MACH_SPECTRO2		SPECTRO2		1279
++h6039			MACH_H6039		H6039			1280
++ep80219			MACH_EP80219		EP80219			1281
++samoa_ii		MACH_SAMOA_II		SAMOA_II		1282
++cwmxl			MACH_CWMXL		CWMXL			1283
++as9200			MACH_AS9200		AS9200			1284
++sfx1149			MACH_SFX1149		SFX1149			1285
++navi010			MACH_NAVI010		NAVI010			1286
++multmdp			MACH_MULTMDP		MULTMDP			1287
++scb9520			MACH_SCB9520		SCB9520			1288
++htcathena		MACH_HTCATHENA		HTCATHENA		1289
++xp179			MACH_XP179		XP179			1290
++h4300			MACH_H4300		H4300			1291
++goramo_mlr		MACH_GORAMO_MLR		GORAMO_MLR		1292
++mxc30020evb		MACH_MXC30020EVB	MXC30020EVB		1293
++adsbitsyg5		MACH_ADSBITSYG5		ADSBITSYG5		1294
++adsportalplus		MACH_ADSPORTALPLUS	ADSPORTALPLUS		1295
++mmsp2plus		MACH_MMSP2PLUS		MMSP2PLUS		1296
++em_x270			MACH_EM_X270		EM_X270			1297
++tpp302			MACH_TPP302		TPP302			1298
++tpp104			MACH_TPM104		TPM104			1299
++tpm102			MACH_TPM102		TPM102			1300
++tpm109			MACH_TPM109		TPM109			1301
++fbxo1			MACH_FBXO1		FBXO1			1302
++hxd8			MACH_HXD8		HXD8			1303
++neo1973_gta02		MACH_NEO1973_GTA02	NEO1973_GTA02		1304
++emtest			MACH_EMTEST		EMTEST			1305
++ad6900			MACH_AD6900		AD6900			1306
++europa			MACH_EUROPA		EUROPA			1307
++metroconnect		MACH_METROCONNECT	METROCONNECT		1308
++ez_s2410		MACH_EZ_S2410		EZ_S2410		1309
++ez_s2440		MACH_EZ_S2440		EZ_S2440		1310
++ez_ep9312		MACH_EZ_EP9312		EZ_EP9312		1311
++ez_ep9315		MACH_EZ_EP9315		EZ_EP9315		1312
++ez_x7			MACH_EZ_X7		EZ_X7			1313
++godotdb			MACH_GODOTDB		GODOTDB			1314
++mistral			MACH_MISTRAL		MISTRAL			1315
++msm			MACH_MSM		MSM			1316
++ct5910			MACH_CT5910		CT5910			1317
++ct5912			MACH_CT5912		CT5912			1318
++hynet_ine		MACH_HYNET_INE		HYNET_INE		1319
++hynet_app		MACH_HYNET_APP		HYNET_APP		1320
++msm7200			MACH_MSM7200		MSM7200			1321
++msm7600			MACH_MSM7600		MSM7600			1322
++ceb255			MACH_CEB255		CEB255			1323
++ciel			MACH_CIEL		CIEL			1324
++slm5650			MACH_SLM5650		SLM5650			1325
++at91sam9rlek		MACH_AT91SAM9RLEK	AT91SAM9RLEK		1326
++comtech_router		MACH_COMTECH_ROUTER	COMTECH_ROUTER		1327
++sbc2410x		MACH_SBC2410X		SBC2410X		1328
++at4x0bd			MACH_AT4X0BD		AT4X0BD			1329
++cbifr			MACH_CBIFR		CBIFR			1330
++arcom_quantum		MACH_ARCOM_QUANTUM	ARCOM_QUANTUM		1331
++matrix520		MACH_MATRIX520		MATRIX520		1332
++matrix510		MACH_MATRIX510		MATRIX510		1333
++matrix500		MACH_MATRIX500		MATRIX500		1334
++m501			MACH_M501		M501			1335
++aaeon1270		MACH_AAEON1270		AAEON1270		1336
++matrix500ev		MACH_MATRIX500EV	MATRIX500EV		1337
++pac500			MACH_PAC500		PAC500			1338
++pnx8181			MACH_PNX8181		PNX8181			1339
++colibri320		MACH_COLIBRI320		COLIBRI320		1340
++aztoolbb		MACH_AZTOOLBB		AZTOOLBB		1341
++aztoolg2		MACH_AZTOOLG2		AZTOOLG2		1342
++dvlhost			MACH_DVLHOST		DVLHOST			1343
++zir9200			MACH_ZIR9200		ZIR9200			1344
++zir9260			MACH_ZIR9260		ZIR9260			1345
++cocopah			MACH_COCOPAH		COCOPAH			1346
++nds			MACH_NDS		NDS			1347
++rosencrantz		MACH_ROSENCRANTZ	ROSENCRANTZ		1348
++fttx_odsc		MACH_FTTX_ODSC		FTTX_ODSC		1349
++classe_r6904		MACH_CLASSE_R6904	CLASSE_R6904		1350
++cam60			MACH_CAM60		CAM60			1351
++mxc30031ads		MACH_MXC30031ADS	MXC30031ADS		1352
++datacall		MACH_DATACALL		DATACALL		1353
++at91eb01		MACH_AT91EB01		AT91EB01		1354
++rty			MACH_RTY		RTY			1355
++dwl2100			MACH_DWL2100		DWL2100			1356
++vinsi			MACH_VINSI		VINSI			1357
++db88f5281		MACH_DB88F5281		DB88F5281		1358
++csb726			MACH_CSB726		CSB726			1359
++tik27			MACH_TIK27		TIK27			1360
++mx_uc7420		MACH_MX_UC7420		MX_UC7420		1361
++rirm3			MACH_RIRM3		RIRM3			1362
++pelco_odyssey		MACH_PELCO_ODYSSEY	PELCO_ODYSSEY		1363
++adx_abox		MACH_ADX_ABOX		ADX_ABOX		1365
++adx_tpid		MACH_ADX_TPID		ADX_TPID		1366
++minicheck		MACH_MINICHECK		MINICHECK		1367
++idam			MACH_IDAM		IDAM			1368
++mario_mx		MACH_MARIO_MX		MARIO_MX		1369
++vi1888			MACH_VI1888		VI1888			1370
++zr4230			MACH_ZR4230		ZR4230			1371
++t1_ix_blue		MACH_T1_IX_BLUE		T1_IX_BLUE		1372
++syhq2			MACH_SYHQ2		SYHQ2			1373
++computime_r3		MACH_COMPUTIME_R3	COMPUTIME_R3		1374
++oratis			MACH_ORATIS		ORATIS			1375
++mikko			MACH_MIKKO		MIKKO			1376
++holon			MACH_HOLON		HOLON			1377
++olip8			MACH_OLIP8		OLIP8			1378
++ghi270hg		MACH_GHI270HG		GHI270HG		1379
++davinci_dm6467_evm	MACH_DAVINCI_DM6467_EVM	DAVINCI_DM6467_EVM	1380
++davinci_dm355_evm	MACH_DAVINCI_DM355_EVM	DAVINCI_DM355_EVM	1381
++blackriver		MACH_BLACKRIVER		BLACKRIVER		1383
++sandgate_wp		MACH_SANDGATEWP		SANDGATEWP		1384
++cdotbwsg		MACH_CDOTBWSG		CDOTBWSG		1385
++quark963		MACH_QUARK963		QUARK963		1386
++csb735			MACH_CSB735		CSB735			1387
++littleton		MACH_LITTLETON		LITTLETON		1388
++mio_p550		MACH_MIO_P550		MIO_P550		1389
++motion2440		MACH_MOTION2440		MOTION2440		1390
++imm500			MACH_IMM500		IMM500			1391
++homematic		MACH_HOMEMATIC		HOMEMATIC		1392
++ermine			MACH_ERMINE		ERMINE			1393
++kb9202b			MACH_KB9202B		KB9202B			1394
++hs1xx			MACH_HS1XX		HS1XX			1395
++studentmate2440		MACH_STUDENTMATE2440	STUDENTMATE2440		1396
++arvoo_l1_z1		MACH_ARVOO_L1_Z1	ARVOO_L1_Z1		1397
++dep2410k		MACH_DEP2410K		DEP2410K		1398
++xxsvideo		MACH_XXSVIDEO		XXSVIDEO		1399
++im4004			MACH_IM4004		IM4004			1400
++ochaya1050		MACH_OCHAYA1050		OCHAYA1050		1401
++lep9261			MACH_LEP9261		LEP9261			1402
++svenmeb			MACH_SVENMEB		SVENMEB			1403
++fortunet2ne		MACH_FORTUNET2NE	FORTUNET2NE		1404
++nxhx			MACH_NXHX		NXHX			1406
++realview_pb11mp		MACH_REALVIEW_PB11MP	REALVIEW_PB11MP		1407
++ids500			MACH_IDS500		IDS500			1408
++ors_n725		MACH_ORS_N725		ORS_N725		1409
++hsdarm			MACH_HSDARM		HSDARM			1410
++sha_pon003		MACH_SHA_PON003		SHA_PON003		1411
++sha_pon004		MACH_SHA_PON004		SHA_PON004		1412
++sha_pon007		MACH_SHA_PON007		SHA_PON007		1413
++sha_pon011		MACH_SHA_PON011		SHA_PON011		1414
++h6042			MACH_H6042		H6042			1415
++h6043			MACH_H6043		H6043			1416
++looxc550		MACH_LOOXC550		LOOXC550		1417
++cnty_titan		MACH_CNTY_TITAN		CNTY_TITAN		1418
++app3xx			MACH_APP3XX		APP3XX			1419
++sideoatsgrama		MACH_SIDEOATSGRAMA	SIDEOATSGRAMA		1420
++treo700p		MACH_TREO700P		TREO700P		1421
++treo700w		MACH_TREO700W		TREO700W		1422
++treo750			MACH_TREO750		TREO750			1423
++treo755p		MACH_TREO755P		TREO755P		1424
++ezreganut9200		MACH_EZREGANUT9200	EZREGANUT9200		1425
++sarge			MACH_SARGE		SARGE			1426
++a696			MACH_A696		A696			1427
++turtle1916		MACH_TURTLE		TURTLE			1428
++mx27_3ds		MACH_MX27_3DS		MX27_3DS		1430
++bishop			MACH_BISHOP		BISHOP			1431
++pxx			MACH_PXX		PXX			1432
++redwood			MACH_REDWOOD		REDWOOD			1433
++omap_2430dlp		MACH_OMAP_2430DLP	OMAP_2430DLP		1436
++omap_2430osk		MACH_OMAP_2430OSK	OMAP_2430OSK		1437
++sardine			MACH_SARDINE		SARDINE			1438
++halibut			MACH_HALIBUT		HALIBUT			1439
++trout			MACH_TROUT		TROUT			1440
++goldfish		MACH_GOLDFISH		GOLDFISH		1441
++gesbc2440		MACH_GESBC2440		GESBC2440		1442
++nomad			MACH_NOMAD		NOMAD			1443
++rosalind		MACH_ROSALIND		ROSALIND		1444
++cc9p9215		MACH_CC9P9215		CC9P9215		1445
++cc9p9210		MACH_CC9P9210		CC9P9210		1446
++cc9p9215js		MACH_CC9P9215JS		CC9P9215JS		1447
++cc9p9210js		MACH_CC9P9210JS		CC9P9210JS		1448
++nasffe			MACH_NASFFE		NASFFE			1449
++tn2x0bd			MACH_TN2X0BD		TN2X0BD			1450
++gwmpxa			MACH_GWMPXA		GWMPXA			1451
++exyplus			MACH_EXYPLUS		EXYPLUS			1452
++jadoo21			MACH_JADOO21		JADOO21			1453
++looxn560		MACH_LOOXN560		LOOXN560		1454
++bonsai			MACH_BONSAI		BONSAI			1455
++adsmilgato		MACH_ADSMILGATO		ADSMILGATO		1456
++gba			MACH_GBA		GBA			1457
++h6044			MACH_H6044		H6044			1458
++app			MACH_APP		APP			1459
++tct_hammer		MACH_TCT_HAMMER		TCT_HAMMER		1460
++herald			MACH_HERALD		HERALD			1461
++artemis			MACH_ARTEMIS		ARTEMIS			1462
++htctitan		MACH_HTCTITAN		HTCTITAN		1463
++qranium			MACH_QRANIUM		QRANIUM			1464
++adx_wsc2		MACH_ADX_WSC2		ADX_WSC2		1465
++adx_medcom		MACH_ADX_MEDCOM		ADX_MEDCOM		1466
++bboard			MACH_BBOARD		BBOARD			1467
++cambria			MACH_CAMBRIA		CAMBRIA			1468
++mt7xxx			MACH_MT7XXX		MT7XXX			1469
++matrix512		MACH_MATRIX512		MATRIX512		1470
++matrix522		MACH_MATRIX522		MATRIX522		1471
++ipac5010		MACH_IPAC5010		IPAC5010		1472
++sakura			MACH_SAKURA		SAKURA			1473
++grocx			MACH_GROCX		GROCX			1474
++pm9263			MACH_PM9263		PM9263			1475
++sim_one			MACH_SIM_ONE		SIM_ONE			1476
++acq132			MACH_ACQ132		ACQ132			1477
++datr			MACH_DATR		DATR			1478
++actux1			MACH_ACTUX1		ACTUX1			1479
++actux2			MACH_ACTUX2		ACTUX2			1480
++actux3			MACH_ACTUX3		ACTUX3			1481
++flexit			MACH_FLEXIT		FLEXIT			1482
++bh2x0bd			MACH_BH2X0BD		BH2X0BD			1483
++atb2002			MACH_ATB2002		ATB2002			1484
++xenon			MACH_XENON		XENON			1485
++fm607			MACH_FM607		FM607			1486
++matrix514		MACH_MATRIX514		MATRIX514		1487
++matrix524		MACH_MATRIX524		MATRIX524		1488
++inpod			MACH_INPOD		INPOD			1489
++jive			MACH_JIVE		JIVE			1490
++tll_mx21		MACH_TLL_MX21		TLL_MX21		1491
++sbc2800			MACH_SBC2800		SBC2800			1492
++cc7ucamry		MACH_CC7UCAMRY		CC7UCAMRY		1493
++ubisys_p9_sc15		MACH_UBISYS_P9_SC15	UBISYS_P9_SC15		1494
++ubisys_p9_ssc2d10	MACH_UBISYS_P9_SSC2D10	UBISYS_P9_SSC2D10	1495
++ubisys_p9_rcu3		MACH_UBISYS_P9_RCU3	UBISYS_P9_RCU3		1496
++aml_m8000		MACH_AML_M8000		AML_M8000		1497
++snapper_270		MACH_SNAPPER_270	SNAPPER_270		1498
++omap_bbx		MACH_OMAP_BBX		OMAP_BBX		1499
++ucn2410			MACH_UCN2410		UCN2410			1500
++sam9_l9260		MACH_SAM9_L9260		SAM9_L9260		1501
++eti_c2			MACH_ETI_C2		ETI_C2			1502
++avalanche		MACH_AVALANCHE		AVALANCHE		1503
++realview_pb1176		MACH_REALVIEW_PB1176	REALVIEW_PB1176		1504
++dp1500			MACH_DP1500		DP1500			1505
++apple_iphone		MACH_APPLE_IPHONE	APPLE_IPHONE		1506
++yl9200			MACH_YL9200		YL9200			1507
++rd88f5182		MACH_RD88F5182		RD88F5182		1508
++kurobox_pro		MACH_KUROBOX_PRO	KUROBOX_PRO		1509
++se_poet			MACH_SE_POET		SE_POET			1510
++mx31_3ds		MACH_MX31_3DS		MX31_3DS		1511
++r270			MACH_R270		R270			1512
++armour21		MACH_ARMOUR21		ARMOUR21		1513
++dt2			MACH_DT2		DT2			1514
++vt4			MACH_VT4		VT4			1515
++tyco320			MACH_TYCO320		TYCO320			1516
++adma			MACH_ADMA		ADMA			1517
++wp188			MACH_WP188		WP188			1518
++corsica			MACH_CORSICA		CORSICA			1519
++bigeye			MACH_BIGEYE		BIGEYE			1520
++tll5000			MACH_TLL5000		TLL5000			1522
++bebot			MACH_BEBOT		BEBOT			1523
++qong			MACH_QONG		QONG			1524
++tcompact		MACH_TCOMPACT		TCOMPACT		1525
++puma5			MACH_PUMA5		PUMA5			1526
++elara			MACH_ELARA		ELARA			1527
++ellington		MACH_ELLINGTON		ELLINGTON		1528
++xda_atom		MACH_XDA_ATOM		XDA_ATOM		1529
++energizer2		MACH_ENERGIZER2		ENERGIZER2		1530
++odin			MACH_ODIN		ODIN			1531
++actux4			MACH_ACTUX4		ACTUX4			1532
++esl_omap		MACH_ESL_OMAP		ESL_OMAP		1533
++omap2evm		MACH_OMAP2EVM		OMAP2EVM		1534
++omap3evm		MACH_OMAP3EVM		OMAP3EVM		1535
++adx_pcu57		MACH_ADX_PCU57		ADX_PCU57		1536
++monaco			MACH_MONACO		MONACO			1537
++levante			MACH_LEVANTE		LEVANTE			1538
++tmxipx425		MACH_TMXIPX425		TMXIPX425		1539
++leep			MACH_LEEP		LEEP			1540
++raad			MACH_RAAD		RAAD			1541
++dns323			MACH_DNS323		DNS323			1542
++ap1000			MACH_AP1000		AP1000			1543
++a9sam6432		MACH_A9SAM6432		A9SAM6432		1544
++shiny			MACH_SHINY		SHINY			1545
++omap3_beagle		MACH_OMAP3_BEAGLE	OMAP3_BEAGLE		1546
++csr_bdb2		MACH_CSR_BDB2		CSR_BDB2		1547
++nokia_n810		MACH_NOKIA_N810		NOKIA_N810		1548
++c270			MACH_C270		C270			1549
++sentry			MACH_SENTRY		SENTRY			1550
++pcm038			MACH_PCM038		PCM038			1551
++anc300			MACH_ANC300		ANC300			1552
++htckaiser		MACH_HTCKAISER		HTCKAISER		1553
++sbat100			MACH_SBAT100		SBAT100			1554
++modunorm		MACH_MODUNORM		MODUNORM		1555
++pelos_twarm		MACH_PELOS_TWARM	PELOS_TWARM		1556
++flank			MACH_FLANK		FLANK			1557
++sirloin			MACH_SIRLOIN		SIRLOIN			1558
++brisket			MACH_BRISKET		BRISKET			1559
++chuck			MACH_CHUCK		CHUCK			1560
++otter			MACH_OTTER		OTTER			1561
++davinci_ldk		MACH_DAVINCI_LDK	DAVINCI_LDK		1562
++phreedom		MACH_PHREEDOM		PHREEDOM		1563
++sg310			MACH_SG310		SG310			1564
++ts_x09			MACH_TS209		TS209			1565
++at91cap9adk		MACH_AT91CAP9ADK	AT91CAP9ADK		1566
++tion9315		MACH_TION9315		TION9315		1567
++mast			MACH_MAST		MAST			1568
++pfw			MACH_PFW		PFW			1569
++yl_p2440		MACH_YL_P2440		YL_P2440		1570
++zsbc32			MACH_ZSBC32		ZSBC32			1571
++omap_pace2		MACH_OMAP_PACE2		OMAP_PACE2		1572
++imx_pace2		MACH_IMX_PACE2		IMX_PACE2		1573
++mx31moboard		MACH_MX31MOBOARD	MX31MOBOARD		1574
++mx37_3ds		MACH_MX37_3DS		MX37_3DS		1575
++rcc			MACH_RCC		RCC			1576
++dmp			MACH_ARM9		ARM9			1577
++vision_ep9307		MACH_VISION_EP9307	VISION_EP9307		1578
++scly1000		MACH_SCLY1000		SCLY1000		1579
++fontel_ep		MACH_FONTEL_EP		FONTEL_EP		1580
++voiceblue3g		MACH_VOICEBLUE3G	VOICEBLUE3G		1581
++tt9200			MACH_TT9200		TT9200			1582
++digi2410		MACH_DIGI2410		DIGI2410		1583
++terastation_pro2	MACH_TERASTATION_PRO2	TERASTATION_PRO2	1584
++linkstation_pro		MACH_LINKSTATION_PRO	LINKSTATION_PRO		1585
++motorola_a780		MACH_MOTOROLA_A780	MOTOROLA_A780		1587
++motorola_e6		MACH_MOTOROLA_E6	MOTOROLA_E6		1588
++motorola_e2		MACH_MOTOROLA_E2	MOTOROLA_E2		1589
++motorola_e680		MACH_MOTOROLA_E680	MOTOROLA_E680		1590
++ur2410			MACH_UR2410		UR2410			1591
++tas9261			MACH_TAS9261		TAS9261			1592
++davinci_hermes_hd	MACH_HERMES_HD		HERMES_HD		1593
++davinci_perseo_hd	MACH_PERSEO_HD		PERSEO_HD		1594
++stargazer2		MACH_STARGAZER2		STARGAZER2		1595
++e350			MACH_E350		E350			1596
++wpcm450			MACH_WPCM450		WPCM450			1597
++cartesio		MACH_CARTESIO		CARTESIO		1598
++toybox			MACH_TOYBOX		TOYBOX			1599
++tx27			MACH_TX27		TX27			1600
++ts409			MACH_TS409		TS409			1601
++p300			MACH_P300		P300			1602
++xdacomet		MACH_XDACOMET		XDACOMET		1603
++dexflex2		MACH_DEXFLEX2		DEXFLEX2		1604
++ow			MACH_OW			OW			1605
++armebs3			MACH_ARMEBS3		ARMEBS3			1606
++u3			MACH_U3			U3			1607
++smdk2450		MACH_SMDK2450		SMDK2450		1608
++rsi_ews			MACH_RSI_EWS		RSI_EWS			1609
++tnb			MACH_TNB		TNB			1610
++toepath			MACH_TOEPATH		TOEPATH			1611
++kb9263			MACH_KB9263		KB9263			1612
++mt7108			MACH_MT7108		MT7108			1613
++smtr2440		MACH_SMTR2440		SMTR2440		1614
++manao			MACH_MANAO		MANAO			1615
++cm_x300			MACH_CM_X300		CM_X300			1616
++gulfstream_kp		MACH_GULFSTREAM_KP	GULFSTREAM_KP		1617
++lanreadyfn522		MACH_LANREADYFN522	LANREADYFN522		1618
++arma37			MACH_ARMA37		ARMA37			1619
++mendel			MACH_MENDEL		MENDEL			1620
++pelco_iliad		MACH_PELCO_ILIAD	PELCO_ILIAD		1621
++unit2p			MACH_UNIT2P		UNIT2P			1622
++inc20otter		MACH_INC20OTTER		INC20OTTER		1623
++at91sam9g20ek		MACH_AT91SAM9G20EK	AT91SAM9G20EK		1624
++sc_ge2			MACH_STORCENTER		STORCENTER		1625
++smdk6410		MACH_SMDK6410		SMDK6410		1626
++u300			MACH_U300		U300			1627
++u500			MACH_U500		U500			1628
++ds9260			MACH_DS9260		DS9260			1629
++riverrock		MACH_RIVERROCK		RIVERROCK		1630
++scibath			MACH_SCIBATH		SCIBATH			1631
++at91sam7se		MACH_AT91SAM7SE512EK	AT91SAM7SE512EK		1632
++wrt350n_v2		MACH_WRT350N_V2		WRT350N_V2		1633
++multimedia		MACH_MULTIMEDIA		MULTIMEDIA		1634
++marvin			MACH_MARVIN		MARVIN			1635
++x500			MACH_X500		X500			1636
++awlug4lcu		MACH_AWLUG4LCU		AWLUG4LCU		1637
++palermoc		MACH_PALERMOC		PALERMOC		1638
++omap_ldp		MACH_OMAP_LDP		OMAP_LDP		1639
++ip500			MACH_IP500		IP500			1640
++ase2			MACH_ASE2		ASE2			1642
++mx35evb			MACH_MX35EVB		MX35EVB			1643
++aml_m8050		MACH_AML_M8050		AML_M8050		1644
++mx35_3ds		MACH_MX35_3DS		MX35_3DS		1645
++mars			MACH_MARS		MARS			1646
++neuros_osd2		MACH_NEUROS_OSD2	NEUROS_OSD2		1647
++badger			MACH_BADGER		BADGER			1648
++trizeps4wl		MACH_TRIZEPS4WL		TRIZEPS4WL		1649
++trizeps5		MACH_TRIZEPS5		TRIZEPS5		1650
++marlin			MACH_MARLIN		MARLIN			1651
++ts78xx			MACH_TS78XX		TS78XX			1652
++hpipaq214		MACH_HPIPAQ214		HPIPAQ214		1653
++at572d940dcm		MACH_AT572D940DCM	AT572D940DCM		1654
++ne1board		MACH_NE1BOARD		NE1BOARD		1655
++zante			MACH_ZANTE		ZANTE			1656
++sffsdr			MACH_SFFSDR		SFFSDR			1657
++tw2662			MACH_TW2662		TW2662			1658
++vf10xx			MACH_VF10XX		VF10XX			1659
++zoran43xx		MACH_ZORAN43XX		ZORAN43XX		1660
++sonix926		MACH_SONIX926		SONIX926		1661
++celestialsemi		MACH_CELESTIALSEMI	CELESTIALSEMI		1662
++cc9m2443js		MACH_CC9M2443JS		CC9M2443JS		1663
++tw5334			MACH_TW5334		TW5334			1664
++omap_htcartemis		MACH_HTCARTEMIS		HTCARTEMIS		1665
++nal_hlite		MACH_NAL_HLITE		NAL_HLITE		1666
++htcvogue		MACH_HTCVOGUE		HTCVOGUE		1667
++smartweb		MACH_SMARTWEB		SMARTWEB		1668
++mv86xx			MACH_MV86XX		MV86XX			1669
++mv87xx			MACH_MV87XX		MV87XX			1670
++songyoungho		MACH_SONGYOUNGHO	SONGYOUNGHO		1671
++younghotema		MACH_YOUNGHOTEMA	YOUNGHOTEMA		1672
++pcm037			MACH_PCM037		PCM037			1673
++mmvp			MACH_MMVP		MMVP			1674
++mmap			MACH_MMAP		MMAP			1675
++ptid2410		MACH_PTID2410		PTID2410		1676
++james_926		MACH_JAMES_926		JAMES_926		1677
++fm6000			MACH_FM6000		FM6000			1678
++db88f6281_bp		MACH_DB88F6281_BP	DB88F6281_BP		1680
++rd88f6192_nas		MACH_RD88F6192_NAS	RD88F6192_NAS		1681
++rd88f6281		MACH_RD88F6281		RD88F6281		1682
++db78x00_bp		MACH_DB78X00_BP		DB78X00_BP		1683
++smdk2416		MACH_SMDK2416		SMDK2416		1685
++oce_spider_si		MACH_OCE_SPIDER_SI	OCE_SPIDER_SI		1686
++oce_spider_sk		MACH_OCE_SPIDER_SK	OCE_SPIDER_SK		1687
++rovern6			MACH_ROVERN6		ROVERN6			1688
++pelco_evolution		MACH_PELCO_EVOLUTION	PELCO_EVOLUTION		1689
++wbd111			MACH_WBD111		WBD111			1690
++elaracpe		MACH_ELARACPE		ELARACPE		1691
++mabv3			MACH_MABV3		MABV3			1692
++mv2120			MACH_MV2120		MV2120			1693
++csb737			MACH_CSB737		CSB737			1695
++mx51_3ds		MACH_MX51_3DS		MX51_3DS		1696
++g900			MACH_G900		G900			1697
++apf27			MACH_APF27		APF27			1698
++ggus2000		MACH_GGUS2000		GGUS2000		1699
++omap_2430_mimic		MACH_OMAP_2430_MIMIC	OMAP_2430_MIMIC		1700
++imx27lite		MACH_IMX27LITE		IMX27LITE		1701
++almex			MACH_ALMEX		ALMEX			1702
++control			MACH_CONTROL		CONTROL			1703
++mba2410			MACH_MBA2410		MBA2410			1704
++volcano			MACH_VOLCANO		VOLCANO			1705
++zenith			MACH_ZENITH		ZENITH			1706
++muchip			MACH_MUCHIP		MUCHIP			1707
++magellan		MACH_MAGELLAN		MAGELLAN		1708
++usb_a9260		MACH_USB_A9260		USB_A9260		1709
++usb_a9263		MACH_USB_A9263		USB_A9263		1710
++qil_a9260		MACH_QIL_A9260		QIL_A9260		1711
++cme9210			MACH_CME9210		CME9210			1712
++hczh4			MACH_HCZH4		HCZH4			1713
++spearbasic		MACH_SPEARBASIC		SPEARBASIC		1714
++dep2440			MACH_DEP2440		DEP2440			1715
++hdl_gxr			MACH_HDL_GXR		HDL_GXR			1716
++hdl_gt			MACH_HDL_GT		HDL_GT			1717
++hdl_4g			MACH_HDL_4G		HDL_4G			1718
++s3c6000			MACH_S3C6000		S3C6000			1719
++mmsp2_mdk		MACH_MMSP2_MDK		MMSP2_MDK		1720
++mpx220			MACH_MPX220		MPX220			1721
++kzm_arm11_01		MACH_KZM_ARM11_01	KZM_ARM11_01		1722
++htc_polaris		MACH_HTC_POLARIS	HTC_POLARIS		1723
++htc_kaiser		MACH_HTC_KAISER		HTC_KAISER		1724
++lg_ks20			MACH_LG_KS20		LG_KS20			1725
++hhgps			MACH_HHGPS		HHGPS			1726
++nokia_n810_wimax	MACH_NOKIA_N810_WIMAX	NOKIA_N810_WIMAX	1727
++insight			MACH_INSIGHT		INSIGHT			1728
++sapphire		MACH_SAPPHIRE		SAPPHIRE		1729
++csb637xo		MACH_CSB637XO		CSB637XO		1730
++evisiong		MACH_EVISIONG		EVISIONG		1731
++stmp37xx		MACH_STMP37XX		STMP37XX		1732
++stmp378x		MACH_STMP378X		STMP378X		1733
++tnt			MACH_TNT		TNT			1734
++tbxt			MACH_TBXT		TBXT			1735
++playmate		MACH_PLAYMATE		PLAYMATE		1736
++pns10			MACH_PNS10		PNS10			1737
++eznavi			MACH_EZNAVI		EZNAVI			1738
++ps4000			MACH_PS4000		PS4000			1739
++ezx_a780		MACH_EZX_A780		EZX_A780		1740
++ezx_e680		MACH_EZX_E680		EZX_E680		1741
++ezx_a1200		MACH_EZX_A1200		EZX_A1200		1742
++ezx_e6			MACH_EZX_E6		EZX_E6			1743
++ezx_e2			MACH_EZX_E2		EZX_E2			1744
++ezx_a910		MACH_EZX_A910		EZX_A910		1745
++cwmx31			MACH_CWMX31		CWMX31			1746
++sl2312			MACH_SL2312		SL2312			1747
++blenny			MACH_BLENNY		BLENNY			1748
++ds107			MACH_DS107		DS107			1749
++dsx07			MACH_DSX07		DSX07			1750
++picocom1		MACH_PICOCOM1		PICOCOM1		1751
++lynx_wolverine		MACH_LYNX_WOLVERINE	LYNX_WOLVERINE		1752
++ubisys_p9_sc19		MACH_UBISYS_P9_SC19	UBISYS_P9_SC19		1753
++kratos_low		MACH_KRATOS_LOW		KRATOS_LOW		1754
++m700			MACH_M700		M700			1755
++edmini_v2		MACH_EDMINI_V2		EDMINI_V2		1756
++zipit2			MACH_ZIPIT2		ZIPIT2			1757
++hslfemtocell		MACH_HSLFEMTOCELL	HSLFEMTOCELL		1758
++daintree_at91		MACH_DAINTREE_AT91	DAINTREE_AT91		1759
++sg560usb		MACH_SG560USB		SG560USB		1760
++omap3_pandora		MACH_OMAP3_PANDORA	OMAP3_PANDORA		1761
++usr8200			MACH_USR8200		USR8200			1762
++s1s65k			MACH_S1S65K		S1S65K			1763
++s2s65a			MACH_S2S65A		S2S65A			1764
++icore			MACH_ICORE		ICORE			1765
++mss2			MACH_MSS2		MSS2			1766
++belmont			MACH_BELMONT		BELMONT			1767
++asusp525		MACH_ASUSP525		ASUSP525		1768
++lb88rc8480		MACH_LB88RC8480		LB88RC8480		1769
++hipxa			MACH_HIPXA		HIPXA			1770
++mx25_3ds		MACH_MX25_3DS		MX25_3DS		1771
++m800			MACH_M800		M800			1772
++omap3530_lv_som		MACH_OMAP3530_LV_SOM	OMAP3530_LV_SOM		1773
++prima_evb		MACH_PRIMA_EVB		PRIMA_EVB		1774
++mx31bt1			MACH_MX31BT1		MX31BT1			1775
++atlas4_evb		MACH_ATLAS4_EVB		ATLAS4_EVB		1776
++mx31cicada		MACH_MX31CICADA		MX31CICADA		1777
++mi424wr			MACH_MI424WR		MI424WR			1778
++axs_ultrax		MACH_AXS_ULTRAX		AXS_ULTRAX		1779
++at572d940deb		MACH_AT572D940DEB	AT572D940DEB		1780
++davinci_da830_evm	MACH_DAVINCI_DA830_EVM	DAVINCI_DA830_EVM	1781
++ep9302			MACH_EP9302		EP9302			1782
++at572d940hfek		MACH_AT572D940HFEB	AT572D940HFEB		1783
++cybook3			MACH_CYBOOK3		CYBOOK3			1784
++wdg002			MACH_WDG002		WDG002			1785
++sg560adsl		MACH_SG560ADSL		SG560ADSL		1786
++nextio_n2800_ica	MACH_NEXTIO_N2800_ICA	NEXTIO_N2800_ICA	1787
++dove_db			MACH_DOVE_DB		DOVE_DB			1788
++marvell_newdb		MACH_MARVELL_NEWDB	MARVELL_NEWDB		1789
++vandihud		MACH_VANDIHUD		VANDIHUD		1790
++magx_e8			MACH_MAGX_E8		MAGX_E8			1791
++magx_z6			MACH_MAGX_Z6		MAGX_Z6			1792
++magx_v8			MACH_MAGX_V8		MAGX_V8			1793
++magx_u9			MACH_MAGX_U9		MAGX_U9			1794
++toughcf08		MACH_TOUGHCF08		TOUGHCF08		1795
++zw4400			MACH_ZW4400		ZW4400			1796
++marat91			MACH_MARAT91		MARAT91			1797
++overo			MACH_OVERO		OVERO			1798
++at2440evb		MACH_AT2440EVB		AT2440EVB		1799
++neocore926		MACH_NEOCORE926		NEOCORE926		1800
++wnr854t			MACH_WNR854T		WNR854T			1801
++imx27			MACH_IMX27		IMX27			1802
++moose_db		MACH_MOOSE_DB		MOOSE_DB		1803
++fab4			MACH_FAB4		FAB4			1804
++htcdiamond		MACH_HTCDIAMOND		HTCDIAMOND		1805
++fiona			MACH_FIONA		FIONA			1806
++mxc30030_x		MACH_MXC30030_X		MXC30030_X		1807
++bmp1000			MACH_BMP1000		BMP1000			1808
++logi9200		MACH_LOGI9200		LOGI9200		1809
++tqma31			MACH_TQMA31		TQMA31			1810
++ccw9p9215js		MACH_CCW9P9215JS	CCW9P9215JS		1811
++rd88f5181l_ge		MACH_RD88F5181L_GE	RD88F5181L_GE		1812
++sifmain			MACH_SIFMAIN		SIFMAIN			1813
++sam9_l9261		MACH_SAM9_L9261		SAM9_L9261		1814
++cc9m2443		MACH_CC9M2443		CC9M2443		1815
++xaria300		MACH_XARIA300		XARIA300		1816
++it9200			MACH_IT9200		IT9200			1817
++rd88f5181l_fxo		MACH_RD88F5181L_FXO	RD88F5181L_FXO		1818
++kriss_sensor		MACH_KRISS_SENSOR	KRISS_SENSOR		1819
++pilz_pmi5		MACH_PILZ_PMI5		PILZ_PMI5		1820
++jade			MACH_JADE		JADE			1821
++ks8695_softplc		MACH_KS8695_SOFTPLC	KS8695_SOFTPLC		1822
++gprisc3			MACH_GPRISC3		GPRISC3			1823
++stamp9g20		MACH_STAMP9G20		STAMP9G20		1824
++smdk6430		MACH_SMDK6430		SMDK6430		1825
++smdkc100		MACH_SMDKC100		SMDKC100		1826
++tavorevb		MACH_TAVOREVB		TAVOREVB		1827
++saar			MACH_SAAR		SAAR			1828
++deister_eyecam		MACH_DEISTER_EYECAM	DEISTER_EYECAM		1829
++at91sam9m10g45ek	MACH_AT91SAM9M10G45EK	AT91SAM9M10G45EK	1830
++linkstation_produo	MACH_LINKSTATION_PRODUO	LINKSTATION_PRODUO	1831
++hit_b0			MACH_HIT_B0		HIT_B0			1832
++adx_rmu			MACH_ADX_RMU		ADX_RMU			1833
++xg_cpe_main		MACH_XG_CPE_MAIN	XG_CPE_MAIN		1834
++edb9407a		MACH_EDB9407A		EDB9407A		1835
++dtb9608			MACH_DTB9608		DTB9608			1836
++em104v1			MACH_EM104V1		EM104V1			1837
++demo			MACH_DEMO		DEMO			1838
++logi9260		MACH_LOGI9260		LOGI9260		1839
++mx31_exm32		MACH_MX31_EXM32		MX31_EXM32		1840
++usb_a9g20		MACH_USB_A9G20		USB_A9G20		1841
++picproje2008		MACH_PICPROJE2008	PICPROJE2008		1842
++cs_e9315		MACH_CS_E9315		CS_E9315		1843
++qil_a9g20		MACH_QIL_A9G20		QIL_A9G20		1844
++sha_pon020		MACH_SHA_PON020		SHA_PON020		1845
++nad			MACH_NAD		NAD			1846
++sbc35_a9260		MACH_SBC35_A9260	SBC35_A9260		1847
++sbc35_a9g20		MACH_SBC35_A9G20	SBC35_A9G20		1848
++davinci_beginning	MACH_DAVINCI_BEGINNING	DAVINCI_BEGINNING	1849
++uwc			MACH_UWC		UWC			1850
++mxlads			MACH_MXLADS		MXLADS			1851
++htcnike			MACH_HTCNIKE		HTCNIKE			1852
++deister_pxa270		MACH_DEISTER_PXA270	DEISTER_PXA270		1853
++cme9210js		MACH_CME9210JS		CME9210JS		1854
++cc9p9360		MACH_CC9P9360		CC9P9360		1855
++mocha			MACH_MOCHA		MOCHA			1856
++wapd170ag		MACH_WAPD170AG		WAPD170AG		1857
++linkstation_mini	MACH_LINKSTATION_MINI	LINKSTATION_MINI	1858
++afeb9260		MACH_AFEB9260		AFEB9260		1859
++w90x900			MACH_W90X900		W90X900			1860
++w90x700			MACH_W90X700		W90X700			1861
++kt300ip			MACH_KT300IP		KT300IP			1862
++kt300ip_g20		MACH_KT300IP_G20	KT300IP_G20		1863
++srcm			MACH_SRCM		SRCM			1864
++wlnx_9260		MACH_WLNX_9260		WLNX_9260		1865
++openmoko_gta03		MACH_OPENMOKO_GTA03	OPENMOKO_GTA03		1866
++osprey2			MACH_OSPREY2		OSPREY2			1867
++kbio9260		MACH_KBIO9260		KBIO9260		1868
++ginza			MACH_GINZA		GINZA			1869
++a636n			MACH_A636N		A636N			1870
++imx27ipcam		MACH_IMX27IPCAM		IMX27IPCAM		1871
++nemoc			MACH_NEMOC		NEMOC			1872
++geneva			MACH_GENEVA		GENEVA			1873
++htcpharos		MACH_HTCPHAROS		HTCPHAROS		1874
++neonc			MACH_NEONC		NEONC			1875
++nas7100			MACH_NAS7100		NAS7100			1876
++teuphone		MACH_TEUPHONE		TEUPHONE		1877
++annax_eth2		MACH_ANNAX_ETH2		ANNAX_ETH2		1878
++csb733			MACH_CSB733		CSB733			1879
++bk3			MACH_BK3		BK3			1880
++omap_em32		MACH_OMAP_EM32		OMAP_EM32		1881
++et9261cp		MACH_ET9261CP		ET9261CP		1882
++jasperc			MACH_JASPERC		JASPERC			1883
++issi_arm9		MACH_ISSI_ARM9		ISSI_ARM9		1884
++ued			MACH_UED		UED			1885
++esiblade		MACH_ESIBLADE		ESIBLADE		1886
++eye02			MACH_EYE02		EYE02			1887
++imx27kbd		MACH_IMX27KBD		IMX27KBD		1888
++sst61vc010_fpga		MACH_SST61VC010_FPGA	SST61VC010_FPGA		1889
++kixvp435		MACH_KIXVP435		KIXVP435		1890
++kixnp435		MACH_KIXNP435		KIXNP435		1891
++africa			MACH_AFRICA		AFRICA			1892
++nh233			MACH_NH233		NH233			1893
++rd88f6183ap_ge		MACH_RD88F6183AP_GE	RD88F6183AP_GE		1894
++bcm4760			MACH_BCM4760		BCM4760			1895
++eddy_v2			MACH_EDDY_V2		EDDY_V2			1896
++realview_pba8		MACH_REALVIEW_PBA8	REALVIEW_PBA8		1897
++hid_a7			MACH_HID_A7		HID_A7			1898
++hero			MACH_HERO		HERO			1899
++omap_poseidon		MACH_OMAP_POSEIDON	OMAP_POSEIDON		1900
++realview_pbx		MACH_REALVIEW_PBX	REALVIEW_PBX		1901
++micro9s			MACH_MICRO9S		MICRO9S			1902
++mako			MACH_MAKO		MAKO			1903
++xdaflame		MACH_XDAFLAME		XDAFLAME		1904
++phidget_sbc2		MACH_PHIDGET_SBC2	PHIDGET_SBC2		1905
++limestone		MACH_LIMESTONE		LIMESTONE		1906
++iprobe_c32		MACH_IPROBE_C32		IPROBE_C32		1907
++rut100			MACH_RUT100		RUT100			1908
++asusp535		MACH_ASUSP535		ASUSP535		1909
++htcraphael		MACH_HTCRAPHAEL		HTCRAPHAEL		1910
++sygdg1			MACH_SYGDG1		SYGDG1			1911
++sygdg2			MACH_SYGDG2		SYGDG2			1912
++seoul			MACH_SEOUL		SEOUL			1913
++salerno			MACH_SALERNO		SALERNO			1914
++ucn_s3c64xx		MACH_UCN_S3C64XX	UCN_S3C64XX		1915
++msm7201a		MACH_MSM7201A		MSM7201A		1916
++lpr1			MACH_LPR1		LPR1			1917
++armadillo500fx		MACH_ARMADILLO500FX	ARMADILLO500FX		1918
++g3evm			MACH_G3EVM		G3EVM			1919
++z3_dm355		MACH_Z3_DM355		Z3_DM355		1920
++w90p910evb		MACH_W90P910EVB		W90P910EVB		1921
++w90p920evb		MACH_W90P920EVB		W90P920EVB		1922
++w90p950evb		MACH_W90P950EVB		W90P950EVB		1923
++w90n960evb		MACH_W90N960EVB		W90N960EVB		1924
++camhd			MACH_CAMHD		CAMHD			1925
++mvc100			MACH_MVC100		MVC100			1926
++electrum_200		MACH_ELECTRUM_200	ELECTRUM_200		1927
++htcjade			MACH_HTCJADE		HTCJADE			1928
++memphis			MACH_MEMPHIS		MEMPHIS			1929
++imx27sbc		MACH_IMX27SBC		IMX27SBC		1930
++lextar			MACH_LEXTAR		LEXTAR			1931
++mv88f6281gtw_ge		MACH_MV88F6281GTW_GE	MV88F6281GTW_GE		1932
++ncp			MACH_NCP		NCP			1933
++z32an_series		MACH_Z32AN		Z32AN			1934
++tmq_capd		MACH_TMQ_CAPD		TMQ_CAPD		1935
++omap3_wl		MACH_OMAP3_WL		OMAP3_WL		1936
++chumby			MACH_CHUMBY		CHUMBY			1937
++atsarm9			MACH_ATSARM9		ATSARM9			1938
++davinci_dm365_evm	MACH_DAVINCI_DM365_EVM	DAVINCI_DM365_EVM	1939
++bahamas			MACH_BAHAMAS		BAHAMAS			1940
++das			MACH_DAS		DAS			1941
++minidas			MACH_MINIDAS		MINIDAS			1942
++vk1000			MACH_VK1000		VK1000			1943
++centro			MACH_CENTRO		CENTRO			1944
++ctera_2bay		MACH_CTERA_2BAY		CTERA_2BAY		1945
++edgeconnect		MACH_EDGECONNECT	EDGECONNECT		1946
++nd27000			MACH_ND27000		ND27000			1947
++cobra			MACH_GEMALTO_COBRA	GEMALTO_COBRA		1948
++ingelabs_comet		MACH_INGELABS_COMET	INGELABS_COMET		1949
++pollux_wiz		MACH_POLLUX_WIZ		POLLUX_WIZ		1950
++blackstone		MACH_BLACKSTONE		BLACKSTONE		1951
++topaz			MACH_TOPAZ		TOPAZ			1952
++aixle			MACH_AIXLE		AIXLE			1953
++mw998			MACH_MW998		MW998			1954
++nokia_rx51		MACH_NOKIA_RX51		NOKIA_RX51		1955
++vsc5605ev		MACH_VSC5605EV		VSC5605EV		1956
++nt98700dk		MACH_NT98700DK		NT98700DK		1957
++icontact		MACH_ICONTACT		ICONTACT		1958
++swarco_frcpu		MACH_SWARCO_FRCPU	SWARCO_FRCPU		1959
++swarco_scpu		MACH_SWARCO_SCPU	SWARCO_SCPU		1960
++bbox_p16		MACH_BBOX_P16		BBOX_P16		1961
++bstd			MACH_BSTD		BSTD			1962
++sbc2440ii		MACH_SBC2440II		SBC2440II		1963
++pcm034			MACH_PCM034		PCM034			1964
++neso			MACH_NESO		NESO			1965
++wlnx_9g20		MACH_WLNX_9G20		WLNX_9G20		1966
++omap_zoom2		MACH_OMAP_ZOOM2		OMAP_ZOOM2		1967
++totemnova		MACH_TOTEMNOVA		TOTEMNOVA		1968
++c5000			MACH_C5000		C5000			1969
++unipo_at91sam9263	MACH_UNIPO_AT91SAM9263	UNIPO_AT91SAM9263	1970
++ethernut5		MACH_ETHERNUT5		ETHERNUT5		1971
++arm11			MACH_ARM11		ARM11			1972
++cpuat9260		MACH_CPUAT9260		CPUAT9260		1973
++cpupxa255		MACH_CPUPXA255		CPUPXA255		1974
++eukrea_cpuimx27		MACH_CPUIMX27		CPUIMX27		1975
++cheflux			MACH_CHEFLUX		CHEFLUX			1976
++eb_cpux9k2		MACH_EB_CPUX9K2		EB_CPUX9K2		1977
++opcotec			MACH_OPCOTEC		OPCOTEC			1978
++yt			MACH_YT			YT			1979
++motoq			MACH_MOTOQ		MOTOQ			1980
++bsb1			MACH_BSB1		BSB1			1981
++acs5k			MACH_ACS5K		ACS5K			1982
++milan			MACH_MILAN		MILAN			1983
++quartzv2		MACH_QUARTZV2		QUARTZV2		1984
++rsvp			MACH_RSVP		RSVP			1985
++rmp200			MACH_RMP200		RMP200			1986
++snapper_9260		MACH_SNAPPER_9260	SNAPPER_9260		1987
++dsm320			MACH_DSM320		DSM320			1988
++adsgcm			MACH_ADSGCM		ADSGCM			1989
++ase2_400		MACH_ASE2_400		ASE2_400		1990
++pizza			MACH_PIZZA		PIZZA			1991
++spot_ngpl		MACH_SPOT_NGPL		SPOT_NGPL		1992
++armata			MACH_ARMATA		ARMATA			1993
++exeda			MACH_EXEDA		EXEDA			1994
++mx31sf005		MACH_MX31SF005		MX31SF005		1995
++f5d8231_4_v2		MACH_F5D8231_4_V2	F5D8231_4_V2		1996
++q2440			MACH_Q2440		Q2440			1997
++qq2440			MACH_QQ2440		QQ2440			1998
++mini2440		MACH_MINI2440		MINI2440		1999
++colibri300		MACH_COLIBRI300		COLIBRI300		2000
++jades			MACH_JADES		JADES			2001
++spark			MACH_SPARK		SPARK			2002
++benzina			MACH_BENZINA		BENZINA			2003
++blaze			MACH_BLAZE		BLAZE			2004
++linkstation_ls_hgl	MACH_LINKSTATION_LS_HGL	LINKSTATION_LS_HGL	2005
++htckovsky		MACH_HTCKOVSKY		HTCKOVSKY		2006
++sony_prs505		MACH_SONY_PRS505	SONY_PRS505		2007
++hanlin_v3		MACH_HANLIN_V3		HANLIN_V3		2008
++sapphira		MACH_SAPPHIRA		SAPPHIRA		2009
++dack_sda_01		MACH_DACK_SDA_01	DACK_SDA_01		2010
++armbox			MACH_ARMBOX		ARMBOX			2011
++harris_rvp		MACH_HARRIS_RVP		HARRIS_RVP		2012
++ribaldo			MACH_RIBALDO		RIBALDO			2013
++agora			MACH_AGORA		AGORA			2014
++omap3_mini		MACH_OMAP3_MINI		OMAP3_MINI		2015
++a9sam6432_b		MACH_A9SAM6432_B	A9SAM6432_B		2016
++usg2410			MACH_USG2410		USG2410			2017
++pc72052_i10_revb	MACH_PC72052_I10_REVB	PC72052_I10_REVB	2018
++mx35_exm32		MACH_MX35_EXM32		MX35_EXM32		2019
++topas910		MACH_TOPAS910		TOPAS910		2020
++hyena			MACH_HYENA		HYENA			2021
++pospax			MACH_POSPAX		POSPAX			2022
++hdl_gx			MACH_HDL_GX		HDL_GX			2023
++ctera_4bay		MACH_CTERA_4BAY		CTERA_4BAY		2024
++ctera_plug_c		MACH_CTERA_PLUG_C	CTERA_PLUG_C		2025
++crwea_plug_i		MACH_CRWEA_PLUG_I	CRWEA_PLUG_I		2026
++egauge2			MACH_EGAUGE2		EGAUGE2			2027
++didj			MACH_DIDJ		DIDJ			2028
++m_s3c2443		MACH_MEISTER		MEISTER			2029
++htcblackstone		MACH_HTCBLACKSTONE	HTCBLACKSTONE		2030
++cpuat9g20		MACH_CPUAT9G20		CPUAT9G20		2031
++smdk6440		MACH_SMDK6440		SMDK6440		2032
++omap_35xx_mvp		MACH_OMAP_35XX_MVP	OMAP_35XX_MVP		2033
++ctera_plug_i		MACH_CTERA_PLUG_I	CTERA_PLUG_I		2034
++pvg610_100		MACH_PVG610		PVG610			2035
++hprw6815		MACH_HPRW6815		HPRW6815		2036
++omap3_oswald		MACH_OMAP3_OSWALD	OMAP3_OSWALD		2037
++nas4220b		MACH_NAS4220B		NAS4220B		2038
++htcraphael_cdma		MACH_HTCRAPHAEL_CDMA	HTCRAPHAEL_CDMA		2039
++htcdiamond_cdma		MACH_HTCDIAMOND_CDMA	HTCDIAMOND_CDMA		2040
++scaler			MACH_SCALER		SCALER			2041
++zylonite2		MACH_ZYLONITE2		ZYLONITE2		2042
++aspenite		MACH_ASPENITE		ASPENITE		2043
++teton			MACH_TETON		TETON			2044
++ttc_dkb			MACH_TTC_DKB		TTC_DKB			2045
++bishop2			MACH_BISHOP2		BISHOP2			2046
++ippv5			MACH_IPPV5		IPPV5			2047
++farm926			MACH_FARM926		FARM926			2048
++mmccpu			MACH_MMCCPU		MMCCPU			2049
++sgmsfl			MACH_SGMSFL		SGMSFL			2050
++tt8000			MACH_TT8000		TT8000			2051
++zrn4300lp		MACH_ZRN4300LP		ZRN4300LP		2052
++mptc			MACH_MPTC		MPTC			2053
++h6051			MACH_H6051		H6051			2054
++pvg610_101		MACH_PVG610_101		PVG610_101		2055
++stamp9261_pc_evb	MACH_STAMP9261_PC_EVB	STAMP9261_PC_EVB	2056
++pelco_odysseus		MACH_PELCO_ODYSSEUS	PELCO_ODYSSEUS		2057
++tny_a9260		MACH_TNY_A9260		TNY_A9260		2058
++tny_a9g20		MACH_TNY_A9G20		TNY_A9G20		2059
++aesop_mp2530f		MACH_AESOP_MP2530F	AESOP_MP2530F		2060
++dx900			MACH_DX900		DX900			2061
++cpodc2			MACH_CPODC2		CPODC2			2062
++tilt_8925		MACH_TILT_8925		TILT_8925		2063
++davinci_dm357_evm	MACH_DAVINCI_DM357_EVM	DAVINCI_DM357_EVM	2064
++swordfish		MACH_SWORDFISH		SWORDFISH		2065
++corvus			MACH_CORVUS		CORVUS			2066
++taurus			MACH_TAURUS		TAURUS			2067
++axm			MACH_AXM		AXM			2068
++axc			MACH_AXC		AXC			2069
++baby			MACH_BABY		BABY			2070
++mp200			MACH_MP200		MP200			2071
++pcm043			MACH_PCM043		PCM043			2072
++hanlin_v3c		MACH_HANLIN_V3C		HANLIN_V3C		2073
++kbk9g20			MACH_KBK9G20		KBK9G20			2074
++adsturbog5		MACH_ADSTURBOG5		ADSTURBOG5		2075
++avenger_lite1		MACH_AVENGER_LITE1	AVENGER_LITE1		2076
++suc82x			MACH_SUC		SUC			2077
++at91sam7s256		MACH_AT91SAM7S256	AT91SAM7S256		2078
++mendoza			MACH_MENDOZA		MENDOZA			2079
++kira			MACH_KIRA		KIRA			2080
++mx1hbm			MACH_MX1HBM		MX1HBM			2081
++quatro43xx		MACH_QUATRO43XX		QUATRO43XX		2082
++quatro4230		MACH_QUATRO4230		QUATRO4230		2083
++nsb400			MACH_NSB400		NSB400			2084
++drp255			MACH_DRP255		DRP255			2085
++thoth			MACH_THOTH		THOTH			2086
++firestone		MACH_FIRESTONE		FIRESTONE		2087
++asusp750		MACH_ASUSP750		ASUSP750		2088
++ctera_dl		MACH_CTERA_DL		CTERA_DL		2089
++socr			MACH_SOCR		SOCR			2090
++htcoxygen		MACH_HTCOXYGEN		HTCOXYGEN		2091
++heroc			MACH_HEROC		HEROC			2092
++zeno6800		MACH_ZENO6800		ZENO6800		2093
++sc2mcs			MACH_SC2MCS		SC2MCS			2094
++gene100			MACH_GENE100		GENE100			2095
++as353x			MACH_AS353X		AS353X			2096
++sheevaplug		MACH_SHEEVAPLUG		SHEEVAPLUG		2097
++at91sam9g20		MACH_AT91SAM9G20	AT91SAM9G20		2098
++mv88f6192gtw_fe		MACH_MV88F6192GTW_FE	MV88F6192GTW_FE		2099
++cc9200			MACH_CC9200		CC9200			2100
++sm9200			MACH_SM9200		SM9200			2101
++tp9200			MACH_TP9200		TP9200			2102
++snapperdv		MACH_SNAPPERDV		SNAPPERDV		2103
++avengers_lite		MACH_AVENGERS_LITE	AVENGERS_LITE		2104
++avengers_lite1		MACH_AVENGERS_LITE1	AVENGERS_LITE1		2105
++omap3axon		MACH_OMAP3AXON		OMAP3AXON		2106
++ma8xx			MACH_MA8XX		MA8XX			2107
++mp201ek			MACH_MP201EK		MP201EK			2108
++davinci_tux		MACH_DAVINCI_TUX	DAVINCI_TUX		2109
++mpa1600			MACH_MPA1600		MPA1600			2110
++pelco_troy		MACH_PELCO_TROY		PELCO_TROY		2111
++nsb667			MACH_NSB667		NSB667			2112
++rovers5_4mpix		MACH_ROVERS5_4MPIX	ROVERS5_4MPIX		2113
++twocom			MACH_TWOCOM		TWOCOM			2114
++ubisys_p9_rcu3r2	MACH_UBISYS_P9_RCU3R2	UBISYS_P9_RCU3R2	2115
++hero_espresso		MACH_HERO_ESPRESSO	HERO_ESPRESSO		2116
++afeusb			MACH_AFEUSB		AFEUSB			2117
++t830			MACH_T830		T830			2118
++spd8020_cc		MACH_SPD8020_CC		SPD8020_CC		2119
++om_3d7k			MACH_OM_3D7K		OM_3D7K			2120
++picocom2		MACH_PICOCOM2		PICOCOM2		2121
++uwg4mx27		MACH_UWG4MX27		UWG4MX27		2122
++uwg4mx31		MACH_UWG4MX31		UWG4MX31		2123
++cherry			MACH_CHERRY		CHERRY			2124
++mx51_babbage		MACH_MX51_BABBAGE	MX51_BABBAGE		2125
++s3c2440turkiye		MACH_S3C2440TURKIYE	S3C2440TURKIYE		2126
++tx37			MACH_TX37		TX37			2127
++sbc2800_9g20		MACH_SBC2800_9G20	SBC2800_9G20		2128
++benzglb			MACH_BENZGLB		BENZGLB			2129
++benztd			MACH_BENZTD		BENZTD			2130
++cartesio_plus		MACH_CARTESIO_PLUS	CARTESIO_PLUS		2131
++solrad_g20		MACH_SOLRAD_G20		SOLRAD_G20		2132
++mx27wallace		MACH_MX27WALLACE	MX27WALLACE		2133
++fmzwebmodul		MACH_FMZWEBMODUL	FMZWEBMODUL		2134
++rd78x00_masa		MACH_RD78X00_MASA	RD78X00_MASA		2135
++smallogger		MACH_SMALLOGGER		SMALLOGGER		2136
++ccw9p9215		MACH_CCW9P9215		CCW9P9215		2137
++dm355_leopard		MACH_DM355_LEOPARD	DM355_LEOPARD		2138
++ts219			MACH_TS219		TS219			2139
++tny_a9263		MACH_TNY_A9263		TNY_A9263		2140
++apollo			MACH_APOLLO		APOLLO			2141
++at91cap9stk		MACH_AT91CAP9STK	AT91CAP9STK		2142
++spc300			MACH_SPC300		SPC300			2143
++eko			MACH_EKO		EKO			2144
++ccw9m2443		MACH_CCW9M2443		CCW9M2443		2145
++ccw9m2443js		MACH_CCW9M2443JS	CCW9M2443JS		2146
++m2m_router_device	MACH_M2M_ROUTER_DEVICE	M2M_ROUTER_DEVICE	2147
++str9104nas		MACH_STAR9104NAS	STAR9104NAS		2148
++pca100			MACH_PCA100		PCA100			2149
++z3_dm365_mod_01		MACH_Z3_DM365_MOD_01	Z3_DM365_MOD_01		2150
++hipox			MACH_HIPOX		HIPOX			2151
++omap3_piteds		MACH_OMAP3_PITEDS	OMAP3_PITEDS		2152
++bm150r			MACH_BM150R		BM150R			2153
++tbone			MACH_TBONE		TBONE			2154
++merlin			MACH_MERLIN		MERLIN			2155
++falcon			MACH_FALCON		FALCON			2156
++davinci_da850_evm	MACH_DAVINCI_DA850_EVM	DAVINCI_DA850_EVM	2157
++s5p6440			MACH_S5P6440		S5P6440			2158
++at91sam9g10ek		MACH_AT91SAM9G10EK	AT91SAM9G10EK		2159
++omap_4430sdp		MACH_OMAP_4430SDP	OMAP_4430SDP		2160
++lpc313x			MACH_LPC313X		LPC313X			2161
++magx_zn5		MACH_MAGX_ZN5		MAGX_ZN5		2162
++magx_em30		MACH_MAGX_EM30		MAGX_EM30		2163
++magx_ve66		MACH_MAGX_VE66		MAGX_VE66		2164
++meesc			MACH_MEESC		MEESC			2165
++otc570			MACH_OTC570		OTC570			2166
++bcu2412			MACH_BCU2412		BCU2412			2167
++beacon			MACH_BEACON		BEACON			2168
++actia_tgw		MACH_ACTIA_TGW		ACTIA_TGW		2169
++e4430			MACH_E4430		E4430			2170
++ql300			MACH_QL300		QL300			2171
++btmavb101		MACH_BTMAVB101		BTMAVB101		2172
++btmawb101		MACH_BTMAWB101		BTMAWB101		2173
++sq201			MACH_SQ201		SQ201			2174
++quatro45xx		MACH_QUATRO45XX		QUATRO45XX		2175
++openpad			MACH_OPENPAD		OPENPAD			2176
++tx25			MACH_TX25		TX25			2177
++omap3_torpedo		MACH_OMAP3_TORPEDO	OMAP3_TORPEDO		2178
++htcraphael_k		MACH_HTCRAPHAEL_K	HTCRAPHAEL_K		2179
++lal43			MACH_LAL43		LAL43			2181
++htcraphael_cdma500	MACH_HTCRAPHAEL_CDMA500	HTCRAPHAEL_CDMA500	2182
++anw6410			MACH_ANW6410		ANW6410			2183
++htcprophet		MACH_HTCPROPHET		HTCPROPHET		2185
++cfa_10022		MACH_CFA_10022		CFA_10022		2186
++imx27_visstrim_m10	MACH_IMX27_VISSTRIM_M10	IMX27_VISSTRIM_M10	2187
++px2imx27		MACH_PX2IMX27		PX2IMX27		2188
++stm3210e_eval		MACH_STM3210E_EVAL	STM3210E_EVAL		2189
++dvs10			MACH_DVS10		DVS10			2190
++portuxg20		MACH_PORTUXG20		PORTUXG20		2191
++arm_spv			MACH_ARM_SPV		ARM_SPV			2192
++smdkc110		MACH_SMDKC110		SMDKC110		2193
++cabespresso		MACH_CABESPRESSO	CABESPRESSO		2194
++hmc800			MACH_HMC800		HMC800			2195
++sholes			MACH_SHOLES		SHOLES			2196
++btmxc31			MACH_BTMXC31		BTMXC31			2197
++dt501			MACH_DT501		DT501			2198
++ktx			MACH_KTX		KTX			2199
++omap3517evm		MACH_OMAP3517EVM	OMAP3517EVM		2200
++netspace_v2		MACH_NETSPACE_V2	NETSPACE_V2		2201
++netspace_max_v2		MACH_NETSPACE_MAX_V2	NETSPACE_MAX_V2		2202
++d2net_v2		MACH_D2NET_V2		D2NET_V2		2203
++net2big_v2		MACH_NET2BIG_V2		NET2BIG_V2		2204
++net4big_v2		MACH_NET4BIG_V2		NET4BIG_V2		2205
++net5big_v2		MACH_NET5BIG_V2		NET5BIG_V2		2206
++endb2443		MACH_ENDB2443		ENDB2443		2207
++inetspace_v2		MACH_INETSPACE_V2	INETSPACE_V2		2208
++tros			MACH_TROS		TROS			2209
++pelco_homer		MACH_PELCO_HOMER	PELCO_HOMER		2210
++ofsp8			MACH_OFSP8		OFSP8			2211
++at91sam9g45ekes		MACH_AT91SAM9G45EKES	AT91SAM9G45EKES		2212
++guf_cupid		MACH_GUF_CUPID		GUF_CUPID		2213
++eab1r			MACH_EAB1R		EAB1R			2214
++desirec			MACH_DESIREC		DESIREC			2215
++cordoba			MACH_CORDOBA		CORDOBA			2216
++irvine			MACH_IRVINE		IRVINE			2217
++sff772			MACH_SFF772		SFF772			2218
++pelco_milano		MACH_PELCO_MILANO	PELCO_MILANO		2219
++pc7302			MACH_PC7302		PC7302			2220
++bip6000			MACH_BIP6000		BIP6000			2221
++silvermoon		MACH_SILVERMOON		SILVERMOON		2222
++vc0830			MACH_VC0830		VC0830			2223
++dt430			MACH_DT430		DT430			2224
++ji42pf			MACH_JI42PF		JI42PF			2225
++gnet_ksm		MACH_GNET_KSM		GNET_KSM		2226
++gnet_sgm		MACH_GNET_SGM		GNET_SGM		2227
++gnet_sgr		MACH_GNET_SGR		GNET_SGR		2228
++omap3_icetekevm		MACH_OMAP3_ICETEKEVM	OMAP3_ICETEKEVM		2229
++pnp			MACH_PNP		PNP			2230
++ctera_2bay_k		MACH_CTERA_2BAY_K	CTERA_2BAY_K		2231
++ctera_2bay_u		MACH_CTERA_2BAY_U	CTERA_2BAY_U		2232
++sas_c			MACH_SAS_C		SAS_C			2233
++vma2315			MACH_VMA2315		VMA2315			2234
++vcs			MACH_VCS		VCS			2235
++spear600		MACH_SPEAR600		SPEAR600		2236
++spear300		MACH_SPEAR300		SPEAR300		2237
++spear1300		MACH_SPEAR1300		SPEAR1300		2238
++lilly1131		MACH_LILLY1131		LILLY1131		2239
++arvoo_ax301		MACH_ARVOO_AX301	ARVOO_AX301		2240
++mapphone		MACH_MAPPHONE		MAPPHONE		2241
++legend			MACH_LEGEND		LEGEND			2242
++salsa			MACH_SALSA		SALSA			2243
++lounge			MACH_LOUNGE		LOUNGE			2244
++vision			MACH_VISION		VISION			2245
++vmb20			MACH_VMB20		VMB20			2246
++hy2410			MACH_HY2410		HY2410			2247
++hy9315			MACH_HY9315		HY9315			2248
++bullwinkle		MACH_BULLWINKLE		BULLWINKLE		2249
++arm_ultimator2		MACH_ARM_ULTIMATOR2	ARM_ULTIMATOR2		2250
++vs_v210			MACH_VS_V210		VS_V210			2252
++vs_v212			MACH_VS_V212		VS_V212			2253
++hmt			MACH_HMT		HMT			2254
++suen3			MACH_SUEN3		SUEN3			2255
++vesper			MACH_VESPER		VESPER			2256
++str9			MACH_STR9		STR9			2257
++omap3_wl_ff		MACH_OMAP3_WL_FF	OMAP3_WL_FF		2258
++simcom			MACH_SIMCOM		SIMCOM			2259
++mcwebio			MACH_MCWEBIO		MCWEBIO			2260
++omap3_phrazer		MACH_OMAP3_PHRAZER	OMAP3_PHRAZER		2261
++darwin			MACH_DARWIN		DARWIN			2262
++oratiscomu		MACH_ORATISCOMU		ORATISCOMU		2263
++rtsbc20			MACH_RTSBC20		RTSBC20			2264
++sgh_i780		MACH_I780		I780			2265
++gemini324		MACH_GEMINI324		GEMINI324		2266
++oratislan		MACH_ORATISLAN		ORATISLAN		2267
++oratisalog		MACH_ORATISALOG		ORATISALOG		2268
++oratismadi		MACH_ORATISMADI		ORATISMADI		2269
++oratisot16		MACH_ORATISOT16		ORATISOT16		2270
++oratisdesk		MACH_ORATISDESK		ORATISDESK		2271
++vexpress		MACH_VEXPRESS		VEXPRESS		2272
++sintexo			MACH_SINTEXO		SINTEXO			2273
++cm3389			MACH_CM3389		CM3389			2274
++omap3_cio		MACH_OMAP3_CIO		OMAP3_CIO		2275
++sgh_i900		MACH_SGH_I900		SGH_I900		2276
++bst100			MACH_BST100		BST100			2277
++passion			MACH_PASSION		PASSION			2278
++indesign_at91sam	MACH_INDESIGN_AT91SAM	INDESIGN_AT91SAM	2279
++c4_badger		MACH_C4_BADGER		C4_BADGER		2280
++c4_viper		MACH_C4_VIPER		C4_VIPER		2281
++d2net			MACH_D2NET		D2NET			2282
++bigdisk			MACH_BIGDISK		BIGDISK			2283
++notalvision		MACH_NOTALVISION	NOTALVISION		2284
++omap3_kboc		MACH_OMAP3_KBOC		OMAP3_KBOC		2285
++cyclone			MACH_CYCLONE		CYCLONE			2286
++ninja			MACH_NINJA		NINJA			2287
++at91sam9g20ek_2mmc	MACH_AT91SAM9G20EK_2MMC	AT91SAM9G20EK_2MMC	2288
++bcmring			MACH_BCMRING		BCMRING			2289
++resol_dl2		MACH_RESOL_DL2		RESOL_DL2		2290
++ifosw			MACH_IFOSW		IFOSW			2291
++htcrhodium		MACH_HTCRHODIUM		HTCRHODIUM		2292
++htctopaz		MACH_HTCTOPAZ		HTCTOPAZ		2293
++matrix504		MACH_MATRIX504		MATRIX504		2294
++mrfsa			MACH_MRFSA		MRFSA			2295
++sc_p270			MACH_SC_P270		SC_P270			2296
++atlas5_evb		MACH_ATLAS5_EVB		ATLAS5_EVB		2297
++pelco_lobox		MACH_PELCO_LOBOX	PELCO_LOBOX		2298
++dilax_pcu200		MACH_DILAX_PCU200	DILAX_PCU200		2299
++leonardo		MACH_LEONARDO		LEONARDO		2300
++zoran_approach7		MACH_ZORAN_APPROACH7	ZORAN_APPROACH7		2301
++dp6xx			MACH_DP6XX		DP6XX			2302
++bcm2153_vesper		MACH_BCM2153_VESPER	BCM2153_VESPER		2303
++mahimahi		MACH_MAHIMAHI		MAHIMAHI		2304
++clickc			MACH_CLICKC		CLICKC			2305
++zb_gateway		MACH_ZB_GATEWAY		ZB_GATEWAY		2306
++tazcard			MACH_TAZCARD		TAZCARD			2307
++tazdev			MACH_TAZDEV		TAZDEV			2308
++annax_cb_arm		MACH_ANNAX_CB_ARM	ANNAX_CB_ARM		2309
++annax_dm3		MACH_ANNAX_DM3		ANNAX_DM3		2310
++cerebric		MACH_CEREBRIC		CEREBRIC		2311
++orca			MACH_ORCA		ORCA			2312
++pc9260			MACH_PC9260		PC9260			2313
++ems285a			MACH_EMS285A		EMS285A			2314
++gec2410			MACH_GEC2410		GEC2410			2315
++gec2440			MACH_GEC2440		GEC2440			2316
++mw903			MACH_ARCH_MW903		ARCH_MW903		2317
++mw2440			MACH_MW2440		MW2440			2318
++ecac2378		MACH_ECAC2378		ECAC2378		2319
++tazkiosk		MACH_TAZKIOSK		TAZKIOSK		2320
++whiterabbit_mch		MACH_WHITERABBIT_MCH	WHITERABBIT_MCH		2321
++sbox9263		MACH_SBOX9263		SBOX9263		2322
++oreo			MACH_OREO		OREO			2323
++smdk6442		MACH_SMDK6442		SMDK6442		2324
++openrd_base		MACH_OPENRD_BASE	OPENRD_BASE		2325
++incredible		MACH_INCREDIBLE		INCREDIBLE		2326
++incrediblec		MACH_INCREDIBLEC	INCREDIBLEC		2327
++heroct			MACH_HEROCT		HEROCT			2328
++mmnet1000		MACH_MMNET1000		MMNET1000		2329
++devkit8000		MACH_DEVKIT8000		DEVKIT8000		2330
++devkit9000		MACH_DEVKIT9000		DEVKIT9000		2331
++mx31txtr		MACH_MX31TXTR		MX31TXTR		2332
++u380			MACH_U380		U380			2333
++oamp3_hualu		MACH_HUALU_BOARD	HUALU_BOARD		2334
++npcmx50			MACH_NPCMX50		NPCMX50			2335
++mx51_lange51		MACH_MX51_LANGE51	MX51_LANGE51		2336
++mx51_lange52		MACH_MX51_LANGE52	MX51_LANGE52		2337
++riom			MACH_RIOM		RIOM			2338
++comcas			MACH_COMCAS		COMCAS			2339
++wsi_mx27		MACH_WSI_MX27		WSI_MX27		2340
++cm_t35			MACH_CM_T35		CM_T35			2341
++net2big			MACH_NET2BIG		NET2BIG			2342
++motorola_a1600		MACH_MOTOROLA_A1600	MOTOROLA_A1600		2343
++igep0020		MACH_IGEP0020		IGEP0020		2344
++igep0010		MACH_IGEP0010		IGEP0010		2345
++mv6281gtwge2		MACH_MV6281GTWGE2	MV6281GTWGE2		2346
++scat100			MACH_SCAT100		SCAT100			2347
++sanmina			MACH_SANMINA		SANMINA			2348
++momento			MACH_MOMENTO		MOMENTO			2349
++nuc9xx			MACH_NUC9XX		NUC9XX			2350
++nuc910evb		MACH_NUC910EVB		NUC910EVB		2351
++nuc920evb		MACH_NUC920EVB		NUC920EVB		2352
++nuc950evb		MACH_NUC950EVB		NUC950EVB		2353
++nuc945evb		MACH_NUC945EVB		NUC945EVB		2354
++nuc960evb		MACH_NUC960EVB		NUC960EVB		2355
++nuc932evb		MACH_NUC932EVB		NUC932EVB		2356
++nuc900			MACH_NUC900		NUC900			2357
++sd1soc			MACH_SD1SOC		SD1SOC			2358
++ln2440bc		MACH_LN2440BC		LN2440BC		2359
++rsbc			MACH_RSBC		RSBC			2360
++openrd_client		MACH_OPENRD_CLIENT	OPENRD_CLIENT		2361
++hpipaq11x		MACH_HPIPAQ11X		HPIPAQ11X		2362
++wayland			MACH_WAYLAND		WAYLAND			2363
++acnbsx102		MACH_ACNBSX102		ACNBSX102		2364
++hwat91			MACH_HWAT91		HWAT91			2365
++at91sam9263cs		MACH_AT91SAM9263CS	AT91SAM9263CS		2366
++csb732			MACH_CSB732		CSB732			2367
++u8500			MACH_U8500		U8500			2368
++huqiu			MACH_HUQIU		HUQIU			2369
++mx51_kunlun		MACH_MX51_KUNLUN	MX51_KUNLUN		2370
++pmt1g			MACH_PMT1G		PMT1G			2371
++htcelf			MACH_HTCELF		HTCELF			2372
++armadillo420		MACH_ARMADILLO420	ARMADILLO420		2373
++armadillo440		MACH_ARMADILLO440	ARMADILLO440		2374
++u_chip_dual_arm		MACH_U_CHIP_DUAL_ARM	U_CHIP_DUAL_ARM		2375
++csr_bdb3		MACH_CSR_BDB3		CSR_BDB3		2376
++dolby_cat1018		MACH_DOLBY_CAT1018	DOLBY_CAT1018		2377
++hy9307			MACH_HY9307		HY9307			2378
++aspire_easystore	MACH_A_ES		A_ES			2379
++davinci_irif		MACH_DAVINCI_IRIF	DAVINCI_IRIF		2380
++agama9263		MACH_AGAMA9263		AGAMA9263		2381
++marvell_jasper		MACH_MARVELL_JASPER	MARVELL_JASPER		2382
++flint			MACH_FLINT		FLINT			2383
++tavorevb3		MACH_TAVOREVB3		TAVOREVB3		2384
++sch_m490		MACH_SCH_M490		SCH_M490		2386
++rbl01			MACH_RBL01		RBL01			2387
++omnifi			MACH_OMNIFI		OMNIFI			2388
++otavalo			MACH_OTAVALO		OTAVALO			2389
++sienna			MACH_SIENNA		SIENNA			2390
++htc_excalibur_s620	MACH_HTC_EXCALIBUR_S620	HTC_EXCALIBUR_S620	2391
++htc_opal		MACH_HTC_OPAL		HTC_OPAL		2392
++touchbook		MACH_TOUCHBOOK		TOUCHBOOK		2393
++latte			MACH_LATTE		LATTE			2394
++xa200			MACH_XA200		XA200			2395
++nimrod			MACH_NIMROD		NIMROD			2396
++cc9p9215_3g		MACH_CC9P9215_3G	CC9P9215_3G		2397
++cc9p9215_3gjs		MACH_CC9P9215_3GJS	CC9P9215_3GJS		2398
++tk71			MACH_TK71		TK71			2399
++comham3525		MACH_COMHAM3525		COMHAM3525		2400
++mx31erebus		MACH_MX31EREBUS		MX31EREBUS		2401
++mcardmx27		MACH_MCARDMX27		MCARDMX27		2402
++paradise		MACH_PARADISE		PARADISE		2403
++tide			MACH_TIDE		TIDE			2404
++wzl2440			MACH_WZL2440		WZL2440			2405
++sdrdemo			MACH_SDRDEMO		SDRDEMO			2406
++ethercan2		MACH_ETHERCAN2		ETHERCAN2		2407
++ecmimg20		MACH_ECMIMG20		ECMIMG20		2408
++omap_dragon		MACH_OMAP_DRAGON	OMAP_DRAGON		2409
++halo			MACH_HALO		HALO			2410
++huangshan		MACH_HUANGSHAN		HUANGSHAN		2411
++vl_ma2sc		MACH_VL_MA2SC		VL_MA2SC		2412
++raumfeld_rc		MACH_RAUMFELD_RC	RAUMFELD_RC		2413
++raumfeld_connector	MACH_RAUMFELD_CONNECTOR	RAUMFELD_CONNECTOR	2414
++raumfeld_speaker	MACH_RAUMFELD_SPEAKER	RAUMFELD_SPEAKER	2415
++multibus_master		MACH_MULTIBUS_MASTER	MULTIBUS_MASTER		2416
++multibus_pbk		MACH_MULTIBUS_PBK	MULTIBUS_PBK		2417
++tnetv107x		MACH_TNETV107X		TNETV107X		2418
++snake			MACH_SNAKE		SNAKE			2419
++cwmx27			MACH_CWMX27		CWMX27			2420
++sch_m480		MACH_SCH_M480		SCH_M480		2421
++platypus		MACH_PLATYPUS		PLATYPUS		2422
++pss2			MACH_PSS2		PSS2			2423
++davinci_apm150		MACH_DAVINCI_APM150	DAVINCI_APM150		2424
++str9100			MACH_STR9100		STR9100			2425
++net5big			MACH_NET5BIG		NET5BIG			2426
++seabed9263		MACH_SEABED9263		SEABED9263		2427
++mx51_m2id		MACH_MX51_M2ID		MX51_M2ID		2428
++octvocplus_eb		MACH_OCTVOCPLUS_EB	OCTVOCPLUS_EB		2429
++klk_firefox		MACH_KLK_FIREFOX	KLK_FIREFOX		2430
++klk_wirma_module	MACH_KLK_WIRMA_MODULE	KLK_WIRMA_MODULE	2431
++klk_wirma_mmi		MACH_KLK_WIRMA_MMI	KLK_WIRMA_MMI		2432
++supersonic		MACH_SUPERSONIC		SUPERSONIC		2433
++liberty			MACH_LIBERTY		LIBERTY			2434
++mh355			MACH_MH355		MH355			2435
++pc7802			MACH_PC7802		PC7802			2436
++gnet_sgc		MACH_GNET_SGC		GNET_SGC		2437
++einstein15		MACH_EINSTEIN15		EINSTEIN15		2438
++cmpd			MACH_CMPD		CMPD			2439
++davinci_hase1		MACH_DAVINCI_HASE1	DAVINCI_HASE1		2440
++lgeincitephone		MACH_LGEINCITEPHONE	LGEINCITEPHONE		2441
++ea313x			MACH_EA313X		EA313X			2442
++fwbd_39064		MACH_FWBD_39064		FWBD_39064		2443
++fwbd_390128		MACH_FWBD_390128	FWBD_390128		2444
++pelco_moe		MACH_PELCO_MOE		PELCO_MOE		2445
++minimix27		MACH_MINIMIX27		MINIMIX27		2446
++omap3_thunder		MACH_OMAP3_THUNDER	OMAP3_THUNDER		2447
++passionc		MACH_PASSIONC		PASSIONC		2448
++mx27amata		MACH_MX27AMATA		MX27AMATA		2449
++bgat1			MACH_BGAT1		BGAT1			2450
++buzz			MACH_BUZZ		BUZZ			2451
++mb9g20			MACH_MB9G20		MB9G20			2452
++yushan			MACH_YUSHAN		YUSHAN			2453
++lizard			MACH_LIZARD		LIZARD			2454
++omap3polycom		MACH_OMAP3POLYCOM	OMAP3POLYCOM		2455
++smdkv210		MACH_SMDKV210		SMDKV210		2456
++bravo			MACH_BRAVO		BRAVO			2457
++siogentoo1		MACH_SIOGENTOO1		SIOGENTOO1		2458
++siogentoo2		MACH_SIOGENTOO2		SIOGENTOO2		2459
++sm3k			MACH_SM3K		SM3K			2460
++acer_tempo_f900		MACH_ACER_TEMPO_F900	ACER_TEMPO_F900		2461
++sst61vc010_dev		MACH_SST61VC010_DEV	SST61VC010_DEV		2462
++glittertind		MACH_GLITTERTIND	GLITTERTIND		2463
++omap_zoom3		MACH_OMAP_ZOOM3		OMAP_ZOOM3		2464
++omap_3630sdp		MACH_OMAP_3630SDP	OMAP_3630SDP		2465
++cybook2440		MACH_CYBOOK2440		CYBOOK2440		2466
++torino_s		MACH_TORINO_S		TORINO_S		2467
++havana			MACH_HAVANA		HAVANA			2468
++beaumont_11		MACH_BEAUMONT_11	BEAUMONT_11		2469
++vanguard		MACH_VANGUARD		VANGUARD		2470
++s5pc110_draco		MACH_S5PC110_DRACO	S5PC110_DRACO		2471
++cartesio_two		MACH_CARTESIO_TWO	CARTESIO_TWO		2472
++aster			MACH_ASTER		ASTER			2473
++voguesv210		MACH_VOGUESV210		VOGUESV210		2474
++acm500x			MACH_ACM500X		ACM500X			2475
++km9260			MACH_KM9260		KM9260			2476
++nideflexg1		MACH_NIDEFLEXG1		NIDEFLEXG1		2477
++ctera_plug_io		MACH_CTERA_PLUG_IO	CTERA_PLUG_IO		2478
++smartq7			MACH_SMARTQ7		SMARTQ7			2479
++at91sam9g10ek2		MACH_AT91SAM9G10EK2	AT91SAM9G10EK2		2480
++asusp527		MACH_ASUSP527		ASUSP527		2481
++at91sam9g20mpm2		MACH_AT91SAM9G20MPM2	AT91SAM9G20MPM2		2482
++topasa900		MACH_TOPASA900		TOPASA900		2483
++electrum_100		MACH_ELECTRUM_100	ELECTRUM_100		2484
++mx51grb			MACH_MX51GRB		MX51GRB			2485
++xea300			MACH_XEA300		XEA300			2486
++htcstartrek		MACH_HTCSTARTREK	HTCSTARTREK		2487
++lima			MACH_LIMA		LIMA			2488
++csb740			MACH_CSB740		CSB740			2489
++usb_s8815		MACH_USB_S8815		USB_S8815		2490
++watson_efm_plugin	MACH_WATSON_EFM_PLUGIN	WATSON_EFM_PLUGIN	2491
++milkyway		MACH_MILKYWAY		MILKYWAY		2492
++g4evm			MACH_G4EVM		G4EVM			2493
++picomod6		MACH_PICOMOD6		PICOMOD6		2494
++omapl138_hawkboard	MACH_OMAPL138_HAWKBOARD	OMAPL138_HAWKBOARD	2495
++ip6000			MACH_IP6000		IP6000			2496
++ip6010			MACH_IP6010		IP6010			2497
++utm400			MACH_UTM400		UTM400			2498
++omap3_zybex		MACH_OMAP3_ZYBEX	OMAP3_ZYBEX		2499
++wireless_space		MACH_WIRELESS_SPACE	WIRELESS_SPACE		2500
++sx560			MACH_SX560		SX560			2501
++ts41x			MACH_TS41X		TS41X			2502
++elphel10373		MACH_ELPHEL10373	ELPHEL10373		2503
++rhobot			MACH_RHOBOT		RHOBOT			2504
++mx51_refresh		MACH_MX51_REFRESH	MX51_REFRESH		2505
++ls9260			MACH_LS9260		LS9260			2506
++shank			MACH_SHANK		SHANK			2507
++qsd8x50_st1		MACH_QSD8X50_ST1	QSD8X50_ST1		2508
++at91sam9m10ekes		MACH_AT91SAM9M10EKES	AT91SAM9M10EKES		2509
++hiram			MACH_HIRAM		HIRAM			2510
++phy3250			MACH_PHY3250		PHY3250			2511
++ea3250			MACH_EA3250		EA3250			2512
++fdi3250			MACH_FDI3250		FDI3250			2513
++whitestone		MACH_WHITESTONE		WHITESTONE		2514
++at91sam9263nit		MACH_AT91SAM9263NIT	AT91SAM9263NIT		2515
++ccmx51			MACH_CCMX51		CCMX51			2516
++ccmx51js		MACH_CCMX51JS		CCMX51JS		2517
++ccwmx51			MACH_CCWMX51		CCWMX51			2518
++ccwmx51js		MACH_CCWMX51JS		CCWMX51JS		2519
++mini6410		MACH_MINI6410		MINI6410		2520
++tiny6410		MACH_TINY6410		TINY6410		2521
++nano6410		MACH_NANO6410		NANO6410		2522
++at572d940hfnldb		MACH_AT572D940HFNLDB	AT572D940HFNLDB		2523
++htcleo			MACH_HTCLEO		HTCLEO			2524
++avp13			MACH_AVP13		AVP13			2525
++xxsvideod		MACH_XXSVIDEOD		XXSVIDEOD		2526
++vpnext			MACH_VPNEXT		VPNEXT			2527
++swarco_itc3		MACH_SWARCO_ITC3	SWARCO_ITC3		2528
++tx51			MACH_TX51		TX51			2529
++dolby_cat1021		MACH_DOLBY_CAT1021	DOLBY_CAT1021		2530
++mx28evk			MACH_MX28EVK		MX28EVK			2531
++phoenix260		MACH_PHOENIX260		PHOENIX260		2532
++uvaca_stork		MACH_UVACA_STORK	UVACA_STORK		2533
++smartq5			MACH_SMARTQ5		SMARTQ5			2534
++all3078			MACH_ALL3078		ALL3078			2535
++ctera_2bay_ds		MACH_CTERA_2BAY_DS	CTERA_2BAY_DS		2536
++siogentoo3		MACH_SIOGENTOO3		SIOGENTOO3		2537
++epb5000			MACH_EPB5000		EPB5000			2538
++hy9263			MACH_HY9263		HY9263			2539
++acer_tempo_m900		MACH_ACER_TEMPO_M900	ACER_TEMPO_M900		2540
++acer_tempo_dx650	MACH_ACER_TEMPO_DX900	ACER_TEMPO_DX900	2541
++acer_tempo_x960		MACH_ACER_TEMPO_X960	ACER_TEMPO_X960		2542
++acer_eten_v900		MACH_ACER_ETEN_V900	ACER_ETEN_V900		2543
++acer_eten_x900		MACH_ACER_ETEN_X900	ACER_ETEN_X900		2544
++bonnell			MACH_BONNELL		BONNELL			2545
++oht_mx27		MACH_OHT_MX27		OHT_MX27		2546
++htcquartz		MACH_HTCQUARTZ		HTCQUARTZ		2547
++davinci_dm6467tevm	MACH_DAVINCI_DM6467TEVM	DAVINCI_DM6467TEVM	2548
++c3ax03			MACH_C3AX03		C3AX03			2549
++mxt_td60		MACH_MXT_TD60		MXT_TD60		2550
++esyx			MACH_ESYX		ESYX			2551
++dove_db2		MACH_DOVE_DB2		DOVE_DB2		2552
++bulldog			MACH_BULLDOG		BULLDOG			2553
++derell_me2000		MACH_DERELL_ME2000	DERELL_ME2000		2554
++bcmring_base		MACH_BCMRING_BASE	BCMRING_BASE		2555
++bcmring_evm		MACH_BCMRING_EVM	BCMRING_EVM		2556
++bcmring_evm_jazz	MACH_BCMRING_EVM_JAZZ	BCMRING_EVM_JAZZ	2557
++bcmring_sp		MACH_BCMRING_SP		BCMRING_SP		2558
++bcmring_sv		MACH_BCMRING_SV		BCMRING_SV		2559
++bcmring_sv_jazz		MACH_BCMRING_SV_JAZZ	BCMRING_SV_JAZZ		2560
++bcmring_tablet		MACH_BCMRING_TABLET	BCMRING_TABLET		2561
++bcmring_vp		MACH_BCMRING_VP		BCMRING_VP		2562
++bcmring_evm_seikor	MACH_BCMRING_EVM_SEIKOR	BCMRING_EVM_SEIKOR	2563
++bcmring_sp_wqvga	MACH_BCMRING_SP_WQVGA	BCMRING_SP_WQVGA	2564
++bcmring_custom		MACH_BCMRING_CUSTOM	BCMRING_CUSTOM		2565
++acer_s200		MACH_ACER_S200		ACER_S200		2566
++bt270			MACH_BT270		BT270			2567
++iseo			MACH_ISEO		ISEO			2568
++cezanne			MACH_CEZANNE		CEZANNE			2569
++lucca			MACH_LUCCA		LUCCA			2570
++supersmart		MACH_SUPERSMART		SUPERSMART		2571
++arm11_board		MACH_CS_MISANO		CS_MISANO		2572
++magnolia2		MACH_MAGNOLIA2		MAGNOLIA2		2573
++emxx			MACH_EMXX		EMXX			2574
++outlaw			MACH_OUTLAW		OUTLAW			2575
++riot_bei2		MACH_RIOT_BEI2		RIOT_BEI2		2576
++riot_vox		MACH_RIOT_VOX		RIOT_VOX		2577
++riot_x37		MACH_RIOT_X37		RIOT_X37		2578
++mega25mx		MACH_MEGA25MX		MEGA25MX		2579
++benzina2		MACH_BENZINA2		BENZINA2		2580
++ignite			MACH_IGNITE		IGNITE			2581
++foggia			MACH_FOGGIA		FOGGIA			2582
++arezzo			MACH_AREZZO		AREZZO			2583
++leica_skywalker		MACH_LEICA_SKYWALKER	LEICA_SKYWALKER		2584
++jacinto2_jamr		MACH_JACINTO2_JAMR	JACINTO2_JAMR		2585
++gts_nova		MACH_GTS_NOVA		GTS_NOVA		2586
++p3600			MACH_P3600		P3600			2587
++dlt2			MACH_DLT2		DLT2			2588
++df3120			MACH_DF3120		DF3120			2589
++ecucore_9g20		MACH_ECUCORE_9G20	ECUCORE_9G20		2590
++nautel_lpc3240		MACH_NAUTEL_LPC3240	NAUTEL_LPC3240		2591
++glacier			MACH_GLACIER		GLACIER			2592
++phrazer_bulldog		MACH_PHRAZER_BULLDOG	PHRAZER_BULLDOG		2593
++omap3_bulldog		MACH_OMAP3_BULLDOG	OMAP3_BULLDOG		2594
++pca101			MACH_PCA101		PCA101			2595
++buzzc			MACH_BUZZC		BUZZC			2596
++sasie2			MACH_SASIE2		SASIE2			2597
++davinci_cio		MACH_DAVINCI_CIO	DAVINCI_CIO		2598
++smartmeter_dl		MACH_SMARTMETER_DL	SMARTMETER_DL		2599
++wzl6410			MACH_WZL6410		WZL6410			2600
++wzl6410m		MACH_WZL6410M		WZL6410M		2601
++wzl6410f		MACH_WZL6410F		WZL6410F		2602
++wzl6410i		MACH_WZL6410I		WZL6410I		2603
++spacecom1		MACH_SPACECOM1		SPACECOM1		2604
++pingu920		MACH_PINGU920		PINGU920		2605
++bravoc			MACH_BRAVOC		BRAVOC			2606
++cybo2440		MACH_CYBO2440		CYBO2440		2607
++vdssw			MACH_VDSSW		VDSSW			2608
++romulus			MACH_ROMULUS		ROMULUS			2609
++omap_magic		MACH_OMAP_MAGIC		OMAP_MAGIC		2610
++eltd100			MACH_ELTD100		ELTD100			2611
++capc7117		MACH_CAPC7117		CAPC7117		2612
++swan			MACH_SWAN		SWAN			2613
++veu			MACH_VEU		VEU			2614
++rm2			MACH_RM2		RM2			2615
++tt2100			MACH_TT2100		TT2100			2616
++venice			MACH_VENICE		VENICE			2617
++pc7323			MACH_PC7323		PC7323			2618
++masp			MACH_MASP		MASP			2619
++fujitsu_tvstbsoc0	MACH_FUJITSU_TVSTBSOC	FUJITSU_TVSTBSOC	2620
++fujitsu_tvstbsoc1	MACH_FUJITSU_TVSTBSOC1	FUJITSU_TVSTBSOC1	2621
++lexikon			MACH_LEXIKON		LEXIKON			2622
++mini2440v2		MACH_MINI2440V2		MINI2440V2		2623
++icontrol		MACH_ICONTROL		ICONTROL		2624
++gplugd			MACH_SHEEVAD		SHEEVAD			2625
++qsd8x50a_st1_1		MACH_QSD8X50A_ST1_1	QSD8X50A_ST1_1		2626
++qsd8x50a_st1_5		MACH_QSD8X50A_ST1_5	QSD8X50A_ST1_5		2627
++bee			MACH_BEE		BEE			2628
++mx23evk			MACH_MX23EVK		MX23EVK			2629
++ap4evb			MACH_AP4EVB		AP4EVB			2630
++stockholm		MACH_STOCKHOLM		STOCKHOLM		2631
++lpc_h3131		MACH_LPC_H3131		LPC_H3131		2632
++stingray		MACH_STINGRAY		STINGRAY		2633
++kraken			MACH_KRAKEN		KRAKEN			2634
++gw2388			MACH_GW2388		GW2388			2635
++jadecpu			MACH_JADECPU		JADECPU			2636
++carlisle		MACH_CARLISLE		CARLISLE		2637
++lux_sf9			MACH_LUX_SFT9		LUX_SFT9		2638
++nemid_tb		MACH_NEMID_TB		NEMID_TB		2639
++terrier			MACH_TERRIER		TERRIER			2640
++turbot			MACH_TURBOT		TURBOT			2641
++sanddab			MACH_SANDDAB		SANDDAB			2642
++mx35_cicada		MACH_MX35_CICADA	MX35_CICADA		2643
++ghi2703d		MACH_GHI2703D		GHI2703D		2644
++lux_sfx9		MACH_LUX_SFX9		LUX_SFX9		2645
++lux_sf9g		MACH_LUX_SF9G		LUX_SF9G		2646
++lux_edk9		MACH_LUX_EDK9		LUX_EDK9		2647
++hw90240			MACH_HW90240		HW90240			2648
++dm365_leopard		MACH_DM365_LEOPARD	DM365_LEOPARD		2649
++mityomapl138		MACH_MITYOMAPL138	MITYOMAPL138		2650
++scat110			MACH_SCAT110		SCAT110			2651
++acer_a1			MACH_ACER_A1		ACER_A1			2652
++cmcontrol		MACH_CMCONTROL		CMCONTROL		2653
++pelco_lamar		MACH_PELCO_LAMAR	PELCO_LAMAR		2654
++rfp43			MACH_RFP43		RFP43			2655
++sk86r0301		MACH_SK86R0301		SK86R0301		2656
++ctpxa			MACH_CTPXA		CTPXA			2657
++epb_arm9_a		MACH_EPB_ARM9_A		EPB_ARM9_A		2658
++guruplug		MACH_GURUPLUG		GURUPLUG		2659
++spear310		MACH_SPEAR310		SPEAR310		2660
++spear320		MACH_SPEAR320		SPEAR320		2661
++robotx			MACH_ROBOTX		ROBOTX			2662
++lsxhl			MACH_LSXHL		LSXHL			2663
++smartlite		MACH_SMARTLITE		SMARTLITE		2664
++cws2			MACH_CWS2		CWS2			2665
++m619			MACH_M619		M619			2666
++smartview		MACH_SMARTVIEW		SMARTVIEW		2667
++lsa_salsa		MACH_LSA_SALSA		LSA_SALSA		2668
++kizbox			MACH_KIZBOX		KIZBOX			2669
++htccharmer		MACH_HTCCHARMER		HTCCHARMER		2670
++guf_neso_lt		MACH_GUF_NESO_LT	GUF_NESO_LT		2671
++pm9g45			MACH_PM9G45		PM9G45			2672
++htcpanther		MACH_HTCPANTHER		HTCPANTHER		2673
++htcpanther_cdma		MACH_HTCPANTHER_CDMA	HTCPANTHER_CDMA		2674
++reb01			MACH_REB01		REB01			2675
++aquila			MACH_AQUILA		AQUILA			2676
++spark_sls_hw2		MACH_SPARK_SLS_HW2	SPARK_SLS_HW2		2677
++sheeva_esata		MACH_ESATA_SHEEVAPLUG	ESATA_SHEEVAPLUG	2678
++msm7x30_surf		MACH_MSM7X30_SURF	MSM7X30_SURF		2679
++micro2440		MACH_MICRO2440		MICRO2440		2680
++am2440			MACH_AM2440		AM2440			2681
++tq2440			MACH_TQ2440		TQ2440			2682
++lpc2478oem		MACH_LPC2478OEM		LPC2478OEM		2683
++ak880x			MACH_AK880X		AK880X			2684
++cobra3530		MACH_COBRA3530		COBRA3530		2685
++pmppb			MACH_PMPPB		PMPPB			2686
++u6715			MACH_U6715		U6715			2687
++axar1500_sender		MACH_AXAR1500_SENDER	AXAR1500_SENDER		2688
++g30_dvb			MACH_G30_DVB		G30_DVB			2689
++vc088x			MACH_VC088X		VC088X			2690
++mioa702			MACH_MIOA702		MIOA702			2691
++hpmin			MACH_HPMIN		HPMIN			2692
++ak880xak		MACH_AK880XAK		AK880XAK		2693
++arm926tomap850		MACH_ARM926TOMAP850	ARM926TOMAP850		2694
++lkevm			MACH_LKEVM		LKEVM			2695
++mw6410			MACH_MW6410		MW6410			2696
++terastation_wxl		MACH_TERASTATION_WXL	TERASTATION_WXL		2697
++cpu8000e		MACH_CPU8000E		CPU8000E		2698
++catania			MACH_CATANIA		CATANIA			2699
++tokyo			MACH_TOKYO		TOKYO			2700
++msm7201a_surf		MACH_MSM7201A_SURF	MSM7201A_SURF		2701
++msm7201a_ffa		MACH_MSM7201A_FFA	MSM7201A_FFA		2702
++msm7x25_surf		MACH_MSM7X25_SURF	MSM7X25_SURF		2703
++msm7x25_ffa		MACH_MSM7X25_FFA	MSM7X25_FFA		2704
++msm7x27_surf		MACH_MSM7X27_SURF	MSM7X27_SURF		2705
++msm7x27_ffa		MACH_MSM7X27_FFA	MSM7X27_FFA		2706
++msm7x30_ffa		MACH_MSM7X30_FFA	MSM7X30_FFA		2707
++qsd8x50_surf		MACH_QSD8X50_SURF	QSD8X50_SURF		2708
++qsd8x50_comet		MACH_QSD8X50_COMET	QSD8X50_COMET		2709
++qsd8x50_ffa		MACH_QSD8X50_FFA	QSD8X50_FFA		2710
++qsd8x50a_surf		MACH_QSD8X50A_SURF	QSD8X50A_SURF		2711
++qsd8x50a_ffa		MACH_QSD8X50A_FFA	QSD8X50A_FFA		2712
++adx_xgcp10		MACH_ADX_XGCP10		ADX_XGCP10		2713
++mcgwumts2a		MACH_MCGWUMTS2A		MCGWUMTS2A		2714
++mobikt			MACH_MOBIKT		MOBIKT			2715
++mx53_evk		MACH_MX53_EVK		MX53_EVK		2716
++igep0030		MACH_IGEP0030		IGEP0030		2717
++axell_h40_h50_ctrl	MACH_AXELL_H40_H50_CTRL	AXELL_H40_H50_CTRL	2718
++dtcommod		MACH_DTCOMMOD		DTCOMMOD		2719
++gould			MACH_GOULD		GOULD			2720
++siberia			MACH_SIBERIA		SIBERIA			2721
++sbc3530			MACH_SBC3530		SBC3530			2722
++qarm			MACH_QARM		QARM			2723
++mips			MACH_MIPS		MIPS			2724
++mx27grb			MACH_MX27GRB		MX27GRB			2725
++sbc8100			MACH_SBC8100		SBC8100			2726
++saarb			MACH_SAARB		SAARB			2727
++omap3mini		MACH_OMAP3MINI		OMAP3MINI		2728
++cnmbook7se		MACH_CNMBOOK7SE		CNMBOOK7SE		2729
++catan			MACH_CATAN		CATAN			2730
++harmony			MACH_HARMONY		HARMONY			2731
++tonga			MACH_TONGA		TONGA			2732
++cybook_orizon		MACH_CYBOOK_ORIZON	CYBOOK_ORIZON		2733
++htcrhodiumcdma		MACH_HTCRHODIUMCDMA	HTCRHODIUMCDMA		2734
++epc_g45			MACH_EPC_G45		EPC_G45			2735
++epc_lpc3250		MACH_EPC_LPC3250	EPC_LPC3250		2736
++mxc91341evb		MACH_MXC91341EVB	MXC91341EVB		2737
++rtw1000			MACH_RTW1000		RTW1000			2738
++bobcat			MACH_BOBCAT		BOBCAT			2739
++trizeps6		MACH_TRIZEPS6		TRIZEPS6		2740
++msm7x30_fluid		MACH_MSM7X30_FLUID	MSM7X30_FLUID		2741
++nedap9263		MACH_NEDAP9263		NEDAP9263		2742
++netgear_ms2110		MACH_NETGEAR_MS2110	NETGEAR_MS2110		2743
++bmx			MACH_BMX		BMX			2744
++netstream		MACH_NETSTREAM		NETSTREAM		2745
++vpnext_rcu		MACH_VPNEXT_RCU		VPNEXT_RCU		2746
++vpnext_mpu		MACH_VPNEXT_MPU		VPNEXT_MPU		2747
++bcmring_tablet_v1	MACH_BCMRING_TABLET_V1	BCMRING_TABLET_V1	2748
++sgarm10			MACH_SGARM10		SGARM10			2749
++cm_t3517		MACH_CM_T3517		CM_T3517		2750
++omap3_cps		MACH_OMAP3_CPS		OMAP3_CPS		2751
++axar1500_receiver	MACH_AXAR1500_RECEIVER	AXAR1500_RECEIVER	2752
++wbd222			MACH_WBD222		WBD222			2753
++mt65xx			MACH_MT65XX		MT65XX			2754
++msm8x60_surf		MACH_MSM8X60_SURF	MSM8X60_SURF		2755
++msm8x60_sim		MACH_MSM8X60_SIM	MSM8X60_SIM		2756
++vmc300			MACH_VMC300		VMC300			2757
++tcc8000_sdk		MACH_TCC8000_SDK	TCC8000_SDK		2758
++nanos			MACH_NANOS		NANOS			2759
++stamp9g10		MACH_STAMP9G10		STAMP9G10		2760
++stamp9g45		MACH_STAMP9G45		STAMP9G45		2761
++h6053			MACH_H6053		H6053			2762
++smint01			MACH_SMINT01		SMINT01			2763
++prtlvt2			MACH_PRTLVT2		PRTLVT2			2764
++ap420			MACH_AP420		AP420			2765
++htcshift		MACH_HTCSHIFT		HTCSHIFT		2766
++davinci_dm365_fc	MACH_DAVINCI_DM365_FC	DAVINCI_DM365_FC	2767
++msm8x55_surf		MACH_MSM8X55_SURF	MSM8X55_SURF		2768
++msm8x55_ffa		MACH_MSM8X55_FFA	MSM8X55_FFA		2769
++esl_vamana		MACH_ESL_VAMANA		ESL_VAMANA		2770
++sbc35			MACH_SBC35		SBC35			2771
++mpx6446			MACH_MPX6446		MPX6446			2772
++oreo_controller		MACH_OREO_CONTROLLER	OREO_CONTROLLER		2773
++kopin_models		MACH_KOPIN_MODELS	KOPIN_MODELS		2774
++ttc_vision2		MACH_TTC_VISION2	TTC_VISION2		2775
++cns3420vb		MACH_CNS3420VB		CNS3420VB		2776
++lpc2			MACH_LPC2		LPC2			2777
++olympus			MACH_OLYMPUS		OLYMPUS			2778
++vortex			MACH_VORTEX		VORTEX			2779
++s5pc200			MACH_S5PC200		S5PC200			2780
++ecucore_9263		MACH_ECUCORE_9263	ECUCORE_9263		2781
++smdkc200		MACH_SMDKC200		SMDKC200		2782
++emsiso_sx27		MACH_EMSISO_SX27	EMSISO_SX27		2783
++apx_som9g45_ek		MACH_APX_SOM9G45_EK	APX_SOM9G45_EK		2784
++songshan		MACH_SONGSHAN		SONGSHAN		2785
++tianshan		MACH_TIANSHAN		TIANSHAN		2786
++vpx500			MACH_VPX500		VPX500			2787
++am3517sam		MACH_AM3517SAM		AM3517SAM		2788
++skat91_sim508		MACH_SKAT91_SIM508	SKAT91_SIM508		2789
++skat91_s3e		MACH_SKAT91_S3E		SKAT91_S3E		2790
++omap4_panda		MACH_OMAP4_PANDA	OMAP4_PANDA		2791
++df7220			MACH_DF7220		DF7220			2792
++nemini			MACH_NEMINI		NEMINI			2793
++t8200			MACH_T8200		T8200			2794
++apf51			MACH_APF51		APF51			2795
++dr_rc_unit		MACH_DR_RC_UNIT		DR_RC_UNIT		2796
++bordeaux		MACH_BORDEAUX		BORDEAUX		2797
++catania_b		MACH_CATANIA_B		CATANIA_B		2798
++mx51_ocean		MACH_MX51_OCEAN		MX51_OCEAN		2799
++ti8168evm		MACH_TI8168EVM		TI8168EVM		2800
++neocoreomap		MACH_NEOCOREOMAP	NEOCOREOMAP		2801
++withings_wbp		MACH_WITHINGS_WBP	WITHINGS_WBP		2802
++dbps			MACH_DBPS		DBPS			2803
++sbc9261			MACH_SBC9261		SBC9261			2804
++pcbfp0001		MACH_PCBFP0001		PCBFP0001		2805
++speedy			MACH_SPEEDY		SPEEDY			2806
++chrysaor		MACH_CHRYSAOR		CHRYSAOR		2807
++tango			MACH_TANGO		TANGO			2808
++synology_dsx11		MACH_SYNOLOGY_DSX11	SYNOLOGY_DSX11		2809
++hanlin_v3ext		MACH_HANLIN_V3EXT	HANLIN_V3EXT		2810
++hanlin_v5		MACH_HANLIN_V5		HANLIN_V5		2811
++hanlin_v3plus		MACH_HANLIN_V3PLUS	HANLIN_V3PLUS		2812
++iriver_story		MACH_IRIVER_STORY	IRIVER_STORY		2813
++irex_iliad		MACH_IREX_ILIAD		IREX_ILIAD		2814
++irex_dr1000		MACH_IREX_DR1000	IREX_DR1000		2815
++teton_bga		MACH_TETON_BGA		TETON_BGA		2816
++snapper9g45		MACH_SNAPPER9G45	SNAPPER9G45		2817
++tam3517			MACH_TAM3517		TAM3517			2818
++pdc100			MACH_PDC100		PDC100			2819
++eukrea_cpuimx25sd	MACH_EUKREA_CPUIMX25	EUKREA_CPUIMX25		2820
++eukrea_cpuimx35sd	MACH_EUKREA_CPUIMX35	EUKREA_CPUIMX35		2821
++eukrea_cpuimx51sd	MACH_EUKREA_CPUIMX51SD	EUKREA_CPUIMX51SD	2822
++eukrea_cpuimx51		MACH_EUKREA_CPUIMX51	EUKREA_CPUIMX51		2823
++p565			MACH_P565		P565			2824
++acer_a4			MACH_ACER_A4		ACER_A4			2825
++davinci_dm368_bip	MACH_DAVINCI_DM368_BIP	DAVINCI_DM368_BIP	2826
++eshare			MACH_ESHARE		ESHARE			2827
++hw_omapl138_europa	MACH_HW_OMAPL138_EUROPA	HW_OMAPL138_EUROPA	2828
++wlbargn			MACH_WLBARGN		WLBARGN			2829
++bm170			MACH_BM170		BM170			2830
++netspace_mini_v2	MACH_NETSPACE_MINI_V2	NETSPACE_MINI_V2	2831
++netspace_plug_v2	MACH_NETSPACE_PLUG_V2	NETSPACE_PLUG_V2	2832
++siemens_l1		MACH_SIEMENS_L1		SIEMENS_L1		2833
++elv_lcu1		MACH_ELV_LCU1		ELV_LCU1		2834
++mcu1			MACH_MCU1		MCU1			2835
++omap3_tao3530		MACH_OMAP3_TAO3530	OMAP3_TAO3530		2836
++omap3_pcutouch		MACH_OMAP3_PCUTOUCH	OMAP3_PCUTOUCH		2837
++smdkc210		MACH_SMDKC210		SMDKC210		2838
++omap3_braillo		MACH_OMAP3_BRAILLO	OMAP3_BRAILLO		2839
++spyplug			MACH_SPYPLUG		SPYPLUG			2840
++ginger			MACH_GINGER		GINGER			2841
++tny_t3530		MACH_TNY_T3530		TNY_T3530		2842
++pca102			MACH_PCA102		PCA102			2843
++spade			MACH_SPADE		SPADE			2844
++mxc25_topaz		MACH_MXC25_TOPAZ	MXC25_TOPAZ		2845
++t5325			MACH_T5325		T5325			2846
++gw2361			MACH_GW2361		GW2361			2847
++elog			MACH_ELOG		ELOG			2848
++income			MACH_INCOME		INCOME			2849
++bcm589x			MACH_BCM589X		BCM589X			2850
++etna			MACH_ETNA		ETNA			2851
++hawks			MACH_HAWKS		HAWKS			2852
++meson			MACH_MESON		MESON			2853
++xsbase255		MACH_XSBASE255		XSBASE255		2854
++pvm2030			MACH_PVM2030		PVM2030			2855
++mioa502			MACH_MIOA502		MIOA502			2856
++vvbox_sdorig2		MACH_VVBOX_SDORIG2	VVBOX_SDORIG2		2857
++vvbox_sdlite2		MACH_VVBOX_SDLITE2	VVBOX_SDLITE2		2858
++vvbox_sdpro4		MACH_VVBOX_SDPRO4	VVBOX_SDPRO4		2859
++htc_spv_m700		MACH_HTC_SPV_M700	HTC_SPV_M700		2860
++mx257sx			MACH_MX257SX		MX257SX			2861
++goni			MACH_GONI		GONI			2862
++msm8x55_svlte_ffa	MACH_MSM8X55_SVLTE_FFA	MSM8X55_SVLTE_FFA	2863
++msm8x55_svlte_surf	MACH_MSM8X55_SVLTE_SURF	MSM8X55_SVLTE_SURF	2864
++quickstep		MACH_QUICKSTEP		QUICKSTEP		2865
++dmw96			MACH_DMW96		DMW96			2866
++hammerhead		MACH_HAMMERHEAD		HAMMERHEAD		2867
++trident			MACH_TRIDENT		TRIDENT			2868
++lightning		MACH_LIGHTNING		LIGHTNING		2869
++iconnect		MACH_ICONNECT		ICONNECT		2870
++autobot			MACH_AUTOBOT		AUTOBOT			2871
++coconut			MACH_COCONUT		COCONUT			2872
++durian			MACH_DURIAN		DURIAN			2873
++cayenne			MACH_CAYENNE		CAYENNE			2874
++fuji			MACH_FUJI		FUJI			2875
++synology_6282		MACH_SYNOLOGY_6282	SYNOLOGY_6282		2876
++em1sy			MACH_EM1SY		EM1SY			2877
++m502			MACH_M502		M502			2878
++matrix518		MACH_MATRIX518		MATRIX518		2879
++tiny_gurnard		MACH_TINY_GURNARD	TINY_GURNARD		2880
++spear1310		MACH_SPEAR1310		SPEAR1310		2881
++bv07			MACH_BV07		BV07			2882
++mxt_td61		MACH_MXT_TD61		MXT_TD61		2883
++openrd_ultimate		MACH_OPENRD_ULTIMATE	OPENRD_ULTIMATE		2884
++devixp			MACH_DEVIXP		DEVIXP			2885
++miccpt			MACH_MICCPT		MICCPT			2886
++mic256			MACH_MIC256		MIC256			2887
++as1167			MACH_AS1167		AS1167			2888
++omap3_ibiza		MACH_OMAP3_IBIZA	OMAP3_IBIZA		2889
++u5500			MACH_U5500		U5500			2890
++davinci_picto		MACH_DAVINCI_PICTO	DAVINCI_PICTO		2891
++mecha			MACH_MECHA		MECHA			2892
++bubba3			MACH_BUBBA3		BUBBA3			2893
++pupitre			MACH_PUPITRE		PUPITRE			2894
++tegra_harmony		MACH_TEGRA_HARMONY	TEGRA_HARMONY		2895
++tegra_vogue		MACH_TEGRA_VOGUE	TEGRA_VOGUE		2896
++tegra_e1165		MACH_TEGRA_E1165	TEGRA_E1165		2897
++simplenet		MACH_SIMPLENET		SIMPLENET		2898
++ec4350tbm		MACH_EC4350TBM		EC4350TBM		2899
++pec_tc			MACH_PEC_TC		PEC_TC			2900
++pec_hc2			MACH_PEC_HC2		PEC_HC2			2901
++esl_mobilis_a		MACH_ESL_MOBILIS_A	ESL_MOBILIS_A		2902
++esl_mobilis_b		MACH_ESL_MOBILIS_B	ESL_MOBILIS_B		2903
++esl_wave_a		MACH_ESL_WAVE_A		ESL_WAVE_A		2904
++esl_wave_b		MACH_ESL_WAVE_B		ESL_WAVE_B		2905
++unisense_mmm		MACH_UNISENSE_MMM	UNISENSE_MMM		2906
++blueshark		MACH_BLUESHARK		BLUESHARK		2907
++e10			MACH_E10		E10			2908
++app3k_robin		MACH_APP3K_ROBIN	APP3K_ROBIN		2909
++pov15hd			MACH_POV15HD		POV15HD			2910
++stella			MACH_STELLA		STELLA			2911
++linkstation_lschl	MACH_LINKSTATION_LSCHL	LINKSTATION_LSCHL	2913
++netwalker		MACH_NETWALKER		NETWALKER		2914
++acsx106			MACH_ACSX106		ACSX106			2915
++atlas5_c1		MACH_ATLAS5_C1		ATLAS5_C1		2916
++nsb3ast			MACH_NSB3AST		NSB3AST			2917
++gnet_slc		MACH_GNET_SLC		GNET_SLC		2918
++af4000			MACH_AF4000		AF4000			2919
++ark9431			MACH_ARK9431		ARK9431			2920
++fs_s5pc100		MACH_FS_S5PC100		FS_S5PC100		2921
++omap3505nova8		MACH_OMAP3505NOVA8	OMAP3505NOVA8		2922
++omap3621_edp1		MACH_OMAP3621_EDP1	OMAP3621_EDP1		2923
++oratisaes		MACH_ORATISAES		ORATISAES		2924
++smdkv310		MACH_SMDKV310		SMDKV310		2925
++siemens_l0		MACH_SIEMENS_L0		SIEMENS_L0		2926
++ventana			MACH_VENTANA		VENTANA			2927
++wm8505_7in_netbook	MACH_WM8505_7IN_NETBOOK	WM8505_7IN_NETBOOK	2928
++ec4350sdb		MACH_EC4350SDB		EC4350SDB		2929
++mimas			MACH_MIMAS		MIMAS			2930
++titan			MACH_TITAN		TITAN			2931
++craneboard		MACH_CRANEBOARD		CRANEBOARD		2932
++es2440			MACH_ES2440		ES2440			2933
++najay_a9263		MACH_NAJAY_A9263	NAJAY_A9263		2934
++htctornado		MACH_HTCTORNADO		HTCTORNADO		2935
++dimm_mx257		MACH_DIMM_MX257		DIMM_MX257		2936
++jigen301		MACH_JIGEN		JIGEN			2937
++smdk6450		MACH_SMDK6450		SMDK6450		2938
++meno_qng		MACH_MENO_QNG		MENO_QNG		2939
++ns2416			MACH_NS2416		NS2416			2940
++rpc353			MACH_RPC353		RPC353			2941
++tq6410			MACH_TQ6410		TQ6410			2942
++sky6410			MACH_SKY6410		SKY6410			2943
++dynasty			MACH_DYNASTY		DYNASTY			2944
++vivo			MACH_VIVO		VIVO			2945
++bury_bl7582		MACH_BURY_BL7582	BURY_BL7582		2946
++bury_bps5270		MACH_BURY_BPS5270	BURY_BPS5270		2947
++basi			MACH_BASI		BASI			2948
++tn200			MACH_TN200		TN200			2949
++c2mmi			MACH_C2MMI		C2MMI			2950
++meson_6236m		MACH_MESON_6236M	MESON_6236M		2951
++meson_8626m		MACH_MESON_8626M	MESON_8626M		2952
++tube			MACH_TUBE		TUBE			2953
++messina			MACH_MESSINA		MESSINA			2954
++mx50_arm2		MACH_MX50_ARM2		MX50_ARM2		2955
++cetus9263		MACH_CETUS9263		CETUS9263		2956
++brownstone		MACH_BROWNSTONE		BROWNSTONE		2957
++vmx25			MACH_VMX25		VMX25			2958
++vmx51			MACH_VMX51		VMX51			2959
++abacus			MACH_ABACUS		ABACUS			2960
++cm4745			MACH_CM4745		CM4745			2961
++oratislink		MACH_ORATISLINK		ORATISLINK		2962
++davinci_dm365_dvr	MACH_DAVINCI_DM365_DVR	DAVINCI_DM365_DVR	2963
++netviz			MACH_NETVIZ		NETVIZ			2964
++flexibity		MACH_FLEXIBITY		FLEXIBITY		2965
++wlan_computer		MACH_WLAN_COMPUTER	WLAN_COMPUTER		2966
+diff -rupN linux-2.6.35.11/drivers/base/core.c linux-2.6.35.11-ts7500/drivers/base/core.c
+--- linux-2.6.35.11/drivers/base/core.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/base/core.c	2011-03-14 11:18:24.000000000 -0400
+@@ -1323,6 +1323,8 @@ struct device *device_find_child(struct
+ 
+ int __init devices_init(void)
+ {
++   //printk("devices_init(), calling kset_create_and_add(devices)\n");
++   
+ 	devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
+ 	if (!devices_kset)
+ 		return -ENOMEM;
+@@ -1336,6 +1338,7 @@ int __init devices_init(void)
+ 	if (!sysfs_dev_char_kobj)
+ 		goto char_kobj_err;
+ 
++//printk("devices_init() done OK\n");
+ 	return 0;
+ 
+  char_kobj_err:
+diff -rupN linux-2.6.35.11/drivers/base/init.c linux-2.6.35.11-ts7500/drivers/base/init.c
+--- linux-2.6.35.11/drivers/base/init.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/base/init.c	2011-03-14 11:18:24.000000000 -0400
+@@ -20,18 +20,28 @@
+ void __init driver_init(void)
+ {
+ 	/* These are the core pieces */
++   //printk("calling devtmpfs_init()\n");
+ 	devtmpfs_init();
++   //printk("calling devices_init()\n");
+ 	devices_init();
++   //printk("calling buses_init()\n");
+ 	buses_init();
++   //printk("calling classes_init()\n");
+ 	classes_init();
++   //printk("calling firmware_init()\n");
+ 	firmware_init();
++   //printk("calling hypervisor_init()\n");
+ 	hypervisor_init();
+-
++   
+ 	/* These are also core pieces, but must come after the
+ 	 * core core pieces.
+ 	 */
++   // printk("calling platform_bus_init()\n");
+ 	platform_bus_init();
++   //printk("calling system_bus_init()\n");
+ 	system_bus_init();
++   //printk("calling cpu_dev_init()\n");
+ 	cpu_dev_init();
++   //printk("calling memory_dev_init()\n");
+ 	memory_dev_init();
+ }
+diff -rupN linux-2.6.35.11/drivers/base/platform.c linux-2.6.35.11-ts7500/drivers/base/platform.c
+--- linux-2.6.35.11/drivers/base/platform.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/base/platform.c	2011-03-14 11:18:24.000000000 -0400
+@@ -1021,11 +1021,17 @@ int __init platform_bus_init(void)
+ {
+ 	int error;
+ 
++   //printk("platform_bus_init() calling early_platform_cleanup()\n");
++   
+ 	early_platform_cleanup();
+ 
++   //printk("platform_bus_init() calling device_register()\n");
++   
+ 	error = device_register(&platform_bus);
+ 	if (error)
+ 		return error;
++   //printk("platform_bus_init() calling bus_register()\n");
++   
+ 	error =  bus_register(&platform_bus_type);
+ 	if (error)
+ 		device_unregister(&platform_bus);
+diff -rupN linux-2.6.35.11/drivers/base/platform.c.orig linux-2.6.35.11-ts7500/drivers/base/platform.c.orig
+--- linux-2.6.35.11/drivers/base/platform.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/base/platform.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,1340 @@
++/*
++ * platform.c - platform 'pseudo' bus for legacy devices
++ *
++ * Copyright (c) 2002-3 Patrick Mochel
++ * Copyright (c) 2002-3 Open Source Development Labs
++ *
++ * This file is released under the GPLv2
++ *
++ * Please see Documentation/driver-model/platform.txt for more
++ * information.
++ */
++
++#include <linux/string.h>
++#include <linux/platform_device.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/dma-mapping.h>
++#include <linux/bootmem.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/pm_runtime.h>
++
++#include "base.h"
++
++#define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
++				 driver))
++
++struct device platform_bus = {
++	.init_name	= "platform",
++};
++EXPORT_SYMBOL_GPL(platform_bus);
++
++/**
++ * platform_get_resource - get a resource for a device
++ * @dev: platform device
++ * @type: resource type
++ * @num: resource index
++ */
++struct resource *platform_get_resource(struct platform_device *dev,
++				       unsigned int type, unsigned int num)
++{
++	int i;
++
++	for (i = 0; i < dev->num_resources; i++) {
++		struct resource *r = &dev->resource[i];
++
++		if (type == resource_type(r) && num-- == 0)
++			return r;
++	}
++	return NULL;
++}
++EXPORT_SYMBOL_GPL(platform_get_resource);
++
++/**
++ * platform_get_irq - get an IRQ for a device
++ * @dev: platform device
++ * @num: IRQ number index
++ */
++int platform_get_irq(struct platform_device *dev, unsigned int num)
++{
++	struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
++
++	return r ? r->start : -ENXIO;
++}
++EXPORT_SYMBOL_GPL(platform_get_irq);
++
++/**
++ * platform_get_resource_byname - get a resource for a device by name
++ * @dev: platform device
++ * @type: resource type
++ * @name: resource name
++ */
++struct resource *platform_get_resource_byname(struct platform_device *dev,
++					      unsigned int type,
++					      const char *name)
++{
++	int i;
++
++	for (i = 0; i < dev->num_resources; i++) {
++		struct resource *r = &dev->resource[i];
++
++		if (type == resource_type(r) && !strcmp(r->name, name))
++			return r;
++	}
++	return NULL;
++}
++EXPORT_SYMBOL_GPL(platform_get_resource_byname);
++
++/**
++ * platform_get_irq - get an IRQ for a device
++ * @dev: platform device
++ * @name: IRQ name
++ */
++int platform_get_irq_byname(struct platform_device *dev, const char *name)
++{
++	struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ,
++							  name);
++
++	return r ? r->start : -ENXIO;
++}
++EXPORT_SYMBOL_GPL(platform_get_irq_byname);
++
++/**
++ * platform_add_devices - add a numbers of platform devices
++ * @devs: array of platform devices to add
++ * @num: number of platform devices in array
++ */
++int platform_add_devices(struct platform_device **devs, int num)
++{
++	int i, ret = 0;
++
++	for (i = 0; i < num; i++) {
++		ret = platform_device_register(devs[i]);
++		if (ret) {
++			while (--i >= 0)
++				platform_device_unregister(devs[i]);
++			break;
++		}
++	}
++
++	return ret;
++}
++EXPORT_SYMBOL_GPL(platform_add_devices);
++
++struct platform_object {
++	struct platform_device pdev;
++	char name[1];
++};
++
++/**
++ * platform_device_put - destroy a platform device
++ * @pdev: platform device to free
++ *
++ * Free all memory associated with a platform device.  This function must
++ * _only_ be externally called in error cases.  All other usage is a bug.
++ */
++void platform_device_put(struct platform_device *pdev)
++{
++	if (pdev)
++		put_device(&pdev->dev);
++}
++EXPORT_SYMBOL_GPL(platform_device_put);
++
++static void platform_device_release(struct device *dev)
++{
++	struct platform_object *pa = container_of(dev, struct platform_object,
++						  pdev.dev);
++
++	kfree(pa->pdev.dev.platform_data);
++	kfree(pa->pdev.resource);
++	kfree(pa);
++}
++
++/**
++ * platform_device_alloc - create a platform device
++ * @name: base name of the device we're adding
++ * @id: instance id
++ *
++ * Create a platform device object which can have other objects attached
++ * to it, and which will have attached objects freed when it is released.
++ */
++struct platform_device *platform_device_alloc(const char *name, int id)
++{
++	struct platform_object *pa;
++
++	pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL);
++	if (pa) {
++		strcpy(pa->name, name);
++		pa->pdev.name = pa->name;
++		pa->pdev.id = id;
++		device_initialize(&pa->pdev.dev);
++		pa->pdev.dev.release = platform_device_release;
++	}
++
++	return pa ? &pa->pdev : NULL;
++}
++EXPORT_SYMBOL_GPL(platform_device_alloc);
++
++/**
++ * platform_device_add_resources - add resources to a platform device
++ * @pdev: platform device allocated by platform_device_alloc to add resources to
++ * @res: set of resources that needs to be allocated for the device
++ * @num: number of resources
++ *
++ * Add a copy of the resources to the platform device.  The memory
++ * associated with the resources will be freed when the platform device is
++ * released.
++ */
++int platform_device_add_resources(struct platform_device *pdev,
++				  const struct resource *res, unsigned int num)
++{
++	struct resource *r;
++
++	r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL);
++	if (r) {
++		memcpy(r, res, sizeof(struct resource) * num);
++		pdev->resource = r;
++		pdev->num_resources = num;
++	}
++	return r ? 0 : -ENOMEM;
++}
++EXPORT_SYMBOL_GPL(platform_device_add_resources);
++
++/**
++ * platform_device_add_data - add platform-specific data to a platform device
++ * @pdev: platform device allocated by platform_device_alloc to add resources to
++ * @data: platform specific data for this platform device
++ * @size: size of platform specific data
++ *
++ * Add a copy of platform specific data to the platform device's
++ * platform_data pointer.  The memory associated with the platform data
++ * will be freed when the platform device is released.
++ */
++int platform_device_add_data(struct platform_device *pdev, const void *data,
++			     size_t size)
++{
++	void *d = kmemdup(data, size, GFP_KERNEL);
++
++	if (d) {
++		pdev->dev.platform_data = d;
++		return 0;
++	}
++	return -ENOMEM;
++}
++EXPORT_SYMBOL_GPL(platform_device_add_data);
++
++/**
++ * platform_device_add - add a platform device to device hierarchy
++ * @pdev: platform device we're adding
++ *
++ * This is part 2 of platform_device_register(), though may be called
++ * separately _iff_ pdev was allocated by platform_device_alloc().
++ */
++int platform_device_add(struct platform_device *pdev)
++{
++	int i, ret = 0;
++
++	if (!pdev)
++		return -EINVAL;
++
++	if (!pdev->dev.parent)
++		pdev->dev.parent = &platform_bus;
++
++	pdev->dev.bus = &platform_bus_type;
++
++	if (pdev->id != -1)
++		dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);
++	else
++		dev_set_name(&pdev->dev, "%s", pdev->name);
++
++	for (i = 0; i < pdev->num_resources; i++) {
++		struct resource *p, *r = &pdev->resource[i];
++
++		if (r->name == NULL)
++			r->name = dev_name(&pdev->dev);
++
++		p = r->parent;
++		if (!p) {
++			if (resource_type(r) == IORESOURCE_MEM)
++				p = &iomem_resource;
++			else if (resource_type(r) == IORESOURCE_IO)
++				p = &ioport_resource;
++		}
++
++		if (p && insert_resource(p, r)) {
++			printk(KERN_ERR
++			       "%s: failed to claim resource %d\n",
++			       dev_name(&pdev->dev), i);
++			ret = -EBUSY;
++			goto failed;
++		}
++	}
++
++	pr_debug("Registering platform device '%s'. Parent at %s\n",
++		 dev_name(&pdev->dev), dev_name(pdev->dev.parent));
++
++	ret = device_add(&pdev->dev);
++	if (ret == 0)
++		return ret;
++
++ failed:
++	while (--i >= 0) {
++		struct resource *r = &pdev->resource[i];
++		unsigned long type = resource_type(r);
++
++		if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
++			release_resource(r);
++	}
++
++	return ret;
++}
++EXPORT_SYMBOL_GPL(platform_device_add);
++
++/**
++ * platform_device_del - remove a platform-level device
++ * @pdev: platform device we're removing
++ *
++ * Note that this function will also release all memory- and port-based
++ * resources owned by the device (@dev->resource).  This function must
++ * _only_ be externally called in error cases.  All other usage is a bug.
++ */
++void platform_device_del(struct platform_device *pdev)
++{
++	int i;
++
++	if (pdev) {
++		device_del(&pdev->dev);
++
++		for (i = 0; i < pdev->num_resources; i++) {
++			struct resource *r = &pdev->resource[i];
++			unsigned long type = resource_type(r);
++
++			if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
++				release_resource(r);
++		}
++	}
++}
++EXPORT_SYMBOL_GPL(platform_device_del);
++
++/**
++ * platform_device_register - add a platform-level device
++ * @pdev: platform device we're adding
++ */
++int platform_device_register(struct platform_device *pdev)
++{
++	device_initialize(&pdev->dev);
++	return platform_device_add(pdev);
++}
++EXPORT_SYMBOL_GPL(platform_device_register);
++
++/**
++ * platform_device_unregister - unregister a platform-level device
++ * @pdev: platform device we're unregistering
++ *
++ * Unregistration is done in 2 steps. First we release all resources
++ * and remove it from the subsystem, then we drop reference count by
++ * calling platform_device_put().
++ */
++void platform_device_unregister(struct platform_device *pdev)
++{
++	platform_device_del(pdev);
++	platform_device_put(pdev);
++}
++EXPORT_SYMBOL_GPL(platform_device_unregister);
++
++/**
++ * platform_device_register_simple - add a platform-level device and its resources
++ * @name: base name of the device we're adding
++ * @id: instance id
++ * @res: set of resources that needs to be allocated for the device
++ * @num: number of resources
++ *
++ * This function creates a simple platform device that requires minimal
++ * resource and memory management. Canned release function freeing memory
++ * allocated for the device allows drivers using such devices to be
++ * unloaded without waiting for the last reference to the device to be
++ * dropped.
++ *
++ * This interface is primarily intended for use with legacy drivers which
++ * probe hardware directly.  Because such drivers create sysfs device nodes
++ * themselves, rather than letting system infrastructure handle such device
++ * enumeration tasks, they don't fully conform to the Linux driver model.
++ * In particular, when such drivers are built as modules, they can't be
++ * "hotplugged".
++ *
++ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
++ */
++struct platform_device *platform_device_register_simple(const char *name,
++							int id,
++							const struct resource *res,
++							unsigned int num)
++{
++	struct platform_device *pdev;
++	int retval;
++
++	pdev = platform_device_alloc(name, id);
++	if (!pdev) {
++		retval = -ENOMEM;
++		goto error;
++	}
++
++	if (num) {
++		retval = platform_device_add_resources(pdev, res, num);
++		if (retval)
++			goto error;
++	}
++
++	retval = platform_device_add(pdev);
++	if (retval)
++		goto error;
++
++	return pdev;
++
++error:
++	platform_device_put(pdev);
++	return ERR_PTR(retval);
++}
++EXPORT_SYMBOL_GPL(platform_device_register_simple);
++
++/**
++ * platform_device_register_data - add a platform-level device with platform-specific data
++ * @parent: parent device for the device we're adding
++ * @name: base name of the device we're adding
++ * @id: instance id
++ * @data: platform specific data for this platform device
++ * @size: size of platform specific data
++ *
++ * This function creates a simple platform device that requires minimal
++ * resource and memory management. Canned release function freeing memory
++ * allocated for the device allows drivers using such devices to be
++ * unloaded without waiting for the last reference to the device to be
++ * dropped.
++ *
++ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
++ */
++struct platform_device *platform_device_register_data(
++		struct device *parent,
++		const char *name, int id,
++		const void *data, size_t size)
++{
++	struct platform_device *pdev;
++	int retval;
++
++	pdev = platform_device_alloc(name, id);
++	if (!pdev) {
++		retval = -ENOMEM;
++		goto error;
++	}
++
++	pdev->dev.parent = parent;
++
++	if (size) {
++		retval = platform_device_add_data(pdev, data, size);
++		if (retval)
++			goto error;
++	}
++
++	retval = platform_device_add(pdev);
++	if (retval)
++		goto error;
++
++	return pdev;
++
++error:
++	platform_device_put(pdev);
++	return ERR_PTR(retval);
++}
++EXPORT_SYMBOL_GPL(platform_device_register_data);
++
++static int platform_drv_probe(struct device *_dev)
++{
++	struct platform_driver *drv = to_platform_driver(_dev->driver);
++	struct platform_device *dev = to_platform_device(_dev);
++
++	return drv->probe(dev);
++}
++
++static int platform_drv_probe_fail(struct device *_dev)
++{
++	return -ENXIO;
++}
++
++static int platform_drv_remove(struct device *_dev)
++{
++	struct platform_driver *drv = to_platform_driver(_dev->driver);
++	struct platform_device *dev = to_platform_device(_dev);
++
++	return drv->remove(dev);
++}
++
++static void platform_drv_shutdown(struct device *_dev)
++{
++	struct platform_driver *drv = to_platform_driver(_dev->driver);
++	struct platform_device *dev = to_platform_device(_dev);
++
++	drv->shutdown(dev);
++}
++
++/**
++ * platform_driver_register - register a driver for platform-level devices
++ * @drv: platform driver structure
++ */
++int platform_driver_register(struct platform_driver *drv)
++{
++	drv->driver.bus = &platform_bus_type;
++	if (drv->probe)
++		drv->driver.probe = platform_drv_probe;
++	if (drv->remove)
++		drv->driver.remove = platform_drv_remove;
++	if (drv->shutdown)
++		drv->driver.shutdown = platform_drv_shutdown;
++
++	return driver_register(&drv->driver);
++}
++EXPORT_SYMBOL_GPL(platform_driver_register);
++
++/**
++ * platform_driver_unregister - unregister a driver for platform-level devices
++ * @drv: platform driver structure
++ */
++void platform_driver_unregister(struct platform_driver *drv)
++{
++	driver_unregister(&drv->driver);
++}
++EXPORT_SYMBOL_GPL(platform_driver_unregister);
++
++/**
++ * platform_driver_probe - register driver for non-hotpluggable device
++ * @drv: platform driver structure
++ * @probe: the driver probe routine, probably from an __init section
++ *
++ * Use this instead of platform_driver_register() when you know the device
++ * is not hotpluggable and has already been registered, and you want to
++ * remove its run-once probe() infrastructure from memory after the driver
++ * has bound to the device.
++ *
++ * One typical use for this would be with drivers for controllers integrated
++ * into system-on-chip processors, where the controller devices have been
++ * configured as part of board setup.
++ *
++ * Returns zero if the driver registered and bound to a device, else returns
++ * a negative error code and with the driver not registered.
++ */
++int __init_or_module platform_driver_probe(struct platform_driver *drv,
++		int (*probe)(struct platform_device *))
++{
++	int retval, code;
++
++	/* make sure driver won't have bind/unbind attributes */
++	drv->driver.suppress_bind_attrs = true;
++
++	/* temporary section violation during probe() */
++	drv->probe = probe;
++	retval = code = platform_driver_register(drv);
++
++	/*
++	 * Fixup that section violation, being paranoid about code scanning
++	 * the list of drivers in order to probe new devices.  Check to see
++	 * if the probe was successful, and make sure any forced probes of
++	 * new devices fail.
++	 */
++	spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
++	drv->probe = NULL;
++	if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
++		retval = -ENODEV;
++	drv->driver.probe = platform_drv_probe_fail;
++	spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
++
++	if (code != retval)
++		platform_driver_unregister(drv);
++	return retval;
++}
++EXPORT_SYMBOL_GPL(platform_driver_probe);
++
++/**
++ * platform_create_bundle - register driver and create corresponding device
++ * @driver: platform driver structure
++ * @probe: the driver probe routine, probably from an __init section
++ * @res: set of resources that needs to be allocated for the device
++ * @n_res: number of resources
++ * @data: platform specific data for this platform device
++ * @size: size of platform specific data
++ *
++ * Use this in legacy-style modules that probe hardware directly and
++ * register a single platform device and corresponding platform driver.
++ *
++ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
++ */
++struct platform_device * __init_or_module platform_create_bundle(
++			struct platform_driver *driver,
++			int (*probe)(struct platform_device *),
++			struct resource *res, unsigned int n_res,
++			const void *data, size_t size)
++{
++	struct platform_device *pdev;
++	int error;
++
++	pdev = platform_device_alloc(driver->driver.name, -1);
++	if (!pdev) {
++		error = -ENOMEM;
++		goto err_out;
++	}
++
++	if (res) {
++		error = platform_device_add_resources(pdev, res, n_res);
++		if (error)
++			goto err_pdev_put;
++	}
++
++	if (data) {
++		error = platform_device_add_data(pdev, data, size);
++		if (error)
++			goto err_pdev_put;
++	}
++
++	error = platform_device_add(pdev);
++	if (error)
++		goto err_pdev_put;
++
++	error = platform_driver_probe(driver, probe);
++	if (error)
++		goto err_pdev_del;
++
++	return pdev;
++
++err_pdev_del:
++	platform_device_del(pdev);
++err_pdev_put:
++	platform_device_put(pdev);
++err_out:
++	return ERR_PTR(error);
++}
++EXPORT_SYMBOL_GPL(platform_create_bundle);
++
++/* modalias support enables more hands-off userspace setup:
++ * (a) environment variable lets new-style hotplug events work once system is
++ *     fully running:  "modprobe $MODALIAS"
++ * (b) sysfs attribute lets new-style coldplug recover from hotplug events
++ *     mishandled before system is fully running:  "modprobe $(cat modalias)"
++ */
++static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
++			     char *buf)
++{
++	struct platform_device	*pdev = to_platform_device(dev);
++	int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name);
++
++	return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
++}
++
++static struct device_attribute platform_dev_attrs[] = {
++	__ATTR_RO(modalias),
++	__ATTR_NULL,
++};
++
++static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
++{
++	struct platform_device	*pdev = to_platform_device(dev);
++
++	add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
++		(pdev->id_entry) ? pdev->id_entry->name : pdev->name);
++	return 0;
++}
++
++static const struct platform_device_id *platform_match_id(
++			const struct platform_device_id *id,
++			struct platform_device *pdev)
++{
++	while (id->name[0]) {
++		if (strcmp(pdev->name, id->name) == 0) {
++			pdev->id_entry = id;
++			return id;
++		}
++		id++;
++	}
++	return NULL;
++}
++
++/**
++ * platform_match - bind platform device to platform driver.
++ * @dev: device.
++ * @drv: driver.
++ *
++ * Platform device IDs are assumed to be encoded like this:
++ * "<name><instance>", where <name> is a short description of the type of
++ * device, like "pci" or "floppy", and <instance> is the enumerated
++ * instance of the device, like '0' or '42'.  Driver IDs are simply
++ * "<name>".  So, extract the <name> from the platform_device structure,
++ * and compare it against the name of the driver. Return whether they match
++ * or not.
++ */
++static int platform_match(struct device *dev, struct device_driver *drv)
++{
++	struct platform_device *pdev = to_platform_device(dev);
++	struct platform_driver *pdrv = to_platform_driver(drv);
++
++	/* match against the id table first */
++	if (pdrv->id_table)
++		return platform_match_id(pdrv->id_table, pdev) != NULL;
++
++	/* fall-back to driver name match */
++	return (strcmp(pdev->name, drv->name) == 0);
++}
++
++#ifdef CONFIG_PM_SLEEP
++
++static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
++{
++	struct platform_driver *pdrv = to_platform_driver(dev->driver);
++	struct platform_device *pdev = to_platform_device(dev);
++	int ret = 0;
++
++	if (dev->driver && pdrv->suspend)
++		ret = pdrv->suspend(pdev, mesg);
++
++	return ret;
++}
++
++static int platform_legacy_resume(struct device *dev)
++{
++	struct platform_driver *pdrv = to_platform_driver(dev->driver);
++	struct platform_device *pdev = to_platform_device(dev);
++	int ret = 0;
++
++	if (dev->driver && pdrv->resume)
++		ret = pdrv->resume(pdev);
++
++	return ret;
++}
++
++static int platform_pm_prepare(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (drv && drv->pm && drv->pm->prepare)
++		ret = drv->pm->prepare(dev);
++
++	return ret;
++}
++
++static void platform_pm_complete(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++
++	if (drv && drv->pm && drv->pm->complete)
++		drv->pm->complete(dev);
++}
++
++#else /* !CONFIG_PM_SLEEP */
++
++#define platform_pm_prepare		NULL
++#define platform_pm_complete		NULL
++
++#endif /* !CONFIG_PM_SLEEP */
++
++#ifdef CONFIG_SUSPEND
++
++int __weak platform_pm_suspend(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->suspend)
++			ret = drv->pm->suspend(dev);
++	} else {
++		ret = platform_legacy_suspend(dev, PMSG_SUSPEND);
++	}
++
++	return ret;
++}
++
++int __weak platform_pm_suspend_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->suspend_noirq)
++			ret = drv->pm->suspend_noirq(dev);
++	}
++
++	return ret;
++}
++
++int __weak platform_pm_resume(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->resume)
++			ret = drv->pm->resume(dev);
++	} else {
++		ret = platform_legacy_resume(dev);
++	}
++
++	return ret;
++}
++
++int __weak platform_pm_resume_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->resume_noirq)
++			ret = drv->pm->resume_noirq(dev);
++	}
++
++	return ret;
++}
++
++#else /* !CONFIG_SUSPEND */
++
++#define platform_pm_suspend		NULL
++#define platform_pm_resume		NULL
++#define platform_pm_suspend_noirq	NULL
++#define platform_pm_resume_noirq	NULL
++
++#endif /* !CONFIG_SUSPEND */
++
++#ifdef CONFIG_HIBERNATION
++
++static int platform_pm_freeze(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->freeze)
++			ret = drv->pm->freeze(dev);
++	} else {
++		ret = platform_legacy_suspend(dev, PMSG_FREEZE);
++	}
++
++	return ret;
++}
++
++static int platform_pm_freeze_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->freeze_noirq)
++			ret = drv->pm->freeze_noirq(dev);
++	}
++
++	return ret;
++}
++
++static int platform_pm_thaw(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->thaw)
++			ret = drv->pm->thaw(dev);
++	} else {
++		ret = platform_legacy_resume(dev);
++	}
++
++	return ret;
++}
++
++static int platform_pm_thaw_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->thaw_noirq)
++			ret = drv->pm->thaw_noirq(dev);
++	}
++
++	return ret;
++}
++
++static int platform_pm_poweroff(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->poweroff)
++			ret = drv->pm->poweroff(dev);
++	} else {
++		ret = platform_legacy_suspend(dev, PMSG_HIBERNATE);
++	}
++
++	return ret;
++}
++
++static int platform_pm_poweroff_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->poweroff_noirq)
++			ret = drv->pm->poweroff_noirq(dev);
++	}
++
++	return ret;
++}
++
++static int platform_pm_restore(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->restore)
++			ret = drv->pm->restore(dev);
++	} else {
++		ret = platform_legacy_resume(dev);
++	}
++
++	return ret;
++}
++
++static int platform_pm_restore_noirq(struct device *dev)
++{
++	struct device_driver *drv = dev->driver;
++	int ret = 0;
++
++	if (!drv)
++		return 0;
++
++	if (drv->pm) {
++		if (drv->pm->restore_noirq)
++			ret = drv->pm->restore_noirq(dev);
++	}
++
++	return ret;
++}
++
++#else /* !CONFIG_HIBERNATION */
++
++#define platform_pm_freeze		NULL
++#define platform_pm_thaw		NULL
++#define platform_pm_poweroff		NULL
++#define platform_pm_restore		NULL
++#define platform_pm_freeze_noirq	NULL
++#define platform_pm_thaw_noirq		NULL
++#define platform_pm_poweroff_noirq	NULL
++#define platform_pm_restore_noirq	NULL
++
++#endif /* !CONFIG_HIBERNATION */
++
++#ifdef CONFIG_PM_RUNTIME
++
++int __weak platform_pm_runtime_suspend(struct device *dev)
++{
++	return pm_generic_runtime_suspend(dev);
++};
++
++int __weak platform_pm_runtime_resume(struct device *dev)
++{
++	return pm_generic_runtime_resume(dev);
++};
++
++int __weak platform_pm_runtime_idle(struct device *dev)
++{
++	return pm_generic_runtime_idle(dev);
++};
++
++#else /* !CONFIG_PM_RUNTIME */
++
++#define platform_pm_runtime_suspend NULL
++#define platform_pm_runtime_resume NULL
++#define platform_pm_runtime_idle NULL
++
++#endif /* !CONFIG_PM_RUNTIME */
++
++static const struct dev_pm_ops platform_dev_pm_ops = {
++	.prepare = platform_pm_prepare,
++	.complete = platform_pm_complete,
++	.suspend = platform_pm_suspend,
++	.resume = platform_pm_resume,
++	.freeze = platform_pm_freeze,
++	.thaw = platform_pm_thaw,
++	.poweroff = platform_pm_poweroff,
++	.restore = platform_pm_restore,
++	.suspend_noirq = platform_pm_suspend_noirq,
++	.resume_noirq = platform_pm_resume_noirq,
++	.freeze_noirq = platform_pm_freeze_noirq,
++	.thaw_noirq = platform_pm_thaw_noirq,
++	.poweroff_noirq = platform_pm_poweroff_noirq,
++	.restore_noirq = platform_pm_restore_noirq,
++	.runtime_suspend = platform_pm_runtime_suspend,
++	.runtime_resume = platform_pm_runtime_resume,
++	.runtime_idle = platform_pm_runtime_idle,
++};
++
++struct bus_type platform_bus_type = {
++	.name		= "platform",
++	.dev_attrs	= platform_dev_attrs,
++	.match		= platform_match,
++	.uevent		= platform_uevent,
++	.pm		= &platform_dev_pm_ops,
++};
++EXPORT_SYMBOL_GPL(platform_bus_type);
++
++int __init platform_bus_init(void)
++{
++	int error;
++
++	early_platform_cleanup();
++
++	error = device_register(&platform_bus);
++	if (error)
++		return error;
++	error =  bus_register(&platform_bus_type);
++	if (error)
++		device_unregister(&platform_bus);
++	return error;
++}
++
++#ifndef ARCH_HAS_DMA_GET_REQUIRED_MASK
++u64 dma_get_required_mask(struct device *dev)
++{
++	u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT);
++	u32 high_totalram = ((max_pfn - 1) >> (32 - PAGE_SHIFT));
++	u64 mask;
++
++	if (!high_totalram) {
++		/* convert to mask just covering totalram */
++		low_totalram = (1 << (fls(low_totalram) - 1));
++		low_totalram += low_totalram - 1;
++		mask = low_totalram;
++	} else {
++		high_totalram = (1 << (fls(high_totalram) - 1));
++		high_totalram += high_totalram - 1;
++		mask = (((u64)high_totalram) << 32) + 0xffffffff;
++	}
++	return mask;
++}
++EXPORT_SYMBOL_GPL(dma_get_required_mask);
++#endif
++
++static __initdata LIST_HEAD(early_platform_driver_list);
++static __initdata LIST_HEAD(early_platform_device_list);
++
++/**
++ * early_platform_driver_register - register early platform driver
++ * @epdrv: early_platform driver structure
++ * @buf: string passed from early_param()
++ *
++ * Helper function for early_platform_init() / early_platform_init_buffer()
++ */
++int __init early_platform_driver_register(struct early_platform_driver *epdrv,
++					  char *buf)
++{
++	char *tmp;
++	int n;
++
++	/* Simply add the driver to the end of the global list.
++	 * Drivers will by default be put on the list in compiled-in order.
++	 */
++	if (!epdrv->list.next) {
++		INIT_LIST_HEAD(&epdrv->list);
++		list_add_tail(&epdrv->list, &early_platform_driver_list);
++	}
++
++	/* If the user has specified device then make sure the driver
++	 * gets prioritized. The driver of the last device specified on
++	 * command line will be put first on the list.
++	 */
++	n = strlen(epdrv->pdrv->driver.name);
++	if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) {
++		list_move(&epdrv->list, &early_platform_driver_list);
++
++		/* Allow passing parameters after device name */
++		if (buf[n] == '\0' || buf[n] == ',')
++			epdrv->requested_id = -1;
++		else {
++			epdrv->requested_id = simple_strtoul(&buf[n + 1],
++							     &tmp, 10);
++
++			if (buf[n] != '.' || (tmp == &buf[n + 1])) {
++				epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
++				n = 0;
++			} else
++				n += strcspn(&buf[n + 1], ",") + 1;
++		}
++
++		if (buf[n] == ',')
++			n++;
++
++		if (epdrv->bufsize) {
++			memcpy(epdrv->buffer, &buf[n],
++			       min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1));
++			epdrv->buffer[epdrv->bufsize - 1] = '\0';
++		}
++	}
++
++	return 0;
++}
++
++/**
++ * early_platform_add_devices - adds a number of early platform devices
++ * @devs: array of early platform devices to add
++ * @num: number of early platform devices in array
++ *
++ * Used by early architecture code to register early platform devices and
++ * their platform data.
++ */
++void __init early_platform_add_devices(struct platform_device **devs, int num)
++{
++	struct device *dev;
++	int i;
++
++	/* simply add the devices to list */
++	for (i = 0; i < num; i++) {
++		dev = &devs[i]->dev;
++
++		if (!dev->devres_head.next) {
++			INIT_LIST_HEAD(&dev->devres_head);
++			list_add_tail(&dev->devres_head,
++				      &early_platform_device_list);
++		}
++	}
++}
++
++/**
++ * early_platform_driver_register_all - register early platform drivers
++ * @class_str: string to identify early platform driver class
++ *
++ * Used by architecture code to register all early platform drivers
++ * for a certain class. If omitted then only early platform drivers
++ * with matching kernel command line class parameters will be registered.
++ */
++void __init early_platform_driver_register_all(char *class_str)
++{
++	/* The "class_str" parameter may or may not be present on the kernel
++	 * command line. If it is present then there may be more than one
++	 * matching parameter.
++	 *
++	 * Since we register our early platform drivers using early_param()
++	 * we need to make sure that they also get registered in the case
++	 * when the parameter is missing from the kernel command line.
++	 *
++	 * We use parse_early_options() to make sure the early_param() gets
++	 * called at least once. The early_param() may be called more than
++	 * once since the name of the preferred device may be specified on
++	 * the kernel command line. early_platform_driver_register() handles
++	 * this case for us.
++	 */
++	parse_early_options(class_str);
++}
++
++/**
++ * early_platform_match - find early platform device matching driver
++ * @epdrv: early platform driver structure
++ * @id: id to match against
++ */
++static  __init struct platform_device *
++early_platform_match(struct early_platform_driver *epdrv, int id)
++{
++	struct platform_device *pd;
++
++	list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
++		if (platform_match(&pd->dev, &epdrv->pdrv->driver))
++			if (pd->id == id)
++				return pd;
++
++	return NULL;
++}
++
++/**
++ * early_platform_left - check if early platform driver has matching devices
++ * @epdrv: early platform driver structure
++ * @id: return true if id or above exists
++ */
++static  __init int early_platform_left(struct early_platform_driver *epdrv,
++				       int id)
++{
++	struct platform_device *pd;
++
++	list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
++		if (platform_match(&pd->dev, &epdrv->pdrv->driver))
++			if (pd->id >= id)
++				return 1;
++
++	return 0;
++}
++
++/**
++ * early_platform_driver_probe_id - probe drivers matching class_str and id
++ * @class_str: string to identify early platform driver class
++ * @id: id to match against
++ * @nr_probe: number of platform devices to successfully probe before exiting
++ */
++static int __init early_platform_driver_probe_id(char *class_str,
++						 int id,
++						 int nr_probe)
++{
++	struct early_platform_driver *epdrv;
++	struct platform_device *match;
++	int match_id;
++	int n = 0;
++	int left = 0;
++
++	list_for_each_entry(epdrv, &early_platform_driver_list, list) {
++		/* only use drivers matching our class_str */
++		if (strcmp(class_str, epdrv->class_str))
++			continue;
++
++		if (id == -2) {
++			match_id = epdrv->requested_id;
++			left = 1;
++
++		} else {
++			match_id = id;
++			left += early_platform_left(epdrv, id);
++
++			/* skip requested id */
++			switch (epdrv->requested_id) {
++			case EARLY_PLATFORM_ID_ERROR:
++			case EARLY_PLATFORM_ID_UNSET:
++				break;
++			default:
++				if (epdrv->requested_id == id)
++					match_id = EARLY_PLATFORM_ID_UNSET;
++			}
++		}
++
++		switch (match_id) {
++		case EARLY_PLATFORM_ID_ERROR:
++			pr_warning("%s: unable to parse %s parameter\n",
++				   class_str, epdrv->pdrv->driver.name);
++			/* fall-through */
++		case EARLY_PLATFORM_ID_UNSET:
++			match = NULL;
++			break;
++		default:
++			match = early_platform_match(epdrv, match_id);
++		}
++
++		if (match) {
++			/*
++			 * Set up a sensible init_name to enable
++			 * dev_name() and others to be used before the
++			 * rest of the driver core is initialized.
++			 */
++			if (!match->dev.init_name && slab_is_available()) {
++				if (match->id != -1)
++					match->dev.init_name =
++						kasprintf(GFP_KERNEL, "%s.%d",
++							  match->name,
++							  match->id);
++				else
++					match->dev.init_name =
++						kasprintf(GFP_KERNEL, "%s",
++							  match->name);
++
++				if (!match->dev.init_name)
++					return -ENOMEM;
++			}
++
++			if (epdrv->pdrv->probe(match))
++				pr_warning("%s: unable to probe %s early.\n",
++					   class_str, match->name);
++			else
++				n++;
++		}
++
++		if (n >= nr_probe)
++			break;
++	}
++
++	if (left)
++		return n;
++	else
++		return -ENODEV;
++}
++
++/**
++ * early_platform_driver_probe - probe a class of registered drivers
++ * @class_str: string to identify early platform driver class
++ * @nr_probe: number of platform devices to successfully probe before exiting
++ * @user_only: only probe user specified early platform devices
++ *
++ * Used by architecture code to probe registered early platform drivers
++ * within a certain class. For probe to happen a registered early platform
++ * device matching a registered early platform driver is needed.
++ */
++int __init early_platform_driver_probe(char *class_str,
++				       int nr_probe,
++				       int user_only)
++{
++	int k, n, i;
++
++	n = 0;
++	for (i = -2; n < nr_probe; i++) {
++		k = early_platform_driver_probe_id(class_str, i, nr_probe - n);
++
++		if (k < 0)
++			break;
++
++		n += k;
++
++		if (user_only)
++			break;
++	}
++
++	return n;
++}
++
++/**
++ * early_platform_cleanup - clean up early platform code
++ */
++void __init early_platform_cleanup(void)
++{
++	struct platform_device *pd, *pd2;
++
++	/* clean up the devres list used to chain devices */
++	list_for_each_entry_safe(pd, pd2, &early_platform_device_list,
++				 dev.devres_head) {
++		list_del(&pd->dev.devres_head);
++		memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head));
++	}
++}
++
+diff -rupN linux-2.6.35.11/drivers/base/sys.c linux-2.6.35.11-ts7500/drivers/base/sys.c
+--- linux-2.6.35.11/drivers/base/sys.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/base/sys.c	2011-03-14 11:18:24.000000000 -0400
+@@ -500,6 +500,7 @@ EXPORT_SYMBOL_GPL(sysdev_resume);
+ 
+ int __init system_bus_init(void)
+ {
++   //printk("system_bus_init(), calling kset_create_and_add(system)\n");
+ 	system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
+ 	if (!system_kset)
+ 		return -ENOMEM;
+diff -rupN linux-2.6.35.11/drivers/char/mem.c linux-2.6.35.11-ts7500/drivers/char/mem.c
+--- linux-2.6.35.11/drivers/char/mem.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/char/mem.c	2011-03-14 11:18:24.000000000 -0400
+@@ -898,6 +898,8 @@ static int __init chr_dev_init(void)
+ 	int minor;
+ 	int err;
+ 
++   //printk("chr_dev_init(), calling bdi_init()\n");
++   
+ 	err = bdi_init(&zero_bdi);
+ 	if (err)
+ 		return err;
+diff -rupN linux-2.6.35.11/drivers/i2c/busses/i2c-str8100.c linux-2.6.35.11-ts7500/drivers/i2c/busses/i2c-str8100.c
+--- linux-2.6.35.11/drivers/i2c/busses/i2c-str8100.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/i2c/busses/i2c-str8100.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,929 @@
++ /*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <asm/uaccess.h>
++#include <asm/irq.h>
++#include <linux/sysctl.h>
++
++#include <mach/star_intc.h>
++#include <mach/star_i2c.h>
++#include <mach/star_misc.h>
++#include <mach/star_powermgt.h>
++
++#include "i2c-str8100.h"
++
++#define STR8100_I2C_DATE          "20060613"
++#define STR8100_I2C_VERSION       "1.0.0"
++
++#define I2C_K                     1000
++#define I2C_M                     1000000
++
++//extern u32 PLL_clock;
++//extern u32 CPU_clock;
++//extern u32 AHB_clock;
++extern u32 APB_clock;
++#define I2C_PCLK                  APB_clock
++/*#if 1 // for ASIC
++#define I2C_PCLK                  200000000
++#else // for FPGA
++#define I2C_PCLK                  13000000
++#endif
++*/
++#define TWI_TIMEOUT	          2*(HZ)
++
++#define I2C_100KHZ	  100000
++#define I2C_200KHZ	  200000
++#define I2C_300KHZ	  300000
++#define I2C_400KHZ	  400000
++
++static i2c_transfer_t i2c_cmd_transfer;
++
++unsigned int debug=0;
++module_param(debug, uint, 0);
++MODULE_PARM_DESC(debug, "STR8100 I2C debug option (0:off 1:on, default=0)");
++
++static unsigned int current_clock;
++unsigned int clock=400000;
++module_param(clock, uint, 0);
++MODULE_PARM_DESC(clock, "STR8100 I2C clock in Hz (default=400000)");
++
++static wait_queue_head_t waitqueue;	/* wait queue for read/write to complete */
++
++extern void str8100_set_interrupt_trigger (unsigned int, unsigned int, unsigned int, unsigned int);
++#define u_int32 unsigned int
++
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_I2c_Is_Bus_Idle
++ * PURPOSE:
++ *
++ ******************************************************************************/
++u_int32 Hal_I2c_Is_Bus_Idle(void)
++{
++    /*
++     * Return value :
++     *    1 : Bus Idle
++     *    0 : Bus Busy
++     */    
++    return ((I2C_CONTROLLER_REG & (0x1 << 6)) ? 0 : 1);
++}
++
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_I2c_Is_Action_Done
++ * PURPOSE:
++ *
++ ******************************************************************************/
++u_int32 Hal_I2c_Is_Action_Done(void)
++{
++    /*
++     * Return value :
++     *    1 : Action Done
++     *    0 : Action is NOT Done
++     */    
++    return ((I2C_INTERRUPT_STATUS_REG & I2C_ACTION_DONE_FLAG) ? 1 : 0);
++}
++
++/******************************************************************************
++ *
++ * FUNCTION:  Hal_I2c_Dispatch_Transfer
++ * PURPOSE:
++ *
++ ******************************************************************************/
++void Hal_I2c_Dispatch_Transfer(i2c_transfer_t *i2c_transfer)
++{
++    u_int32 volatile    i2c_control;
++    u_int32 volatile    i2c_control_reg;
++
++
++    /*
++     * Wait unti I2C Bus is idle and the previous action is done
++     */
++//    while (!Hal_I2c_Is_Bus_Idle() && !Hal_I2c_Is_Action_Done());
++    int retries = 2000;    
++   
++    while (!Hal_I2c_Is_Bus_Idle() && !Hal_I2c_Is_Action_Done() && retries--);	
++         udelay(1000); 
++
++    if (retries == 0) {
++      printk ("%s: Bus idle fail!!\n",__FUNCTION__);  
++      return;
++    }
++
++
++    // Configure transfer command, write data length, and read data length
++    i2c_control = ((i2c_transfer->transfer_cmd & 0x3) << 4) |
++                  ((i2c_transfer->write_data_len & 0x3) << 2) |
++                  ((i2c_transfer->read_data_len & 0x3) << 0);
++    
++    // Note we enable I2C again!!
++    i2c_control_reg = I2C_CONTROLLER_REG;
++    
++    i2c_control_reg &= ~(0x3F);
++    i2c_control_reg |= (i2c_control & 0x3F) | ((u_int32)0x1 << 31);
++
++    I2C_CONTROLLER_REG = i2c_control_reg;
++
++    // Write output data
++    I2C_WRITE_DATA_REG = i2c_transfer->write_data;
++
++    // Configure slave address
++    I2C_SLAVE_ADDRESS_REG = i2c_transfer->slave_addr & 0xFE;
++
++    // Start IC transfer
++    HAL_I2C_START_TRANSFER();
++}
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2c_Read_Only_Command
++ * PURPOSE:
++ *
++ ******************************************************************************/
++u_int32 I2c_Read_Only_Command(u_int32 slave_addr, u_int32 read_data_len, 
++                              u_int32 *read_data)
++{
++    long timeout;
++
++
++    // Clear previous I2C interrupt status
++    IO_OUT_WORD(I2C_INTERRUPT_STATUS_REG_ADDR, I2C_BUS_ERROR_FLAG | I2C_ACTION_DONE_FLAG);
++
++    // Enable I2C interrupt sources
++    IO_OUT_WORD(I2C_INTERRUPT_ENABLE_REG_ADDR, I2C_BUS_ERROR_FLAG | I2C_ACTION_DONE_FLAG);
++
++
++    /*
++     * Configure this I2C command tranfer settings
++     */
++    i2c_cmd_transfer.transfer_cmd = I2C_READ_ONLY_CMD;
++    
++    i2c_cmd_transfer.write_data_len = 0;
++    
++    i2c_cmd_transfer.read_data_len = read_data_len & 0x3;
++
++    i2c_cmd_transfer.slave_addr = slave_addr & 0xFF;
++
++    i2c_cmd_transfer.write_data = 0;
++
++    i2c_cmd_transfer.error_status = 0;
++
++    i2c_cmd_transfer.action_done = 0;
++
++
++    /*
++     * Issue this command
++     */
++    Hal_I2c_Dispatch_Transfer(&i2c_cmd_transfer);
++
++
++    // Check if this I2C bus action is done or not
++/*    while (1)
++    {
++        Sys_Interrupt_Disable_Save_Flags(&cpsr_flags);
++   
++        if ((i2c_cmd_transfer.action_done) || (i2c_cmd_transfer.error_status))
++        {
++            break;
++        }
++
++        Sys_Interrupt_Restore_Flags(cpsr_flags);
++    }
++
++    Sys_Interrupt_Restore_Flags(cpsr_flags);
++*/
++    timeout = interruptible_sleep_on_timeout(&waitqueue, TWI_TIMEOUT);
++    if (timeout == 0) return 0x99; 
++
++    // I2C Bus error!!
++    if (i2c_cmd_transfer.error_status && (i2c_cmd_transfer.error_status != 0xFF))
++    {
++        return (i2c_cmd_transfer.error_status);
++    }
++
++    // Get the read data byte
++    i2c_cmd_transfer.read_data = IO_IN_WORD(I2C_READ_DATA_REG_ADDR);
++    
++    switch (read_data_len & 0x3)
++    {
++        case I2C_DATA_LEN_1_BYTE :
++        
++            i2c_cmd_transfer.read_data &= 0xFF;//8
++            
++            break;
++
++        case I2C_DATA_LEN_2_BYTE :
++        
++            i2c_cmd_transfer.read_data &= 0xFFFF;//16
++            
++            break;
++
++        case I2C_DATA_LEN_3_BYTE :
++        
++            i2c_cmd_transfer.read_data &= 0xFFFFFF;//24
++            
++            break;
++
++        case I2C_DATA_LEN_4_BYTE :
++
++        default :
++        
++            break;
++    }
++
++
++    // Set the data for return
++    *read_data = i2c_cmd_transfer.read_data;
++
++    return (0);
++}
++
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2c_Write_Only_Command
++ * PURPOSE:
++ *
++ ******************************************************************************/
++u_int32 I2c_Write_Only_Command(u_int32 slave_addr, u_int32 write_data_len,
++                               u_int32 write_data)
++{
++    long timeout;
++
++
++    // Clear previous I2C interrupt status
++    IO_OUT_WORD(I2C_INTERRUPT_STATUS_REG_ADDR, I2C_BUS_ERROR_FLAG | I2C_ACTION_DONE_FLAG);
++
++    // Enable I2C interrupt sources
++    IO_OUT_WORD(I2C_INTERRUPT_ENABLE_REG_ADDR, I2C_BUS_ERROR_FLAG | I2C_ACTION_DONE_FLAG);
++
++
++    /*
++     * Configure this I2C command tranfer settings
++     */
++    i2c_cmd_transfer.transfer_cmd = I2C_WRITE_ONLY_CMD;
++    
++    i2c_cmd_transfer.write_data_len = write_data_len & 0x3;
++    
++    i2c_cmd_transfer.read_data_len = 0;
++
++    i2c_cmd_transfer.slave_addr = slave_addr & 0xFF;
++
++    switch (write_data_len & 0x3)
++    {
++        case I2C_DATA_LEN_1_BYTE :
++        
++            i2c_cmd_transfer.write_data = write_data & 0xFF;
++            
++            break;
++
++        case I2C_DATA_LEN_2_BYTE :
++        
++            i2c_cmd_transfer.write_data = write_data & 0xFFFF;
++            
++            break;
++
++        case I2C_DATA_LEN_3_BYTE :
++        
++            i2c_cmd_transfer.write_data = write_data & 0xFFFFFF;
++            
++            break;
++
++        case I2C_DATA_LEN_4_BYTE :
++
++            i2c_cmd_transfer.write_data = write_data;
++
++        default :
++
++            i2c_cmd_transfer.write_data = write_data;
++            
++            break;
++    }
++
++    i2c_cmd_transfer.error_status = 0;
++
++    i2c_cmd_transfer.action_done = 0;
++
++
++    /*
++     * Issue this command
++     */
++    Hal_I2c_Dispatch_Transfer(&i2c_cmd_transfer);
++
++
++    // Check if this I2C bus action is done or not
++/*    while (1)
++    {
++        Sys_Interrupt_Disable_Save_Flags(&cpsr_flags);
++   
++        if ((i2c_cmd_transfer.action_done) || (i2c_cmd_transfer.error_status))
++        {
++            break;
++        }
++
++        Sys_Interrupt_Restore_Flags(cpsr_flags);
++    }
++
++    Sys_Interrupt_Restore_Flags(cpsr_flags);
++*/
++    timeout = interruptible_sleep_on_timeout(&waitqueue, TWI_TIMEOUT);
++    if (timeout == 0) return 0x99; 
++
++    // I2C Bus error!!
++    if (i2c_cmd_transfer.error_status && (i2c_cmd_transfer.error_status != 0xFF))
++    {
++        return (i2c_cmd_transfer.error_status);
++    }
++    else
++    {
++        return (0);
++    }
++}
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2c_Write_Read_Command
++ * PURPOSE:
++ *
++ ******************************************************************************/
++u_int32 I2c_Write_Read_Command(u_int32 slave_addr, 
++                               u_int32 write_data_len, u_int32 write_data,
++                               u_int32 read_data_len, u_int32 *read_data)
++{
++    long timeout;
++
++
++    // Clear previous I2C interrupt status
++    IO_OUT_WORD(I2C_INTERRUPT_STATUS_REG_ADDR, I2C_BUS_ERROR_FLAG | I2C_ACTION_DONE_FLAG);
++
++    // Enable I2C interrupt sources
++    IO_OUT_WORD(I2C_INTERRUPT_ENABLE_REG_ADDR, I2C_BUS_ERROR_FLAG | I2C_ACTION_DONE_FLAG);
++
++
++    /*
++     * Configure this I2C command tranfer settings
++     */
++    i2c_cmd_transfer.transfer_cmd = I2C_WRITE_READ_CMD;
++    
++    i2c_cmd_transfer.write_data_len = write_data_len & 0x3;
++    
++    i2c_cmd_transfer.read_data_len = read_data_len & 0x3;
++
++    i2c_cmd_transfer.slave_addr = slave_addr & 0xFF;
++
++    switch (write_data_len & 0x3)
++    {
++        case I2C_DATA_LEN_1_BYTE :
++        
++            i2c_cmd_transfer.write_data = write_data & 0xFF;
++            
++            break;
++
++        case I2C_DATA_LEN_2_BYTE :
++        
++            i2c_cmd_transfer.write_data = write_data & 0xFFFF;
++            
++            break;
++
++        case I2C_DATA_LEN_3_BYTE :
++        
++            i2c_cmd_transfer.write_data = write_data & 0xFFFFFF;
++            
++            break;
++
++        case I2C_DATA_LEN_4_BYTE :
++
++            i2c_cmd_transfer.write_data = write_data;
++
++        default :
++
++            i2c_cmd_transfer.write_data = write_data;
++            
++            break;
++    }
++
++    i2c_cmd_transfer.error_status = 0;
++
++    i2c_cmd_transfer.action_done = 0;
++
++
++    /*
++     * Issue this command
++     */
++    Hal_I2c_Dispatch_Transfer(&i2c_cmd_transfer);
++
++
++    // Check if this I2C bus action is done or not
++/*    while (1)
++    {
++        Sys_Interrupt_Disable_Save_Flags(&cpsr_flags);
++   
++        if ((i2c_cmd_transfer.action_done) || (i2c_cmd_transfer.error_status))
++        {
++            break;
++        }
++
++        Sys_Interrupt_Restore_Flags(cpsr_flags);
++    }
++
++    Sys_Interrupt_Restore_Flags(cpsr_flags);
++*/
++    timeout = interruptible_sleep_on_timeout(&waitqueue, TWI_TIMEOUT);
++    if (timeout == 0) return 0x99; 
++
++    // I2C Bus error!!
++    if (i2c_cmd_transfer.error_status && (i2c_cmd_transfer.error_status != 0xFF))
++    {
++        return (i2c_cmd_transfer.error_status);
++    }
++
++    // Get the read data byte
++    i2c_cmd_transfer.read_data = IO_IN_WORD(I2C_READ_DATA_REG_ADDR);
++    
++    switch (read_data_len & 0x3)
++    {
++        case I2C_DATA_LEN_1_BYTE :
++        
++            i2c_cmd_transfer.read_data &= 0xFF;
++            
++            break;
++
++        case I2C_DATA_LEN_2_BYTE :
++        
++            i2c_cmd_transfer.read_data &= 0xFFFF;
++            
++            break;
++
++        case I2C_DATA_LEN_3_BYTE :
++        
++            i2c_cmd_transfer.read_data &= 0xFFFFFF;
++            
++            break;
++
++        case I2C_DATA_LEN_4_BYTE :
++
++        default :
++            break;
++    }
++
++
++    // Set the data for return
++    *read_data = i2c_cmd_transfer.read_data;
++
++    return (0);
++}
++
++
++
++/******************************************************************************
++ *
++ * FUNCTION:  I2c_Read_Write_Command
++ * PURPOSE:
++ *
++ ******************************************************************************/
++u_int32 I2c_Read_Write_Command(u_int32 slave_addr, 
++                               u_int32 read_data_len, u_int32 *read_data,
++                               u_int32 write_data_len, u_int32 write_data)
++{
++    long timeout;
++
++
++    // Clear previous I2C interrupt status
++    IO_OUT_WORD(I2C_INTERRUPT_STATUS_REG_ADDR, I2C_BUS_ERROR_FLAG | I2C_ACTION_DONE_FLAG);
++
++    // Enable I2C interrupt sources
++    IO_OUT_WORD(I2C_INTERRUPT_ENABLE_REG_ADDR, I2C_BUS_ERROR_FLAG | I2C_ACTION_DONE_FLAG);
++
++
++    /*
++     * Configure this I2C command tranfer settings
++     */
++    i2c_cmd_transfer.transfer_cmd = I2C_READ_WRITE_CMD;
++    
++    i2c_cmd_transfer.write_data_len = write_data_len & 0x3;
++    
++    i2c_cmd_transfer.read_data_len = read_data_len & 0x3;
++
++    i2c_cmd_transfer.slave_addr = slave_addr & 0xFF;
++
++    switch (write_data_len & 0x3)
++    {
++        case I2C_DATA_LEN_1_BYTE :
++        
++            i2c_cmd_transfer.write_data = write_data & 0xFF;
++            
++            break;
++
++        case I2C_DATA_LEN_2_BYTE :
++        
++            i2c_cmd_transfer.write_data = write_data & 0xFFFF;
++            
++            break;
++
++        case I2C_DATA_LEN_3_BYTE :
++        
++            i2c_cmd_transfer.write_data = write_data & 0xFFFFFF;
++            
++            break;
++
++        case I2C_DATA_LEN_4_BYTE :
++
++            i2c_cmd_transfer.write_data = write_data;
++
++        default :
++        
++            i2c_cmd_transfer.write_data = write_data;
++            
++            break;
++    }
++
++    i2c_cmd_transfer.error_status = 0;
++
++    i2c_cmd_transfer.action_done = 0;
++
++
++    /*
++     * Issue this command
++     */
++    Hal_I2c_Dispatch_Transfer(&i2c_cmd_transfer);
++
++
++    // Check if this I2C bus action is done or not
++/*    while (1)
++    {
++        Sys_Interrupt_Disable_Save_Flags(&cpsr_flags);
++   
++        if ((i2c_cmd_transfer.action_done) || (i2c_cmd_transfer.error_status))
++        {
++            break;
++        }
++
++        Sys_Interrupt_Restore_Flags(cpsr_flags);
++    }
++
++    Sys_Interrupt_Restore_Flags(cpsr_flags);
++*/
++    timeout = interruptible_sleep_on_timeout(&waitqueue, TWI_TIMEOUT);
++    if (timeout == 0) return 0x99; 
++
++
++    // I2C Bus error!!
++    if (i2c_cmd_transfer.error_status && (i2c_cmd_transfer.error_status != 0xFF))
++    {
++        return (i2c_cmd_transfer.error_status);
++    }
++
++    // Get the read data byte
++    i2c_cmd_transfer.read_data = IO_IN_WORD(I2C_READ_DATA_REG_ADDR);
++    
++    switch (read_data_len & 0x3)
++    {
++        case I2C_DATA_LEN_1_BYTE :
++        
++            i2c_cmd_transfer.read_data &= 0xFF;
++            
++            break;
++
++        case I2C_DATA_LEN_2_BYTE :
++        
++            i2c_cmd_transfer.read_data &= 0xFFFF;
++            
++            break;
++
++        case I2C_DATA_LEN_3_BYTE :
++        
++            i2c_cmd_transfer.read_data &= 0xFFFFFF;
++            
++            break;
++
++        case I2C_DATA_LEN_4_BYTE :
++
++        default :
++
++            break;
++    }
++
++    // Set the data for return
++    *read_data = i2c_cmd_transfer.read_data;
++
++    return (0);
++}
++//====================================================================================
++// Eileen , for linux kernel 2.6.24 , 20080416
++// old :static void str8100_i2c_init()
++static void str8100_i2c_init(void)
++{ 
++//	unsigned long clock = 100 * (priv->twi_cwgr + 1) * I2C_K; 
++
++	current_clock=clock;
++//	if(debug)
++		printk("%s: current_clock=%ul, CLKDIV=%d\n",__FUNCTION__,current_clock,(I2C_PCLK / (2 * current_clock) - 1));
++	
++	HAL_MISC_ENABLE_I2C_PINS();
++		
++	HAL_PWRMGT_ENABLE_I2C_CLOCK();
++		
++#if 0
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX);   
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX);   
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX);
++#endif
++//	I2C_CONTROLLER_REG = (0 << 6) | (0 << 24) | (0 << 31);
++	I2C_CONTROLLER_REG = 0 ;
++//	I2C_TIME_OUT_REG = (((I2C_PCLK / (2 * clock) - 1)<<8)|(1 << 7)|0x40);
++	I2C_TIME_OUT_REG = (((I2C_PCLK / (2 * current_clock) - 1)<<8)|(1 << 7)|0x10);
++	I2C_INTERRUPT_ENABLE_REG = 0;
++	I2C_INTERRUPT_STATUS_REG = I2C_BUS_ERROR_FLAG | I2C_ACTION_DONE_FLAG;
++	HAL_I2C_ENABLE_I2C();
++		
++}
++/*
++typedef union __data_t{
++	struct{
++		unsigned char byte[4];
++	} byte;
++	unsigned int u32;
++} data;
++
++unsigned int i2c_read_len(unsigned int addr, unsigned char *buf, unsigned int len){
++	data	data;
++	if((ret=I2c_Read_Only_Command(addr,&data.u32,len)))
++		return ret;
++		
++	switch(rem_len){
++	case 1:
++		*tmp_buf=byte[0];tmp_buf++;
++		break;
++	case 2:
++		*tmp_buf=byte[1];tmp_buf++;
++		*tmp_buf=byte[0];tmp_buf++;
++		break;
++	case 3:
++		*tmp_buf=byte[2];tmp_buf++;
++		*tmp_buf=byte[1];tmp_buf++;
++		*tmp_buf=byte[0];tmp_buf++;
++		break;
++	case 4:
++		*tmp_buf=byte[3];tmp_buf++;
++		*tmp_buf=byte[2];tmp_buf++;
++		*tmp_buf=byte[1];tmp_buf++;
++		*tmp_buf=byte[0];tmp_buf++;
++		break;
++	default:
++		return 99;
++	}
++	return 0;
++}
++*/
++static int
++i2c_read(unsigned int addr, unsigned char *buf, unsigned int len)
++{
++	unsigned int i;
++	unsigned int data;
++	int ret;
++
++	if (len == 0) return 0;
++
++	for(i=0;i<len;i++){
++//	if(I2c_Write_Read_Command((addr<<1),0,0,3,&data)){
++//	if(I2c_Eeprom_AT24C16A_Read_Byte(0x0a,7,0,&data)){
++		if((ret=I2c_Read_Only_Command((addr<<1),0,&data))){
++			if(debug)
++				printk("Error %s: ret=0x%x\n",__FUNCTION__,ret);
++			return -EIO;
++		}
++		buf[i] = data;
++	}
++
++	return 0;
++}
++
++static int
++i2c_write(unsigned int addr, unsigned char *buf, unsigned int len)
++{
++	unsigned int i,data=0;
++	int ret;
++	if (len == 0) return 0;
++
++	if (len >4) return -EIO;
++	
++	for(i=0;i<len;i++) data=data|(buf[i]<<(i<<3));
++
++		if((ret=I2c_Write_Only_Command((addr<<1),len-1,data))){
++			if(debug)
++				printk("Error %s: ret=0x%x\n",__FUNCTION__,ret);
++			return -EIO;
++		}
++
++	return 0;
++}
++
++static int str8100_xfer(struct i2c_adapter *adapter, struct i2c_msg msgs[], int num)
++{
++	struct i2c_msg *p;
++	int i, err = 0;
++
++	// Eileen , for linux kernel 2.6.24 , 20080416
++	// old : if(clock!=current_clock) str8100_i2c_init(adapter);
++	if(clock!=current_clock) str8100_i2c_init(); 
++	
++	if(debug)
++		printk("\n%s: num=%d\n",__FUNCTION__,num);
++	for (i = 0; !err && i < num; i++) {
++		if(debug)
++			printk("%s: %s msgs[%d] addr=%x len=%d\n",__FUNCTION__,(msgs[i].flags & I2C_M_RD)?"read":"write",i,msgs[i].addr,msgs[i].len);
++		p = &msgs[i];
++		if (!p->len) continue;
++		if (p->flags & I2C_M_RD)
++			err = i2c_read(p->addr, p->buf, p->len);
++		else
++			err = i2c_write(p->addr, p->buf, p->len);
++	}
++
++	/* Return the number of messages processed, or the error code.
++	*/
++	if (err == 0)
++		err = num;
++
++	return err;
++}
++
++static u32 str8100_func(struct i2c_adapter *adapter)
++{
++/*    return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE
++		| I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA
++		| I2C_FUNC_SMBUS_BLOCK_DATA;
++*/
++//    return I2C_FUNC_I2C;
++	return I2C_FUNC_SMBUS_EMUL|I2C_FUNC_I2C | I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE
++		| I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA
++		| I2C_FUNC_SMBUS_BLOCK_DATA;
++}
++
++static int str8100_ioctl(struct i2c_adapter *adapter,unsigned int cmd, unsigned long arg)
++{
++	unsigned int s_msg;    
++    
++	if(debug)
++		printk("===> %s: \n",__FUNCTION__);
++	if (copy_from_user(&s_msg, (unsigned int *)arg, sizeof(unsigned int))) 
++		return -EFAULT;
++	if ((clock != s_msg) && s_msg>= I2C_100KHZ && s_msg<= I2C_400KHZ){
++		clock=s_msg;
++		str8100_i2c_init();
++	}
++	return 0;   
++}
++
++
++//MKL: adapter ====================================================================
++// Eileen , for linux kernel 2.6.24 , 20080416
++// old : static irqreturn_t str8100_i2c_int(int irq, void *private, struct pt_regs *regs)
++static irqreturn_t str8100_i2c_int(int irq, void *private)
++{
++	unsigned int volatile interrupt_status;	
++    
++	interrupt_status = *((u32 volatile *)I2C_INTERRUPT_STATUS_REG_ADDR);
++	*((u32 volatile *)I2C_INTERRUPT_STATUS_REG_ADDR) = interrupt_status;
++	i2c_cmd_transfer.action_done = (interrupt_status & I2C_ACTION_DONE_FLAG) ? 1 : 0;
++	i2c_cmd_transfer.error_status = (interrupt_status & I2C_BUS_ERROR_FLAG) ? ((interrupt_status >> 8) & 0xFF) : 0;
++	if(debug)
++		printk("%s: i2c_cmd_transfer.error_status=0x%x\n",__FUNCTION__,i2c_cmd_transfer.error_status);
++	if (i2c_cmd_transfer.error_status && (i2c_cmd_transfer.error_status != 0xFF))
++	HAL_I2C_DISABLE_I2C();  
++	wake_up_interruptible(&waitqueue);
++	return IRQ_HANDLED;
++}
++
++#define I2C_HW_STR8100	0x1b0000
++static struct i2c_algorithm str8100_algorithm = {
++//    name:"str8100 i2c",
++//    id:I2C_ALGO_SMBUS,
++    master_xfer: str8100_xfer,
++    algo_control: str8100_ioctl, 
++    functionality: str8100_func,
++};
++
++static struct i2c_adapter str8100_i2c_adapter = {
++	name:              "Str8100 i2c",
++	id:                I2C_HW_STR8100,
++	algo:              &str8100_algorithm,
++};
++
++static ctl_table str8100_i2c_table[]={
++	{	//.ctl_name = DEV_I2C_CLOCK,
++		.procname = "str8100_clock",
++		.data=&clock,
++		.maxlen=sizeof(clock),
++		.mode = 0644,
++		.proc_handler=&proc_dointvec
++	},
++	{	//.ctl_name = DEV_I2C_DEBUG,
++		.procname = "str8100_debug",
++		.data=&debug,
++		.maxlen=sizeof(debug),
++		.mode = 0644,
++		.proc_handler=&proc_dointvec
++	},
++	//{ .ctl_name = 0 }
++};
++
++static ctl_table i2c_dir_table[] = {
++	{ //.ctl_name	= DEV_I2C,
++	  .procname	= "i2c",
++	  .mode		= 0555,
++	  .child	= str8100_i2c_table },
++	//{ .ctl_name = 0 }
++};
++
++static ctl_table i2c_root_table[] = {
++	{ //.ctl_name	= CTL_DEV,
++	  .procname	= "dev",
++	  .mode		= 0555,
++	  .child	= i2c_dir_table },
++	//{ .ctl_name = 0 }
++};
++static struct ctl_table_header *i2c_table_header;//=NULL;
++
++int  str8100_i2c_dev_init(void)
++{
++    
++	int rc;
++
++	printk(KERN_INFO "%s: i2c module version %s\n",__FUNCTION__, STR8100_I2C_VERSION); 
++
++	init_waitqueue_head(&waitqueue);
++	str8100_i2c_init();
++	if ((rc = i2c_add_adapter(&str8100_i2c_adapter))) {
++		printk(KERN_ERR "%s: Adapter %s registration failed\n",__FUNCTION__, str8100_i2c_adapter.name);
++	}
++	if (request_irq(INTC_I2C_BIT_INDEX, str8100_i2c_int, 0, "HS STR8100_I2C", NULL)) {
++		printk("%s: unable to get IRQ %d\n",__FUNCTION__, INTC_I2C_BIT_INDEX);
++		return -EAGAIN;
++	}
++	// Eileen , for linux kernel 2.6.24 , 20080416
++	// old : i2c_table_header = register_sysctl_table(i2c_root_table, 1);
++	i2c_table_header = register_sysctl_table(i2c_root_table);
++	
++	if(!i2c_table_header)
++		printk("%s: unable register sysctl\n",__FUNCTION__);
++	
++	return rc; 
++}
++
++static __init int i2c_init(void) 
++{
++	if(debug)
++		printk("%s: \n",__FUNCTION__);
++	return str8100_i2c_dev_init();
++}
++
++static __exit void i2c_exit(void) 
++{ 
++	int rc;
++	if(debug)
++		printk("%s: \n",__FUNCTION__);
++	if ((rc = i2c_del_adapter(&str8100_i2c_adapter))) printk(KERN_ERR "%s: i2c_del_adapter failed (%i), that's bad!\n",__FUNCTION__, rc);	
++	unregister_sysctl_table(i2c_table_header);
++	free_irq(INTC_I2C_BIT_INDEX,NULL);
++	
++}
++
++module_init(i2c_init);
++module_exit(i2c_exit);
++
++MODULE_AUTHOR("Mac Lin");
++MODULE_DESCRIPTION("I2C driver for Str8100");
++MODULE_LICENSE("GPL");
++
+diff -rupN linux-2.6.35.11/drivers/i2c/busses/i2c-str8100.h linux-2.6.35.11-ts7500/drivers/i2c/busses/i2c-str8100.h
+--- linux-2.6.35.11/drivers/i2c/busses/i2c-str8100.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/i2c/busses/i2c-str8100.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,23 @@
++#ifndef STR8100_I2C_H
++#define STR8100_I2C_H
++
++typedef struct _i2c_transfer_s_
++{
++  unsigned int transfer_cmd;    
++  unsigned int write_data_len;    
++  unsigned int read_data_len;    
++  unsigned int write_data;    
++  unsigned int read_data;    
++  unsigned int slave_addr;    
++  unsigned int action_done;    
++  unsigned int error_status;
++}i2c_transfer_t;
++
++
++/*
++ * define 32 bit IO access macros
++ */ 
++#define IO_OUT_WORD(reg, data)     ((*((volatile u_int32 *)(reg))) = (u_int32)(data))
++#define IO_IN_WORD(reg)            (*((volatile u_int32 *)(reg)))
++
++#endif
+diff -rupN linux-2.6.35.11/drivers/i2c/busses/Kconfig linux-2.6.35.11-ts7500/drivers/i2c/busses/Kconfig
+--- linux-2.6.35.11/drivers/i2c/busses/Kconfig	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/i2c/busses/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -323,6 +323,11 @@ config I2C_BLACKFIN_TWI_CLK_KHZ
+ 	help
+ 	  The unit of the TWI clock is kHz.
+ 
++
++config I2C_STR8100
++ 	tristate "STR8100 I2C"
++ 	depends on ARCH_STR8100 
++
+ config I2C_CPM
+ 	tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
+ 	depends on (CPM1 || CPM2) && OF_I2C
+diff -rupN linux-2.6.35.11/drivers/i2c/busses/Makefile linux-2.6.35.11-ts7500/drivers/i2c/busses/Makefile
+--- linux-2.6.35.11/drivers/i2c/busses/Makefile	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/i2c/busses/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -59,6 +59,7 @@ obj-$(CONFIG_I2C_STU300)	+= i2c-stu300.o
+ obj-$(CONFIG_I2C_VERSATILE)	+= i2c-versatile.o
+ obj-$(CONFIG_I2C_OCTEON)	+= i2c-octeon.o
+ obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
++obj-$(CONFIG_I2C_STR8100)	+= i2c-str8100.o
+ 
+ # External I2C/SMBus adapter drivers
+ obj-$(CONFIG_I2C_PARPORT)	+= i2c-parport.o
+diff -rupN linux-2.6.35.11/drivers/i2c/busses/Makefile.orig linux-2.6.35.11-ts7500/drivers/i2c/busses/Makefile.orig
+--- linux-2.6.35.11/drivers/i2c/busses/Makefile.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/i2c/busses/Makefile.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,80 @@
++#
++# Makefile for the i2c bus drivers.
++#
++
++# ACPI drivers
++obj-$(CONFIG_I2C_SCMI)		+= i2c-scmi.o
++
++# PC SMBus host controller drivers
++obj-$(CONFIG_I2C_ALI1535)	+= i2c-ali1535.o
++obj-$(CONFIG_I2C_ALI1563)	+= i2c-ali1563.o
++obj-$(CONFIG_I2C_ALI15X3)	+= i2c-ali15x3.o
++obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
++obj-$(CONFIG_I2C_AMD756_S4882)	+= i2c-amd756-s4882.o
++obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
++obj-$(CONFIG_I2C_I801)		+= i2c-i801.o
++obj-$(CONFIG_I2C_ISCH)		+= i2c-isch.o
++obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
++obj-$(CONFIG_I2C_NFORCE2_S4985)	+= i2c-nforce2-s4985.o
++obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
++obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
++obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
++obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
++obj-$(CONFIG_I2C_VIA)		+= i2c-via.o
++obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
++
++# Mac SMBus host controller drivers
++obj-$(CONFIG_I2C_HYDRA)		+= i2c-hydra.o
++obj-$(CONFIG_I2C_POWERMAC)	+= i2c-powermac.o
++
++# Embedded system I2C/SMBus host controller drivers
++obj-$(CONFIG_I2C_AT91)		+= i2c-at91.o
++obj-$(CONFIG_I2C_AU1550)	+= i2c-au1550.o
++obj-$(CONFIG_I2C_BLACKFIN_TWI)	+= i2c-bfin-twi.o
++obj-$(CONFIG_I2C_CPM)		+= i2c-cpm.o
++obj-$(CONFIG_I2C_DAVINCI)	+= i2c-davinci.o
++obj-$(CONFIG_I2C_DESIGNWARE)	+= i2c-designware.o
++obj-$(CONFIG_I2C_GPIO)		+= i2c-gpio.o
++obj-$(CONFIG_I2C_HIGHLANDER)	+= i2c-highlander.o
++obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o
++obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
++obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
++obj-$(CONFIG_I2C_IXP2000)	+= i2c-ixp2000.o
++obj-$(CONFIG_I2C_MPC)		+= i2c-mpc.o
++obj-$(CONFIG_I2C_MV64XXX)	+= i2c-mv64xxx.o
++obj-$(CONFIG_I2C_NOMADIK)	+= i2c-nomadik.o
++obj-$(CONFIG_I2C_OCORES)	+= i2c-ocores.o
++obj-$(CONFIG_I2C_OMAP)		+= i2c-omap.o
++obj-$(CONFIG_I2C_PASEMI)	+= i2c-pasemi.o
++obj-$(CONFIG_I2C_PCA_PLATFORM)	+= i2c-pca-platform.o
++obj-$(CONFIG_I2C_PMCMSP)	+= i2c-pmcmsp.o
++obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o
++obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.o
++obj-$(CONFIG_I2C_S3C2410)	+= i2c-s3c2410.o
++obj-$(CONFIG_I2C_S6000)		+= i2c-s6000.o
++obj-$(CONFIG_I2C_SH7760)	+= i2c-sh7760.o
++obj-$(CONFIG_I2C_SH_MOBILE)	+= i2c-sh_mobile.o
++obj-$(CONFIG_I2C_SIMTEC)	+= i2c-simtec.o
++obj-$(CONFIG_I2C_STU300)	+= i2c-stu300.o
++obj-$(CONFIG_I2C_VERSATILE)	+= i2c-versatile.o
++obj-$(CONFIG_I2C_OCTEON)	+= i2c-octeon.o
++obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
++
++# External I2C/SMBus adapter drivers
++obj-$(CONFIG_I2C_PARPORT)	+= i2c-parport.o
++obj-$(CONFIG_I2C_PARPORT_LIGHT)	+= i2c-parport-light.o
++obj-$(CONFIG_I2C_TAOS_EVM)	+= i2c-taos-evm.o
++obj-$(CONFIG_I2C_TINY_USB)	+= i2c-tiny-usb.o
++
++# Other I2C/SMBus bus drivers
++obj-$(CONFIG_I2C_ACORN)		+= i2c-acorn.o
++obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
++obj-$(CONFIG_I2C_PCA_ISA)	+= i2c-pca-isa.o
++obj-$(CONFIG_I2C_SIBYTE)	+= i2c-sibyte.o
++obj-$(CONFIG_I2C_STUB)		+= i2c-stub.o
++obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
++obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
++
++ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
++EXTRA_CFLAGS += -DDEBUG
++endif
+diff -rupN linux-2.6.35.11/drivers/Makefile linux-2.6.35.11-ts7500/drivers/Makefile
+--- linux-2.6.35.11/drivers/Makefile	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -113,3 +113,4 @@ obj-$(CONFIG_VLYNQ)		+= vlynq/
+ obj-$(CONFIG_STAGING)		+= staging/
+ obj-y				+= platform/
+ obj-y				+= ieee802154/
++obj-y				+= star/
+diff -rupN linux-2.6.35.11/drivers/Makefile.orig linux-2.6.35.11-ts7500/drivers/Makefile.orig
+--- linux-2.6.35.11/drivers/Makefile.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/Makefile.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,115 @@
++#
++# Makefile for the Linux kernel device drivers.
++#
++# 15 Sep 2000, Christoph Hellwig <hch@infradead.org>
++# Rewritten to use lists instead of if-statements.
++#
++
++obj-y				+= gpio/
++obj-$(CONFIG_PCI)		+= pci/
++obj-$(CONFIG_PARISC)		+= parisc/
++obj-$(CONFIG_RAPIDIO)		+= rapidio/
++obj-y				+= video/
++obj-y				+= idle/
++obj-$(CONFIG_ACPI)		+= acpi/
++obj-$(CONFIG_SFI)		+= sfi/
++# PnP must come after ACPI since it will eventually need to check if acpi
++# was used and do nothing if so
++obj-$(CONFIG_PNP)		+= pnp/
++obj-$(CONFIG_ARM_AMBA)		+= amba/
++
++obj-$(CONFIG_VIRTIO)		+= virtio/
++obj-$(CONFIG_XEN)		+= xen/
++
++# regulators early, since some subsystems rely on them to initialize
++obj-$(CONFIG_REGULATOR)		+= regulator/
++
++# char/ comes before serial/ etc so that the VT console is the boot-time
++# default.
++obj-y				+= char/
++
++# gpu/ comes after char for AGP vs DRM startup
++obj-y				+= gpu/
++
++obj-$(CONFIG_CONNECTOR)		+= connector/
++
++# i810fb and intelfb depend on char/agp/
++obj-$(CONFIG_FB_I810)           += video/i810/
++obj-$(CONFIG_FB_INTEL)          += video/intelfb/
++
++obj-y				+= serial/
++obj-$(CONFIG_PARPORT)		+= parport/
++obj-y				+= base/ block/ misc/ mfd/
++obj-$(CONFIG_NUBUS)		+= nubus/
++obj-y				+= macintosh/
++obj-$(CONFIG_IDE)		+= ide/
++obj-$(CONFIG_SCSI)		+= scsi/
++obj-$(CONFIG_ATA)		+= ata/
++obj-$(CONFIG_MTD)		+= mtd/
++obj-$(CONFIG_SPI)		+= spi/
++obj-y				+= net/
++obj-$(CONFIG_ATM)		+= atm/
++obj-$(CONFIG_FUSION)		+= message/
++obj-$(CONFIG_FIREWIRE)		+= firewire/
++obj-y				+= ieee1394/
++obj-$(CONFIG_UIO)		+= uio/
++obj-y				+= cdrom/
++obj-y				+= auxdisplay/
++obj-$(CONFIG_PCCARD)		+= pcmcia/
++obj-$(CONFIG_DIO)		+= dio/
++obj-$(CONFIG_SBUS)		+= sbus/
++obj-$(CONFIG_ZORRO)		+= zorro/
++obj-$(CONFIG_MAC)		+= macintosh/
++obj-$(CONFIG_ATA_OVER_ETH)	+= block/aoe/
++obj-$(CONFIG_PARIDE) 		+= block/paride/
++obj-$(CONFIG_TC)		+= tc/
++obj-$(CONFIG_UWB)		+= uwb/
++obj-$(CONFIG_USB_OTG_UTILS)	+= usb/otg/
++obj-$(CONFIG_USB)		+= usb/
++obj-$(CONFIG_USB_MUSB_HDRC)	+= usb/musb/
++obj-$(CONFIG_PCI)		+= usb/
++obj-$(CONFIG_USB_GADGET)	+= usb/gadget/
++obj-$(CONFIG_SERIO)		+= input/serio/
++obj-$(CONFIG_GAMEPORT)		+= input/gameport/
++obj-$(CONFIG_INPUT)		+= input/
++obj-$(CONFIG_I2O)		+= message/
++obj-$(CONFIG_RTC_LIB)		+= rtc/
++obj-y				+= i2c/ media/
++obj-$(CONFIG_PPS)		+= pps/
++obj-$(CONFIG_W1)		+= w1/
++obj-$(CONFIG_POWER_SUPPLY)	+= power/
++obj-$(CONFIG_HWMON)		+= hwmon/
++obj-$(CONFIG_THERMAL)		+= thermal/
++obj-$(CONFIG_WATCHDOG)		+= watchdog/
++obj-$(CONFIG_PHONE)		+= telephony/
++obj-$(CONFIG_MD)		+= md/
++obj-$(CONFIG_BT)		+= bluetooth/
++obj-$(CONFIG_ACCESSIBILITY)	+= accessibility/
++obj-$(CONFIG_ISDN)		+= isdn/
++obj-$(CONFIG_EDAC)		+= edac/
++obj-$(CONFIG_MCA)		+= mca/
++obj-$(CONFIG_EISA)		+= eisa/
++obj-y				+= lguest/
++obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
++obj-$(CONFIG_CPU_IDLE)		+= cpuidle/
++obj-$(CONFIG_MMC)		+= mmc/
++obj-$(CONFIG_MEMSTICK)		+= memstick/
++obj-$(CONFIG_NEW_LEDS)		+= leds/
++obj-$(CONFIG_INFINIBAND)	+= infiniband/
++obj-$(CONFIG_SGI_SN)		+= sn/
++obj-y				+= firmware/
++obj-$(CONFIG_CRYPTO)		+= crypto/
++obj-$(CONFIG_SUPERH)		+= sh/
++obj-$(CONFIG_ARCH_SHMOBILE)	+= sh/
++obj-$(CONFIG_GENERIC_TIME)	+= clocksource/
++obj-$(CONFIG_DMA_ENGINE)	+= dma/
++obj-$(CONFIG_DCA)		+= dca/
++obj-$(CONFIG_HID)		+= hid/
++obj-$(CONFIG_PPC_PS3)		+= ps3/
++obj-$(CONFIG_OF)		+= of/
++obj-$(CONFIG_SSB)		+= ssb/
++obj-$(CONFIG_VHOST_NET)		+= vhost/
++obj-$(CONFIG_VLYNQ)		+= vlynq/
++obj-$(CONFIG_STAGING)		+= staging/
++obj-y				+= platform/
++obj-y				+= ieee802154/
+diff -rupN linux-2.6.35.11/drivers/net/e1000/e1000_main.c linux-2.6.35.11-ts7500/drivers/net/e1000/e1000_main.c
+--- linux-2.6.35.11/drivers/net/e1000/e1000_main.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/e1000/e1000_main.c	2011-03-14 11:18:24.000000000 -0400
+@@ -883,7 +883,12 @@ static int __devinit e1000_probe(struct
+ 			if (pci_resource_len(pdev, i) == 0)
+ 				continue;
+ 			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++            hw.io_base = (unsigned long)ioremap(pci_resource_start(pdev, i),
++			                pci_resource_len(pdev, i));
++#else            
+ 				hw->io_base = pci_resource_start(pdev, i);
++#endif            
+ 				break;
+ 			}
+ 		}
+diff -rupN linux-2.6.35.11/drivers/net/e1000/e1000_main.c.orig linux-2.6.35.11-ts7500/drivers/net/e1000/e1000_main.c.orig
+--- linux-2.6.35.11/drivers/net/e1000/e1000_main.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/e1000/e1000_main.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,4784 @@
++/*******************************************************************************
++
++  Intel PRO/1000 Linux driver
++  Copyright(c) 1999 - 2006 Intel Corporation.
++
++  This program is free software; you can redistribute it and/or modify it
++  under the terms and conditions of the GNU General Public License,
++  version 2, as published by the Free Software Foundation.
++
++  This program is distributed in the hope it will be useful, but WITHOUT
++  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++  more details.
++
++  You should have received a copy of the GNU General Public License along with
++  this program; if not, write to the Free Software Foundation, Inc.,
++  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
++
++  The full GNU General Public License is included in this distribution in
++  the file called "COPYING".
++
++  Contact Information:
++  Linux NICS <linux.nics@intel.com>
++  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
++  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
++
++*******************************************************************************/
++
++#include "e1000.h"
++#include <net/ip6_checksum.h>
++
++char e1000_driver_name[] = "e1000";
++static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
++#define DRV_VERSION "7.3.21-k8-NAPI"
++const char e1000_driver_version[] = DRV_VERSION;
++static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
++
++/* e1000_pci_tbl - PCI Device ID Table
++ *
++ * Last entry must be all 0s
++ *
++ * Macro expands to...
++ *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
++ */
++static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
++	INTEL_E1000_ETHERNET_DEVICE(0x1000),
++	INTEL_E1000_ETHERNET_DEVICE(0x1001),
++	INTEL_E1000_ETHERNET_DEVICE(0x1004),
++	INTEL_E1000_ETHERNET_DEVICE(0x1008),
++	INTEL_E1000_ETHERNET_DEVICE(0x1009),
++	INTEL_E1000_ETHERNET_DEVICE(0x100C),
++	INTEL_E1000_ETHERNET_DEVICE(0x100D),
++	INTEL_E1000_ETHERNET_DEVICE(0x100E),
++	INTEL_E1000_ETHERNET_DEVICE(0x100F),
++	INTEL_E1000_ETHERNET_DEVICE(0x1010),
++	INTEL_E1000_ETHERNET_DEVICE(0x1011),
++	INTEL_E1000_ETHERNET_DEVICE(0x1012),
++	INTEL_E1000_ETHERNET_DEVICE(0x1013),
++	INTEL_E1000_ETHERNET_DEVICE(0x1014),
++	INTEL_E1000_ETHERNET_DEVICE(0x1015),
++	INTEL_E1000_ETHERNET_DEVICE(0x1016),
++	INTEL_E1000_ETHERNET_DEVICE(0x1017),
++	INTEL_E1000_ETHERNET_DEVICE(0x1018),
++	INTEL_E1000_ETHERNET_DEVICE(0x1019),
++	INTEL_E1000_ETHERNET_DEVICE(0x101A),
++	INTEL_E1000_ETHERNET_DEVICE(0x101D),
++	INTEL_E1000_ETHERNET_DEVICE(0x101E),
++	INTEL_E1000_ETHERNET_DEVICE(0x1026),
++	INTEL_E1000_ETHERNET_DEVICE(0x1027),
++	INTEL_E1000_ETHERNET_DEVICE(0x1028),
++	INTEL_E1000_ETHERNET_DEVICE(0x1075),
++	INTEL_E1000_ETHERNET_DEVICE(0x1076),
++	INTEL_E1000_ETHERNET_DEVICE(0x1077),
++	INTEL_E1000_ETHERNET_DEVICE(0x1078),
++	INTEL_E1000_ETHERNET_DEVICE(0x1079),
++	INTEL_E1000_ETHERNET_DEVICE(0x107A),
++	INTEL_E1000_ETHERNET_DEVICE(0x107B),
++	INTEL_E1000_ETHERNET_DEVICE(0x107C),
++	INTEL_E1000_ETHERNET_DEVICE(0x108A),
++	INTEL_E1000_ETHERNET_DEVICE(0x1099),
++	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
++	/* required last entry */
++	{0,}
++};
++
++MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
++
++int e1000_up(struct e1000_adapter *adapter);
++void e1000_down(struct e1000_adapter *adapter);
++void e1000_reinit_locked(struct e1000_adapter *adapter);
++void e1000_reset(struct e1000_adapter *adapter);
++int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
++int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
++int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
++void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
++void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
++static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
++                             struct e1000_tx_ring *txdr);
++static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
++                             struct e1000_rx_ring *rxdr);
++static void e1000_free_tx_resources(struct e1000_adapter *adapter,
++                             struct e1000_tx_ring *tx_ring);
++static void e1000_free_rx_resources(struct e1000_adapter *adapter,
++                             struct e1000_rx_ring *rx_ring);
++void e1000_update_stats(struct e1000_adapter *adapter);
++
++static int e1000_init_module(void);
++static void e1000_exit_module(void);
++static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
++static void __devexit e1000_remove(struct pci_dev *pdev);
++static int e1000_alloc_queues(struct e1000_adapter *adapter);
++static int e1000_sw_init(struct e1000_adapter *adapter);
++static int e1000_open(struct net_device *netdev);
++static int e1000_close(struct net_device *netdev);
++static void e1000_configure_tx(struct e1000_adapter *adapter);
++static void e1000_configure_rx(struct e1000_adapter *adapter);
++static void e1000_setup_rctl(struct e1000_adapter *adapter);
++static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
++static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
++static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
++                                struct e1000_tx_ring *tx_ring);
++static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
++                                struct e1000_rx_ring *rx_ring);
++static void e1000_set_rx_mode(struct net_device *netdev);
++static void e1000_update_phy_info(unsigned long data);
++static void e1000_watchdog(unsigned long data);
++static void e1000_82547_tx_fifo_stall(unsigned long data);
++static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
++				    struct net_device *netdev);
++static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
++static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
++static int e1000_set_mac(struct net_device *netdev, void *p);
++static irqreturn_t e1000_intr(int irq, void *data);
++static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
++			       struct e1000_tx_ring *tx_ring);
++static int e1000_clean(struct napi_struct *napi, int budget);
++static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
++			       struct e1000_rx_ring *rx_ring,
++			       int *work_done, int work_to_do);
++static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
++				     struct e1000_rx_ring *rx_ring,
++				     int *work_done, int work_to_do);
++static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
++				   struct e1000_rx_ring *rx_ring,
++				   int cleaned_count);
++static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
++					 struct e1000_rx_ring *rx_ring,
++					 int cleaned_count);
++static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
++static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
++			   int cmd);
++static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
++static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
++static void e1000_tx_timeout(struct net_device *dev);
++static void e1000_reset_task(struct work_struct *work);
++static void e1000_smartspeed(struct e1000_adapter *adapter);
++static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
++                                       struct sk_buff *skb);
++
++static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
++static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
++static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
++static void e1000_restore_vlan(struct e1000_adapter *adapter);
++
++#ifdef CONFIG_PM
++static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
++static int e1000_resume(struct pci_dev *pdev);
++#endif
++static void e1000_shutdown(struct pci_dev *pdev);
++
++#ifdef CONFIG_NET_POLL_CONTROLLER
++/* for netdump / net console */
++static void e1000_netpoll (struct net_device *netdev);
++#endif
++
++#define COPYBREAK_DEFAULT 256
++static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
++module_param(copybreak, uint, 0644);
++MODULE_PARM_DESC(copybreak,
++	"Maximum size of packet that is copied to a new buffer on receive");
++
++static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
++                     pci_channel_state_t state);
++static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
++static void e1000_io_resume(struct pci_dev *pdev);
++
++static struct pci_error_handlers e1000_err_handler = {
++	.error_detected = e1000_io_error_detected,
++	.slot_reset = e1000_io_slot_reset,
++	.resume = e1000_io_resume,
++};
++
++static struct pci_driver e1000_driver = {
++	.name     = e1000_driver_name,
++	.id_table = e1000_pci_tbl,
++	.probe    = e1000_probe,
++	.remove   = __devexit_p(e1000_remove),
++#ifdef CONFIG_PM
++	/* Power Managment Hooks */
++	.suspend  = e1000_suspend,
++	.resume   = e1000_resume,
++#endif
++	.shutdown = e1000_shutdown,
++	.err_handler = &e1000_err_handler
++};
++
++MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
++MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_VERSION);
++
++static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
++module_param(debug, int, 0);
++MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
++
++/**
++ * e1000_get_hw_dev - return device
++ * used by hardware layer to print debugging information
++ *
++ **/
++struct net_device *e1000_get_hw_dev(struct e1000_hw *hw)
++{
++	struct e1000_adapter *adapter = hw->back;
++	return adapter->netdev;
++}
++
++/**
++ * e1000_init_module - Driver Registration Routine
++ *
++ * e1000_init_module is the first routine called when the driver is
++ * loaded. All it does is register with the PCI subsystem.
++ **/
++
++static int __init e1000_init_module(void)
++{
++	int ret;
++	pr_info("%s - version %s\n", e1000_driver_string, e1000_driver_version);
++
++	pr_info("%s\n", e1000_copyright);
++
++	ret = pci_register_driver(&e1000_driver);
++	if (copybreak != COPYBREAK_DEFAULT) {
++		if (copybreak == 0)
++			pr_info("copybreak disabled\n");
++		else
++			pr_info("copybreak enabled for "
++				   "packets <= %u bytes\n", copybreak);
++	}
++	return ret;
++}
++
++module_init(e1000_init_module);
++
++/**
++ * e1000_exit_module - Driver Exit Cleanup Routine
++ *
++ * e1000_exit_module is called just before the driver is removed
++ * from memory.
++ **/
++
++static void __exit e1000_exit_module(void)
++{
++	pci_unregister_driver(&e1000_driver);
++}
++
++module_exit(e1000_exit_module);
++
++static int e1000_request_irq(struct e1000_adapter *adapter)
++{
++	struct net_device *netdev = adapter->netdev;
++	irq_handler_t handler = e1000_intr;
++	int irq_flags = IRQF_SHARED;
++	int err;
++
++	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
++	                  netdev);
++	if (err) {
++		e_err("Unable to allocate interrupt Error: %d\n", err);
++	}
++
++	return err;
++}
++
++static void e1000_free_irq(struct e1000_adapter *adapter)
++{
++	struct net_device *netdev = adapter->netdev;
++
++	free_irq(adapter->pdev->irq, netdev);
++}
++
++/**
++ * e1000_irq_disable - Mask off interrupt generation on the NIC
++ * @adapter: board private structure
++ **/
++
++static void e1000_irq_disable(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++
++	ew32(IMC, ~0);
++	E1000_WRITE_FLUSH();
++	synchronize_irq(adapter->pdev->irq);
++}
++
++/**
++ * e1000_irq_enable - Enable default interrupt generation settings
++ * @adapter: board private structure
++ **/
++
++static void e1000_irq_enable(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++
++	ew32(IMS, IMS_ENABLE_MASK);
++	E1000_WRITE_FLUSH();
++}
++
++static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct net_device *netdev = adapter->netdev;
++	u16 vid = hw->mng_cookie.vlan_id;
++	u16 old_vid = adapter->mng_vlan_id;
++	if (adapter->vlgrp) {
++		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
++			if (hw->mng_cookie.status &
++				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
++				e1000_vlan_rx_add_vid(netdev, vid);
++				adapter->mng_vlan_id = vid;
++			} else
++				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
++
++			if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
++					(vid != old_vid) &&
++			    !vlan_group_get_device(adapter->vlgrp, old_vid))
++				e1000_vlan_rx_kill_vid(netdev, old_vid);
++		} else
++			adapter->mng_vlan_id = vid;
++	}
++}
++
++static void e1000_init_manageability(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++
++	if (adapter->en_mng_pt) {
++		u32 manc = er32(MANC);
++
++		/* disable hardware interception of ARP */
++		manc &= ~(E1000_MANC_ARP_EN);
++
++		ew32(MANC, manc);
++	}
++}
++
++static void e1000_release_manageability(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++
++	if (adapter->en_mng_pt) {
++		u32 manc = er32(MANC);
++
++		/* re-enable hardware interception of ARP */
++		manc |= E1000_MANC_ARP_EN;
++
++		ew32(MANC, manc);
++	}
++}
++
++/**
++ * e1000_configure - configure the hardware for RX and TX
++ * @adapter = private board structure
++ **/
++static void e1000_configure(struct e1000_adapter *adapter)
++{
++	struct net_device *netdev = adapter->netdev;
++	int i;
++
++	e1000_set_rx_mode(netdev);
++
++	e1000_restore_vlan(adapter);
++	e1000_init_manageability(adapter);
++
++	e1000_configure_tx(adapter);
++	e1000_setup_rctl(adapter);
++	e1000_configure_rx(adapter);
++	/* call E1000_DESC_UNUSED which always leaves
++	 * at least 1 descriptor unused to make sure
++	 * next_to_use != next_to_clean */
++	for (i = 0; i < adapter->num_rx_queues; i++) {
++		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
++		adapter->alloc_rx_buf(adapter, ring,
++		                      E1000_DESC_UNUSED(ring));
++	}
++}
++
++int e1000_up(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++
++	/* hardware has been reset, we need to reload some things */
++	e1000_configure(adapter);
++
++	clear_bit(__E1000_DOWN, &adapter->flags);
++
++	napi_enable(&adapter->napi);
++
++	e1000_irq_enable(adapter);
++
++	netif_wake_queue(adapter->netdev);
++
++	/* fire a link change interrupt to start the watchdog */
++	ew32(ICS, E1000_ICS_LSC);
++	return 0;
++}
++
++/**
++ * e1000_power_up_phy - restore link in case the phy was powered down
++ * @adapter: address of board private structure
++ *
++ * The phy may be powered down to save power and turn off link when the
++ * driver is unloaded and wake on lan is not enabled (among others)
++ * *** this routine MUST be followed by a call to e1000_reset ***
++ *
++ **/
++
++void e1000_power_up_phy(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	u16 mii_reg = 0;
++
++	/* Just clear the power down bit to wake the phy back up */
++	if (hw->media_type == e1000_media_type_copper) {
++		/* according to the manual, the phy will retain its
++		 * settings across a power-down/up cycle */
++		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
++		mii_reg &= ~MII_CR_POWER_DOWN;
++		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
++	}
++}
++
++static void e1000_power_down_phy(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++
++	/* Power down the PHY so no link is implied when interface is down *
++	 * The PHY cannot be powered down if any of the following is true *
++	 * (a) WoL is enabled
++	 * (b) AMT is active
++	 * (c) SoL/IDER session is active */
++	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
++	   hw->media_type == e1000_media_type_copper) {
++		u16 mii_reg = 0;
++
++		switch (hw->mac_type) {
++		case e1000_82540:
++		case e1000_82545:
++		case e1000_82545_rev_3:
++		case e1000_82546:
++		case e1000_82546_rev_3:
++		case e1000_82541:
++		case e1000_82541_rev_2:
++		case e1000_82547:
++		case e1000_82547_rev_2:
++			if (er32(MANC) & E1000_MANC_SMBUS_EN)
++				goto out;
++			break;
++		default:
++			goto out;
++		}
++		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
++		mii_reg |= MII_CR_POWER_DOWN;
++		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
++		mdelay(1);
++	}
++out:
++	return;
++}
++
++void e1000_down(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct net_device *netdev = adapter->netdev;
++	u32 rctl, tctl;
++
++
++	/* disable receives in the hardware */
++	rctl = er32(RCTL);
++	ew32(RCTL, rctl & ~E1000_RCTL_EN);
++	/* flush and sleep below */
++
++	netif_tx_disable(netdev);
++
++	/* disable transmits in the hardware */
++	tctl = er32(TCTL);
++	tctl &= ~E1000_TCTL_EN;
++	ew32(TCTL, tctl);
++	/* flush both disables and wait for them to finish */
++	E1000_WRITE_FLUSH();
++	msleep(10);
++
++	napi_disable(&adapter->napi);
++
++	e1000_irq_disable(adapter);
++
++	/*
++	 * Setting DOWN must be after irq_disable to prevent
++	 * a screaming interrupt.  Setting DOWN also prevents
++	 * timers and tasks from rescheduling.
++	 */
++	set_bit(__E1000_DOWN, &adapter->flags);
++
++	del_timer_sync(&adapter->tx_fifo_stall_timer);
++	del_timer_sync(&adapter->watchdog_timer);
++	del_timer_sync(&adapter->phy_info_timer);
++
++	adapter->link_speed = 0;
++	adapter->link_duplex = 0;
++	netif_carrier_off(netdev);
++
++	e1000_reset(adapter);
++	e1000_clean_all_tx_rings(adapter);
++	e1000_clean_all_rx_rings(adapter);
++}
++
++void e1000_reinit_locked(struct e1000_adapter *adapter)
++{
++	WARN_ON(in_interrupt());
++	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
++		msleep(1);
++	e1000_down(adapter);
++	e1000_up(adapter);
++	clear_bit(__E1000_RESETTING, &adapter->flags);
++}
++
++void e1000_reset(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
++	bool legacy_pba_adjust = false;
++	u16 hwm;
++
++	/* Repartition Pba for greater than 9k mtu
++	 * To take effect CTRL.RST is required.
++	 */
++
++	switch (hw->mac_type) {
++	case e1000_82542_rev2_0:
++	case e1000_82542_rev2_1:
++	case e1000_82543:
++	case e1000_82544:
++	case e1000_82540:
++	case e1000_82541:
++	case e1000_82541_rev_2:
++		legacy_pba_adjust = true;
++		pba = E1000_PBA_48K;
++		break;
++	case e1000_82545:
++	case e1000_82545_rev_3:
++	case e1000_82546:
++	case e1000_82546_rev_3:
++		pba = E1000_PBA_48K;
++		break;
++	case e1000_82547:
++	case e1000_82547_rev_2:
++		legacy_pba_adjust = true;
++		pba = E1000_PBA_30K;
++		break;
++	case e1000_undefined:
++	case e1000_num_macs:
++		break;
++	}
++
++	if (legacy_pba_adjust) {
++		if (hw->max_frame_size > E1000_RXBUFFER_8192)
++			pba -= 8; /* allocate more FIFO for Tx */
++
++		if (hw->mac_type == e1000_82547) {
++			adapter->tx_fifo_head = 0;
++			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
++			adapter->tx_fifo_size =
++				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
++			atomic_set(&adapter->tx_fifo_stall, 0);
++		}
++	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
++		/* adjust PBA for jumbo frames */
++		ew32(PBA, pba);
++
++		/* To maintain wire speed transmits, the Tx FIFO should be
++		 * large enough to accommodate two full transmit packets,
++		 * rounded up to the next 1KB and expressed in KB.  Likewise,
++		 * the Rx FIFO should be large enough to accommodate at least
++		 * one full receive packet and is similarly rounded up and
++		 * expressed in KB. */
++		pba = er32(PBA);
++		/* upper 16 bits has Tx packet buffer allocation size in KB */
++		tx_space = pba >> 16;
++		/* lower 16 bits has Rx packet buffer allocation size in KB */
++		pba &= 0xffff;
++		/*
++		 * the tx fifo also stores 16 bytes of information about the tx
++		 * but don't include ethernet FCS because hardware appends it
++		 */
++		min_tx_space = (hw->max_frame_size +
++		                sizeof(struct e1000_tx_desc) -
++		                ETH_FCS_LEN) * 2;
++		min_tx_space = ALIGN(min_tx_space, 1024);
++		min_tx_space >>= 10;
++		/* software strips receive CRC, so leave room for it */
++		min_rx_space = hw->max_frame_size;
++		min_rx_space = ALIGN(min_rx_space, 1024);
++		min_rx_space >>= 10;
++
++		/* If current Tx allocation is less than the min Tx FIFO size,
++		 * and the min Tx FIFO size is less than the current Rx FIFO
++		 * allocation, take space away from current Rx allocation */
++		if (tx_space < min_tx_space &&
++		    ((min_tx_space - tx_space) < pba)) {
++			pba = pba - (min_tx_space - tx_space);
++
++			/* PCI/PCIx hardware has PBA alignment constraints */
++			switch (hw->mac_type) {
++			case e1000_82545 ... e1000_82546_rev_3:
++				pba &= ~(E1000_PBA_8K - 1);
++				break;
++			default:
++				break;
++			}
++
++			/* if short on rx space, rx wins and must trump tx
++			 * adjustment or use Early Receive if available */
++			if (pba < min_rx_space)
++				pba = min_rx_space;
++		}
++	}
++
++	ew32(PBA, pba);
++
++	/*
++	 * flow control settings:
++	 * The high water mark must be low enough to fit one full frame
++	 * (or the size used for early receive) above it in the Rx FIFO.
++	 * Set it to the lower of:
++	 * - 90% of the Rx FIFO size, and
++	 * - the full Rx FIFO size minus the early receive size (for parts
++	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
++	 * - the full Rx FIFO size minus one full frame
++	 */
++	hwm = min(((pba << 10) * 9 / 10),
++		  ((pba << 10) - hw->max_frame_size));
++
++	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
++	hw->fc_low_water = hw->fc_high_water - 8;
++	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
++	hw->fc_send_xon = 1;
++	hw->fc = hw->original_fc;
++
++	/* Allow time for pending master requests to run */
++	e1000_reset_hw(hw);
++	if (hw->mac_type >= e1000_82544)
++		ew32(WUC, 0);
++
++	if (e1000_init_hw(hw))
++		e_err("Hardware Error\n");
++	e1000_update_mng_vlan(adapter);
++
++	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
++	if (hw->mac_type >= e1000_82544 &&
++	    hw->autoneg == 1 &&
++	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
++		u32 ctrl = er32(CTRL);
++		/* clear phy power management bit if we are in gig only mode,
++		 * which if enabled will attempt negotiation to 100Mb, which
++		 * can cause a loss of link at power off or driver unload */
++		ctrl &= ~E1000_CTRL_SWDPIN3;
++		ew32(CTRL, ctrl);
++	}
++
++	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
++	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
++
++	e1000_reset_adaptive(hw);
++	e1000_phy_get_info(hw, &adapter->phy_info);
++
++	e1000_release_manageability(adapter);
++}
++
++/**
++ *  Dump the eeprom for users having checksum issues
++ **/
++static void e1000_dump_eeprom(struct e1000_adapter *adapter)
++{
++	struct net_device *netdev = adapter->netdev;
++	struct ethtool_eeprom eeprom;
++	const struct ethtool_ops *ops = netdev->ethtool_ops;
++	u8 *data;
++	int i;
++	u16 csum_old, csum_new = 0;
++
++	eeprom.len = ops->get_eeprom_len(netdev);
++	eeprom.offset = 0;
++
++	data = kmalloc(eeprom.len, GFP_KERNEL);
++	if (!data) {
++		pr_err("Unable to allocate memory to dump EEPROM data\n");
++		return;
++	}
++
++	ops->get_eeprom(netdev, &eeprom, data);
++
++	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
++		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
++	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
++		csum_new += data[i] + (data[i + 1] << 8);
++	csum_new = EEPROM_SUM - csum_new;
++
++	pr_err("/*********************/\n");
++	pr_err("Current EEPROM Checksum : 0x%04x\n", csum_old);
++	pr_err("Calculated              : 0x%04x\n", csum_new);
++
++	pr_err("Offset    Values\n");
++	pr_err("========  ======\n");
++	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
++
++	pr_err("Include this output when contacting your support provider.\n");
++	pr_err("This is not a software error! Something bad happened to\n");
++	pr_err("your hardware or EEPROM image. Ignoring this problem could\n");
++	pr_err("result in further problems, possibly loss of data,\n");
++	pr_err("corruption or system hangs!\n");
++	pr_err("The MAC Address will be reset to 00:00:00:00:00:00,\n");
++	pr_err("which is invalid and requires you to set the proper MAC\n");
++	pr_err("address manually before continuing to enable this network\n");
++	pr_err("device. Please inspect the EEPROM dump and report the\n");
++	pr_err("issue to your hardware vendor or Intel Customer Support.\n");
++	pr_err("/*********************/\n");
++
++	kfree(data);
++}
++
++/**
++ * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
++ * @pdev: PCI device information struct
++ *
++ * Return true if an adapter needs ioport resources
++ **/
++static int e1000_is_need_ioport(struct pci_dev *pdev)
++{
++	switch (pdev->device) {
++	case E1000_DEV_ID_82540EM:
++	case E1000_DEV_ID_82540EM_LOM:
++	case E1000_DEV_ID_82540EP:
++	case E1000_DEV_ID_82540EP_LOM:
++	case E1000_DEV_ID_82540EP_LP:
++	case E1000_DEV_ID_82541EI:
++	case E1000_DEV_ID_82541EI_MOBILE:
++	case E1000_DEV_ID_82541ER:
++	case E1000_DEV_ID_82541ER_LOM:
++	case E1000_DEV_ID_82541GI:
++	case E1000_DEV_ID_82541GI_LF:
++	case E1000_DEV_ID_82541GI_MOBILE:
++	case E1000_DEV_ID_82544EI_COPPER:
++	case E1000_DEV_ID_82544EI_FIBER:
++	case E1000_DEV_ID_82544GC_COPPER:
++	case E1000_DEV_ID_82544GC_LOM:
++	case E1000_DEV_ID_82545EM_COPPER:
++	case E1000_DEV_ID_82545EM_FIBER:
++	case E1000_DEV_ID_82546EB_COPPER:
++	case E1000_DEV_ID_82546EB_FIBER:
++	case E1000_DEV_ID_82546EB_QUAD_COPPER:
++		return true;
++	default:
++		return false;
++	}
++}
++
++static const struct net_device_ops e1000_netdev_ops = {
++	.ndo_open		= e1000_open,
++	.ndo_stop		= e1000_close,
++	.ndo_start_xmit		= e1000_xmit_frame,
++	.ndo_get_stats		= e1000_get_stats,
++	.ndo_set_rx_mode	= e1000_set_rx_mode,
++	.ndo_set_mac_address	= e1000_set_mac,
++	.ndo_tx_timeout 	= e1000_tx_timeout,
++	.ndo_change_mtu		= e1000_change_mtu,
++	.ndo_do_ioctl		= e1000_ioctl,
++	.ndo_validate_addr	= eth_validate_addr,
++
++	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
++	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
++	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	.ndo_poll_controller	= e1000_netpoll,
++#endif
++};
++
++/**
++ * e1000_probe - Device Initialization Routine
++ * @pdev: PCI device information struct
++ * @ent: entry in e1000_pci_tbl
++ *
++ * Returns 0 on success, negative on failure
++ *
++ * e1000_probe initializes an adapter identified by a pci_dev structure.
++ * The OS initialization, configuring of the adapter private structure,
++ * and a hardware reset occur.
++ **/
++static int __devinit e1000_probe(struct pci_dev *pdev,
++				 const struct pci_device_id *ent)
++{
++	struct net_device *netdev;
++	struct e1000_adapter *adapter;
++	struct e1000_hw *hw;
++
++	static int cards_found = 0;
++	static int global_quad_port_a = 0; /* global ksp3 port a indication */
++	int i, err, pci_using_dac;
++	u16 eeprom_data = 0;
++	u16 eeprom_apme_mask = E1000_EEPROM_APME;
++	int bars, need_ioport;
++
++	/* do not allocate ioport bars when not needed */
++	need_ioport = e1000_is_need_ioport(pdev);
++	if (need_ioport) {
++		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
++		err = pci_enable_device(pdev);
++	} else {
++		bars = pci_select_bars(pdev, IORESOURCE_MEM);
++		err = pci_enable_device_mem(pdev);
++	}
++	if (err)
++		return err;
++
++	if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
++	    !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
++		pci_using_dac = 1;
++	} else {
++		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
++		if (err) {
++			err = dma_set_coherent_mask(&pdev->dev,
++						    DMA_BIT_MASK(32));
++			if (err) {
++				pr_err("No usable DMA config, aborting\n");
++				goto err_dma;
++			}
++		}
++		pci_using_dac = 0;
++	}
++
++	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
++	if (err)
++		goto err_pci_reg;
++
++	pci_set_master(pdev);
++	err = pci_save_state(pdev);
++	if (err)
++		goto err_alloc_etherdev;
++
++	err = -ENOMEM;
++	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
++	if (!netdev)
++		goto err_alloc_etherdev;
++
++	SET_NETDEV_DEV(netdev, &pdev->dev);
++
++	pci_set_drvdata(pdev, netdev);
++	adapter = netdev_priv(netdev);
++	adapter->netdev = netdev;
++	adapter->pdev = pdev;
++	adapter->msg_enable = (1 << debug) - 1;
++	adapter->bars = bars;
++	adapter->need_ioport = need_ioport;
++
++	hw = &adapter->hw;
++	hw->back = adapter;
++
++	err = -EIO;
++	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
++	if (!hw->hw_addr)
++		goto err_ioremap;
++
++	if (adapter->need_ioport) {
++		for (i = BAR_1; i <= BAR_5; i++) {
++			if (pci_resource_len(pdev, i) == 0)
++				continue;
++			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
++				hw->io_base = pci_resource_start(pdev, i);
++				break;
++			}
++		}
++	}
++
++	netdev->netdev_ops = &e1000_netdev_ops;
++	e1000_set_ethtool_ops(netdev);
++	netdev->watchdog_timeo = 5 * HZ;
++	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
++
++	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
++
++	adapter->bd_number = cards_found;
++
++	/* setup the private structure */
++
++	err = e1000_sw_init(adapter);
++	if (err)
++		goto err_sw_init;
++
++	err = -EIO;
++
++	if (hw->mac_type >= e1000_82543) {
++		netdev->features = NETIF_F_SG |
++				   NETIF_F_HW_CSUM |
++				   NETIF_F_HW_VLAN_TX |
++				   NETIF_F_HW_VLAN_RX |
++				   NETIF_F_HW_VLAN_FILTER;
++	}
++
++	if ((hw->mac_type >= e1000_82544) &&
++	   (hw->mac_type != e1000_82547))
++		netdev->features |= NETIF_F_TSO;
++
++	if (pci_using_dac)
++		netdev->features |= NETIF_F_HIGHDMA;
++
++	netdev->vlan_features |= NETIF_F_TSO;
++	netdev->vlan_features |= NETIF_F_HW_CSUM;
++	netdev->vlan_features |= NETIF_F_SG;
++
++	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
++
++	/* initialize eeprom parameters */
++	if (e1000_init_eeprom_params(hw)) {
++		e_err("EEPROM initialization failed\n");
++		goto err_eeprom;
++	}
++
++	/* before reading the EEPROM, reset the controller to
++	 * put the device in a known good starting state */
++
++	e1000_reset_hw(hw);
++
++	/* make sure the EEPROM is good */
++	if (e1000_validate_eeprom_checksum(hw) < 0) {
++		e_err("The EEPROM Checksum Is Not Valid\n");
++		e1000_dump_eeprom(adapter);
++		/*
++		 * set MAC address to all zeroes to invalidate and temporary
++		 * disable this device for the user. This blocks regular
++		 * traffic while still permitting ethtool ioctls from reaching
++		 * the hardware as well as allowing the user to run the
++		 * interface after manually setting a hw addr using
++		 * `ip set address`
++		 */
++		memset(hw->mac_addr, 0, netdev->addr_len);
++	} else {
++		/* copy the MAC address out of the EEPROM */
++		if (e1000_read_mac_addr(hw))
++			e_err("EEPROM Read Error\n");
++	}
++	/* don't block initalization here due to bad MAC address */
++	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
++	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
++
++	if (!is_valid_ether_addr(netdev->perm_addr))
++		e_err("Invalid MAC Address\n");
++
++	e1000_get_bus_info(hw);
++
++	init_timer(&adapter->tx_fifo_stall_timer);
++	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
++	adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
++
++	init_timer(&adapter->watchdog_timer);
++	adapter->watchdog_timer.function = &e1000_watchdog;
++	adapter->watchdog_timer.data = (unsigned long) adapter;
++
++	init_timer(&adapter->phy_info_timer);
++	adapter->phy_info_timer.function = &e1000_update_phy_info;
++	adapter->phy_info_timer.data = (unsigned long)adapter;
++
++	INIT_WORK(&adapter->reset_task, e1000_reset_task);
++
++	e1000_check_options(adapter);
++
++	/* Initial Wake on LAN setting
++	 * If APM wake is enabled in the EEPROM,
++	 * enable the ACPI Magic Packet filter
++	 */
++
++	switch (hw->mac_type) {
++	case e1000_82542_rev2_0:
++	case e1000_82542_rev2_1:
++	case e1000_82543:
++		break;
++	case e1000_82544:
++		e1000_read_eeprom(hw,
++			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
++		eeprom_apme_mask = E1000_EEPROM_82544_APM;
++		break;
++	case e1000_82546:
++	case e1000_82546_rev_3:
++		if (er32(STATUS) & E1000_STATUS_FUNC_1){
++			e1000_read_eeprom(hw,
++				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
++			break;
++		}
++		/* Fall Through */
++	default:
++		e1000_read_eeprom(hw,
++			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
++		break;
++	}
++	if (eeprom_data & eeprom_apme_mask)
++		adapter->eeprom_wol |= E1000_WUFC_MAG;
++
++	/* now that we have the eeprom settings, apply the special cases
++	 * where the eeprom may be wrong or the board simply won't support
++	 * wake on lan on a particular port */
++	switch (pdev->device) {
++	case E1000_DEV_ID_82546GB_PCIE:
++		adapter->eeprom_wol = 0;
++		break;
++	case E1000_DEV_ID_82546EB_FIBER:
++	case E1000_DEV_ID_82546GB_FIBER:
++		/* Wake events only supported on port A for dual fiber
++		 * regardless of eeprom setting */
++		if (er32(STATUS) & E1000_STATUS_FUNC_1)
++			adapter->eeprom_wol = 0;
++		break;
++	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
++		/* if quad port adapter, disable WoL on all but port A */
++		if (global_quad_port_a != 0)
++			adapter->eeprom_wol = 0;
++		else
++			adapter->quad_port_a = 1;
++		/* Reset for multiple quad port adapters */
++		if (++global_quad_port_a == 4)
++			global_quad_port_a = 0;
++		break;
++	}
++
++	/* initialize the wol settings based on the eeprom settings */
++	adapter->wol = adapter->eeprom_wol;
++	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
++
++	/* reset the hardware with the new settings */
++	e1000_reset(adapter);
++
++	strcpy(netdev->name, "eth%d");
++	err = register_netdev(netdev);
++	if (err)
++		goto err_register;
++
++	/* print bus type/speed/width info */
++	e_info("(PCI%s:%dMHz:%d-bit) %pM\n",
++	       ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
++	       ((hw->bus_speed == e1000_bus_speed_133) ? 133 :
++		(hw->bus_speed == e1000_bus_speed_120) ? 120 :
++		(hw->bus_speed == e1000_bus_speed_100) ? 100 :
++		(hw->bus_speed == e1000_bus_speed_66) ? 66 : 33),
++	       ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
++	       netdev->dev_addr);
++
++	/* carrier off reporting is important to ethtool even BEFORE open */
++	netif_carrier_off(netdev);
++
++	e_info("Intel(R) PRO/1000 Network Connection\n");
++
++	cards_found++;
++	return 0;
++
++err_register:
++err_eeprom:
++	e1000_phy_hw_reset(hw);
++
++	if (hw->flash_address)
++		iounmap(hw->flash_address);
++	kfree(adapter->tx_ring);
++	kfree(adapter->rx_ring);
++err_sw_init:
++	iounmap(hw->hw_addr);
++err_ioremap:
++	free_netdev(netdev);
++err_alloc_etherdev:
++	pci_release_selected_regions(pdev, bars);
++err_pci_reg:
++err_dma:
++	pci_disable_device(pdev);
++	return err;
++}
++
++/**
++ * e1000_remove - Device Removal Routine
++ * @pdev: PCI device information struct
++ *
++ * e1000_remove is called by the PCI subsystem to alert the driver
++ * that it should release a PCI device.  The could be caused by a
++ * Hot-Plug event, or because the driver is going to be removed from
++ * memory.
++ **/
++
++static void __devexit e1000_remove(struct pci_dev *pdev)
++{
++	struct net_device *netdev = pci_get_drvdata(pdev);
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++
++	set_bit(__E1000_DOWN, &adapter->flags);
++	del_timer_sync(&adapter->tx_fifo_stall_timer);
++	del_timer_sync(&adapter->watchdog_timer);
++	del_timer_sync(&adapter->phy_info_timer);
++
++	cancel_work_sync(&adapter->reset_task);
++
++	e1000_release_manageability(adapter);
++
++	unregister_netdev(netdev);
++
++	e1000_phy_hw_reset(hw);
++
++	kfree(adapter->tx_ring);
++	kfree(adapter->rx_ring);
++
++	iounmap(hw->hw_addr);
++	if (hw->flash_address)
++		iounmap(hw->flash_address);
++	pci_release_selected_regions(pdev, adapter->bars);
++
++	free_netdev(netdev);
++
++	pci_disable_device(pdev);
++}
++
++/**
++ * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
++ * @adapter: board private structure to initialize
++ *
++ * e1000_sw_init initializes the Adapter private data structure.
++ * Fields are initialized based on PCI device information and
++ * OS network device settings (MTU size).
++ **/
++
++static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct net_device *netdev = adapter->netdev;
++	struct pci_dev *pdev = adapter->pdev;
++
++	/* PCI config space info */
++
++	hw->vendor_id = pdev->vendor;
++	hw->device_id = pdev->device;
++	hw->subsystem_vendor_id = pdev->subsystem_vendor;
++	hw->subsystem_id = pdev->subsystem_device;
++	hw->revision_id = pdev->revision;
++
++	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
++
++	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
++	hw->max_frame_size = netdev->mtu +
++			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
++	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
++
++	/* identify the MAC */
++
++	if (e1000_set_mac_type(hw)) {
++		e_err("Unknown MAC Type\n");
++		return -EIO;
++	}
++
++	switch (hw->mac_type) {
++	default:
++		break;
++	case e1000_82541:
++	case e1000_82547:
++	case e1000_82541_rev_2:
++	case e1000_82547_rev_2:
++		hw->phy_init_script = 1;
++		break;
++	}
++
++	e1000_set_media_type(hw);
++
++	hw->wait_autoneg_complete = false;
++	hw->tbi_compatibility_en = true;
++	hw->adaptive_ifs = true;
++
++	/* Copper options */
++
++	if (hw->media_type == e1000_media_type_copper) {
++		hw->mdix = AUTO_ALL_MODES;
++		hw->disable_polarity_correction = false;
++		hw->master_slave = E1000_MASTER_SLAVE;
++	}
++
++	adapter->num_tx_queues = 1;
++	adapter->num_rx_queues = 1;
++
++	if (e1000_alloc_queues(adapter)) {
++		e_err("Unable to allocate memory for queues\n");
++		return -ENOMEM;
++	}
++
++	/* Explicitly disable IRQ since the NIC can be in any state. */
++	e1000_irq_disable(adapter);
++
++	spin_lock_init(&adapter->stats_lock);
++
++	set_bit(__E1000_DOWN, &adapter->flags);
++
++	return 0;
++}
++
++/**
++ * e1000_alloc_queues - Allocate memory for all rings
++ * @adapter: board private structure to initialize
++ *
++ * We allocate one ring per queue at run-time since we don't know the
++ * number of queues at compile-time.
++ **/
++
++static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
++{
++	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
++	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
++	if (!adapter->tx_ring)
++		return -ENOMEM;
++
++	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
++	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
++	if (!adapter->rx_ring) {
++		kfree(adapter->tx_ring);
++		return -ENOMEM;
++	}
++
++	return E1000_SUCCESS;
++}
++
++/**
++ * e1000_open - Called when a network interface is made active
++ * @netdev: network interface device structure
++ *
++ * Returns 0 on success, negative value on failure
++ *
++ * The open entry point is called when a network interface is made
++ * active by the system (IFF_UP).  At this point all resources needed
++ * for transmit and receive operations are allocated, the interrupt
++ * handler is registered with the OS, the watchdog timer is started,
++ * and the stack is notified that the interface is ready.
++ **/
++
++static int e1000_open(struct net_device *netdev)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	int err;
++
++	/* disallow open during test */
++	if (test_bit(__E1000_TESTING, &adapter->flags))
++		return -EBUSY;
++
++	netif_carrier_off(netdev);
++
++	/* allocate transmit descriptors */
++	err = e1000_setup_all_tx_resources(adapter);
++	if (err)
++		goto err_setup_tx;
++
++	/* allocate receive descriptors */
++	err = e1000_setup_all_rx_resources(adapter);
++	if (err)
++		goto err_setup_rx;
++
++	e1000_power_up_phy(adapter);
++
++	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
++	if ((hw->mng_cookie.status &
++			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
++		e1000_update_mng_vlan(adapter);
++	}
++
++	/* before we allocate an interrupt, we must be ready to handle it.
++	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
++	 * as soon as we call pci_request_irq, so we have to setup our
++	 * clean_rx handler before we do so.  */
++	e1000_configure(adapter);
++
++	err = e1000_request_irq(adapter);
++	if (err)
++		goto err_req_irq;
++
++	/* From here on the code is the same as e1000_up() */
++	clear_bit(__E1000_DOWN, &adapter->flags);
++
++	napi_enable(&adapter->napi);
++
++	e1000_irq_enable(adapter);
++
++	netif_start_queue(netdev);
++
++	/* fire a link status change interrupt to start the watchdog */
++	ew32(ICS, E1000_ICS_LSC);
++
++	return E1000_SUCCESS;
++
++err_req_irq:
++	e1000_power_down_phy(adapter);
++	e1000_free_all_rx_resources(adapter);
++err_setup_rx:
++	e1000_free_all_tx_resources(adapter);
++err_setup_tx:
++	e1000_reset(adapter);
++
++	return err;
++}
++
++/**
++ * e1000_close - Disables a network interface
++ * @netdev: network interface device structure
++ *
++ * Returns 0, this is not allowed to fail
++ *
++ * The close entry point is called when an interface is de-activated
++ * by the OS.  The hardware is still under the drivers control, but
++ * needs to be disabled.  A global MAC reset is issued to stop the
++ * hardware, and all transmit and receive resources are freed.
++ **/
++
++static int e1000_close(struct net_device *netdev)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++
++	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
++	e1000_down(adapter);
++	e1000_power_down_phy(adapter);
++	e1000_free_irq(adapter);
++
++	e1000_free_all_tx_resources(adapter);
++	e1000_free_all_rx_resources(adapter);
++
++	/* kill manageability vlan ID if supported, but not if a vlan with
++	 * the same ID is registered on the host OS (let 8021q kill it) */
++	if ((hw->mng_cookie.status &
++			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
++	     !(adapter->vlgrp &&
++	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
++		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
++	}
++
++	return 0;
++}
++
++/**
++ * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
++ * @adapter: address of board private structure
++ * @start: address of beginning of memory
++ * @len: length of memory
++ **/
++static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
++				  unsigned long len)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	unsigned long begin = (unsigned long)start;
++	unsigned long end = begin + len;
++
++	/* First rev 82545 and 82546 need to not allow any memory
++	 * write location to cross 64k boundary due to errata 23 */
++	if (hw->mac_type == e1000_82545 ||
++	    hw->mac_type == e1000_82546) {
++		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
++	}
++
++	return true;
++}
++
++/**
++ * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
++ * @adapter: board private structure
++ * @txdr:    tx descriptor ring (for a specific queue) to setup
++ *
++ * Return 0 on success, negative on failure
++ **/
++
++static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
++				    struct e1000_tx_ring *txdr)
++{
++	struct pci_dev *pdev = adapter->pdev;
++	int size;
++
++	size = sizeof(struct e1000_buffer) * txdr->count;
++	txdr->buffer_info = vmalloc(size);
++	if (!txdr->buffer_info) {
++		e_err("Unable to allocate memory for the Tx descriptor ring\n");
++		return -ENOMEM;
++	}
++	memset(txdr->buffer_info, 0, size);
++
++	/* round up to nearest 4K */
++
++	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
++	txdr->size = ALIGN(txdr->size, 4096);
++
++	txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma,
++					GFP_KERNEL);
++	if (!txdr->desc) {
++setup_tx_desc_die:
++		vfree(txdr->buffer_info);
++		e_err("Unable to allocate memory for the Tx descriptor ring\n");
++		return -ENOMEM;
++	}
++
++	/* Fix for errata 23, can't cross 64kB boundary */
++	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
++		void *olddesc = txdr->desc;
++		dma_addr_t olddma = txdr->dma;
++		e_err("txdr align check failed: %u bytes at %p\n",
++		      txdr->size, txdr->desc);
++		/* Try again, without freeing the previous */
++		txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size,
++						&txdr->dma, GFP_KERNEL);
++		/* Failed allocation, critical failure */
++		if (!txdr->desc) {
++			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
++					  olddma);
++			goto setup_tx_desc_die;
++		}
++
++		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
++			/* give up */
++			dma_free_coherent(&pdev->dev, txdr->size, txdr->desc,
++					  txdr->dma);
++			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
++					  olddma);
++			e_err("Unable to allocate aligned memory "
++			      "for the transmit descriptor ring\n");
++			vfree(txdr->buffer_info);
++			return -ENOMEM;
++		} else {
++			/* Free old allocation, new allocation was successful */
++			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
++					  olddma);
++		}
++	}
++	memset(txdr->desc, 0, txdr->size);
++
++	txdr->next_to_use = 0;
++	txdr->next_to_clean = 0;
++
++	return 0;
++}
++
++/**
++ * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
++ * 				  (Descriptors) for all queues
++ * @adapter: board private structure
++ *
++ * Return 0 on success, negative on failure
++ **/
++
++int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
++{
++	int i, err = 0;
++
++	for (i = 0; i < adapter->num_tx_queues; i++) {
++		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
++		if (err) {
++			e_err("Allocation for Tx Queue %u failed\n", i);
++			for (i-- ; i >= 0; i--)
++				e1000_free_tx_resources(adapter,
++							&adapter->tx_ring[i]);
++			break;
++		}
++	}
++
++	return err;
++}
++
++/**
++ * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
++ * @adapter: board private structure
++ *
++ * Configure the Tx unit of the MAC after a reset.
++ **/
++
++static void e1000_configure_tx(struct e1000_adapter *adapter)
++{
++	u64 tdba;
++	struct e1000_hw *hw = &adapter->hw;
++	u32 tdlen, tctl, tipg;
++	u32 ipgr1, ipgr2;
++
++	/* Setup the HW Tx Head and Tail descriptor pointers */
++
++	switch (adapter->num_tx_queues) {
++	case 1:
++	default:
++		tdba = adapter->tx_ring[0].dma;
++		tdlen = adapter->tx_ring[0].count *
++			sizeof(struct e1000_tx_desc);
++		ew32(TDLEN, tdlen);
++		ew32(TDBAH, (tdba >> 32));
++		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
++		ew32(TDT, 0);
++		ew32(TDH, 0);
++		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
++		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
++		break;
++	}
++
++	/* Set the default values for the Tx Inter Packet Gap timer */
++	if ((hw->media_type == e1000_media_type_fiber ||
++	     hw->media_type == e1000_media_type_internal_serdes))
++		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
++	else
++		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
++
++	switch (hw->mac_type) {
++	case e1000_82542_rev2_0:
++	case e1000_82542_rev2_1:
++		tipg = DEFAULT_82542_TIPG_IPGT;
++		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
++		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
++		break;
++	default:
++		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
++		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
++		break;
++	}
++	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
++	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
++	ew32(TIPG, tipg);
++
++	/* Set the Tx Interrupt Delay register */
++
++	ew32(TIDV, adapter->tx_int_delay);
++	if (hw->mac_type >= e1000_82540)
++		ew32(TADV, adapter->tx_abs_int_delay);
++
++	/* Program the Transmit Control Register */
++
++	tctl = er32(TCTL);
++	tctl &= ~E1000_TCTL_CT;
++	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
++		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
++
++	e1000_config_collision_dist(hw);
++
++	/* Setup Transmit Descriptor Settings for eop descriptor */
++	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
++
++	/* only set IDE if we are delaying interrupts using the timers */
++	if (adapter->tx_int_delay)
++		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
++
++	if (hw->mac_type < e1000_82543)
++		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
++	else
++		adapter->txd_cmd |= E1000_TXD_CMD_RS;
++
++	/* Cache if we're 82544 running in PCI-X because we'll
++	 * need this to apply a workaround later in the send path. */
++	if (hw->mac_type == e1000_82544 &&
++	    hw->bus_type == e1000_bus_type_pcix)
++		adapter->pcix_82544 = 1;
++
++	ew32(TCTL, tctl);
++
++}
++
++/**
++ * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
++ * @adapter: board private structure
++ * @rxdr:    rx descriptor ring (for a specific queue) to setup
++ *
++ * Returns 0 on success, negative on failure
++ **/
++
++static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
++				    struct e1000_rx_ring *rxdr)
++{
++	struct pci_dev *pdev = adapter->pdev;
++	int size, desc_len;
++
++	size = sizeof(struct e1000_buffer) * rxdr->count;
++	rxdr->buffer_info = vmalloc(size);
++	if (!rxdr->buffer_info) {
++		e_err("Unable to allocate memory for the Rx descriptor ring\n");
++		return -ENOMEM;
++	}
++	memset(rxdr->buffer_info, 0, size);
++
++	desc_len = sizeof(struct e1000_rx_desc);
++
++	/* Round up to nearest 4K */
++
++	rxdr->size = rxdr->count * desc_len;
++	rxdr->size = ALIGN(rxdr->size, 4096);
++
++	rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
++					GFP_KERNEL);
++
++	if (!rxdr->desc) {
++		e_err("Unable to allocate memory for the Rx descriptor ring\n");
++setup_rx_desc_die:
++		vfree(rxdr->buffer_info);
++		return -ENOMEM;
++	}
++
++	/* Fix for errata 23, can't cross 64kB boundary */
++	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
++		void *olddesc = rxdr->desc;
++		dma_addr_t olddma = rxdr->dma;
++		e_err("rxdr align check failed: %u bytes at %p\n",
++		      rxdr->size, rxdr->desc);
++		/* Try again, without freeing the previous */
++		rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size,
++						&rxdr->dma, GFP_KERNEL);
++		/* Failed allocation, critical failure */
++		if (!rxdr->desc) {
++			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
++					  olddma);
++			e_err("Unable to allocate memory for the Rx descriptor "
++			      "ring\n");
++			goto setup_rx_desc_die;
++		}
++
++		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
++			/* give up */
++			dma_free_coherent(&pdev->dev, rxdr->size, rxdr->desc,
++					  rxdr->dma);
++			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
++					  olddma);
++			e_err("Unable to allocate aligned memory for the Rx "
++			      "descriptor ring\n");
++			goto setup_rx_desc_die;
++		} else {
++			/* Free old allocation, new allocation was successful */
++			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
++					  olddma);
++		}
++	}
++	memset(rxdr->desc, 0, rxdr->size);
++
++	rxdr->next_to_clean = 0;
++	rxdr->next_to_use = 0;
++	rxdr->rx_skb_top = NULL;
++
++	return 0;
++}
++
++/**
++ * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
++ * 				  (Descriptors) for all queues
++ * @adapter: board private structure
++ *
++ * Return 0 on success, negative on failure
++ **/
++
++int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
++{
++	int i, err = 0;
++
++	for (i = 0; i < adapter->num_rx_queues; i++) {
++		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
++		if (err) {
++			e_err("Allocation for Rx Queue %u failed\n", i);
++			for (i-- ; i >= 0; i--)
++				e1000_free_rx_resources(adapter,
++							&adapter->rx_ring[i]);
++			break;
++		}
++	}
++
++	return err;
++}
++
++/**
++ * e1000_setup_rctl - configure the receive control registers
++ * @adapter: Board private structure
++ **/
++static void e1000_setup_rctl(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	u32 rctl;
++
++	rctl = er32(RCTL);
++
++	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
++
++	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
++		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
++		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
++
++	if (hw->tbi_compatibility_on == 1)
++		rctl |= E1000_RCTL_SBP;
++	else
++		rctl &= ~E1000_RCTL_SBP;
++
++	if (adapter->netdev->mtu <= ETH_DATA_LEN)
++		rctl &= ~E1000_RCTL_LPE;
++	else
++		rctl |= E1000_RCTL_LPE;
++
++	/* Setup buffer sizes */
++	rctl &= ~E1000_RCTL_SZ_4096;
++	rctl |= E1000_RCTL_BSEX;
++	switch (adapter->rx_buffer_len) {
++		case E1000_RXBUFFER_2048:
++		default:
++			rctl |= E1000_RCTL_SZ_2048;
++			rctl &= ~E1000_RCTL_BSEX;
++			break;
++		case E1000_RXBUFFER_4096:
++			rctl |= E1000_RCTL_SZ_4096;
++			break;
++		case E1000_RXBUFFER_8192:
++			rctl |= E1000_RCTL_SZ_8192;
++			break;
++		case E1000_RXBUFFER_16384:
++			rctl |= E1000_RCTL_SZ_16384;
++			break;
++	}
++
++	ew32(RCTL, rctl);
++}
++
++/**
++ * e1000_configure_rx - Configure 8254x Receive Unit after Reset
++ * @adapter: board private structure
++ *
++ * Configure the Rx unit of the MAC after a reset.
++ **/
++
++static void e1000_configure_rx(struct e1000_adapter *adapter)
++{
++	u64 rdba;
++	struct e1000_hw *hw = &adapter->hw;
++	u32 rdlen, rctl, rxcsum;
++
++	if (adapter->netdev->mtu > ETH_DATA_LEN) {
++		rdlen = adapter->rx_ring[0].count *
++		        sizeof(struct e1000_rx_desc);
++		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
++		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
++	} else {
++		rdlen = adapter->rx_ring[0].count *
++		        sizeof(struct e1000_rx_desc);
++		adapter->clean_rx = e1000_clean_rx_irq;
++		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
++	}
++
++	/* disable receives while setting up the descriptors */
++	rctl = er32(RCTL);
++	ew32(RCTL, rctl & ~E1000_RCTL_EN);
++
++	/* set the Receive Delay Timer Register */
++	ew32(RDTR, adapter->rx_int_delay);
++
++	if (hw->mac_type >= e1000_82540) {
++		ew32(RADV, adapter->rx_abs_int_delay);
++		if (adapter->itr_setting != 0)
++			ew32(ITR, 1000000000 / (adapter->itr * 256));
++	}
++
++	/* Setup the HW Rx Head and Tail Descriptor Pointers and
++	 * the Base and Length of the Rx Descriptor Ring */
++	switch (adapter->num_rx_queues) {
++	case 1:
++	default:
++		rdba = adapter->rx_ring[0].dma;
++		ew32(RDLEN, rdlen);
++		ew32(RDBAH, (rdba >> 32));
++		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
++		ew32(RDT, 0);
++		ew32(RDH, 0);
++		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
++		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
++		break;
++	}
++
++	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
++	if (hw->mac_type >= e1000_82543) {
++		rxcsum = er32(RXCSUM);
++		if (adapter->rx_csum)
++			rxcsum |= E1000_RXCSUM_TUOFL;
++		else
++			/* don't need to clear IPPCSE as it defaults to 0 */
++			rxcsum &= ~E1000_RXCSUM_TUOFL;
++		ew32(RXCSUM, rxcsum);
++	}
++
++	/* Enable Receives */
++	ew32(RCTL, rctl);
++}
++
++/**
++ * e1000_free_tx_resources - Free Tx Resources per Queue
++ * @adapter: board private structure
++ * @tx_ring: Tx descriptor ring for a specific queue
++ *
++ * Free all transmit software resources
++ **/
++
++static void e1000_free_tx_resources(struct e1000_adapter *adapter,
++				    struct e1000_tx_ring *tx_ring)
++{
++	struct pci_dev *pdev = adapter->pdev;
++
++	e1000_clean_tx_ring(adapter, tx_ring);
++
++	vfree(tx_ring->buffer_info);
++	tx_ring->buffer_info = NULL;
++
++	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
++			  tx_ring->dma);
++
++	tx_ring->desc = NULL;
++}
++
++/**
++ * e1000_free_all_tx_resources - Free Tx Resources for All Queues
++ * @adapter: board private structure
++ *
++ * Free all transmit software resources
++ **/
++
++void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
++{
++	int i;
++
++	for (i = 0; i < adapter->num_tx_queues; i++)
++		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
++}
++
++static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
++					     struct e1000_buffer *buffer_info)
++{
++	if (buffer_info->dma) {
++		if (buffer_info->mapped_as_page)
++			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
++				       buffer_info->length, DMA_TO_DEVICE);
++		else
++			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
++					 buffer_info->length,
++					 DMA_TO_DEVICE);
++		buffer_info->dma = 0;
++	}
++	if (buffer_info->skb) {
++		dev_kfree_skb_any(buffer_info->skb);
++		buffer_info->skb = NULL;
++	}
++	buffer_info->time_stamp = 0;
++	/* buffer_info must be completely set up in the transmit path */
++}
++
++/**
++ * e1000_clean_tx_ring - Free Tx Buffers
++ * @adapter: board private structure
++ * @tx_ring: ring to be cleaned
++ **/
++
++static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
++				struct e1000_tx_ring *tx_ring)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct e1000_buffer *buffer_info;
++	unsigned long size;
++	unsigned int i;
++
++	/* Free all the Tx ring sk_buffs */
++
++	for (i = 0; i < tx_ring->count; i++) {
++		buffer_info = &tx_ring->buffer_info[i];
++		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
++	}
++
++	size = sizeof(struct e1000_buffer) * tx_ring->count;
++	memset(tx_ring->buffer_info, 0, size);
++
++	/* Zero out the descriptor ring */
++
++	memset(tx_ring->desc, 0, tx_ring->size);
++
++	tx_ring->next_to_use = 0;
++	tx_ring->next_to_clean = 0;
++	tx_ring->last_tx_tso = 0;
++
++	writel(0, hw->hw_addr + tx_ring->tdh);
++	writel(0, hw->hw_addr + tx_ring->tdt);
++}
++
++/**
++ * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
++ * @adapter: board private structure
++ **/
++
++static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
++{
++	int i;
++
++	for (i = 0; i < adapter->num_tx_queues; i++)
++		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
++}
++
++/**
++ * e1000_free_rx_resources - Free Rx Resources
++ * @adapter: board private structure
++ * @rx_ring: ring to clean the resources from
++ *
++ * Free all receive software resources
++ **/
++
++static void e1000_free_rx_resources(struct e1000_adapter *adapter,
++				    struct e1000_rx_ring *rx_ring)
++{
++	struct pci_dev *pdev = adapter->pdev;
++
++	e1000_clean_rx_ring(adapter, rx_ring);
++
++	vfree(rx_ring->buffer_info);
++	rx_ring->buffer_info = NULL;
++
++	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
++			  rx_ring->dma);
++
++	rx_ring->desc = NULL;
++}
++
++/**
++ * e1000_free_all_rx_resources - Free Rx Resources for All Queues
++ * @adapter: board private structure
++ *
++ * Free all receive software resources
++ **/
++
++void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
++{
++	int i;
++
++	for (i = 0; i < adapter->num_rx_queues; i++)
++		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
++}
++
++/**
++ * e1000_clean_rx_ring - Free Rx Buffers per Queue
++ * @adapter: board private structure
++ * @rx_ring: ring to free buffers from
++ **/
++
++static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
++				struct e1000_rx_ring *rx_ring)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct e1000_buffer *buffer_info;
++	struct pci_dev *pdev = adapter->pdev;
++	unsigned long size;
++	unsigned int i;
++
++	/* Free all the Rx ring sk_buffs */
++	for (i = 0; i < rx_ring->count; i++) {
++		buffer_info = &rx_ring->buffer_info[i];
++		if (buffer_info->dma &&
++		    adapter->clean_rx == e1000_clean_rx_irq) {
++			dma_unmap_single(&pdev->dev, buffer_info->dma,
++			                 buffer_info->length,
++					 DMA_FROM_DEVICE);
++		} else if (buffer_info->dma &&
++		           adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
++			dma_unmap_page(&pdev->dev, buffer_info->dma,
++				       buffer_info->length,
++				       DMA_FROM_DEVICE);
++		}
++
++		buffer_info->dma = 0;
++		if (buffer_info->page) {
++			put_page(buffer_info->page);
++			buffer_info->page = NULL;
++		}
++		if (buffer_info->skb) {
++			dev_kfree_skb(buffer_info->skb);
++			buffer_info->skb = NULL;
++		}
++	}
++
++	/* there also may be some cached data from a chained receive */
++	if (rx_ring->rx_skb_top) {
++		dev_kfree_skb(rx_ring->rx_skb_top);
++		rx_ring->rx_skb_top = NULL;
++	}
++
++	size = sizeof(struct e1000_buffer) * rx_ring->count;
++	memset(rx_ring->buffer_info, 0, size);
++
++	/* Zero out the descriptor ring */
++	memset(rx_ring->desc, 0, rx_ring->size);
++
++	rx_ring->next_to_clean = 0;
++	rx_ring->next_to_use = 0;
++
++	writel(0, hw->hw_addr + rx_ring->rdh);
++	writel(0, hw->hw_addr + rx_ring->rdt);
++}
++
++/**
++ * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
++ * @adapter: board private structure
++ **/
++
++static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
++{
++	int i;
++
++	for (i = 0; i < adapter->num_rx_queues; i++)
++		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
++}
++
++/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
++ * and memory write and invalidate disabled for certain operations
++ */
++static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct net_device *netdev = adapter->netdev;
++	u32 rctl;
++
++	e1000_pci_clear_mwi(hw);
++
++	rctl = er32(RCTL);
++	rctl |= E1000_RCTL_RST;
++	ew32(RCTL, rctl);
++	E1000_WRITE_FLUSH();
++	mdelay(5);
++
++	if (netif_running(netdev))
++		e1000_clean_all_rx_rings(adapter);
++}
++
++static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct net_device *netdev = adapter->netdev;
++	u32 rctl;
++
++	rctl = er32(RCTL);
++	rctl &= ~E1000_RCTL_RST;
++	ew32(RCTL, rctl);
++	E1000_WRITE_FLUSH();
++	mdelay(5);
++
++	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
++		e1000_pci_set_mwi(hw);
++
++	if (netif_running(netdev)) {
++		/* No need to loop, because 82542 supports only 1 queue */
++		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
++		e1000_configure_rx(adapter);
++		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
++	}
++}
++
++/**
++ * e1000_set_mac - Change the Ethernet Address of the NIC
++ * @netdev: network interface device structure
++ * @p: pointer to an address structure
++ *
++ * Returns 0 on success, negative on failure
++ **/
++
++static int e1000_set_mac(struct net_device *netdev, void *p)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	struct sockaddr *addr = p;
++
++	if (!is_valid_ether_addr(addr->sa_data))
++		return -EADDRNOTAVAIL;
++
++	/* 82542 2.0 needs to be in reset to write receive address registers */
++
++	if (hw->mac_type == e1000_82542_rev2_0)
++		e1000_enter_82542_rst(adapter);
++
++	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
++	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
++
++	e1000_rar_set(hw, hw->mac_addr, 0);
++
++	if (hw->mac_type == e1000_82542_rev2_0)
++		e1000_leave_82542_rst(adapter);
++
++	return 0;
++}
++
++/**
++ * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
++ * @netdev: network interface device structure
++ *
++ * The set_rx_mode entry point is called whenever the unicast or multicast
++ * address lists or the network interface flags are updated. This routine is
++ * responsible for configuring the hardware for proper unicast, multicast,
++ * promiscuous mode, and all-multi behavior.
++ **/
++
++static void e1000_set_rx_mode(struct net_device *netdev)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	struct netdev_hw_addr *ha;
++	bool use_uc = false;
++	u32 rctl;
++	u32 hash_value;
++	int i, rar_entries = E1000_RAR_ENTRIES;
++	int mta_reg_count = E1000_NUM_MTA_REGISTERS;
++	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
++
++	if (!mcarray) {
++		e_err("memory allocation failed\n");
++		return;
++	}
++
++	/* Check for Promiscuous and All Multicast modes */
++
++	rctl = er32(RCTL);
++
++	if (netdev->flags & IFF_PROMISC) {
++		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
++		rctl &= ~E1000_RCTL_VFE;
++	} else {
++		if (netdev->flags & IFF_ALLMULTI)
++			rctl |= E1000_RCTL_MPE;
++		else
++			rctl &= ~E1000_RCTL_MPE;
++		/* Enable VLAN filter if there is a VLAN */
++		if (adapter->vlgrp)
++			rctl |= E1000_RCTL_VFE;
++	}
++
++	if (netdev_uc_count(netdev) > rar_entries - 1) {
++		rctl |= E1000_RCTL_UPE;
++	} else if (!(netdev->flags & IFF_PROMISC)) {
++		rctl &= ~E1000_RCTL_UPE;
++		use_uc = true;
++	}
++
++	ew32(RCTL, rctl);
++
++	/* 82542 2.0 needs to be in reset to write receive address registers */
++
++	if (hw->mac_type == e1000_82542_rev2_0)
++		e1000_enter_82542_rst(adapter);
++
++	/* load the first 14 addresses into the exact filters 1-14. Unicast
++	 * addresses take precedence to avoid disabling unicast filtering
++	 * when possible.
++	 *
++	 * RAR 0 is used for the station MAC adddress
++	 * if there are not 14 addresses, go ahead and clear the filters
++	 */
++	i = 1;
++	if (use_uc)
++		netdev_for_each_uc_addr(ha, netdev) {
++			if (i == rar_entries)
++				break;
++			e1000_rar_set(hw, ha->addr, i++);
++		}
++
++	netdev_for_each_mc_addr(ha, netdev) {
++		if (i == rar_entries) {
++			/* load any remaining addresses into the hash table */
++			u32 hash_reg, hash_bit, mta;
++			hash_value = e1000_hash_mc_addr(hw, ha->addr);
++			hash_reg = (hash_value >> 5) & 0x7F;
++			hash_bit = hash_value & 0x1F;
++			mta = (1 << hash_bit);
++			mcarray[hash_reg] |= mta;
++		} else {
++			e1000_rar_set(hw, ha->addr, i++);
++		}
++	}
++
++	for (; i < rar_entries; i++) {
++		E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
++		E1000_WRITE_FLUSH();
++		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
++		E1000_WRITE_FLUSH();
++	}
++
++	/* write the hash table completely, write from bottom to avoid
++	 * both stupid write combining chipsets, and flushing each write */
++	for (i = mta_reg_count - 1; i >= 0 ; i--) {
++		/*
++		 * If we are on an 82544 has an errata where writing odd
++		 * offsets overwrites the previous even offset, but writing
++		 * backwards over the range solves the issue by always
++		 * writing the odd offset first
++		 */
++		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
++	}
++	E1000_WRITE_FLUSH();
++
++	if (hw->mac_type == e1000_82542_rev2_0)
++		e1000_leave_82542_rst(adapter);
++
++	kfree(mcarray);
++}
++
++/* Need to wait a few seconds after link up to get diagnostic information from
++ * the phy */
++
++static void e1000_update_phy_info(unsigned long data)
++{
++	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
++	struct e1000_hw *hw = &adapter->hw;
++	e1000_phy_get_info(hw, &adapter->phy_info);
++}
++
++/**
++ * e1000_82547_tx_fifo_stall - Timer Call-back
++ * @data: pointer to adapter cast into an unsigned long
++ **/
++
++static void e1000_82547_tx_fifo_stall(unsigned long data)
++{
++	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
++	struct e1000_hw *hw = &adapter->hw;
++	struct net_device *netdev = adapter->netdev;
++	u32 tctl;
++
++	if (atomic_read(&adapter->tx_fifo_stall)) {
++		if ((er32(TDT) == er32(TDH)) &&
++		   (er32(TDFT) == er32(TDFH)) &&
++		   (er32(TDFTS) == er32(TDFHS))) {
++			tctl = er32(TCTL);
++			ew32(TCTL, tctl & ~E1000_TCTL_EN);
++			ew32(TDFT, adapter->tx_head_addr);
++			ew32(TDFH, adapter->tx_head_addr);
++			ew32(TDFTS, adapter->tx_head_addr);
++			ew32(TDFHS, adapter->tx_head_addr);
++			ew32(TCTL, tctl);
++			E1000_WRITE_FLUSH();
++
++			adapter->tx_fifo_head = 0;
++			atomic_set(&adapter->tx_fifo_stall, 0);
++			netif_wake_queue(netdev);
++		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
++			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
++		}
++	}
++}
++
++bool e1000_has_link(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	bool link_active = false;
++
++	/* get_link_status is set on LSC (link status) interrupt or
++	 * rx sequence error interrupt.  get_link_status will stay
++	 * false until the e1000_check_for_link establishes link
++	 * for copper adapters ONLY
++	 */
++	switch (hw->media_type) {
++	case e1000_media_type_copper:
++		if (hw->get_link_status) {
++			e1000_check_for_link(hw);
++			link_active = !hw->get_link_status;
++		} else {
++			link_active = true;
++		}
++		break;
++	case e1000_media_type_fiber:
++		e1000_check_for_link(hw);
++		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
++		break;
++	case e1000_media_type_internal_serdes:
++		e1000_check_for_link(hw);
++		link_active = hw->serdes_has_link;
++		break;
++	default:
++		break;
++	}
++
++	return link_active;
++}
++
++/**
++ * e1000_watchdog - Timer Call-back
++ * @data: pointer to adapter cast into an unsigned long
++ **/
++static void e1000_watchdog(unsigned long data)
++{
++	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
++	struct e1000_hw *hw = &adapter->hw;
++	struct net_device *netdev = adapter->netdev;
++	struct e1000_tx_ring *txdr = adapter->tx_ring;
++	u32 link, tctl;
++
++	link = e1000_has_link(adapter);
++	if ((netif_carrier_ok(netdev)) && link)
++		goto link_up;
++
++	if (link) {
++		if (!netif_carrier_ok(netdev)) {
++			u32 ctrl;
++			bool txb2b = true;
++			/* update snapshot of PHY registers on LSC */
++			e1000_get_speed_and_duplex(hw,
++			                           &adapter->link_speed,
++			                           &adapter->link_duplex);
++
++			ctrl = er32(CTRL);
++			pr_info("%s NIC Link is Up %d Mbps %s, "
++				"Flow Control: %s\n",
++				netdev->name,
++				adapter->link_speed,
++				adapter->link_duplex == FULL_DUPLEX ?
++				"Full Duplex" : "Half Duplex",
++				((ctrl & E1000_CTRL_TFCE) && (ctrl &
++				E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
++				E1000_CTRL_RFCE) ? "RX" : ((ctrl &
++				E1000_CTRL_TFCE) ? "TX" : "None")));
++
++			/* adjust timeout factor according to speed/duplex */
++			adapter->tx_timeout_factor = 1;
++			switch (adapter->link_speed) {
++			case SPEED_10:
++				txb2b = false;
++				adapter->tx_timeout_factor = 16;
++				break;
++			case SPEED_100:
++				txb2b = false;
++				/* maybe add some timeout factor ? */
++				break;
++			}
++
++			/* enable transmits in the hardware */
++			tctl = er32(TCTL);
++			tctl |= E1000_TCTL_EN;
++			ew32(TCTL, tctl);
++
++			netif_carrier_on(netdev);
++			if (!test_bit(__E1000_DOWN, &adapter->flags))
++				mod_timer(&adapter->phy_info_timer,
++				          round_jiffies(jiffies + 2 * HZ));
++			adapter->smartspeed = 0;
++		}
++	} else {
++		if (netif_carrier_ok(netdev)) {
++			adapter->link_speed = 0;
++			adapter->link_duplex = 0;
++			pr_info("%s NIC Link is Down\n",
++				netdev->name);
++			netif_carrier_off(netdev);
++
++			if (!test_bit(__E1000_DOWN, &adapter->flags))
++				mod_timer(&adapter->phy_info_timer,
++				          round_jiffies(jiffies + 2 * HZ));
++		}
++
++		e1000_smartspeed(adapter);
++	}
++
++link_up:
++	e1000_update_stats(adapter);
++
++	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
++	adapter->tpt_old = adapter->stats.tpt;
++	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
++	adapter->colc_old = adapter->stats.colc;
++
++	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
++	adapter->gorcl_old = adapter->stats.gorcl;
++	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
++	adapter->gotcl_old = adapter->stats.gotcl;
++
++	e1000_update_adaptive(hw);
++
++	if (!netif_carrier_ok(netdev)) {
++		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
++			/* We've lost link, so the controller stops DMA,
++			 * but we've got queued Tx work that's never going
++			 * to get done, so reset controller to flush Tx.
++			 * (Do the reset outside of interrupt context). */
++			adapter->tx_timeout_count++;
++			schedule_work(&adapter->reset_task);
++			/* return immediately since reset is imminent */
++			return;
++		}
++	}
++
++	/* Simple mode for Interrupt Throttle Rate (ITR) */
++	if (hw->mac_type >= e1000_82540 && adapter->itr_setting == 4) {
++		/*
++		 * Symmetric Tx/Rx gets a reduced ITR=2000;
++		 * Total asymmetrical Tx or Rx gets ITR=8000;
++		 * everyone else is between 2000-8000.
++		 */
++		u32 goc = (adapter->gotcl + adapter->gorcl) / 10000;
++		u32 dif = (adapter->gotcl > adapter->gorcl ?
++			    adapter->gotcl - adapter->gorcl :
++			    adapter->gorcl - adapter->gotcl) / 10000;
++		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
++
++		ew32(ITR, 1000000000 / (itr * 256));
++	}
++
++	/* Cause software interrupt to ensure rx ring is cleaned */
++	ew32(ICS, E1000_ICS_RXDMT0);
++
++	/* Force detection of hung controller every watchdog period */
++	adapter->detect_tx_hung = true;
++
++	/* Reset the timer */
++	if (!test_bit(__E1000_DOWN, &adapter->flags))
++		mod_timer(&adapter->watchdog_timer,
++		          round_jiffies(jiffies + 2 * HZ));
++}
++
++enum latency_range {
++	lowest_latency = 0,
++	low_latency = 1,
++	bulk_latency = 2,
++	latency_invalid = 255
++};
++
++/**
++ * e1000_update_itr - update the dynamic ITR value based on statistics
++ * @adapter: pointer to adapter
++ * @itr_setting: current adapter->itr
++ * @packets: the number of packets during this measurement interval
++ * @bytes: the number of bytes during this measurement interval
++ *
++ *      Stores a new ITR value based on packets and byte
++ *      counts during the last interrupt.  The advantage of per interrupt
++ *      computation is faster updates and more accurate ITR for the current
++ *      traffic pattern.  Constants in this function were computed
++ *      based on theoretical maximum wire speed and thresholds were set based
++ *      on testing data as well as attempting to minimize response time
++ *      while increasing bulk throughput.
++ *      this functionality is controlled by the InterruptThrottleRate module
++ *      parameter (see e1000_param.c)
++ **/
++static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
++				     u16 itr_setting, int packets, int bytes)
++{
++	unsigned int retval = itr_setting;
++	struct e1000_hw *hw = &adapter->hw;
++
++	if (unlikely(hw->mac_type < e1000_82540))
++		goto update_itr_done;
++
++	if (packets == 0)
++		goto update_itr_done;
++
++	switch (itr_setting) {
++	case lowest_latency:
++		/* jumbo frames get bulk treatment*/
++		if (bytes/packets > 8000)
++			retval = bulk_latency;
++		else if ((packets < 5) && (bytes > 512))
++			retval = low_latency;
++		break;
++	case low_latency:  /* 50 usec aka 20000 ints/s */
++		if (bytes > 10000) {
++			/* jumbo frames need bulk latency setting */
++			if (bytes/packets > 8000)
++				retval = bulk_latency;
++			else if ((packets < 10) || ((bytes/packets) > 1200))
++				retval = bulk_latency;
++			else if ((packets > 35))
++				retval = lowest_latency;
++		} else if (bytes/packets > 2000)
++			retval = bulk_latency;
++		else if (packets <= 2 && bytes < 512)
++			retval = lowest_latency;
++		break;
++	case bulk_latency: /* 250 usec aka 4000 ints/s */
++		if (bytes > 25000) {
++			if (packets > 35)
++				retval = low_latency;
++		} else if (bytes < 6000) {
++			retval = low_latency;
++		}
++		break;
++	}
++
++update_itr_done:
++	return retval;
++}
++
++static void e1000_set_itr(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	u16 current_itr;
++	u32 new_itr = adapter->itr;
++
++	if (unlikely(hw->mac_type < e1000_82540))
++		return;
++
++	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
++	if (unlikely(adapter->link_speed != SPEED_1000)) {
++		current_itr = 0;
++		new_itr = 4000;
++		goto set_itr_now;
++	}
++
++	adapter->tx_itr = e1000_update_itr(adapter,
++	                            adapter->tx_itr,
++	                            adapter->total_tx_packets,
++	                            adapter->total_tx_bytes);
++	/* conservative mode (itr 3) eliminates the lowest_latency setting */
++	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
++		adapter->tx_itr = low_latency;
++
++	adapter->rx_itr = e1000_update_itr(adapter,
++	                            adapter->rx_itr,
++	                            adapter->total_rx_packets,
++	                            adapter->total_rx_bytes);
++	/* conservative mode (itr 3) eliminates the lowest_latency setting */
++	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
++		adapter->rx_itr = low_latency;
++
++	current_itr = max(adapter->rx_itr, adapter->tx_itr);
++
++	switch (current_itr) {
++	/* counts and packets in update_itr are dependent on these numbers */
++	case lowest_latency:
++		new_itr = 70000;
++		break;
++	case low_latency:
++		new_itr = 20000; /* aka hwitr = ~200 */
++		break;
++	case bulk_latency:
++		new_itr = 4000;
++		break;
++	default:
++		break;
++	}
++
++set_itr_now:
++	if (new_itr != adapter->itr) {
++		/* this attempts to bias the interrupt rate towards Bulk
++		 * by adding intermediate steps when interrupt rate is
++		 * increasing */
++		new_itr = new_itr > adapter->itr ?
++		             min(adapter->itr + (new_itr >> 2), new_itr) :
++		             new_itr;
++		adapter->itr = new_itr;
++		ew32(ITR, 1000000000 / (new_itr * 256));
++	}
++}
++
++#define E1000_TX_FLAGS_CSUM		0x00000001
++#define E1000_TX_FLAGS_VLAN		0x00000002
++#define E1000_TX_FLAGS_TSO		0x00000004
++#define E1000_TX_FLAGS_IPV4		0x00000008
++#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
++#define E1000_TX_FLAGS_VLAN_SHIFT	16
++
++static int e1000_tso(struct e1000_adapter *adapter,
++		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
++{
++	struct e1000_context_desc *context_desc;
++	struct e1000_buffer *buffer_info;
++	unsigned int i;
++	u32 cmd_length = 0;
++	u16 ipcse = 0, tucse, mss;
++	u8 ipcss, ipcso, tucss, tucso, hdr_len;
++	int err;
++
++	if (skb_is_gso(skb)) {
++		if (skb_header_cloned(skb)) {
++			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
++			if (err)
++				return err;
++		}
++
++		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
++		mss = skb_shinfo(skb)->gso_size;
++		if (skb->protocol == htons(ETH_P_IP)) {
++			struct iphdr *iph = ip_hdr(skb);
++			iph->tot_len = 0;
++			iph->check = 0;
++			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
++								 iph->daddr, 0,
++								 IPPROTO_TCP,
++								 0);
++			cmd_length = E1000_TXD_CMD_IP;
++			ipcse = skb_transport_offset(skb) - 1;
++		} else if (skb->protocol == htons(ETH_P_IPV6)) {
++			ipv6_hdr(skb)->payload_len = 0;
++			tcp_hdr(skb)->check =
++				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
++						 &ipv6_hdr(skb)->daddr,
++						 0, IPPROTO_TCP, 0);
++			ipcse = 0;
++		}
++		ipcss = skb_network_offset(skb);
++		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
++		tucss = skb_transport_offset(skb);
++		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
++		tucse = 0;
++
++		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
++			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
++
++		i = tx_ring->next_to_use;
++		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
++		buffer_info = &tx_ring->buffer_info[i];
++
++		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
++		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
++		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
++		context_desc->upper_setup.tcp_fields.tucss = tucss;
++		context_desc->upper_setup.tcp_fields.tucso = tucso;
++		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
++		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
++		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
++		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
++
++		buffer_info->time_stamp = jiffies;
++		buffer_info->next_to_watch = i;
++
++		if (++i == tx_ring->count) i = 0;
++		tx_ring->next_to_use = i;
++
++		return true;
++	}
++	return false;
++}
++
++static bool e1000_tx_csum(struct e1000_adapter *adapter,
++			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
++{
++	struct e1000_context_desc *context_desc;
++	struct e1000_buffer *buffer_info;
++	unsigned int i;
++	u8 css;
++	u32 cmd_len = E1000_TXD_CMD_DEXT;
++
++	if (skb->ip_summed != CHECKSUM_PARTIAL)
++		return false;
++
++	switch (skb->protocol) {
++	case cpu_to_be16(ETH_P_IP):
++		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
++			cmd_len |= E1000_TXD_CMD_TCP;
++		break;
++	case cpu_to_be16(ETH_P_IPV6):
++		/* XXX not handling all IPV6 headers */
++		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
++			cmd_len |= E1000_TXD_CMD_TCP;
++		break;
++	default:
++		if (unlikely(net_ratelimit()))
++			e_warn("checksum_partial proto=%x!\n", skb->protocol);
++		break;
++	}
++
++	css = skb_transport_offset(skb);
++
++	i = tx_ring->next_to_use;
++	buffer_info = &tx_ring->buffer_info[i];
++	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
++
++	context_desc->lower_setup.ip_config = 0;
++	context_desc->upper_setup.tcp_fields.tucss = css;
++	context_desc->upper_setup.tcp_fields.tucso =
++		css + skb->csum_offset;
++	context_desc->upper_setup.tcp_fields.tucse = 0;
++	context_desc->tcp_seg_setup.data = 0;
++	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
++
++	buffer_info->time_stamp = jiffies;
++	buffer_info->next_to_watch = i;
++
++	if (unlikely(++i == tx_ring->count)) i = 0;
++	tx_ring->next_to_use = i;
++
++	return true;
++}
++
++#define E1000_MAX_TXD_PWR	12
++#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
++
++static int e1000_tx_map(struct e1000_adapter *adapter,
++			struct e1000_tx_ring *tx_ring,
++			struct sk_buff *skb, unsigned int first,
++			unsigned int max_per_txd, unsigned int nr_frags,
++			unsigned int mss)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct pci_dev *pdev = adapter->pdev;
++	struct e1000_buffer *buffer_info;
++	unsigned int len = skb_headlen(skb);
++	unsigned int offset = 0, size, count = 0, i;
++	unsigned int f;
++
++	i = tx_ring->next_to_use;
++
++	while (len) {
++		buffer_info = &tx_ring->buffer_info[i];
++		size = min(len, max_per_txd);
++		/* Workaround for Controller erratum --
++		 * descriptor for non-tso packet in a linear SKB that follows a
++		 * tso gets written back prematurely before the data is fully
++		 * DMA'd to the controller */
++		if (!skb->data_len && tx_ring->last_tx_tso &&
++		    !skb_is_gso(skb)) {
++			tx_ring->last_tx_tso = 0;
++			size -= 4;
++		}
++
++		/* Workaround for premature desc write-backs
++		 * in TSO mode.  Append 4-byte sentinel desc */
++		if (unlikely(mss && !nr_frags && size == len && size > 8))
++			size -= 4;
++		/* work-around for errata 10 and it applies
++		 * to all controllers in PCI-X mode
++		 * The fix is to make sure that the first descriptor of a
++		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
++		 */
++		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
++		                (size > 2015) && count == 0))
++		        size = 2015;
++
++		/* Workaround for potential 82544 hang in PCI-X.  Avoid
++		 * terminating buffers within evenly-aligned dwords. */
++		if (unlikely(adapter->pcix_82544 &&
++		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
++		   size > 4))
++			size -= 4;
++
++		buffer_info->length = size;
++		/* set time_stamp *before* dma to help avoid a possible race */
++		buffer_info->time_stamp = jiffies;
++		buffer_info->mapped_as_page = false;
++		buffer_info->dma = dma_map_single(&pdev->dev,
++						  skb->data + offset,
++						  size,	DMA_TO_DEVICE);
++		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
++			goto dma_error;
++		buffer_info->next_to_watch = i;
++
++		len -= size;
++		offset += size;
++		count++;
++		if (len) {
++			i++;
++			if (unlikely(i == tx_ring->count))
++				i = 0;
++		}
++	}
++
++	for (f = 0; f < nr_frags; f++) {
++		struct skb_frag_struct *frag;
++
++		frag = &skb_shinfo(skb)->frags[f];
++		len = frag->size;
++		offset = frag->page_offset;
++
++		while (len) {
++			i++;
++			if (unlikely(i == tx_ring->count))
++				i = 0;
++
++			buffer_info = &tx_ring->buffer_info[i];
++			size = min(len, max_per_txd);
++			/* Workaround for premature desc write-backs
++			 * in TSO mode.  Append 4-byte sentinel desc */
++			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
++				size -= 4;
++			/* Workaround for potential 82544 hang in PCI-X.
++			 * Avoid terminating buffers within evenly-aligned
++			 * dwords. */
++			if (unlikely(adapter->pcix_82544 &&
++			    !((unsigned long)(page_to_phys(frag->page) + offset
++			                      + size - 1) & 4) &&
++			    size > 4))
++				size -= 4;
++
++			buffer_info->length = size;
++			buffer_info->time_stamp = jiffies;
++			buffer_info->mapped_as_page = true;
++			buffer_info->dma = dma_map_page(&pdev->dev, frag->page,
++							offset,	size,
++							DMA_TO_DEVICE);
++			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
++				goto dma_error;
++			buffer_info->next_to_watch = i;
++
++			len -= size;
++			offset += size;
++			count++;
++		}
++	}
++
++	tx_ring->buffer_info[i].skb = skb;
++	tx_ring->buffer_info[first].next_to_watch = i;
++
++	return count;
++
++dma_error:
++	dev_err(&pdev->dev, "TX DMA map failed\n");
++	buffer_info->dma = 0;
++	if (count)
++		count--;
++
++	while (count--) {
++		if (i==0)
++			i += tx_ring->count;
++		i--;
++		buffer_info = &tx_ring->buffer_info[i];
++		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
++	}
++
++	return 0;
++}
++
++static void e1000_tx_queue(struct e1000_adapter *adapter,
++			   struct e1000_tx_ring *tx_ring, int tx_flags,
++			   int count)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct e1000_tx_desc *tx_desc = NULL;
++	struct e1000_buffer *buffer_info;
++	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
++	unsigned int i;
++
++	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
++		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
++		             E1000_TXD_CMD_TSE;
++		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
++
++		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
++			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
++	}
++
++	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
++		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
++		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
++	}
++
++	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
++		txd_lower |= E1000_TXD_CMD_VLE;
++		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
++	}
++
++	i = tx_ring->next_to_use;
++
++	while (count--) {
++		buffer_info = &tx_ring->buffer_info[i];
++		tx_desc = E1000_TX_DESC(*tx_ring, i);
++		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
++		tx_desc->lower.data =
++			cpu_to_le32(txd_lower | buffer_info->length);
++		tx_desc->upper.data = cpu_to_le32(txd_upper);
++		if (unlikely(++i == tx_ring->count)) i = 0;
++	}
++
++	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
++
++	/* Force memory writes to complete before letting h/w
++	 * know there are new descriptors to fetch.  (Only
++	 * applicable for weak-ordered memory model archs,
++	 * such as IA-64). */
++	wmb();
++
++	tx_ring->next_to_use = i;
++	writel(i, hw->hw_addr + tx_ring->tdt);
++	/* we need this if more than one processor can write to our tail
++	 * at a time, it syncronizes IO on IA64/Altix systems */
++	mmiowb();
++}
++
++/**
++ * 82547 workaround to avoid controller hang in half-duplex environment.
++ * The workaround is to avoid queuing a large packet that would span
++ * the internal Tx FIFO ring boundary by notifying the stack to resend
++ * the packet at a later time.  This gives the Tx FIFO an opportunity to
++ * flush all packets.  When that occurs, we reset the Tx FIFO pointers
++ * to the beginning of the Tx FIFO.
++ **/
++
++#define E1000_FIFO_HDR			0x10
++#define E1000_82547_PAD_LEN		0x3E0
++
++static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
++				       struct sk_buff *skb)
++{
++	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
++	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
++
++	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
++
++	if (adapter->link_duplex != HALF_DUPLEX)
++		goto no_fifo_stall_required;
++
++	if (atomic_read(&adapter->tx_fifo_stall))
++		return 1;
++
++	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
++		atomic_set(&adapter->tx_fifo_stall, 1);
++		return 1;
++	}
++
++no_fifo_stall_required:
++	adapter->tx_fifo_head += skb_fifo_len;
++	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
++		adapter->tx_fifo_head -= adapter->tx_fifo_size;
++	return 0;
++}
++
++static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
++
++	netif_stop_queue(netdev);
++	/* Herbert's original patch had:
++	 *  smp_mb__after_netif_stop_queue();
++	 * but since that doesn't exist yet, just open code it. */
++	smp_mb();
++
++	/* We need to check again in a case another CPU has just
++	 * made room available. */
++	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
++		return -EBUSY;
++
++	/* A reprieve! */
++	netif_start_queue(netdev);
++	++adapter->restart_queue;
++	return 0;
++}
++
++static int e1000_maybe_stop_tx(struct net_device *netdev,
++                               struct e1000_tx_ring *tx_ring, int size)
++{
++	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
++		return 0;
++	return __e1000_maybe_stop_tx(netdev, size);
++}
++
++#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
++static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
++				    struct net_device *netdev)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	struct e1000_tx_ring *tx_ring;
++	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
++	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
++	unsigned int tx_flags = 0;
++	unsigned int len = skb_headlen(skb);
++	unsigned int nr_frags;
++	unsigned int mss;
++	int count = 0;
++	int tso;
++	unsigned int f;
++
++	/* This goes back to the question of how to logically map a tx queue
++	 * to a flow.  Right now, performance is impacted slightly negatively
++	 * if using multiple tx queues.  If the stack breaks away from a
++	 * single qdisc implementation, we can look at this again. */
++	tx_ring = adapter->tx_ring;
++
++	if (unlikely(skb->len <= 0)) {
++		dev_kfree_skb_any(skb);
++		return NETDEV_TX_OK;
++	}
++
++	mss = skb_shinfo(skb)->gso_size;
++	/* The controller does a simple calculation to
++	 * make sure there is enough room in the FIFO before
++	 * initiating the DMA for each buffer.  The calc is:
++	 * 4 = ceil(buffer len/mss).  To make sure we don't
++	 * overrun the FIFO, adjust the max buffer len if mss
++	 * drops. */
++	if (mss) {
++		u8 hdr_len;
++		max_per_txd = min(mss << 2, max_per_txd);
++		max_txd_pwr = fls(max_per_txd) - 1;
++
++		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
++		if (skb->data_len && hdr_len == len) {
++			switch (hw->mac_type) {
++				unsigned int pull_size;
++			case e1000_82544:
++				/* Make sure we have room to chop off 4 bytes,
++				 * and that the end alignment will work out to
++				 * this hardware's requirements
++				 * NOTE: this is a TSO only workaround
++				 * if end byte alignment not correct move us
++				 * into the next dword */
++				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
++					break;
++				/* fall through */
++				pull_size = min((unsigned int)4, skb->data_len);
++				if (!__pskb_pull_tail(skb, pull_size)) {
++					e_err("__pskb_pull_tail failed.\n");
++					dev_kfree_skb_any(skb);
++					return NETDEV_TX_OK;
++				}
++				len = skb_headlen(skb);
++				break;
++			default:
++				/* do nothing */
++				break;
++			}
++		}
++	}
++
++	/* reserve a descriptor for the offload context */
++	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
++		count++;
++	count++;
++
++	/* Controller Erratum workaround */
++	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
++		count++;
++
++	count += TXD_USE_COUNT(len, max_txd_pwr);
++
++	if (adapter->pcix_82544)
++		count++;
++
++	/* work-around for errata 10 and it applies to all controllers
++	 * in PCI-X mode, so add one more descriptor to the count
++	 */
++	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
++			(len > 2015)))
++		count++;
++
++	nr_frags = skb_shinfo(skb)->nr_frags;
++	for (f = 0; f < nr_frags; f++)
++		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
++				       max_txd_pwr);
++	if (adapter->pcix_82544)
++		count += nr_frags;
++
++	/* need: count + 2 desc gap to keep tail from touching
++	 * head, otherwise try next time */
++	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
++		return NETDEV_TX_BUSY;
++
++	if (unlikely(hw->mac_type == e1000_82547)) {
++		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
++			netif_stop_queue(netdev);
++			if (!test_bit(__E1000_DOWN, &adapter->flags))
++				mod_timer(&adapter->tx_fifo_stall_timer,
++				          jiffies + 1);
++			return NETDEV_TX_BUSY;
++		}
++	}
++
++	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
++		tx_flags |= E1000_TX_FLAGS_VLAN;
++		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
++	}
++
++	first = tx_ring->next_to_use;
++
++	tso = e1000_tso(adapter, tx_ring, skb);
++	if (tso < 0) {
++		dev_kfree_skb_any(skb);
++		return NETDEV_TX_OK;
++	}
++
++	if (likely(tso)) {
++		if (likely(hw->mac_type != e1000_82544))
++			tx_ring->last_tx_tso = 1;
++		tx_flags |= E1000_TX_FLAGS_TSO;
++	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
++		tx_flags |= E1000_TX_FLAGS_CSUM;
++
++	if (likely(skb->protocol == htons(ETH_P_IP)))
++		tx_flags |= E1000_TX_FLAGS_IPV4;
++
++	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
++	                     nr_frags, mss);
++
++	if (count) {
++		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
++		/* Make sure there is space in the ring for the next send. */
++		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
++
++	} else {
++		dev_kfree_skb_any(skb);
++		tx_ring->buffer_info[first].time_stamp = 0;
++		tx_ring->next_to_use = first;
++	}
++
++	return NETDEV_TX_OK;
++}
++
++/**
++ * e1000_tx_timeout - Respond to a Tx Hang
++ * @netdev: network interface device structure
++ **/
++
++static void e1000_tx_timeout(struct net_device *netdev)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++
++	/* Do the reset outside of interrupt context */
++	adapter->tx_timeout_count++;
++	schedule_work(&adapter->reset_task);
++}
++
++static void e1000_reset_task(struct work_struct *work)
++{
++	struct e1000_adapter *adapter =
++		container_of(work, struct e1000_adapter, reset_task);
++
++	e1000_reinit_locked(adapter);
++}
++
++/**
++ * e1000_get_stats - Get System Network Statistics
++ * @netdev: network interface device structure
++ *
++ * Returns the address of the device statistics structure.
++ * The statistics are actually updated from the timer callback.
++ **/
++
++static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
++{
++	/* only return the current stats */
++	return &netdev->stats;
++}
++
++/**
++ * e1000_change_mtu - Change the Maximum Transfer Unit
++ * @netdev: network interface device structure
++ * @new_mtu: new value for maximum frame size
++ *
++ * Returns 0 on success, negative on failure
++ **/
++
++static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
++
++	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
++	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
++		e_err("Invalid MTU setting\n");
++		return -EINVAL;
++	}
++
++	/* Adapter-specific max frame size limits. */
++	switch (hw->mac_type) {
++	case e1000_undefined ... e1000_82542_rev2_1:
++		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
++			e_err("Jumbo Frames not supported.\n");
++			return -EINVAL;
++		}
++		break;
++	default:
++		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
++		break;
++	}
++
++	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
++		msleep(1);
++	/* e1000_down has a dependency on max_frame_size */
++	hw->max_frame_size = max_frame;
++	if (netif_running(netdev))
++		e1000_down(adapter);
++
++	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
++	 * means we reserve 2 more, this pushes us to allocate from the next
++	 * larger slab size.
++	 * i.e. RXBUFFER_2048 --> size-4096 slab
++	 *  however with the new *_jumbo_rx* routines, jumbo receives will use
++	 *  fragmented skbs */
++
++	if (max_frame <= E1000_RXBUFFER_2048)
++		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
++	else
++#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
++		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
++#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
++		adapter->rx_buffer_len = PAGE_SIZE;
++#endif
++
++	/* adjust allocation if LPE protects us, and we aren't using SBP */
++	if (!hw->tbi_compatibility_on &&
++	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
++	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
++		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
++
++	pr_info("%s changing MTU from %d to %d\n",
++		netdev->name, netdev->mtu, new_mtu);
++	netdev->mtu = new_mtu;
++
++	if (netif_running(netdev))
++		e1000_up(adapter);
++	else
++		e1000_reset(adapter);
++
++	clear_bit(__E1000_RESETTING, &adapter->flags);
++
++	return 0;
++}
++
++/**
++ * e1000_update_stats - Update the board statistics counters
++ * @adapter: board private structure
++ **/
++
++void e1000_update_stats(struct e1000_adapter *adapter)
++{
++	struct net_device *netdev = adapter->netdev;
++	struct e1000_hw *hw = &adapter->hw;
++	struct pci_dev *pdev = adapter->pdev;
++	unsigned long flags;
++	u16 phy_tmp;
++
++#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
++
++	/*
++	 * Prevent stats update while adapter is being reset, or if the pci
++	 * connection is down.
++	 */
++	if (adapter->link_speed == 0)
++		return;
++	if (pci_channel_offline(pdev))
++		return;
++
++	spin_lock_irqsave(&adapter->stats_lock, flags);
++
++	/* these counters are modified from e1000_tbi_adjust_stats,
++	 * called from the interrupt context, so they must only
++	 * be written while holding adapter->stats_lock
++	 */
++
++	adapter->stats.crcerrs += er32(CRCERRS);
++	adapter->stats.gprc += er32(GPRC);
++	adapter->stats.gorcl += er32(GORCL);
++	adapter->stats.gorch += er32(GORCH);
++	adapter->stats.bprc += er32(BPRC);
++	adapter->stats.mprc += er32(MPRC);
++	adapter->stats.roc += er32(ROC);
++
++	adapter->stats.prc64 += er32(PRC64);
++	adapter->stats.prc127 += er32(PRC127);
++	adapter->stats.prc255 += er32(PRC255);
++	adapter->stats.prc511 += er32(PRC511);
++	adapter->stats.prc1023 += er32(PRC1023);
++	adapter->stats.prc1522 += er32(PRC1522);
++
++	adapter->stats.symerrs += er32(SYMERRS);
++	adapter->stats.mpc += er32(MPC);
++	adapter->stats.scc += er32(SCC);
++	adapter->stats.ecol += er32(ECOL);
++	adapter->stats.mcc += er32(MCC);
++	adapter->stats.latecol += er32(LATECOL);
++	adapter->stats.dc += er32(DC);
++	adapter->stats.sec += er32(SEC);
++	adapter->stats.rlec += er32(RLEC);
++	adapter->stats.xonrxc += er32(XONRXC);
++	adapter->stats.xontxc += er32(XONTXC);
++	adapter->stats.xoffrxc += er32(XOFFRXC);
++	adapter->stats.xofftxc += er32(XOFFTXC);
++	adapter->stats.fcruc += er32(FCRUC);
++	adapter->stats.gptc += er32(GPTC);
++	adapter->stats.gotcl += er32(GOTCL);
++	adapter->stats.gotch += er32(GOTCH);
++	adapter->stats.rnbc += er32(RNBC);
++	adapter->stats.ruc += er32(RUC);
++	adapter->stats.rfc += er32(RFC);
++	adapter->stats.rjc += er32(RJC);
++	adapter->stats.torl += er32(TORL);
++	adapter->stats.torh += er32(TORH);
++	adapter->stats.totl += er32(TOTL);
++	adapter->stats.toth += er32(TOTH);
++	adapter->stats.tpr += er32(TPR);
++
++	adapter->stats.ptc64 += er32(PTC64);
++	adapter->stats.ptc127 += er32(PTC127);
++	adapter->stats.ptc255 += er32(PTC255);
++	adapter->stats.ptc511 += er32(PTC511);
++	adapter->stats.ptc1023 += er32(PTC1023);
++	adapter->stats.ptc1522 += er32(PTC1522);
++
++	adapter->stats.mptc += er32(MPTC);
++	adapter->stats.bptc += er32(BPTC);
++
++	/* used for adaptive IFS */
++
++	hw->tx_packet_delta = er32(TPT);
++	adapter->stats.tpt += hw->tx_packet_delta;
++	hw->collision_delta = er32(COLC);
++	adapter->stats.colc += hw->collision_delta;
++
++	if (hw->mac_type >= e1000_82543) {
++		adapter->stats.algnerrc += er32(ALGNERRC);
++		adapter->stats.rxerrc += er32(RXERRC);
++		adapter->stats.tncrs += er32(TNCRS);
++		adapter->stats.cexterr += er32(CEXTERR);
++		adapter->stats.tsctc += er32(TSCTC);
++		adapter->stats.tsctfc += er32(TSCTFC);
++	}
++
++	/* Fill out the OS statistics structure */
++	netdev->stats.multicast = adapter->stats.mprc;
++	netdev->stats.collisions = adapter->stats.colc;
++
++	/* Rx Errors */
++
++	/* RLEC on some newer hardware can be incorrect so build
++	* our own version based on RUC and ROC */
++	netdev->stats.rx_errors = adapter->stats.rxerrc +
++		adapter->stats.crcerrs + adapter->stats.algnerrc +
++		adapter->stats.ruc + adapter->stats.roc +
++		adapter->stats.cexterr;
++	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
++	netdev->stats.rx_length_errors = adapter->stats.rlerrc;
++	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
++	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
++	netdev->stats.rx_missed_errors = adapter->stats.mpc;
++
++	/* Tx Errors */
++	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
++	netdev->stats.tx_errors = adapter->stats.txerrc;
++	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
++	netdev->stats.tx_window_errors = adapter->stats.latecol;
++	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
++	if (hw->bad_tx_carr_stats_fd &&
++	    adapter->link_duplex == FULL_DUPLEX) {
++		netdev->stats.tx_carrier_errors = 0;
++		adapter->stats.tncrs = 0;
++	}
++
++	/* Tx Dropped needs to be maintained elsewhere */
++
++	/* Phy Stats */
++	if (hw->media_type == e1000_media_type_copper) {
++		if ((adapter->link_speed == SPEED_1000) &&
++		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
++			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
++			adapter->phy_stats.idle_errors += phy_tmp;
++		}
++
++		if ((hw->mac_type <= e1000_82546) &&
++		   (hw->phy_type == e1000_phy_m88) &&
++		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
++			adapter->phy_stats.receive_errors += phy_tmp;
++	}
++
++	/* Management Stats */
++	if (hw->has_smbus) {
++		adapter->stats.mgptc += er32(MGTPTC);
++		adapter->stats.mgprc += er32(MGTPRC);
++		adapter->stats.mgpdc += er32(MGTPDC);
++	}
++
++	spin_unlock_irqrestore(&adapter->stats_lock, flags);
++}
++
++/**
++ * e1000_intr - Interrupt Handler
++ * @irq: interrupt number
++ * @data: pointer to a network interface device structure
++ **/
++
++static irqreturn_t e1000_intr(int irq, void *data)
++{
++	struct net_device *netdev = data;
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	u32 icr = er32(ICR);
++
++	if (unlikely((!icr) || test_bit(__E1000_DOWN, &adapter->flags)))
++		return IRQ_NONE;  /* Not our interrupt */
++
++	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
++		hw->get_link_status = 1;
++		/* guard against interrupt when we're going down */
++		if (!test_bit(__E1000_DOWN, &adapter->flags))
++			mod_timer(&adapter->watchdog_timer, jiffies + 1);
++	}
++
++	/* disable interrupts, without the synchronize_irq bit */
++	ew32(IMC, ~0);
++	E1000_WRITE_FLUSH();
++
++	if (likely(napi_schedule_prep(&adapter->napi))) {
++		adapter->total_tx_bytes = 0;
++		adapter->total_tx_packets = 0;
++		adapter->total_rx_bytes = 0;
++		adapter->total_rx_packets = 0;
++		__napi_schedule(&adapter->napi);
++	} else {
++		/* this really should not happen! if it does it is basically a
++		 * bug, but not a hard error, so enable ints and continue */
++		if (!test_bit(__E1000_DOWN, &adapter->flags))
++			e1000_irq_enable(adapter);
++	}
++
++	return IRQ_HANDLED;
++}
++
++/**
++ * e1000_clean - NAPI Rx polling callback
++ * @adapter: board private structure
++ **/
++static int e1000_clean(struct napi_struct *napi, int budget)
++{
++	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
++	int tx_clean_complete = 0, work_done = 0;
++
++	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
++
++	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
++
++	if (!tx_clean_complete)
++		work_done = budget;
++
++	/* If budget not fully consumed, exit the polling mode */
++	if (work_done < budget) {
++		if (likely(adapter->itr_setting & 3))
++			e1000_set_itr(adapter);
++		napi_complete(napi);
++		if (!test_bit(__E1000_DOWN, &adapter->flags))
++			e1000_irq_enable(adapter);
++	}
++
++	return work_done;
++}
++
++/**
++ * e1000_clean_tx_irq - Reclaim resources after transmit completes
++ * @adapter: board private structure
++ **/
++static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
++			       struct e1000_tx_ring *tx_ring)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct net_device *netdev = adapter->netdev;
++	struct e1000_tx_desc *tx_desc, *eop_desc;
++	struct e1000_buffer *buffer_info;
++	unsigned int i, eop;
++	unsigned int count = 0;
++	unsigned int total_tx_bytes=0, total_tx_packets=0;
++
++	i = tx_ring->next_to_clean;
++	eop = tx_ring->buffer_info[i].next_to_watch;
++	eop_desc = E1000_TX_DESC(*tx_ring, eop);
++
++	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
++	       (count < tx_ring->count)) {
++		bool cleaned = false;
++		rmb();	/* read buffer_info after eop_desc */
++		for ( ; !cleaned; count++) {
++			tx_desc = E1000_TX_DESC(*tx_ring, i);
++			buffer_info = &tx_ring->buffer_info[i];
++			cleaned = (i == eop);
++
++			if (cleaned) {
++				struct sk_buff *skb = buffer_info->skb;
++				unsigned int segs, bytecount;
++				segs = skb_shinfo(skb)->gso_segs ?: 1;
++				/* multiply data chunks by size of headers */
++				bytecount = ((segs - 1) * skb_headlen(skb)) +
++				            skb->len;
++				total_tx_packets += segs;
++				total_tx_bytes += bytecount;
++			}
++			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
++			tx_desc->upper.data = 0;
++
++			if (unlikely(++i == tx_ring->count)) i = 0;
++		}
++
++		eop = tx_ring->buffer_info[i].next_to_watch;
++		eop_desc = E1000_TX_DESC(*tx_ring, eop);
++	}
++
++	tx_ring->next_to_clean = i;
++
++#define TX_WAKE_THRESHOLD 32
++	if (unlikely(count && netif_carrier_ok(netdev) &&
++		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
++		/* Make sure that anybody stopping the queue after this
++		 * sees the new next_to_clean.
++		 */
++		smp_mb();
++
++		if (netif_queue_stopped(netdev) &&
++		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
++			netif_wake_queue(netdev);
++			++adapter->restart_queue;
++		}
++	}
++
++	if (adapter->detect_tx_hung) {
++		/* Detect a transmit hang in hardware, this serializes the
++		 * check with the clearing of time_stamp and movement of i */
++		adapter->detect_tx_hung = false;
++		if (tx_ring->buffer_info[eop].time_stamp &&
++		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
++		               (adapter->tx_timeout_factor * HZ)) &&
++		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
++
++			/* detected Tx unit hang */
++			e_err("Detected Tx Unit Hang\n"
++			      "  Tx Queue             <%lu>\n"
++			      "  TDH                  <%x>\n"
++			      "  TDT                  <%x>\n"
++			      "  next_to_use          <%x>\n"
++			      "  next_to_clean        <%x>\n"
++			      "buffer_info[next_to_clean]\n"
++			      "  time_stamp           <%lx>\n"
++			      "  next_to_watch        <%x>\n"
++			      "  jiffies              <%lx>\n"
++			      "  next_to_watch.status <%x>\n",
++				(unsigned long)((tx_ring - adapter->tx_ring) /
++					sizeof(struct e1000_tx_ring)),
++				readl(hw->hw_addr + tx_ring->tdh),
++				readl(hw->hw_addr + tx_ring->tdt),
++				tx_ring->next_to_use,
++				tx_ring->next_to_clean,
++				tx_ring->buffer_info[eop].time_stamp,
++				eop,
++				jiffies,
++				eop_desc->upper.fields.status);
++			netif_stop_queue(netdev);
++		}
++	}
++	adapter->total_tx_bytes += total_tx_bytes;
++	adapter->total_tx_packets += total_tx_packets;
++	netdev->stats.tx_bytes += total_tx_bytes;
++	netdev->stats.tx_packets += total_tx_packets;
++	return (count < tx_ring->count);
++}
++
++/**
++ * e1000_rx_checksum - Receive Checksum Offload for 82543
++ * @adapter:     board private structure
++ * @status_err:  receive descriptor status and error fields
++ * @csum:        receive descriptor csum field
++ * @sk_buff:     socket buffer with received data
++ **/
++
++static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
++			      u32 csum, struct sk_buff *skb)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	u16 status = (u16)status_err;
++	u8 errors = (u8)(status_err >> 24);
++	skb->ip_summed = CHECKSUM_NONE;
++
++	/* 82543 or newer only */
++	if (unlikely(hw->mac_type < e1000_82543)) return;
++	/* Ignore Checksum bit is set */
++	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
++	/* TCP/UDP checksum error bit is set */
++	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
++		/* let the stack verify checksum errors */
++		adapter->hw_csum_err++;
++		return;
++	}
++	/* TCP/UDP Checksum has not been calculated */
++	if (!(status & E1000_RXD_STAT_TCPCS))
++		return;
++
++	/* It must be a TCP or UDP packet with a valid checksum */
++	if (likely(status & E1000_RXD_STAT_TCPCS)) {
++		/* TCP checksum is good */
++		skb->ip_summed = CHECKSUM_UNNECESSARY;
++	}
++	adapter->hw_csum_good++;
++}
++
++/**
++ * e1000_consume_page - helper function
++ **/
++static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
++                               u16 length)
++{
++	bi->page = NULL;
++	skb->len += length;
++	skb->data_len += length;
++	skb->truesize += length;
++}
++
++/**
++ * e1000_receive_skb - helper function to handle rx indications
++ * @adapter: board private structure
++ * @status: descriptor status field as written by hardware
++ * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
++ * @skb: pointer to sk_buff to be indicated to stack
++ */
++static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
++			      __le16 vlan, struct sk_buff *skb)
++{
++	if (unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))) {
++		vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
++		                         le16_to_cpu(vlan) &
++		                         E1000_RXD_SPC_VLAN_MASK);
++	} else {
++		netif_receive_skb(skb);
++	}
++}
++
++/**
++ * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
++ * @adapter: board private structure
++ * @rx_ring: ring to clean
++ * @work_done: amount of napi work completed this call
++ * @work_to_do: max amount of work allowed for this call to do
++ *
++ * the return value indicates whether actual cleaning was done, there
++ * is no guarantee that everything was cleaned
++ */
++static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
++				     struct e1000_rx_ring *rx_ring,
++				     int *work_done, int work_to_do)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct net_device *netdev = adapter->netdev;
++	struct pci_dev *pdev = adapter->pdev;
++	struct e1000_rx_desc *rx_desc, *next_rxd;
++	struct e1000_buffer *buffer_info, *next_buffer;
++	unsigned long irq_flags;
++	u32 length;
++	unsigned int i;
++	int cleaned_count = 0;
++	bool cleaned = false;
++	unsigned int total_rx_bytes=0, total_rx_packets=0;
++
++	i = rx_ring->next_to_clean;
++	rx_desc = E1000_RX_DESC(*rx_ring, i);
++	buffer_info = &rx_ring->buffer_info[i];
++
++	while (rx_desc->status & E1000_RXD_STAT_DD) {
++		struct sk_buff *skb;
++		u8 status;
++
++		if (*work_done >= work_to_do)
++			break;
++		(*work_done)++;
++		rmb(); /* read descriptor and rx_buffer_info after status DD */
++
++		status = rx_desc->status;
++		skb = buffer_info->skb;
++		buffer_info->skb = NULL;
++
++		if (++i == rx_ring->count) i = 0;
++		next_rxd = E1000_RX_DESC(*rx_ring, i);
++		prefetch(next_rxd);
++
++		next_buffer = &rx_ring->buffer_info[i];
++
++		cleaned = true;
++		cleaned_count++;
++		dma_unmap_page(&pdev->dev, buffer_info->dma,
++			       buffer_info->length, DMA_FROM_DEVICE);
++		buffer_info->dma = 0;
++
++		length = le16_to_cpu(rx_desc->length);
++
++		/* errors is only valid for DD + EOP descriptors */
++		if (unlikely((status & E1000_RXD_STAT_EOP) &&
++		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
++			u8 last_byte = *(skb->data + length - 1);
++			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
++				       last_byte)) {
++				spin_lock_irqsave(&adapter->stats_lock,
++				                  irq_flags);
++				e1000_tbi_adjust_stats(hw, &adapter->stats,
++				                       length, skb->data);
++				spin_unlock_irqrestore(&adapter->stats_lock,
++				                       irq_flags);
++				length--;
++			} else {
++				/* recycle both page and skb */
++				buffer_info->skb = skb;
++				/* an error means any chain goes out the window
++				 * too */
++				if (rx_ring->rx_skb_top)
++					dev_kfree_skb(rx_ring->rx_skb_top);
++				rx_ring->rx_skb_top = NULL;
++				goto next_desc;
++			}
++		}
++
++#define rxtop rx_ring->rx_skb_top
++		if (!(status & E1000_RXD_STAT_EOP)) {
++			/* this descriptor is only the beginning (or middle) */
++			if (!rxtop) {
++				/* this is the beginning of a chain */
++				rxtop = skb;
++				skb_fill_page_desc(rxtop, 0, buffer_info->page,
++				                   0, length);
++			} else {
++				/* this is the middle of a chain */
++				skb_fill_page_desc(rxtop,
++				    skb_shinfo(rxtop)->nr_frags,
++				    buffer_info->page, 0, length);
++				/* re-use the skb, only consumed the page */
++				buffer_info->skb = skb;
++			}
++			e1000_consume_page(buffer_info, rxtop, length);
++			goto next_desc;
++		} else {
++			if (rxtop) {
++				/* end of the chain */
++				skb_fill_page_desc(rxtop,
++				    skb_shinfo(rxtop)->nr_frags,
++				    buffer_info->page, 0, length);
++				/* re-use the current skb, we only consumed the
++				 * page */
++				buffer_info->skb = skb;
++				skb = rxtop;
++				rxtop = NULL;
++				e1000_consume_page(buffer_info, skb, length);
++			} else {
++				/* no chain, got EOP, this buf is the packet
++				 * copybreak to save the put_page/alloc_page */
++				if (length <= copybreak &&
++				    skb_tailroom(skb) >= length) {
++					u8 *vaddr;
++					vaddr = kmap_atomic(buffer_info->page,
++					                    KM_SKB_DATA_SOFTIRQ);
++					memcpy(skb_tail_pointer(skb), vaddr, length);
++					kunmap_atomic(vaddr,
++					              KM_SKB_DATA_SOFTIRQ);
++					/* re-use the page, so don't erase
++					 * buffer_info->page */
++					skb_put(skb, length);
++				} else {
++					skb_fill_page_desc(skb, 0,
++					                   buffer_info->page, 0,
++				                           length);
++					e1000_consume_page(buffer_info, skb,
++					                   length);
++				}
++			}
++		}
++
++		/* Receive Checksum Offload XXX recompute due to CRC strip? */
++		e1000_rx_checksum(adapter,
++		                  (u32)(status) |
++		                  ((u32)(rx_desc->errors) << 24),
++		                  le16_to_cpu(rx_desc->csum), skb);
++
++		pskb_trim(skb, skb->len - 4);
++
++		/* probably a little skewed due to removing CRC */
++		total_rx_bytes += skb->len;
++		total_rx_packets++;
++
++		/* eth type trans needs skb->data to point to something */
++		if (!pskb_may_pull(skb, ETH_HLEN)) {
++			e_err("pskb_may_pull failed.\n");
++			dev_kfree_skb(skb);
++			goto next_desc;
++		}
++
++		skb->protocol = eth_type_trans(skb, netdev);
++
++		e1000_receive_skb(adapter, status, rx_desc->special, skb);
++
++next_desc:
++		rx_desc->status = 0;
++
++		/* return some buffers to hardware, one at a time is too slow */
++		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
++			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
++			cleaned_count = 0;
++		}
++
++		/* use prefetched values */
++		rx_desc = next_rxd;
++		buffer_info = next_buffer;
++	}
++	rx_ring->next_to_clean = i;
++
++	cleaned_count = E1000_DESC_UNUSED(rx_ring);
++	if (cleaned_count)
++		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
++
++	adapter->total_rx_packets += total_rx_packets;
++	adapter->total_rx_bytes += total_rx_bytes;
++	netdev->stats.rx_bytes += total_rx_bytes;
++	netdev->stats.rx_packets += total_rx_packets;
++	return cleaned;
++}
++
++/*
++ * this should improve performance for small packets with large amounts
++ * of reassembly being done in the stack
++ */
++static void e1000_check_copybreak(struct net_device *netdev,
++				 struct e1000_buffer *buffer_info,
++				 u32 length, struct sk_buff **skb)
++{
++	struct sk_buff *new_skb;
++
++	if (length > copybreak)
++		return;
++
++	new_skb = netdev_alloc_skb_ip_align(netdev, length);
++	if (!new_skb)
++		return;
++
++	skb_copy_to_linear_data_offset(new_skb, -NET_IP_ALIGN,
++				       (*skb)->data - NET_IP_ALIGN,
++				       length + NET_IP_ALIGN);
++	/* save the skb in buffer_info as good */
++	buffer_info->skb = *skb;
++	*skb = new_skb;
++}
++
++/**
++ * e1000_clean_rx_irq - Send received data up the network stack; legacy
++ * @adapter: board private structure
++ * @rx_ring: ring to clean
++ * @work_done: amount of napi work completed this call
++ * @work_to_do: max amount of work allowed for this call to do
++ */
++static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
++			       struct e1000_rx_ring *rx_ring,
++			       int *work_done, int work_to_do)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct net_device *netdev = adapter->netdev;
++	struct pci_dev *pdev = adapter->pdev;
++	struct e1000_rx_desc *rx_desc, *next_rxd;
++	struct e1000_buffer *buffer_info, *next_buffer;
++	unsigned long flags;
++	u32 length;
++	unsigned int i;
++	int cleaned_count = 0;
++	bool cleaned = false;
++	unsigned int total_rx_bytes=0, total_rx_packets=0;
++
++	i = rx_ring->next_to_clean;
++	rx_desc = E1000_RX_DESC(*rx_ring, i);
++	buffer_info = &rx_ring->buffer_info[i];
++
++	while (rx_desc->status & E1000_RXD_STAT_DD) {
++		struct sk_buff *skb;
++		u8 status;
++
++		if (*work_done >= work_to_do)
++			break;
++		(*work_done)++;
++		rmb(); /* read descriptor and rx_buffer_info after status DD */
++
++		status = rx_desc->status;
++		skb = buffer_info->skb;
++		buffer_info->skb = NULL;
++
++		prefetch(skb->data - NET_IP_ALIGN);
++
++		if (++i == rx_ring->count) i = 0;
++		next_rxd = E1000_RX_DESC(*rx_ring, i);
++		prefetch(next_rxd);
++
++		next_buffer = &rx_ring->buffer_info[i];
++
++		cleaned = true;
++		cleaned_count++;
++		dma_unmap_single(&pdev->dev, buffer_info->dma,
++				 buffer_info->length, DMA_FROM_DEVICE);
++		buffer_info->dma = 0;
++
++		length = le16_to_cpu(rx_desc->length);
++		/* !EOP means multiple descriptors were used to store a single
++		 * packet, if thats the case we need to toss it.  In fact, we
++		 * to toss every packet with the EOP bit clear and the next
++		 * frame that _does_ have the EOP bit set, as it is by
++		 * definition only a frame fragment
++		 */
++		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
++			adapter->discarding = true;
++
++		if (adapter->discarding) {
++			/* All receives must fit into a single buffer */
++			e_info("Receive packet consumed multiple buffers\n");
++			/* recycle */
++			buffer_info->skb = skb;
++			if (status & E1000_RXD_STAT_EOP)
++				adapter->discarding = false;
++			goto next_desc;
++		}
++
++		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
++			u8 last_byte = *(skb->data + length - 1);
++			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
++				       last_byte)) {
++				spin_lock_irqsave(&adapter->stats_lock, flags);
++				e1000_tbi_adjust_stats(hw, &adapter->stats,
++				                       length, skb->data);
++				spin_unlock_irqrestore(&adapter->stats_lock,
++				                       flags);
++				length--;
++			} else {
++				/* recycle */
++				buffer_info->skb = skb;
++				goto next_desc;
++			}
++		}
++
++		/* adjust length to remove Ethernet CRC, this must be
++		 * done after the TBI_ACCEPT workaround above */
++		length -= 4;
++
++		/* probably a little skewed due to removing CRC */
++		total_rx_bytes += length;
++		total_rx_packets++;
++
++		e1000_check_copybreak(netdev, buffer_info, length, &skb);
++
++		skb_put(skb, length);
++
++		/* Receive Checksum Offload */
++		e1000_rx_checksum(adapter,
++				  (u32)(status) |
++				  ((u32)(rx_desc->errors) << 24),
++				  le16_to_cpu(rx_desc->csum), skb);
++
++		skb->protocol = eth_type_trans(skb, netdev);
++
++		e1000_receive_skb(adapter, status, rx_desc->special, skb);
++
++next_desc:
++		rx_desc->status = 0;
++
++		/* return some buffers to hardware, one at a time is too slow */
++		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
++			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
++			cleaned_count = 0;
++		}
++
++		/* use prefetched values */
++		rx_desc = next_rxd;
++		buffer_info = next_buffer;
++	}
++	rx_ring->next_to_clean = i;
++
++	cleaned_count = E1000_DESC_UNUSED(rx_ring);
++	if (cleaned_count)
++		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
++
++	adapter->total_rx_packets += total_rx_packets;
++	adapter->total_rx_bytes += total_rx_bytes;
++	netdev->stats.rx_bytes += total_rx_bytes;
++	netdev->stats.rx_packets += total_rx_packets;
++	return cleaned;
++}
++
++/**
++ * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
++ * @adapter: address of board private structure
++ * @rx_ring: pointer to receive ring structure
++ * @cleaned_count: number of buffers to allocate this pass
++ **/
++
++static void
++e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
++                             struct e1000_rx_ring *rx_ring, int cleaned_count)
++{
++	struct net_device *netdev = adapter->netdev;
++	struct pci_dev *pdev = adapter->pdev;
++	struct e1000_rx_desc *rx_desc;
++	struct e1000_buffer *buffer_info;
++	struct sk_buff *skb;
++	unsigned int i;
++	unsigned int bufsz = 256 - 16 /*for skb_reserve */ ;
++
++	i = rx_ring->next_to_use;
++	buffer_info = &rx_ring->buffer_info[i];
++
++	while (cleaned_count--) {
++		skb = buffer_info->skb;
++		if (skb) {
++			skb_trim(skb, 0);
++			goto check_page;
++		}
++
++		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
++		if (unlikely(!skb)) {
++			/* Better luck next round */
++			adapter->alloc_rx_buff_failed++;
++			break;
++		}
++
++		/* Fix for errata 23, can't cross 64kB boundary */
++		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
++			struct sk_buff *oldskb = skb;
++			e_err("skb align check failed: %u bytes at %p\n",
++			      bufsz, skb->data);
++			/* Try again, without freeing the previous */
++			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
++			/* Failed allocation, critical failure */
++			if (!skb) {
++				dev_kfree_skb(oldskb);
++				adapter->alloc_rx_buff_failed++;
++				break;
++			}
++
++			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
++				/* give up */
++				dev_kfree_skb(skb);
++				dev_kfree_skb(oldskb);
++				break; /* while (cleaned_count--) */
++			}
++
++			/* Use new allocation */
++			dev_kfree_skb(oldskb);
++		}
++		buffer_info->skb = skb;
++		buffer_info->length = adapter->rx_buffer_len;
++check_page:
++		/* allocate a new page if necessary */
++		if (!buffer_info->page) {
++			buffer_info->page = alloc_page(GFP_ATOMIC);
++			if (unlikely(!buffer_info->page)) {
++				adapter->alloc_rx_buff_failed++;
++				break;
++			}
++		}
++
++		if (!buffer_info->dma) {
++			buffer_info->dma = dma_map_page(&pdev->dev,
++			                                buffer_info->page, 0,
++							buffer_info->length,
++							DMA_FROM_DEVICE);
++			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
++				put_page(buffer_info->page);
++				dev_kfree_skb(skb);
++				buffer_info->page = NULL;
++				buffer_info->skb = NULL;
++				buffer_info->dma = 0;
++				adapter->alloc_rx_buff_failed++;
++				break; /* while !buffer_info->skb */
++			}
++		}
++
++		rx_desc = E1000_RX_DESC(*rx_ring, i);
++		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
++
++		if (unlikely(++i == rx_ring->count))
++			i = 0;
++		buffer_info = &rx_ring->buffer_info[i];
++	}
++
++	if (likely(rx_ring->next_to_use != i)) {
++		rx_ring->next_to_use = i;
++		if (unlikely(i-- == 0))
++			i = (rx_ring->count - 1);
++
++		/* Force memory writes to complete before letting h/w
++		 * know there are new descriptors to fetch.  (Only
++		 * applicable for weak-ordered memory model archs,
++		 * such as IA-64). */
++		wmb();
++		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
++	}
++}
++
++/**
++ * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
++ * @adapter: address of board private structure
++ **/
++
++static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
++				   struct e1000_rx_ring *rx_ring,
++				   int cleaned_count)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	struct net_device *netdev = adapter->netdev;
++	struct pci_dev *pdev = adapter->pdev;
++	struct e1000_rx_desc *rx_desc;
++	struct e1000_buffer *buffer_info;
++	struct sk_buff *skb;
++	unsigned int i;
++	unsigned int bufsz = adapter->rx_buffer_len;
++
++	i = rx_ring->next_to_use;
++	buffer_info = &rx_ring->buffer_info[i];
++
++	while (cleaned_count--) {
++		skb = buffer_info->skb;
++		if (skb) {
++			skb_trim(skb, 0);
++			goto map_skb;
++		}
++
++		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
++		if (unlikely(!skb)) {
++			/* Better luck next round */
++			adapter->alloc_rx_buff_failed++;
++			break;
++		}
++
++		/* Fix for errata 23, can't cross 64kB boundary */
++		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
++			struct sk_buff *oldskb = skb;
++			e_err("skb align check failed: %u bytes at %p\n",
++			      bufsz, skb->data);
++			/* Try again, without freeing the previous */
++			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
++			/* Failed allocation, critical failure */
++			if (!skb) {
++				dev_kfree_skb(oldskb);
++				adapter->alloc_rx_buff_failed++;
++				break;
++			}
++
++			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
++				/* give up */
++				dev_kfree_skb(skb);
++				dev_kfree_skb(oldskb);
++				adapter->alloc_rx_buff_failed++;
++				break; /* while !buffer_info->skb */
++			}
++
++			/* Use new allocation */
++			dev_kfree_skb(oldskb);
++		}
++		buffer_info->skb = skb;
++		buffer_info->length = adapter->rx_buffer_len;
++map_skb:
++		buffer_info->dma = dma_map_single(&pdev->dev,
++						  skb->data,
++						  buffer_info->length,
++						  DMA_FROM_DEVICE);
++		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
++			dev_kfree_skb(skb);
++			buffer_info->skb = NULL;
++			buffer_info->dma = 0;
++			adapter->alloc_rx_buff_failed++;
++			break; /* while !buffer_info->skb */
++		}
++
++		/*
++		 * XXX if it was allocated cleanly it will never map to a
++		 * boundary crossing
++		 */
++
++		/* Fix for errata 23, can't cross 64kB boundary */
++		if (!e1000_check_64k_bound(adapter,
++					(void *)(unsigned long)buffer_info->dma,
++					adapter->rx_buffer_len)) {
++			e_err("dma align check failed: %u bytes at %p\n",
++			      adapter->rx_buffer_len,
++			      (void *)(unsigned long)buffer_info->dma);
++			dev_kfree_skb(skb);
++			buffer_info->skb = NULL;
++
++			dma_unmap_single(&pdev->dev, buffer_info->dma,
++					 adapter->rx_buffer_len,
++					 DMA_FROM_DEVICE);
++			buffer_info->dma = 0;
++
++			adapter->alloc_rx_buff_failed++;
++			break; /* while !buffer_info->skb */
++		}
++		rx_desc = E1000_RX_DESC(*rx_ring, i);
++		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
++
++		if (unlikely(++i == rx_ring->count))
++			i = 0;
++		buffer_info = &rx_ring->buffer_info[i];
++	}
++
++	if (likely(rx_ring->next_to_use != i)) {
++		rx_ring->next_to_use = i;
++		if (unlikely(i-- == 0))
++			i = (rx_ring->count - 1);
++
++		/* Force memory writes to complete before letting h/w
++		 * know there are new descriptors to fetch.  (Only
++		 * applicable for weak-ordered memory model archs,
++		 * such as IA-64). */
++		wmb();
++		writel(i, hw->hw_addr + rx_ring->rdt);
++	}
++}
++
++/**
++ * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
++ * @adapter:
++ **/
++
++static void e1000_smartspeed(struct e1000_adapter *adapter)
++{
++	struct e1000_hw *hw = &adapter->hw;
++	u16 phy_status;
++	u16 phy_ctrl;
++
++	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
++	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
++		return;
++
++	if (adapter->smartspeed == 0) {
++		/* If Master/Slave config fault is asserted twice,
++		 * we assume back-to-back */
++		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
++		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
++		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
++		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
++		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
++		if (phy_ctrl & CR_1000T_MS_ENABLE) {
++			phy_ctrl &= ~CR_1000T_MS_ENABLE;
++			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
++					    phy_ctrl);
++			adapter->smartspeed++;
++			if (!e1000_phy_setup_autoneg(hw) &&
++			   !e1000_read_phy_reg(hw, PHY_CTRL,
++				   	       &phy_ctrl)) {
++				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
++					     MII_CR_RESTART_AUTO_NEG);
++				e1000_write_phy_reg(hw, PHY_CTRL,
++						    phy_ctrl);
++			}
++		}
++		return;
++	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
++		/* If still no link, perhaps using 2/3 pair cable */
++		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
++		phy_ctrl |= CR_1000T_MS_ENABLE;
++		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
++		if (!e1000_phy_setup_autoneg(hw) &&
++		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
++			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
++				     MII_CR_RESTART_AUTO_NEG);
++			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
++		}
++	}
++	/* Restart process after E1000_SMARTSPEED_MAX iterations */
++	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
++		adapter->smartspeed = 0;
++}
++
++/**
++ * e1000_ioctl -
++ * @netdev:
++ * @ifreq:
++ * @cmd:
++ **/
++
++static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
++{
++	switch (cmd) {
++	case SIOCGMIIPHY:
++	case SIOCGMIIREG:
++	case SIOCSMIIREG:
++		return e1000_mii_ioctl(netdev, ifr, cmd);
++	default:
++		return -EOPNOTSUPP;
++	}
++}
++
++/**
++ * e1000_mii_ioctl -
++ * @netdev:
++ * @ifreq:
++ * @cmd:
++ **/
++
++static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
++			   int cmd)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	struct mii_ioctl_data *data = if_mii(ifr);
++	int retval;
++	u16 mii_reg;
++	u16 spddplx;
++	unsigned long flags;
++
++	if (hw->media_type != e1000_media_type_copper)
++		return -EOPNOTSUPP;
++
++	switch (cmd) {
++	case SIOCGMIIPHY:
++		data->phy_id = hw->phy_addr;
++		break;
++	case SIOCGMIIREG:
++		spin_lock_irqsave(&adapter->stats_lock, flags);
++		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
++				   &data->val_out)) {
++			spin_unlock_irqrestore(&adapter->stats_lock, flags);
++			return -EIO;
++		}
++		spin_unlock_irqrestore(&adapter->stats_lock, flags);
++		break;
++	case SIOCSMIIREG:
++		if (data->reg_num & ~(0x1F))
++			return -EFAULT;
++		mii_reg = data->val_in;
++		spin_lock_irqsave(&adapter->stats_lock, flags);
++		if (e1000_write_phy_reg(hw, data->reg_num,
++					mii_reg)) {
++			spin_unlock_irqrestore(&adapter->stats_lock, flags);
++			return -EIO;
++		}
++		spin_unlock_irqrestore(&adapter->stats_lock, flags);
++		if (hw->media_type == e1000_media_type_copper) {
++			switch (data->reg_num) {
++			case PHY_CTRL:
++				if (mii_reg & MII_CR_POWER_DOWN)
++					break;
++				if (mii_reg & MII_CR_AUTO_NEG_EN) {
++					hw->autoneg = 1;
++					hw->autoneg_advertised = 0x2F;
++				} else {
++					if (mii_reg & 0x40)
++						spddplx = SPEED_1000;
++					else if (mii_reg & 0x2000)
++						spddplx = SPEED_100;
++					else
++						spddplx = SPEED_10;
++					spddplx += (mii_reg & 0x100)
++						   ? DUPLEX_FULL :
++						   DUPLEX_HALF;
++					retval = e1000_set_spd_dplx(adapter,
++								    spddplx);
++					if (retval)
++						return retval;
++				}
++				if (netif_running(adapter->netdev))
++					e1000_reinit_locked(adapter);
++				else
++					e1000_reset(adapter);
++				break;
++			case M88E1000_PHY_SPEC_CTRL:
++			case M88E1000_EXT_PHY_SPEC_CTRL:
++				if (e1000_phy_reset(hw))
++					return -EIO;
++				break;
++			}
++		} else {
++			switch (data->reg_num) {
++			case PHY_CTRL:
++				if (mii_reg & MII_CR_POWER_DOWN)
++					break;
++				if (netif_running(adapter->netdev))
++					e1000_reinit_locked(adapter);
++				else
++					e1000_reset(adapter);
++				break;
++			}
++		}
++		break;
++	default:
++		return -EOPNOTSUPP;
++	}
++	return E1000_SUCCESS;
++}
++
++void e1000_pci_set_mwi(struct e1000_hw *hw)
++{
++	struct e1000_adapter *adapter = hw->back;
++	int ret_val = pci_set_mwi(adapter->pdev);
++
++	if (ret_val)
++		e_err("Error in setting MWI\n");
++}
++
++void e1000_pci_clear_mwi(struct e1000_hw *hw)
++{
++	struct e1000_adapter *adapter = hw->back;
++
++	pci_clear_mwi(adapter->pdev);
++}
++
++int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
++{
++	struct e1000_adapter *adapter = hw->back;
++	return pcix_get_mmrbc(adapter->pdev);
++}
++
++void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
++{
++	struct e1000_adapter *adapter = hw->back;
++	pcix_set_mmrbc(adapter->pdev, mmrbc);
++}
++
++void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
++{
++	outl(value, port);
++}
++
++static void e1000_vlan_rx_register(struct net_device *netdev,
++				   struct vlan_group *grp)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	u32 ctrl, rctl;
++
++	if (!test_bit(__E1000_DOWN, &adapter->flags))
++		e1000_irq_disable(adapter);
++	adapter->vlgrp = grp;
++
++	if (grp) {
++		/* enable VLAN tag insert/strip */
++		ctrl = er32(CTRL);
++		ctrl |= E1000_CTRL_VME;
++		ew32(CTRL, ctrl);
++
++		/* enable VLAN receive filtering */
++		rctl = er32(RCTL);
++		rctl &= ~E1000_RCTL_CFIEN;
++		if (!(netdev->flags & IFF_PROMISC))
++			rctl |= E1000_RCTL_VFE;
++		ew32(RCTL, rctl);
++		e1000_update_mng_vlan(adapter);
++	} else {
++		/* disable VLAN tag insert/strip */
++		ctrl = er32(CTRL);
++		ctrl &= ~E1000_CTRL_VME;
++		ew32(CTRL, ctrl);
++
++		/* disable VLAN receive filtering */
++		rctl = er32(RCTL);
++		rctl &= ~E1000_RCTL_VFE;
++		ew32(RCTL, rctl);
++
++		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
++			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
++			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
++		}
++	}
++
++	if (!test_bit(__E1000_DOWN, &adapter->flags))
++		e1000_irq_enable(adapter);
++}
++
++static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	u32 vfta, index;
++
++	if ((hw->mng_cookie.status &
++	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
++	    (vid == adapter->mng_vlan_id))
++		return;
++	/* add VID to filter table */
++	index = (vid >> 5) & 0x7F;
++	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
++	vfta |= (1 << (vid & 0x1F));
++	e1000_write_vfta(hw, index, vfta);
++}
++
++static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	u32 vfta, index;
++
++	if (!test_bit(__E1000_DOWN, &adapter->flags))
++		e1000_irq_disable(adapter);
++	vlan_group_set_device(adapter->vlgrp, vid, NULL);
++	if (!test_bit(__E1000_DOWN, &adapter->flags))
++		e1000_irq_enable(adapter);
++
++	/* remove VID from filter table */
++	index = (vid >> 5) & 0x7F;
++	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
++	vfta &= ~(1 << (vid & 0x1F));
++	e1000_write_vfta(hw, index, vfta);
++}
++
++static void e1000_restore_vlan(struct e1000_adapter *adapter)
++{
++	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
++
++	if (adapter->vlgrp) {
++		u16 vid;
++		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
++			if (!vlan_group_get_device(adapter->vlgrp, vid))
++				continue;
++			e1000_vlan_rx_add_vid(adapter->netdev, vid);
++		}
++	}
++}
++
++int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
++{
++	struct e1000_hw *hw = &adapter->hw;
++
++	hw->autoneg = 0;
++
++	/* Fiber NICs only allow 1000 gbps Full duplex */
++	if ((hw->media_type == e1000_media_type_fiber) &&
++		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
++		e_err("Unsupported Speed/Duplex configuration\n");
++		return -EINVAL;
++	}
++
++	switch (spddplx) {
++	case SPEED_10 + DUPLEX_HALF:
++		hw->forced_speed_duplex = e1000_10_half;
++		break;
++	case SPEED_10 + DUPLEX_FULL:
++		hw->forced_speed_duplex = e1000_10_full;
++		break;
++	case SPEED_100 + DUPLEX_HALF:
++		hw->forced_speed_duplex = e1000_100_half;
++		break;
++	case SPEED_100 + DUPLEX_FULL:
++		hw->forced_speed_duplex = e1000_100_full;
++		break;
++	case SPEED_1000 + DUPLEX_FULL:
++		hw->autoneg = 1;
++		hw->autoneg_advertised = ADVERTISE_1000_FULL;
++		break;
++	case SPEED_1000 + DUPLEX_HALF: /* not supported */
++	default:
++		e_err("Unsupported Speed/Duplex configuration\n");
++		return -EINVAL;
++	}
++	return 0;
++}
++
++static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
++{
++	struct net_device *netdev = pci_get_drvdata(pdev);
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	u32 ctrl, ctrl_ext, rctl, status;
++	u32 wufc = adapter->wol;
++#ifdef CONFIG_PM
++	int retval = 0;
++#endif
++
++	netif_device_detach(netdev);
++
++	if (netif_running(netdev)) {
++		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
++		e1000_down(adapter);
++	}
++
++#ifdef CONFIG_PM
++	retval = pci_save_state(pdev);
++	if (retval)
++		return retval;
++#endif
++
++	status = er32(STATUS);
++	if (status & E1000_STATUS_LU)
++		wufc &= ~E1000_WUFC_LNKC;
++
++	if (wufc) {
++		e1000_setup_rctl(adapter);
++		e1000_set_rx_mode(netdev);
++
++		/* turn on all-multi mode if wake on multicast is enabled */
++		if (wufc & E1000_WUFC_MC) {
++			rctl = er32(RCTL);
++			rctl |= E1000_RCTL_MPE;
++			ew32(RCTL, rctl);
++		}
++
++		if (hw->mac_type >= e1000_82540) {
++			ctrl = er32(CTRL);
++			/* advertise wake from D3Cold */
++			#define E1000_CTRL_ADVD3WUC 0x00100000
++			/* phy power management enable */
++			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
++			ctrl |= E1000_CTRL_ADVD3WUC |
++				E1000_CTRL_EN_PHY_PWR_MGMT;
++			ew32(CTRL, ctrl);
++		}
++
++		if (hw->media_type == e1000_media_type_fiber ||
++		    hw->media_type == e1000_media_type_internal_serdes) {
++			/* keep the laser running in D3 */
++			ctrl_ext = er32(CTRL_EXT);
++			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
++			ew32(CTRL_EXT, ctrl_ext);
++		}
++
++		ew32(WUC, E1000_WUC_PME_EN);
++		ew32(WUFC, wufc);
++	} else {
++		ew32(WUC, 0);
++		ew32(WUFC, 0);
++	}
++
++	e1000_release_manageability(adapter);
++
++	*enable_wake = !!wufc;
++
++	/* make sure adapter isn't asleep if manageability is enabled */
++	if (adapter->en_mng_pt)
++		*enable_wake = true;
++
++	if (netif_running(netdev))
++		e1000_free_irq(adapter);
++
++	pci_disable_device(pdev);
++
++	return 0;
++}
++
++#ifdef CONFIG_PM
++static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
++{
++	int retval;
++	bool wake;
++
++	retval = __e1000_shutdown(pdev, &wake);
++	if (retval)
++		return retval;
++
++	if (wake) {
++		pci_prepare_to_sleep(pdev);
++	} else {
++		pci_wake_from_d3(pdev, false);
++		pci_set_power_state(pdev, PCI_D3hot);
++	}
++
++	return 0;
++}
++
++static int e1000_resume(struct pci_dev *pdev)
++{
++	struct net_device *netdev = pci_get_drvdata(pdev);
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	u32 err;
++
++	pci_set_power_state(pdev, PCI_D0);
++	pci_restore_state(pdev);
++	pci_save_state(pdev);
++
++	if (adapter->need_ioport)
++		err = pci_enable_device(pdev);
++	else
++		err = pci_enable_device_mem(pdev);
++	if (err) {
++		pr_err("Cannot enable PCI device from suspend\n");
++		return err;
++	}
++	pci_set_master(pdev);
++
++	pci_enable_wake(pdev, PCI_D3hot, 0);
++	pci_enable_wake(pdev, PCI_D3cold, 0);
++
++	if (netif_running(netdev)) {
++		err = e1000_request_irq(adapter);
++		if (err)
++			return err;
++	}
++
++	e1000_power_up_phy(adapter);
++	e1000_reset(adapter);
++	ew32(WUS, ~0);
++
++	e1000_init_manageability(adapter);
++
++	if (netif_running(netdev))
++		e1000_up(adapter);
++
++	netif_device_attach(netdev);
++
++	return 0;
++}
++#endif
++
++static void e1000_shutdown(struct pci_dev *pdev)
++{
++	bool wake;
++
++	__e1000_shutdown(pdev, &wake);
++
++	if (system_state == SYSTEM_POWER_OFF) {
++		pci_wake_from_d3(pdev, wake);
++		pci_set_power_state(pdev, PCI_D3hot);
++	}
++}
++
++#ifdef CONFIG_NET_POLL_CONTROLLER
++/*
++ * Polling 'interrupt' - used by things like netconsole to send skbs
++ * without having to re-enable interrupts. It's not called while
++ * the interrupt routine is executing.
++ */
++static void e1000_netpoll(struct net_device *netdev)
++{
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++
++	disable_irq(adapter->pdev->irq);
++	e1000_intr(adapter->pdev->irq, netdev);
++	enable_irq(adapter->pdev->irq);
++}
++#endif
++
++/**
++ * e1000_io_error_detected - called when PCI error is detected
++ * @pdev: Pointer to PCI device
++ * @state: The current pci connection state
++ *
++ * This function is called after a PCI bus error affecting
++ * this device has been detected.
++ */
++static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
++						pci_channel_state_t state)
++{
++	struct net_device *netdev = pci_get_drvdata(pdev);
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++
++	netif_device_detach(netdev);
++
++	if (state == pci_channel_io_perm_failure)
++		return PCI_ERS_RESULT_DISCONNECT;
++
++	if (netif_running(netdev))
++		e1000_down(adapter);
++	pci_disable_device(pdev);
++
++	/* Request a slot slot reset. */
++	return PCI_ERS_RESULT_NEED_RESET;
++}
++
++/**
++ * e1000_io_slot_reset - called after the pci bus has been reset.
++ * @pdev: Pointer to PCI device
++ *
++ * Restart the card from scratch, as if from a cold-boot. Implementation
++ * resembles the first-half of the e1000_resume routine.
++ */
++static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
++{
++	struct net_device *netdev = pci_get_drvdata(pdev);
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++	struct e1000_hw *hw = &adapter->hw;
++	int err;
++
++	if (adapter->need_ioport)
++		err = pci_enable_device(pdev);
++	else
++		err = pci_enable_device_mem(pdev);
++	if (err) {
++		pr_err("Cannot re-enable PCI device after reset.\n");
++		return PCI_ERS_RESULT_DISCONNECT;
++	}
++	pci_set_master(pdev);
++
++	pci_enable_wake(pdev, PCI_D3hot, 0);
++	pci_enable_wake(pdev, PCI_D3cold, 0);
++
++	e1000_reset(adapter);
++	ew32(WUS, ~0);
++
++	return PCI_ERS_RESULT_RECOVERED;
++}
++
++/**
++ * e1000_io_resume - called when traffic can start flowing again.
++ * @pdev: Pointer to PCI device
++ *
++ * This callback is called when the error recovery driver tells us that
++ * its OK to resume normal operation. Implementation resembles the
++ * second-half of the e1000_resume routine.
++ */
++static void e1000_io_resume(struct pci_dev *pdev)
++{
++	struct net_device *netdev = pci_get_drvdata(pdev);
++	struct e1000_adapter *adapter = netdev_priv(netdev);
++
++	e1000_init_manageability(adapter);
++
++	if (netif_running(netdev)) {
++		if (e1000_up(adapter)) {
++			pr_info("can't bring device back up after reset\n");
++			return;
++		}
++	}
++
++	netif_device_attach(netdev);
++}
++
++/* e1000_main.c */
+diff -rupN linux-2.6.35.11/drivers/net/fast_bridge.c linux-2.6.35.11-ts7500/drivers/net/fast_bridge.c
+--- linux-2.6.35.11/drivers/net/fast_bridge.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/fast_bridge.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,184 @@
++#include <linux/stddef.h>
++//#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <asm/byteorder.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <net/sock.h>
++#include <linux/rtnetlink.h>
++#include <linux/delay.h>
++#include <linux/timer.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/interrupt.h>
++#include <linux/string.h>
++#include <linux/pagemap.h>
++#include <linux/proc_fs.h>
++#include <asm/bitops.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <linux/capability.h>
++#include <linux/in.h>
++#include <linux/ip.h>
++#include <linux/tcp.h>
++#include <linux/udp.h>
++#include <net/pkt_sched.h>
++#include <linux/list.h>
++#include <linux/reboot.h>
++#ifdef NETIF_F_TSO
++#include <net/checksum.h>
++#endif
++#ifdef SIOCGMIIPHY
++#include <linux/mii.h>
++#endif
++#ifdef SIOCETHTOOL
++#include <linux/ethtool.h>
++#endif
++#ifdef NETIF_F_HW_VLAN_TX
++#include <linux/if_vlan.h>
++#endif
++
++static struct net_device *fast_bridge_dev1;
++static struct net_device *fast_bridge_dev2;
++static int fast_bridge_dev1_ready;
++static int fast_bridge_dev2_ready;
++
++static struct proc_dir_entry *fast_bridge_proc_entry;
++int fast_bridge_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data);
++int fast_bridge_write_proc(struct file *file, const char *buffer, unsigned long count, void *data);
++
++#ifdef CONFIG_CPU_ISPAD_ENABLE
++__attribute__((section(".ispad"))) \
++int fast_bridge_forward_skb(struct sk_buff *skb)
++#else
++int fast_bridge_forward_skb(struct sk_buff *skb)
++#endif
++{
++#if 0
++	skb->h.raw = skb->nh.raw = skb->data;
++	skb->mac_len = skb->nh.raw - skb->mac.raw;
++#endif
++
++	if (!fast_bridge_dev1_ready || !fast_bridge_dev2_ready) {
++#if 0
++		kfree_skb(skb);
++#endif
++		return -1;
++	}
++
++	if (skb->dev != fast_bridge_dev1 && skb->dev != fast_bridge_dev2) {
++		return -1;
++	}
++
++	if (skb->dev == fast_bridge_dev1) {
++		skb->dev = fast_bridge_dev2;
++	} else if (skb->dev == fast_bridge_dev2) {
++		skb->dev = fast_bridge_dev1;
++	}
++	skb->ip_summed = CHECKSUM_NONE;
++	skb_push(skb, ETH_HLEN);
++#if 1
++	dev_queue_xmit(skb);
++#else
++   // not in 2.6.34!!!
++	skb->dev->hard_start_xmit(skb, skb->dev);
++#endif
++
++	return 0;
++}
++
++int fast_bridge_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
++{
++	return 0;
++}
++
++int fast_bridge_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
++{
++	char *str;
++	char *dev1;
++	char *dev2;
++
++	if (count > 0) {
++		str = (char *)buffer;
++		dev1 = strsep(&str, "\t \n");
++		if (!dev1) goto out;
++		dev2 = strsep(&str, "\t \n");
++		if (!dev2) goto out;
++		/* scott.nic
++		fast_bridge_dev1 = dev_get_by_name(dev1);
++		*/
++		fast_bridge_dev1 = dev_get_by_name(&init_net, dev1);
++		if (!fast_bridge_dev1) goto out;
++
++		/* scott.nic
++		fast_bridge_dev2 = dev_get_by_name(dev2);
++		*/
++		fast_bridge_dev2 = dev_get_by_name(&init_net, dev2);
++		if (!fast_bridge_dev2) {
++			dev_put(fast_bridge_dev1);
++			goto out;
++		}
++		/* scott.nic
++		rtnl_shlock();
++		*/
++		if (!(fast_bridge_dev1->flags & IFF_UP)) {
++			dev_open(fast_bridge_dev1);
++		}
++		if (!(fast_bridge_dev2->flags & IFF_UP)) {
++			dev_open(fast_bridge_dev2);
++		}
++		if (!(fast_bridge_dev1->flags & IFF_PROMISC)) {
++			dev_set_promiscuity(fast_bridge_dev1, 1);
++		}
++		if (!(fast_bridge_dev2->flags & IFF_PROMISC)) {
++			dev_set_promiscuity(fast_bridge_dev2, 1);
++		}
++		fast_bridge_dev1_ready = 1;
++		fast_bridge_dev2_ready = 1;
++		/* scott.nic
++		rtnl_shunlock();
++		*/
++	}
++
++	return count;
++
++out:
++	return -EFAULT;
++}
++
++static void fast_bridge_proc_init(void)
++{
++	fast_bridge_proc_entry = create_proc_entry("fast_bridge", S_IFREG | S_IRUGO | S_IWUSR, NULL);
++	if (fast_bridge_proc_entry) {
++		fast_bridge_proc_entry->read_proc = fast_bridge_read_proc;
++		fast_bridge_proc_entry->write_proc = fast_bridge_write_proc;
++		fast_bridge_proc_entry->data = NULL;
++	}
++}
++
++static int __init fast_bridge_init_module(void)
++{
++	fast_bridge_proc_init();
++	return 0;
++}
++
++static void __exit fast_bridge_exit_module(void)
++{
++
++}
++
++module_init(fast_bridge_init_module);
++module_exit(fast_bridge_exit_module);
++
++MODULE_AUTHOR("KC Huang");
++MODULE_DESCRIPTION("FAST SIMPLE BRIDGE");
++MODULE_LICENSE("GPL");
++
+diff -rupN linux-2.6.35.11/drivers/net/Kconfig linux-2.6.35.11-ts7500/drivers/net/Kconfig
+--- linux-2.6.35.11/drivers/net/Kconfig	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -2005,6 +2005,10 @@ menuconfig NETDEV_1000
+ 
+ if NETDEV_1000
+ 
++config FAST_BRIDGE
++	depends on NET
++	bool "Simple Fast Bridge driver support"
++   
+ config ACENIC
+ 	tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
+ 	depends on PCI
+@@ -2840,6 +2844,10 @@ source "drivers/net/benet/Kconfig"
+ 
+ endif # NETDEV_10000
+ 
++source "drivers/net/str9100/Kconfig"
++
++source "drivers/net/str8100/Kconfig"
++
+ source "drivers/net/tokenring/Kconfig"
+ 
+ source "drivers/net/wireless/Kconfig"
+diff -rupN linux-2.6.35.11/drivers/net/Kconfig.orig linux-2.6.35.11-ts7500/drivers/net/Kconfig.orig
+--- linux-2.6.35.11/drivers/net/Kconfig.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/Kconfig.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,3314 @@
++#
++# Network device configuration
++#
++
++menuconfig NETDEVICES
++	default y if UML
++	depends on NET
++	bool "Network device support"
++	---help---
++	  You can say N here if you don't intend to connect your Linux box to
++	  any other computer at all.
++
++	  You'll have to say Y if your computer contains a network card that
++	  you want to use under Linux. If you are going to run SLIP or PPP over
++	  telephone line or null modem cable you need say Y here. Connecting
++	  two machines with parallel ports using PLIP needs this, as well as
++	  AX.25/KISS for sending Internet traffic over amateur radio links.
++
++	  See also "The Linux Network Administrator's Guide" by Olaf Kirch and
++	  Terry Dawson. Available at <http://www.tldp.org/guides.html>.
++
++	  If unsure, say Y.
++
++# All the following symbols are dependent on NETDEVICES - do not repeat
++# that for each of the symbols.
++if NETDEVICES
++
++config IFB
++	tristate "Intermediate Functional Block support"
++	depends on NET_CLS_ACT
++	---help---
++	  This is an intermediate driver that allows sharing of
++	  resources.
++	  To compile this driver as a module, choose M here: the module
++	  will be called ifb.  If you want to use more than one ifb
++	  device at a time, you need to compile this driver as a module.
++	  Instead of 'ifb', the devices will then be called 'ifb0',
++	  'ifb1' etc.
++	  Look at the iproute2 documentation directory for usage etc
++
++config DUMMY
++	tristate "Dummy net driver support"
++	---help---
++	  This is essentially a bit-bucket device (i.e. traffic you send to
++	  this device is consigned into oblivion) with a configurable IP
++	  address. It is most commonly used in order to make your currently
++	  inactive SLIP address seem like a real address for local programs.
++	  If you use SLIP or PPP, you might want to say Y here. Since this
++	  thing often comes in handy, the default is Y. It won't enlarge your
++	  kernel either. What a deal. Read about it in the Network
++	  Administrator's Guide, available from
++	  <http://www.tldp.org/docs.html#guide>.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called dummy.  If you want to use more than one dummy
++	  device at a time, you need to compile this driver as a module.
++	  Instead of 'dummy', the devices will then be called 'dummy0',
++	  'dummy1' etc.
++
++config BONDING
++	tristate "Bonding driver support"
++	depends on INET
++	depends on IPV6 || IPV6=n
++	---help---
++	  Say 'Y' or 'M' if you wish to be able to 'bond' multiple Ethernet
++	  Channels together. This is called 'Etherchannel' by Cisco,
++	  'Trunking' by Sun, 802.3ad by the IEEE, and 'Bonding' in Linux.
++
++	  The driver supports multiple bonding modes to allow for both high
++	  performance and high availability operation.
++
++	  Refer to <file:Documentation/networking/bonding.txt> for more
++	  information.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called bonding.
++
++config MACVLAN
++	tristate "MAC-VLAN support (EXPERIMENTAL)"
++	depends on EXPERIMENTAL
++	---help---
++	  This allows one to create virtual interfaces that map packets to
++	  or from specific MAC addresses to a particular interface.
++
++	  Macvlan devices can be added using the "ip" command from the
++	  iproute2 package starting with the iproute2-2.6.23 release:
++
++	  "ip link add link <real dev> [ address MAC ] [ NAME ] type macvlan"
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called macvlan.
++
++config MACVTAP
++	tristate "MAC-VLAN based tap driver (EXPERIMENTAL)"
++	depends on MACVLAN
++	help
++	  This adds a specialized tap character device driver that is based
++	  on the MAC-VLAN network interface, called macvtap. A macvtap device
++	  can be added in the same way as a macvlan device, using 'type
++	  macvlan', and then be accessed through the tap user space interface.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called macvtap.
++
++config EQUALIZER
++	tristate "EQL (serial line load balancing) support"
++	---help---
++	  If you have two serial connections to some other computer (this
++	  usually requires two modems and two telephone lines) and you use
++	  SLIP (the protocol for sending Internet traffic over telephone
++	  lines) or PPP (a better SLIP) on them, you can make them behave like
++	  one double speed connection using this driver.  Naturally, this has
++	  to be supported at the other end as well, either with a similar EQL
++	  Linux driver or with a Livingston Portmaster 2e.
++
++	  Say Y if you want this and read
++	  <file:Documentation/networking/eql.txt>.  You may also want to read
++	  section 6.2 of the NET-3-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called eql.  If unsure, say N.
++
++config TUN
++	tristate "Universal TUN/TAP device driver support"
++	select CRC32
++	---help---
++	  TUN/TAP provides packet reception and transmission for user space
++	  programs.  It can be viewed as a simple Point-to-Point or Ethernet
++	  device, which instead of receiving packets from a physical media,
++	  receives them from user space program and instead of sending packets
++	  via physical media writes them to the user space program.
++
++	  When a program opens /dev/net/tun, driver creates and registers
++	  corresponding net device tunX or tapX.  After a program closed above
++	  devices, driver will automatically delete tunXX or tapXX device and
++	  all routes corresponding to it.
++
++	  Please read <file:Documentation/networking/tuntap.txt> for more
++	  information.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called tun.
++
++	  If you don't know what to use this for, you don't need it.
++
++config VETH
++	tristate "Virtual ethernet pair device"
++	---help---
++	  This device is a local ethernet tunnel. Devices are created in pairs.
++	  When one end receives the packet it appears on its pair and vice
++	  versa.
++
++config NET_SB1000
++	tristate "General Instruments Surfboard 1000"
++	depends on PNP
++	---help---
++	  This is a driver for the General Instrument (also known as
++	  NextLevel) SURFboard 1000 internal
++	  cable modem. This is an ISA card which is used by a number of cable
++	  TV companies to provide cable modem access. It's a one-way
++	  downstream-only cable modem, meaning that your upstream net link is
++	  provided by your regular phone modem.
++
++	  At present this driver only compiles as a module, so say M here if
++	  you have this card. The module will be called sb1000. Then read
++	  <file:Documentation/networking/README.sb1000> for information on how
++	  to use this module, as it needs special ppp scripts for establishing
++	  a connection. Further documentation and the necessary scripts can be
++	  found at:
++
++	  <http://www.jacksonville.net/~fventuri/>
++	  <http://home.adelphia.net/~siglercm/sb1000.html>
++	  <http://linuxpower.cx/~cable/>
++
++	  If you don't have this card, of course say N.
++
++source "drivers/net/arcnet/Kconfig"
++
++source "drivers/net/phy/Kconfig"
++
++#
++#	Ethernet
++#
++
++menuconfig NET_ETHERNET
++	bool "Ethernet (10 or 100Mbit)"
++	depends on !UML
++	---help---
++	  Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
++	  type of Local Area Network (LAN) in universities and companies.
++
++	  Common varieties of Ethernet are: 10BASE-2 or Thinnet (10 Mbps over
++	  coaxial cable, linking computers in a chain), 10BASE-T or twisted
++	  pair (10 Mbps over twisted pair cable, linking computers to central
++	  hubs), 10BASE-F (10 Mbps over optical fiber links, using hubs),
++	  100BASE-TX (100 Mbps over two twisted pair cables, using hubs),
++	  100BASE-T4 (100 Mbps over 4 standard voice-grade twisted pair
++	  cables, using hubs), 100BASE-FX (100 Mbps over optical fiber links)
++	  [the 100BASE varieties are also known as Fast Ethernet], and Gigabit
++	  Ethernet (1 Gbps over optical fiber or short copper links).
++
++	  If your Linux machine will be connected to an Ethernet and you have
++	  an Ethernet network interface card (NIC) installed in your computer,
++	  say Y here and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>. You will then also have
++	  to say Y to the driver for your particular NIC.
++
++	  Note that the answer to this question won't directly affect the
++	  kernel: saying N will just cause the configurator to skip all
++	  the questions about Ethernet network cards. If unsure, say N.
++
++if NET_ETHERNET
++
++config MII
++	tristate "Generic Media Independent Interface device support"
++	help
++	  Most ethernet controllers have MII transceiver either as an external
++	  or internal device.  It is safe to say Y or M here even if your
++	  ethernet card lack MII.
++
++config MACB
++	tristate "Atmel MACB support"
++	depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45 || ARCH_AT91CAP9
++	select PHYLIB
++	help
++	  The Atmel MACB ethernet interface is found on many AT32 and AT91
++	  parts. Say Y to include support for the MACB chip.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called macb.
++
++source "drivers/net/arm/Kconfig"
++
++config AX88796
++	tristate "ASIX AX88796 NE2000 clone support"
++	depends on ARM || MIPS || SUPERH
++	select CRC32
++	select MII
++	help
++	  AX88796 driver, using platform bus to provide
++	  chip detection and resources
++
++config AX88796_93CX6
++	bool "ASIX AX88796 external 93CX6 eeprom support"
++	depends on AX88796
++	select EEPROM_93CX6
++	help
++	  Select this if your platform comes with an external 93CX6 eeprom.
++
++config MACE
++	tristate "MACE (Power Mac ethernet) support"
++	depends on PPC_PMAC && PPC32
++	select CRC32
++	help
++	  Power Macintoshes and clones with Ethernet built-in on the
++	  motherboard will usually use a MACE (Medium Access Control for
++	  Ethernet) interface. Say Y to include support for the MACE chip.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called mace.
++
++config MACE_AAUI_PORT
++	bool "Use AAUI port instead of TP by default"
++	depends on MACE
++	help
++	  Some Apple machines (notably the Apple Network Server) which use the
++	  MACE ethernet chip have an Apple AUI port (small 15-pin connector),
++	  instead of an 8-pin RJ45 connector for twisted-pair ethernet.  Say
++	  Y here if you have such a machine.  If unsure, say N.
++	  The driver will default to AAUI on ANS anyway, and if you use it as
++	  a module, you can provide the port_aaui=0|1 to force the driver.
++
++config BMAC
++	tristate "BMAC (G3 ethernet) support"
++	depends on PPC_PMAC && PPC32
++	select CRC32
++	help
++	  Say Y for support of BMAC Ethernet interfaces. These are used on G3
++	  computers.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called bmac.
++
++config ARIADNE
++	tristate "Ariadne support"
++	depends on ZORRO
++	help
++	  If you have a Village Tronic Ariadne Ethernet adapter, say Y.
++	  Otherwise, say N.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called ariadne.
++
++config A2065
++	tristate "A2065 support"
++	depends on ZORRO
++	select CRC32
++	help
++	  If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise,
++	  say N.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called a2065.
++
++config HYDRA
++	tristate "Hydra support"
++	depends on ZORRO
++	select CRC32
++	help
++	  If you have a Hydra Ethernet adapter, say Y. Otherwise, say N.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called hydra.
++
++config ZORRO8390
++	tristate "Zorro NS8390-based Ethernet support"
++	depends on ZORRO
++	select CRC32
++	help
++	  This driver is for Zorro Ethernet cards using an NS8390-compatible
++	  chipset, like the Village Tronic Ariadne II and the Individual
++	  Computers X-Surf Ethernet cards. If you have such a card, say Y.
++	  Otherwise, say N.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called zorro8390.
++
++config APNE
++	tristate "PCMCIA NE2000 support"
++	depends on AMIGA_PCMCIA
++	select CRC32
++	help
++	  If you have a PCMCIA NE2000 compatible adapter, say Y.  Otherwise,
++	  say N.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called apne.
++
++config MAC8390
++	bool "Macintosh NS 8390 based ethernet cards"
++	depends on MAC
++	select CRC32
++	help
++	  If you want to include a driver to support Nubus or LC-PDS
++	  Ethernet cards using an NS8390 chipset or its equivalent, say Y
++	  and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++config MAC89x0
++	tristate "Macintosh CS89x0 based ethernet cards"
++	depends on MAC
++	---help---
++	  Support for CS89x0 chipset based Ethernet cards.  If you have a
++	  Nubus or LC-PDS network (Ethernet) card of this type, say Y and
++	  read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. This module will
++	  be called mac89x0.
++
++config MACSONIC
++	tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)"
++	depends on MAC
++	---help---
++	  Support for NatSemi SONIC based Ethernet devices.  This includes
++	  the onboard Ethernet in many Quadras as well as some LC-PDS,
++	  a few Nubus and all known Comm Slot Ethernet cards.  If you have
++	  one of these say Y and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. This module will
++	  be called macsonic.
++
++config MACMACE
++	bool "Macintosh (AV) onboard MACE ethernet"
++	depends on MAC
++	select CRC32
++	help
++	  Support for the onboard AMD 79C940 MACE Ethernet controller used in
++	  the 660AV and 840AV Macintosh.  If you have one of these Macintoshes
++	  say Y and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++config MVME147_NET
++	tristate "MVME147 (Lance) Ethernet support"
++	depends on MVME147
++	select CRC32
++	help
++	  Support for the on-board Ethernet interface on the Motorola MVME147
++	  single-board computer.  Say Y here to include the
++	  driver for this chip in your kernel.
++	  To compile this driver as a module, choose M here.
++
++config MVME16x_NET
++	tristate "MVME16x Ethernet support"
++	depends on MVME16x
++	help
++	  This is the driver for the Ethernet interface on the Motorola
++	  MVME162, 166, 167, 172 and 177 boards.  Say Y here to include the
++	  driver for this chip in your kernel.
++	  To compile this driver as a module, choose M here.
++
++config BVME6000_NET
++	tristate "BVME6000 Ethernet support"
++	depends on BVME6000
++	help
++	  This is the driver for the Ethernet interface on BVME4000 and
++	  BVME6000 VME boards.  Say Y here to include the driver for this chip
++	  in your kernel.
++	  To compile this driver as a module, choose M here.
++
++config ATARILANCE
++	tristate "Atari Lance support"
++	depends on ATARI
++	help
++	  Say Y to include support for several Atari Ethernet adapters based
++	  on the AMD Lance chipset: RieblCard (with or without battery), or
++	  PAMCard VME (also the version by Rhotron, with different addresses).
++
++config SUN3LANCE
++	tristate "Sun3/Sun3x on-board LANCE support"
++	depends on SUN3 || SUN3X
++	help
++	  Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
++	  featured an AMD Lance 10Mbit Ethernet controller on board; say Y
++	  here to compile in the Linux driver for this and enable Ethernet.
++	  General Linux information on the Sun 3 and 3x series (now
++	  discontinued) is at
++	  <http://www.angelfire.com/ca2/tech68k/sun3.html>.
++
++	  If you're not building a kernel for a Sun 3, say N.
++
++config SUN3_82586
++	bool "Sun3 on-board Intel 82586 support"
++	depends on SUN3
++	help
++	  This driver enables support for the on-board Intel 82586 based
++	  Ethernet adapter found on Sun 3/1xx and 3/2xx motherboards.  Note
++	  that this driver does not support 82586-based adapters on additional
++	  VME boards.
++
++config HPLANCE
++	bool "HP on-board LANCE support"
++	depends on DIO
++	select CRC32
++	help
++	  If you want to use the builtin "LANCE" Ethernet controller on an
++	  HP300 machine, say Y here.
++
++config LASI_82596
++	tristate "Lasi ethernet"
++	depends on GSC
++	help
++	  Say Y here to support the builtin Intel 82596 ethernet controller
++	  found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet.
++
++config SNI_82596
++	tristate "SNI RM ethernet"
++	depends on NET_ETHERNET && SNI_RM
++	help
++	  Say Y here to support the on-board Intel 82596 ethernet controller
++	  built into SNI RM machines.
++
++config KORINA
++	tristate "Korina (IDT RC32434) Ethernet support"
++	depends on NET_ETHERNET && MIKROTIK_RB532
++	help
++	  If you have a Mikrotik RouterBoard 500 or IDT RC32434
++	  based system say Y. Otherwise say N.
++
++config MIPS_JAZZ_SONIC
++	tristate "MIPS JAZZ onboard SONIC Ethernet support"
++	depends on MACH_JAZZ
++	help
++	  This is the driver for the onboard card of MIPS Magnum 4000,
++	  Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
++
++config XTENSA_XT2000_SONIC
++	tristate "Xtensa XT2000 onboard SONIC Ethernet support"
++	depends on XTENSA_PLATFORM_XT2000
++	help
++	  This is the driver for the onboard card of the Xtensa XT2000 board.
++
++config MIPS_AU1X00_ENET
++	tristate "MIPS AU1000 Ethernet support"
++	depends on SOC_AU1X00
++	select PHYLIB
++	select CRC32
++	help
++	  If you have an Alchemy Semi AU1X00 based system
++	  say Y.  Otherwise, say N.
++
++config SGI_IOC3_ETH
++	bool "SGI IOC3 Ethernet"
++	depends on PCI && SGI_IP27
++	select CRC32
++	select MII
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++config MIPS_SIM_NET
++	tristate "MIPS simulator Network device"
++	depends on MIPS_SIM
++	help
++	  The MIPSNET device is a simple Ethernet network device which is
++	  emulated by the MIPS Simulator.
++	  If you are not using a MIPSsim or are unsure, say N.
++
++config SGI_O2MACE_ETH
++	tristate "SGI O2 MACE Fast Ethernet support"
++	depends on SGI_IP32=y
++
++config STNIC
++	tristate "National DP83902AV  support"
++	depends on SUPERH
++	select CRC32
++	help
++	  Support for cards based on the National Semiconductor DP83902AV
++	  ST-NIC Serial Network Interface Controller for Twisted Pair.  This
++	  is a 10Mbit/sec Ethernet controller.  Product overview and specs at
++	  <http://www.national.com/pf/DP/DP83902A.html>.
++
++	  If unsure, say N.
++
++config SH_ETH
++	tristate "Renesas SuperH Ethernet support"
++	depends on SUPERH && \
++		(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
++		 CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
++		 CPU_SUBTYPE_SH7724)
++	select CRC32
++	select MII
++	select MDIO_BITBANG
++	select PHYLIB
++	help
++	  Renesas SuperH Ethernet device driver.
++	  This driver support SH7710, SH7712, SH7763, SH7619, and SH7724.
++
++config SUNLANCE
++	tristate "Sun LANCE support"
++	depends on SBUS
++	select CRC32
++	help
++	  This driver supports the "le" interface present on all 32-bit Sparc
++	  systems, on some older Ultra systems and as an Sbus option.  These
++	  cards are based on the AMD Lance chipset, which is better known
++	  via the NE2100 cards.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called sunlance.
++
++config HAPPYMEAL
++	tristate "Sun Happy Meal 10/100baseT support"
++	depends on SBUS || PCI
++	select CRC32
++	help
++	  This driver supports the "hme" interface present on most Ultra
++	  systems and as an option on older Sbus systems. This driver supports
++	  both PCI and Sbus devices. This driver also supports the "qfe" quad
++	  100baseT device available in both PCI and Sbus configurations.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called sunhme.
++
++config SUNBMAC
++	tristate "Sun BigMAC 10/100baseT support (EXPERIMENTAL)"
++	depends on SBUS && EXPERIMENTAL
++	select CRC32
++	help
++	  This driver supports the "be" interface available as an Sbus option.
++	  This is Sun's older 100baseT Ethernet device.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called sunbmac.
++
++config SUNQE
++	tristate "Sun QuadEthernet support"
++	depends on SBUS
++	select CRC32
++	help
++	  This driver supports the "qe" 10baseT Ethernet device, available as
++	  an Sbus option. Note that this is not the same as Quad FastEthernet
++	  "qfe" which is supported by the Happy Meal driver instead.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called sunqe.
++
++config SUNGEM
++	tristate "Sun GEM support"
++	depends on PCI
++	select CRC32
++	help
++	  Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0.  See also
++	  <http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>.
++
++config CASSINI
++	tristate "Sun Cassini support"
++	depends on PCI
++	select CRC32
++	help
++	  Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also
++	  <http://www.sun.com/products-n-solutions/hardware/docs/pdf/817-4341-10.pdf>
++
++config SUNVNET
++	tristate "Sun Virtual Network support"
++	depends on SUN_LDOMS
++	help
++	  Support for virtual network devices under Sun Logical Domains.
++
++config NET_VENDOR_3COM
++	bool "3COM cards"
++	depends on ISA || EISA || MCA || PCI
++	help
++	  If you have a network (Ethernet) card belonging to this class, say Y
++	  and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  Note that the answer to this question doesn't directly affect the
++	  kernel: saying N will just cause the configurator to skip all
++	  the questions about 3COM cards. If you say Y, you will be asked for
++	  your specific card in the following questions.
++
++config EL1
++	tristate "3c501 \"EtherLink\" support"
++	depends on NET_VENDOR_3COM && ISA
++	---help---
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.  Also, consider buying a
++	  new card, since the 3c501 is slow, broken, and obsolete: you will
++	  have problems.  Some people suggest to ping ("man ping") a nearby
++	  machine every minute ("man cron") when using this card.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called 3c501.
++
++config EL2
++	tristate "3c503 \"EtherLink II\" support"
++	depends on NET_VENDOR_3COM && ISA
++	select CRC32
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called 3c503.
++
++config ELPLUS
++	tristate "3c505 \"EtherLink Plus\" support"
++	depends on NET_VENDOR_3COM && ISA && ISA_DMA_API
++	---help---
++	  Information about this network (Ethernet) card can be found in
++	  <file:Documentation/networking/3c505.txt>.  If you have a card of
++	  this type, say Y and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called 3c505.
++
++config EL16
++	tristate "3c507 \"EtherLink 16\" support (EXPERIMENTAL)"
++	depends on NET_VENDOR_3COM && ISA && EXPERIMENTAL
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called 3c507.
++
++config EL3
++	tristate "3c509/3c529 (MCA)/3c579 \"EtherLink III\" support"
++	depends on NET_VENDOR_3COM && (ISA || EISA || MCA)
++	---help---
++	  If you have a network (Ethernet) card belonging to the 3Com
++	  EtherLinkIII series, say Y and read the Ethernet-HOWTO, available
++	  from <http://www.tldp.org/docs.html#howto>.
++
++	  If your card is not working you may need to use the DOS
++	  setup disk to disable Plug & Play mode, and to select the default
++	  media type.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called 3c509.
++
++config 3C515
++	tristate "3c515 ISA \"Fast EtherLink\""
++	depends on NET_VENDOR_3COM && (ISA || EISA) && ISA_DMA_API
++	help
++	  If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet
++	  network card, say Y and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called 3c515.
++
++config ELMC
++	tristate "3c523 \"EtherLink/MC\" support"
++	depends on NET_VENDOR_3COM && MCA_LEGACY
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called 3c523.
++
++config ELMC_II
++	tristate "3c527 \"EtherLink/MC 32\" support (EXPERIMENTAL)"
++	depends on NET_VENDOR_3COM && MCA && MCA_LEGACY
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called 3c527.
++
++config VORTEX
++	tristate "3c590/3c900 series (592/595/597) \"Vortex/Boomerang\" support"
++	depends on NET_VENDOR_3COM && (PCI || EISA)
++	select MII
++	---help---
++	  This option enables driver support for a large number of 10Mbps and
++	  10/100Mbps EISA, PCI and PCMCIA 3Com network cards:
++
++	  "Vortex"    (Fast EtherLink 3c590/3c592/3c595/3c597) EISA and PCI
++	  "Boomerang" (EtherLink XL 3c900 or 3c905)            PCI
++	  "Cyclone"   (3c540/3c900/3c905/3c980/3c575/3c656)    PCI and Cardbus
++	  "Tornado"   (3c905)                                  PCI
++	  "Hurricane" (3c555/3cSOHO)                           PCI
++
++	  If you have such a card, say Y and read the Ethernet-HOWTO,
++	  available from <http://www.tldp.org/docs.html#howto>. More
++	  specific information is in
++	  <file:Documentation/networking/vortex.txt> and in the comments at
++	  the beginning of <file:drivers/net/3c59x.c>.
++
++	  To compile this support as a module, choose M here.
++
++config TYPHOON
++	tristate "3cr990 series \"Typhoon\" support"
++	depends on NET_VENDOR_3COM && PCI
++	select CRC32
++	---help---
++	  This option enables driver support for the 3cr990 series of cards:
++
++	  3C990-TX, 3CR990-TX-95, 3CR990-TX-97, 3CR990-FX-95, 3CR990-FX-97,
++	  3CR990SVR, 3CR990SVR95, 3CR990SVR97, 3CR990-FX-95 Server,
++	  3CR990-FX-97 Server, 3C990B-TX-M, 3C990BSVR
++
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called typhoon.
++
++config LANCE
++	tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
++	depends on ISA && ISA_DMA_API
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>. Some LinkSys cards are
++	  of this type.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called lance.  This is recommended.
++
++config NET_VENDOR_SMC
++	bool "Western Digital/SMC cards"
++	depends on ISA || MCA || EISA || MAC
++	help
++	  If you have a network (Ethernet) card belonging to this class, say Y
++	  and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  Note that the answer to this question doesn't directly affect the
++	  kernel: saying N will just cause the configurator to skip all
++	  the questions about Western Digital cards. If you say Y, you will be
++	  asked for your specific card in the following questions.
++
++config WD80x3
++	tristate "WD80*3 support"
++	depends on NET_VENDOR_SMC && ISA
++	select CRC32
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called wd.
++
++config ULTRAMCA
++	tristate "SMC Ultra MCA support"
++	depends on NET_VENDOR_SMC && MCA
++	select CRC32
++	help
++	  If you have a network (Ethernet) card of this type and are running
++	  an MCA based system (PS/2), say Y and read the Ethernet-HOWTO,
++	  available from <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called smc-mca.
++
++config ULTRA
++	tristate "SMC Ultra support"
++	depends on NET_VENDOR_SMC && ISA
++	select CRC32
++	---help---
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  Important: There have been many reports that, with some motherboards
++	  mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible,
++	  such as some BusLogic models) causes corruption problems with many
++	  operating systems. The Linux smc-ultra driver has a work-around for
++	  this but keep it in mind if you have such a SCSI card and have
++	  problems.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called smc-ultra.
++
++config ULTRA32
++	tristate "SMC Ultra32 EISA support"
++	depends on NET_VENDOR_SMC && EISA
++	select CRC32
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called smc-ultra32.
++
++config BFIN_MAC
++	tristate "Blackfin on-chip MAC support"
++	depends on NET_ETHERNET && (BF516 || BF518 || BF526 || BF527 || BF536 || BF537)
++	select CRC32
++	select MII
++	select PHYLIB
++	select BFIN_MAC_USE_L1 if DMA_UNCACHED_NONE
++	help
++	  This is the driver for Blackfin on-chip mac device. Say Y if you want it
++	  compiled into the kernel. This driver is also available as a module
++	  ( = code which can be inserted in and removed from the running kernel
++	  whenever you want). The module will be called bfin_mac.
++
++config BFIN_MAC_USE_L1
++	bool "Use L1 memory for rx/tx packets"
++	depends on BFIN_MAC && (BF527 || BF537)
++	default y
++	help
++	  To get maximum network performance, you should use L1 memory as rx/tx buffers.
++	  Say N here if you want to reserve L1 memory for other uses.
++
++config BFIN_TX_DESC_NUM
++	int "Number of transmit buffer packets"
++	depends on BFIN_MAC
++	range 6 10 if BFIN_MAC_USE_L1
++	range 10 100
++	default "10"
++	help
++	  Set the number of buffer packets used in driver.
++
++config BFIN_RX_DESC_NUM
++	int "Number of receive buffer packets"
++	depends on BFIN_MAC
++	range 20 100 if BFIN_MAC_USE_L1
++	range 20 800
++	default "20"
++	help
++	  Set the number of buffer packets used in driver.
++
++config BFIN_MAC_RMII
++	bool "RMII PHY Interface"
++	depends on BFIN_MAC
++	default y if BFIN527_EZKIT
++	default n if BFIN537_STAMP
++	help
++	  Use Reduced PHY MII Interface
++
++config BFIN_MAC_USE_HWSTAMP
++	bool "Use IEEE 1588 hwstamp"
++	depends on BFIN_MAC && BF518
++	default y
++	help
++	  To support the IEEE 1588 Precision Time Protocol (PTP), select y here
++
++config SMC9194
++	tristate "SMC 9194 support"
++	depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
++	select CRC32
++	---help---
++	  This is support for the SMC9xxx based Ethernet cards. Choose this
++	  option if you have a DELL laptop with the docking station, or
++	  another SMC9192/9194 based chipset.  Say Y if you want it compiled
++	  into the kernel, and read the file
++	  <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
++	  available from <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called smc9194.
++
++config SMC91X
++	tristate "SMC 91C9x/91C1xxx support"
++	select CRC32
++	select MII
++	depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \
++		MIPS || BLACKFIN || MN10300 || COLDFIRE
++	help
++	  This is a driver for SMC's 91x series of Ethernet chipsets,
++	  including the SMC91C94 and the SMC91C111. Say Y if you want it
++	  compiled into the kernel, and read the file
++	  <file:Documentation/networking/smc9.txt>  and the Ethernet-HOWTO,
++	  available from  <http://www.linuxdoc.org/docs.html#howto>.
++
++	  This driver is also available as a module ( = code which can be
++	  inserted in and removed from the running kernel whenever you want).
++	  The module will be called smc91x.  If you want to compile it as a
++	  module, say M here and read <file:Documentation/kbuild/modules.txt>.
++
++config NET_NETX
++	tristate "NetX Ethernet support"
++	select MII
++	depends on ARCH_NETX
++	help
++	  This is support for the Hilscher netX builtin Ethernet ports
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called netx-eth.
++
++config TI_DAVINCI_EMAC
++	tristate "TI DaVinci EMAC Support"
++	depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
++	select PHYLIB
++	help
++	  This driver supports TI's DaVinci Ethernet .
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called davinci_emac_driver.  This is recommended.
++
++config DM9000
++	tristate "DM9000 support"
++	depends on ARM || BLACKFIN || MIPS
++	select CRC32
++	select MII
++	---help---
++	  Support for DM9000 chipset.
++
++	  To compile this driver as a module, choose M here.  The module
++	  will be called dm9000.
++
++config DM9000_DEBUGLEVEL
++	int "DM9000 maximum debug level"
++	depends on DM9000
++	default 4
++	help
++	  The maximum level of debugging code compiled into the DM9000
++	  driver.
++
++config DM9000_FORCE_SIMPLE_PHY_POLL
++	bool "Force simple NSR based PHY polling"
++	depends on DM9000
++	---help---
++	  This configuration forces the DM9000 to use the NSR's LinkStatus
++	  bit to determine if the link is up or down instead of the more
++	  costly MII PHY reads. Note, this will not work if the chip is
++	  operating with an external PHY.
++
++config ENC28J60
++	tristate "ENC28J60 support"
++	depends on EXPERIMENTAL && SPI && NET_ETHERNET
++	select CRC32
++	---help---
++	  Support for the Microchip EN28J60 ethernet chip.
++
++	  To compile this driver as a module, choose M here. The module will be
++	  called enc28j60.
++
++config ENC28J60_WRITEVERIFY
++	bool "Enable write verify"
++	depends on ENC28J60
++	---help---
++	  Enable the verify after the buffer write useful for debugging purpose.
++	  If unsure, say N.
++
++config ETHOC
++	tristate "OpenCores 10/100 Mbps Ethernet MAC support"
++	depends on NET_ETHERNET && HAS_IOMEM && HAS_DMA
++	select MII
++	select PHYLIB
++	select CRC32
++	select BITREVERSE
++	help
++	  Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
++
++config GRETH
++	tristate "Aeroflex Gaisler GRETH Ethernet MAC support"
++	depends on SPARC
++	select PHYLIB
++	select CRC32
++	help
++	  Say Y here if you want to use the Aeroflex Gaisler GRETH Ethernet MAC.
++
++config SMC911X
++	tristate "SMSC LAN911[5678] support"
++	select CRC32
++	select MII
++	depends on ARM || SUPERH
++	help
++	  This is a driver for SMSC's LAN911x series of Ethernet chipsets
++	  including the new LAN9115, LAN9116, LAN9117, and LAN9118.
++	  Say Y if you want it compiled into the kernel, 
++	  and read the Ethernet-HOWTO, available from
++	  <http://www.linuxdoc.org/docs.html#howto>.
++
++	  This driver is also available as a module. The module will be 
++	  called smc911x.  If you want to compile it as a module, say M 
++	  here and read <file:Documentation/kbuild/modules.txt>
++
++config SMSC911X
++	tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
++	depends on ARM || SUPERH || BLACKFIN || MIPS
++	select CRC32
++	select MII
++	select PHYLIB
++	---help---
++	  Say Y here if you want support for SMSC LAN911x and LAN921x families
++	  of ethernet controllers.
++
++	  To compile this driver as a module, choose M here and read
++	  <file:Documentation/networking/net-modules.txt>. The module
++	  will be called smsc911x.
++
++config NET_VENDOR_RACAL
++	bool "Racal-Interlan (Micom) NI cards"
++	depends on ISA
++	help
++	  If you have a network (Ethernet) card belonging to this class, such
++	  as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
++	  available from <http://www.tldp.org/docs.html#howto>.
++
++	  Note that the answer to this question doesn't directly affect the
++	  kernel: saying N will just cause the configurator to skip all
++	  the questions about NI cards. If you say Y, you will be asked for
++	  your specific card in the following questions.
++
++config NI5010
++	tristate "NI5010 support (EXPERIMENTAL)"
++	depends on NET_VENDOR_RACAL && ISA && EXPERIMENTAL && BROKEN_ON_SMP
++	---help---
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>. Note that this is still
++	  experimental code.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ni5010.
++
++config NI52
++	tristate "NI5210 support"
++	depends on NET_VENDOR_RACAL && ISA
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ni52.
++
++config NI65
++	tristate "NI6510 support"
++	depends on NET_VENDOR_RACAL && ISA && ISA_DMA_API
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ni65.
++
++config DNET
++	tristate "Dave ethernet support (DNET)"
++	depends on NET_ETHERNET && HAS_IOMEM
++	select PHYLIB
++	help
++	  The Dave ethernet interface (DNET) is found on Qong Board FPGA.
++	  Say Y to include support for the DNET chip.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called dnet.
++
++source "drivers/net/tulip/Kconfig"
++
++config AT1700
++	tristate "AT1700/1720 support (EXPERIMENTAL)"
++	depends on (ISA || MCA_LEGACY) && EXPERIMENTAL
++	select CRC32
++	---help---
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called at1700.
++
++config DEPCA
++	tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support"
++	depends on ISA || EISA || MCA
++	select CRC32
++	---help---
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto> as well as
++	  <file:drivers/net/depca.c>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called depca.
++
++config HP100
++	tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support"
++	depends on ISA || EISA || PCI
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called hp100.
++
++config NET_ISA
++	bool "Other ISA cards"
++	depends on ISA
++	---help---
++	  If your network (Ethernet) card hasn't been mentioned yet and its
++	  bus system (that's the way the cards talks to the other components
++	  of your computer) is ISA (as opposed to EISA, VLB or PCI), say Y.
++	  Make sure you know the name of your card. Read the Ethernet-HOWTO,
++	  available from <http://www.tldp.org/docs.html#howto>.
++
++	  If unsure, say Y.
++
++	  Note that the answer to this question doesn't directly affect the
++	  kernel: saying N will just cause the configurator to skip all
++	  the remaining ISA network card questions. If you say Y, you will be
++	  asked for your specific card in the following questions.
++
++config E2100
++	tristate "Cabletron E21xx support"
++	depends on NET_ISA
++	select CRC32
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called e2100.
++
++config EWRK3
++	tristate "EtherWORKS 3 (DE203, DE204, DE205) support"
++	depends on NET_ISA
++	select CRC32
++	---help---
++	  This driver supports the DE203, DE204 and DE205 network (Ethernet)
++	  cards. If this is for you, say Y and read
++	  <file:Documentation/networking/ewrk3.txt> in the kernel source as
++	  well as the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ewrk3.
++
++config EEXPRESS
++	tristate "EtherExpress 16 support"
++	depends on NET_ISA
++	---help---
++	  If you have an EtherExpress16 network (Ethernet) card, say Y and
++	  read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.  Note that the Intel
++	  EtherExpress16 card used to be regarded as a very poor choice
++	  because the driver was very unreliable. We now have a new driver
++	  that should do better.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called eexpress.
++
++config EEXPRESS_PRO
++	tristate "EtherExpressPro support/EtherExpress 10 (i82595) support"
++	depends on NET_ISA
++	---help---
++	  If you have a network (Ethernet) card of this type, say Y. This
++	  driver supports Intel i82595{FX,TX} based boards. Note however
++	  that the EtherExpress PRO/100 Ethernet card has its own separate
++	  driver.  Please read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called eepro.
++
++config HPLAN_PLUS
++	tristate "HP PCLAN+ (27247B and 27252A) support"
++	depends on NET_ISA
++	select CRC32
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called hp-plus.
++
++config HPLAN
++	tristate "HP PCLAN (27245 and other 27xxx series) support"
++	depends on NET_ISA
++	select CRC32
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called hp.
++
++config LP486E
++	tristate "LP486E on board Ethernet"
++	depends on NET_ISA
++	help
++	  Say Y here to support the 82596-based on-board Ethernet controller
++	  for the Panther motherboard, which is one of the two shipped in the
++	  Intel Professional Workstation.
++
++config ETH16I
++	tristate "ICL EtherTeam 16i/32 support"
++	depends on NET_ISA
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called eth16i.
++
++config NE2000
++	tristate "NE2000/NE1000 support"
++	depends on NET_ISA || (Q40 && m) || M32R || MACH_TX49XX
++	select CRC32
++	---help---
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.  Many Ethernet cards
++	  without a specific driver are compatible with NE2000.
++
++	  If you have a PCI NE2000 card however, say N here and Y to "PCI
++	  NE2000 and clone support" under "EISA, VLB, PCI and on board
++	  controllers" below. If you have a NE2000 card and are running on
++	  an MCA system (a bus system used on some IBM PS/2 computers and
++	  laptops), say N here and Y to "NE/2 (ne2000 MCA version) support",
++	  below.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ne.
++
++config ZNET
++	tristate "Zenith Z-Note support (EXPERIMENTAL)"
++	depends on NET_ISA && EXPERIMENTAL && ISA_DMA_API
++	help
++	  The Zenith Z-Note notebook computer has a built-in network
++	  (Ethernet) card, and this is the Linux driver for it. Note that the
++	  IBM Thinkpad 300 is compatible with the Z-Note and is also supported
++	  by this driver. Read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++config SEEQ8005
++	tristate "SEEQ8005 support (EXPERIMENTAL)"
++	depends on NET_ISA && EXPERIMENTAL
++	help
++	  This is a driver for the SEEQ 8005 network (Ethernet) card.  If this
++	  is for you, read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called seeq8005.
++
++config NE2_MCA
++	tristate "NE/2 (ne2000 MCA version) support"
++	depends on MCA_LEGACY
++	select CRC32
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ne2.
++
++config IBMLANA
++	tristate "IBM LAN Adapter/A support"
++	depends on MCA
++	---help---
++	  This is a Micro Channel Ethernet adapter.  You need to set
++	  CONFIG_MCA to use this driver.  It is both available as an in-kernel
++	  driver and as a module.
++
++	  To compile this driver as a module, choose M here. The only
++	  currently supported card is the IBM LAN Adapter/A for Ethernet.  It
++	  will both support 16K and 32K memory windows, however a 32K window
++	  gives a better security against packet losses.  Usage of multiple
++	  boards with this driver should be possible, but has not been tested
++	  up to now due to lack of hardware.
++
++config IBMVETH
++	tristate "IBM LAN Virtual Ethernet support"
++	depends on PPC_PSERIES
++	---help---
++	  This driver supports virtual ethernet adapters on newer IBM iSeries
++	  and pSeries systems.
++
++	  To compile this driver as a module, choose M here. The module will
++	  be called ibmveth.
++
++source "drivers/net/ibm_newemac/Kconfig"
++
++config NET_PCI
++	bool "EISA, VLB, PCI and on board controllers"
++	depends on ISA || EISA || PCI
++	help
++	  This is another class of network cards which attach directly to the
++	  bus. If you have one of those, say Y and read the Ethernet-HOWTO,
++	  available from <http://www.tldp.org/docs.html#howto>.
++
++	  Note that the answer to this question doesn't directly affect the
++	  kernel: saying N will just cause the configurator to skip all
++	  the questions about this class of network cards. If you say Y, you
++	  will be asked for your specific card in the following questions. If
++	  you are unsure, say Y.
++
++config PCNET32
++	tristate "AMD PCnet32 PCI support"
++	depends on NET_PCI && PCI
++	select CRC32
++	select MII
++	help
++	  If you have a PCnet32 or PCnetPCI based network (Ethernet) card,
++	  answer Y here and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called pcnet32.
++
++config AMD8111_ETH
++	tristate "AMD 8111 (new PCI lance) support"
++	depends on NET_PCI && PCI
++	select CRC32
++	select MII
++	help
++	  If you have an AMD 8111-based PCI lance ethernet card,
++	  answer Y here and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called amd8111e.
++
++config ADAPTEC_STARFIRE
++	tristate "Adaptec Starfire/DuraLAN support"
++	depends on NET_PCI && PCI
++	select CRC32
++	select MII
++	help
++	  Say Y here if you have an Adaptec Starfire (or DuraLAN) PCI network
++	  adapter. The DuraLAN chip is used on the 64 bit PCI boards from
++	  Adaptec e.g. the ANA-6922A. The older 32 bit boards use the tulip
++	  driver.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called starfire.  This is recommended.
++
++config AC3200
++	tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)"
++	depends on NET_PCI && (ISA || EISA) && EXPERIMENTAL
++	select CRC32
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ac3200.
++
++config KSZ884X_PCI
++	tristate "Micrel KSZ8841/2 PCI"
++	depends on NET_PCI && PCI
++	select MII
++	select CRC32
++	help
++	  This PCI driver is for Micrel KSZ8841/KSZ8842 PCI Ethernet chip.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ksz884x.
++
++config APRICOT
++	tristate "Apricot Xen-II on board Ethernet"
++	depends on NET_PCI && ISA
++	help
++	  If you have a network (Ethernet) controller of this type, say Y and
++	  read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called apricot.
++
++config B44
++	tristate "Broadcom 440x/47xx ethernet support"
++	depends on SSB_POSSIBLE && HAS_DMA
++	select SSB
++	select MII
++	help
++	  If you have a network (Ethernet) controller of this type, say Y
++	  or M and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called b44.
++
++# Auto-select SSB PCI-HOST support, if possible
++config B44_PCI_AUTOSELECT
++	bool
++	depends on B44 && SSB_PCIHOST_POSSIBLE
++	select SSB_PCIHOST
++	default y
++
++# Auto-select SSB PCICORE driver, if possible
++config B44_PCICORE_AUTOSELECT
++	bool
++	depends on B44 && SSB_DRIVER_PCICORE_POSSIBLE
++	select SSB_DRIVER_PCICORE
++	default y
++
++config B44_PCI
++	bool
++	depends on B44_PCI_AUTOSELECT && B44_PCICORE_AUTOSELECT
++	default y
++
++config FORCEDETH
++	tristate "nForce Ethernet support"
++	depends on NET_PCI && PCI
++	help
++	  If you have a network (Ethernet) controller of this type, say Y and
++	  read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called forcedeth.
++
++config CS89x0
++	tristate "CS89x0 support"
++	depends on NET_ETHERNET && (ISA || EISA || MACH_IXDP2351 \
++		|| ARCH_IXDP2X01 || ARCH_PNX010X || MACH_MX31ADS)
++	---help---
++	  Support for CS89x0 chipset based Ethernet cards. If you have a
++	  network (Ethernet) card of this type, say Y and read the
++	  Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto> as well as
++	  <file:Documentation/networking/cs89x0.txt>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called cs89x0.
++
++config CS89x0_NONISA_IRQ
++	def_bool y
++	depends on CS89x0 != n
++	depends on MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X || MACH_MX31ADS
++
++config TC35815
++	tristate "TOSHIBA TC35815 Ethernet support"
++	depends on NET_PCI && PCI && MIPS
++	select PHYLIB
++
++config E100
++	tristate "Intel(R) PRO/100+ support"
++	depends on NET_PCI && PCI
++	select MII
++	---help---
++	  This driver supports Intel(R) PRO/100 family of adapters.
++	  To verify that your adapter is supported, find the board ID number 
++	  on the adapter. Look for a label that has a barcode and a number 
++	  in the format 123456-001 (six digits hyphen three digits). 
++
++	  Use the above information and the Adapter & Driver ID Guide at:
++
++	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
++
++          to identify the adapter.
++
++	  For the latest Intel PRO/100 network driver for Linux, see:
++
++	  <http://appsr.intel.com/scripts-df/support_intel.asp>
++
++	  More specific information on configuring the driver is in 
++	  <file:Documentation/networking/e100.txt>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called e100.
++
++config LNE390
++	tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)"
++	depends on NET_PCI && EISA && EXPERIMENTAL
++	select CRC32
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called lne390.
++
++config FEALNX
++	tristate "Myson MTD-8xx PCI Ethernet support"
++	depends on NET_PCI && PCI
++	select CRC32
++	select MII
++	help
++	  Say Y here to support the Mysom MTD-800 family of PCI-based Ethernet
++	  cards. Specifications and data at
++	  <http://www.myson.com.hk/mtd/datasheet/>.
++
++config NATSEMI
++	tristate "National Semiconductor DP8381x series PCI Ethernet support"
++	depends on NET_PCI && PCI
++	select CRC32
++	help
++	  This driver is for the National Semiconductor DP83810 series,
++	  which is used in cards from PureData, NetGear, Linksys
++	  and others, including the 83815 chip.
++	  More specific information and updates are available from
++	  <http://www.scyld.com/network/natsemi.html>.
++
++config NE2K_PCI
++	tristate "PCI NE2000 and clones support (see help)"
++	depends on NET_PCI && PCI
++	select CRC32
++	---help---
++	  This driver is for NE2000 compatible PCI cards. It will not work
++	  with ISA NE2000 cards (they have their own driver, "NE2000/NE1000
++	  support" below). If you have a PCI NE2000 network (Ethernet) card,
++	  say Y and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  This driver also works for the following NE2000 clone cards:
++	  RealTek RTL-8029  Winbond 89C940  Compex RL2000  KTI ET32P2
++	  NetVin NV5000SC   Via 86C926      SureCom NE34   Winbond
++	  Holtek HT80232    Holtek HT80229
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ne2k-pci.
++
++config NE3210
++	tristate "Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)"
++	depends on NET_PCI && EISA && EXPERIMENTAL
++	select CRC32
++	---help---
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.  Note that this driver
++	  will NOT WORK for NE3200 cards as they are completely different.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ne3210.
++
++config ES3210
++	tristate "Racal-Interlan EISA ES3210 support (EXPERIMENTAL)"
++	depends on NET_PCI && EISA && EXPERIMENTAL
++	select CRC32
++	help
++	  If you have a network (Ethernet) card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called es3210.
++
++config 8139CP
++	tristate "RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support (EXPERIMENTAL)"
++	depends on NET_PCI && PCI && EXPERIMENTAL
++	select CRC32
++	select MII
++	help
++	  This is a driver for the Fast Ethernet PCI network cards based on
++	  the RTL8139C+ chips. If you have one of those, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called 8139cp.  This is recommended.
++
++config 8139TOO
++	tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support"
++	depends on NET_PCI && PCI
++	select CRC32
++	select MII
++	---help---
++	  This is a driver for the Fast Ethernet PCI network cards based on
++	  the RTL 8129/8130/8139 chips. If you have one of those, say Y and
++	  read the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called 8139too.  This is recommended.
++
++config 8139TOO_PIO
++	bool "Use PIO instead of MMIO"
++	default y
++	depends on 8139TOO
++	help
++	  This instructs the driver to use programmed I/O ports (PIO) instead
++	  of PCI shared memory (MMIO).  This can possibly solve some problems
++	  in case your mainboard has memory consistency issues.  If unsure,
++	  say N.
++
++config 8139TOO_TUNE_TWISTER
++	bool "Support for uncommon RTL-8139 rev. K (automatic channel equalization)"
++	depends on 8139TOO
++	help
++	  This implements a function which might come in handy in case you
++	  are using low quality on long cabling. It is required for RealTek
++	  RTL-8139 revision K boards, and totally unused otherwise.  It tries
++	  to match the transceiver to the cable characteristics. This is
++	  experimental since hardly documented by the manufacturer.
++	  If unsure, say Y.
++
++config 8139TOO_8129
++	bool "Support for older RTL-8129/8130 boards"
++	depends on 8139TOO
++	help
++	  This enables support for the older and uncommon RTL-8129 and
++	  RTL-8130 chips, which support MII via an external transceiver,
++	  instead of an internal one.  Disabling this option will save some
++	  memory by making the code size smaller.  If unsure, say Y.
++
++config 8139_OLD_RX_RESET
++	bool "Use older RX-reset method"
++	depends on 8139TOO
++	help
++	  The 8139too driver was recently updated to contain a more rapid
++	  reset sequence, in the face of severe receive errors.  This "new"
++	  RX-reset method should be adequate for all boards.  But if you
++	  experience problems, you can enable this option to restore the
++	  old RX-reset behavior.  If unsure, say N.
++
++config R6040
++	tristate "RDC R6040 Fast Ethernet Adapter support"
++	depends on NET_PCI && PCI
++	select CRC32
++	select MII
++	help
++	  This is a driver for the R6040 Fast Ethernet MACs found in the
++	  the RDC R-321x System-on-chips.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called r6040. This is recommended.
++
++config SIS900
++	tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
++	depends on NET_PCI && PCI
++	select CRC32
++	select MII
++	---help---
++	  This is a driver for the Fast Ethernet PCI network cards based on
++	  the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in
++	  SiS 630 and SiS 540 chipsets.
++
++	  This driver also supports AMD 79C901 HomePNA so that you can use
++	  your phone line as a network cable.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called sis900.  This is recommended.
++
++config EPIC100
++	tristate "SMC EtherPower II"
++	depends on NET_PCI && PCI
++	select CRC32
++	select MII
++	help
++	  This driver is for the SMC EtherPower II 9432 PCI Ethernet NIC,
++	  which is based on the SMC83c17x (EPIC/100).
++	  More specific information and updates are available from
++	  <http://www.scyld.com/network/epic100.html>.
++
++config SMSC9420
++	tristate "SMSC LAN9420 PCI ethernet adapter support"
++	depends on NET_PCI && PCI
++	select CRC32
++	select PHYLIB
++	select SMSC_PHY
++	help
++	  This is a driver for SMSC's LAN9420 PCI ethernet adapter.
++	  Say Y if you want it compiled into the kernel,
++	  and read the Ethernet-HOWTO, available from
++	  <http://www.linuxdoc.org/docs.html#howto>.
++
++	  This driver is also available as a module. The module will be
++	  called smsc9420.  If you want to compile it as a module, say M
++	  here and read <file:Documentation/kbuild/modules.txt>
++
++config SUNDANCE
++	tristate "Sundance Alta support"
++	depends on NET_PCI && PCI
++	select CRC32
++	select MII
++	help
++	  This driver is for the Sundance "Alta" chip.
++	  More specific information and updates are available from
++	  <http://www.scyld.com/network/sundance.html>.
++
++config SUNDANCE_MMIO
++	bool "Use MMIO instead of PIO"
++	depends on SUNDANCE
++	help
++	  Enable memory-mapped I/O for interaction with Sundance NIC registers.
++	  Do NOT enable this by default, PIO (enabled when MMIO is disabled)
++	  is known to solve bugs on certain chips.
++
++	  If unsure, say N.
++
++config TLAN
++	tristate "TI ThunderLAN support"
++	depends on NET_PCI && (PCI || EISA)
++	---help---
++	  If you have a PCI Ethernet network card based on the ThunderLAN chip
++	  which is supported by this driver, say Y and read the
++	  Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  Devices currently supported by this driver are Compaq Netelligent,
++	  Compaq NetFlex and Olicom cards.  Please read the file
++	  <file:Documentation/networking/tlan.txt> for more details.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called tlan.
++
++	  Please email feedback to <torben.mathiasen@compaq.com>.
++
++config KS8842
++	tristate "Micrel KSZ8842"
++	depends on HAS_IOMEM
++	help
++	  This platform driver is for Micrel KSZ8842 / KS8842
++	  2-port ethernet switch chip (managed, VLAN, QoS).
++
++config KS8851
++       tristate "Micrel KS8851 SPI"
++       depends on SPI
++       select MII
++	select CRC32
++       help
++         SPI driver for Micrel KS8851 SPI attached network chip.
++
++config KS8851_MLL
++	tristate "Micrel KS8851 MLL"
++	depends on HAS_IOMEM
++	select MII
++	help
++	  This platform driver is for Micrel KS8851 Address/data bus
++	  multiplexed network chip.
++
++config VIA_RHINE
++	tristate "VIA Rhine support"
++	depends on NET_PCI && PCI
++	select CRC32
++	select MII
++	help
++	  If you have a VIA "Rhine" based network card (Rhine-I (VT86C100A),
++	  Rhine-II (VT6102), or Rhine-III (VT6105)), say Y here. Rhine-type
++	  Ethernet functions can also be found integrated on South Bridges
++	  (e.g. VT8235).
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called via-rhine.
++
++config VIA_RHINE_MMIO
++	bool "Use MMIO instead of PIO"
++	depends on VIA_RHINE
++	help
++	  This instructs the driver to use PCI shared memory (MMIO) instead of
++	  programmed I/O ports (PIO). Enabling this gives an improvement in
++	  processing time in parts of the driver.
++
++	  If unsure, say Y.
++
++config SC92031
++	tristate "Silan SC92031 PCI Fast Ethernet Adapter driver (EXPERIMENTAL)"
++	depends on NET_PCI && PCI && EXPERIMENTAL
++	select CRC32
++	---help---
++	  This is a driver for the Fast Ethernet PCI network cards based on
++	  the Silan SC92031 chip (sometimes also called Rsltek 8139D). If you
++	  have one of these, say Y here.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called sc92031.  This is recommended.
++
++config CPMAC
++	tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
++	depends on NET_ETHERNET && EXPERIMENTAL && AR7
++	select PHYLIB
++	help
++	  TI AR7 CPMAC Ethernet support
++
++config NET_POCKET
++	bool "Pocket and portable adapters"
++	depends on PARPORT
++	---help---
++	  Cute little network (Ethernet) devices which attach to the parallel
++	  port ("pocket adapters"), commonly used with laptops. If you have
++	  one of those, say Y and read the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  If you want to plug a network (or some other) card into the PCMCIA
++	  (or PC-card) slot of your laptop instead (PCMCIA is the standard for
++	  credit card size extension cards used by all modern laptops), you
++	  need the pcmcia-cs package (location contained in the file
++	  <file:Documentation/Changes>) and you can say N here.
++
++	  Laptop users should read the Linux Laptop home page at
++	  <http://www.linux-on-laptops.com/> or
++	  Tuxmobil - Linux on Mobile Computers at <http://www.tuxmobil.org/>.
++
++	  Note that the answer to this question doesn't directly affect the
++	  kernel: saying N will just cause the configurator to skip all
++	  the questions about this class of network devices. If you say Y, you
++	  will be asked for your specific device in the following questions.
++
++config ATP
++	tristate "AT-LAN-TEC/RealTek pocket adapter support"
++	depends on NET_POCKET && PARPORT && X86
++	select CRC32
++	---help---
++	  This is a network (Ethernet) device which attaches to your parallel
++	  port. Read <file:drivers/net/atp.c> as well as the Ethernet-HOWTO,
++	  available from <http://www.tldp.org/docs.html#howto>, if you
++	  want to use this.  If you intend to use this driver, you should have
++	  said N to the "Parallel printer support", because the two drivers
++	  don't like each other.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called atp.
++
++config DE600
++	tristate "D-Link DE600 pocket adapter support"
++	depends on NET_POCKET && PARPORT
++	---help---
++	  This is a network (Ethernet) device which attaches to your parallel
++	  port. Read <file:Documentation/networking/DLINK.txt> as well as the
++	  Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>, if you want to use
++	  this. It is possible to have several devices share a single parallel
++	  port and it is safe to compile the corresponding drivers into the
++	  kernel.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called de600.
++
++config DE620
++	tristate "D-Link DE620 pocket adapter support"
++	depends on NET_POCKET && PARPORT
++	---help---
++	  This is a network (Ethernet) device which attaches to your parallel
++	  port. Read <file:Documentation/networking/DLINK.txt> as well as the
++	  Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>, if you want to use
++	  this. It is possible to have several devices share a single parallel
++	  port and it is safe to compile the corresponding drivers into the
++	  kernel.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called de620.
++
++config SGISEEQ
++	tristate "SGI Seeq ethernet controller support"
++	depends on SGI_HAS_SEEQ
++	help
++	  Say Y here if you have an Seeq based Ethernet network card. This is
++	  used in many Silicon Graphics machines.
++
++config DECLANCE
++	tristate "DEC LANCE ethernet controller support"
++	depends on MACH_DECSTATION
++	select CRC32
++	help
++	  This driver is for the series of Ethernet controllers produced by
++	  DEC (now Compaq) based on the AMD Lance chipset, including the
++	  DEPCA series.  (This chipset is better known via the NE2100 cards.)
++
++config 68360_ENET
++	bool "Motorola 68360 ethernet controller"
++	depends on M68360
++	help
++	  Say Y here if you want to use the built-in ethernet controller of
++	  the Motorola 68360 processor.
++
++config FEC
++	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
++	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
++		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
++	select PHYLIB
++	help
++	  Say Y here if you want to use the built-in 10/100 Fast ethernet
++	  controller on some Motorola ColdFire and Freescale i.MX processors.
++
++config FEC2
++	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
++	depends on FEC
++	help
++	  Say Y here if you want to use the second built-in 10/100 Fast
++	  ethernet controller on some Motorola ColdFire processors.
++
++config FEC_MPC52xx
++	tristate "MPC52xx FEC driver"
++	depends on PPC_MPC52xx && PPC_BESTCOMM
++	select CRC32
++	select PHYLIB
++	select PPC_BESTCOMM_FEC
++	---help---
++	  This option enables support for the MPC5200's on-chip
++	  Fast Ethernet Controller
++	  If compiled as module, it will be called fec_mpc52xx.
++
++config FEC_MPC52xx_MDIO
++	bool "MPC52xx FEC MDIO bus driver"
++	depends on FEC_MPC52xx
++	default y
++	---help---
++	  The MPC5200's FEC can connect to the Ethernet either with
++	  an external MII PHY chip or 10 Mbps 7-wire interface
++	  (Motorola? industry standard).
++	  If your board uses an external PHY connected to FEC, enable this.
++	  If not sure, enable.
++	  If compiled as module, it will be called fec_mpc52xx_phy.
++
++config NE_H8300
++	tristate "NE2000 compatible support for H8/300"
++	depends on H8300
++	help
++	  Say Y here if you want to use the NE2000 compatible
++	  controller on the Renesas H8/300 processor.
++
++config ATL2
++	tristate "Atheros L2 Fast Ethernet support"
++	depends on PCI
++	select CRC32
++	select MII
++	help
++	  This driver supports the Atheros L2 fast ethernet adapter.
++
++	  To compile this driver as a module, choose M here.  The module
++	  will be called atl2.
++
++config XILINX_EMACLITE
++	tristate "Xilinx 10/100 Ethernet Lite support"
++	depends on PPC32 || MICROBLAZE
++	select PHYLIB
++	help
++	  This driver supports the 10/100 Ethernet Lite from Xilinx.
++
++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"
++
++source "drivers/net/octeon/Kconfig"
++
++endif # NET_ETHERNET
++
++#
++#	Gigabit Ethernet
++#
++
++menuconfig NETDEV_1000
++	bool "Ethernet (1000 Mbit)"
++	depends on !UML
++	default y
++	---help---
++	  Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
++	  type of Local Area Network (LAN) in universities and companies.
++
++	  Say Y here to get to see options for Gigabit Ethernet drivers.
++	  This option alone does not add any kernel code.
++	  Note that drivers supporting both 100 and 1000 MBit may be listed
++	  under "Ethernet (10 or 100MBit)" instead.
++
++	  If you say N, all options in this submenu will be skipped and disabled.
++
++if NETDEV_1000
++
++config ACENIC
++	tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
++	depends on PCI
++	---help---
++	  Say Y here if you have an Alteon AceNIC, 3Com 3C985(B), NetGear
++	  GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit Ethernet
++	  adapter. The driver allows for using the Jumbo Frame option (9000
++	  bytes/frame) however it requires that your switches can handle this
++	  as well. To enable Jumbo Frames, add `mtu 9000' to your ifconfig
++	  line.
++
++	  To compile this driver as a module, choose M here: the
++	  module will be called acenic.
++
++config ACENIC_OMIT_TIGON_I
++	bool "Omit support for old Tigon I based AceNICs"
++	depends on ACENIC
++	help
++	  Say Y here if you only have Tigon II based AceNICs and want to leave
++	  out support for the older Tigon I based cards which are no longer
++	  being sold (ie. the original Alteon AceNIC and 3Com 3C985 (non B
++	  version)).  This will reduce the size of the driver object by
++	  app. 100KB.  If you are not sure whether your card is a Tigon I or a
++	  Tigon II, say N here.
++
++	  The safe and default value for this is N.
++
++config DL2K
++	tristate "DL2000/TC902x-based Gigabit Ethernet support"
++	depends on PCI
++	select CRC32
++	help
++	  This driver supports DL2000/TC902x-based Gigabit ethernet cards,
++	  which includes
++	  D-Link DGE-550T Gigabit Ethernet Adapter.
++	  D-Link DL2000-based Gigabit Ethernet Adapter.
++	  Sundance/Tamarack TC902x Gigabit Ethernet Adapter.
++
++	  To compile this driver as a module, choose M here: the
++	  module will be called dl2k.
++
++config E1000
++	tristate "Intel(R) PRO/1000 Gigabit Ethernet support"
++	depends on PCI
++	---help---
++	  This driver supports Intel(R) PRO/1000 gigabit ethernet family of
++	  adapters.  For more information on how to identify your adapter, go 
++	  to the Adapter & Driver ID Guide at:
++
++	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
++
++	  For general information and support, go to the Intel support
++	  website at:
++
++	  <http://support.intel.com>
++
++	  More specific information on configuring the driver is in 
++	  <file:Documentation/networking/e1000.txt>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called e1000.
++
++config E1000E
++	tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support"
++	depends on PCI && (!SPARC32 || BROKEN)
++	---help---
++	  This driver supports the PCI-Express Intel(R) PRO/1000 gigabit
++	  ethernet family of adapters. For PCI or PCI-X e1000 adapters,
++	  use the regular e1000 driver For more information on how to
++	  identify your adapter, go to the Adapter & Driver ID Guide at:
++
++	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
++
++	  For general information and support, go to the Intel support
++	  website at:
++
++	  <http://support.intel.com>
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called e1000e.
++
++config IP1000
++	tristate "IP1000 Gigabit Ethernet support"
++	depends on PCI && EXPERIMENTAL
++	select MII
++	---help---
++	  This driver supports IP1000 gigabit Ethernet cards.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called ipg.  This is recommended.
++
++config IGB
++       tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support"
++       depends on PCI
++       ---help---
++         This driver supports Intel(R) 82575/82576 gigabit ethernet family of
++         adapters.  For more information on how to identify your adapter, go
++         to the Adapter & Driver ID Guide at:
++
++         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
++
++         For general information and support, go to the Intel support
++         website at:
++
++         <http://support.intel.com>
++
++         More specific information on configuring the driver is in
++         <file:Documentation/networking/e1000.txt>.
++
++         To compile this driver as a module, choose M here. The module
++         will be called igb.
++
++config IGB_DCA
++	bool "Direct Cache Access (DCA) Support"
++	default y
++	depends on IGB && DCA && !(IGB=y && DCA=m)
++	---help---
++	  Say Y here if you want to use Direct Cache Access (DCA) in the
++	  driver.  DCA is a method for warming the CPU cache before data
++	  is used, with the intent of lessening the impact of cache misses.
++
++config IGBVF
++       tristate "Intel(R) 82576 Virtual Function Ethernet support"
++       depends on PCI
++       ---help---
++         This driver supports Intel(R) 82576 virtual functions.  For more
++         information on how to identify your adapter, go to the Adapter &
++         Driver ID Guide at:
++
++         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
++
++         For general information and support, go to the Intel support
++         website at:
++
++         <http://support.intel.com>
++
++         More specific information on configuring the driver is in
++         <file:Documentation/networking/e1000.txt>.
++
++         To compile this driver as a module, choose M here. The module
++         will be called igbvf.
++
++source "drivers/net/ixp2000/Kconfig"
++
++config MYRI_SBUS
++	tristate "MyriCOM Gigabit Ethernet support"
++	depends on SBUS
++	help
++	  This driver supports MyriCOM Sbus gigabit Ethernet cards.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called myri_sbus.  This is recommended.
++
++config NS83820
++	tristate "National Semiconductor DP83820 support"
++	depends on PCI
++	help
++	  This is a driver for the National Semiconductor DP83820 series
++	  of gigabit ethernet MACs.  Cards using this chipset include
++	  the D-Link DGE-500T, PureData's PDP8023Z-TG, SMC's SMC9462TX,
++	  SOHO-GA2000T, SOHO-GA2500T.  The driver supports the use of
++	  zero copy.
++
++config HAMACHI
++	tristate "Packet Engines Hamachi GNIC-II support"
++	depends on PCI
++	select MII
++	help
++	  If you have a Gigabit Ethernet card of this type, say Y and read
++	  the Ethernet-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>.
++
++	  To compile this driver as a module, choose M here. The module will be
++	  called hamachi.
++
++config YELLOWFIN
++	tristate "Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)"
++	depends on PCI && EXPERIMENTAL
++	select CRC32
++	---help---
++	  Say Y here if you have a Packet Engines G-NIC PCI Gigabit Ethernet
++	  adapter or the SYM53C885 Ethernet controller. The Gigabit adapter is
++	  used by the Beowulf Linux cluster project.  See
++	  <http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.html> for more
++	  information about this driver in particular and Beowulf in general.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called yellowfin.  This is recommended.
++
++config R8169
++	tristate "Realtek 8169 gigabit ethernet support"
++	depends on PCI
++	select CRC32
++	select MII
++	---help---
++	  Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called r8169.  This is recommended.
++
++config R8169_VLAN
++	bool "VLAN support"
++	depends on R8169 && VLAN_8021Q
++	---help---
++	  Say Y here for the r8169 driver to support the functions required
++	  by the kernel 802.1Q code.
++
++	  If in doubt, say Y.
++
++config SB1250_MAC
++	tristate "SB1250 Gigabit Ethernet support"
++	depends on SIBYTE_SB1xxx_SOC
++	select PHYLIB
++	---help---
++	  This driver supports Gigabit Ethernet interfaces based on the
++	  Broadcom SiByte family of System-On-a-Chip parts.  They include
++	  the BCM1120, BCM1125, BCM1125H, BCM1250, BCM1255, BCM1280, BCM1455
++	  and BCM1480 chips.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called sb1250-mac.
++
++config SIS190
++	tristate "SiS190/SiS191 gigabit ethernet support"
++	depends on PCI
++	select CRC32
++	select MII
++	---help---
++	  Say Y here if you have a SiS 190 PCI Fast Ethernet adapter or
++	  a SiS 191 PCI Gigabit Ethernet adapter. Both are expected to
++	  appear in lan on motherboard designs which are based on SiS 965
++	  and SiS 966 south bridge.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called sis190.  This is recommended.
++
++config SKGE
++	tristate "New SysKonnect GigaEthernet support"
++	depends on PCI
++	select CRC32
++	---help---
++	  This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
++	  and related Gigabit Ethernet adapters. It is a new smaller driver
++	  with better performance and more complete ethtool support.
++
++	  It does not support the link failover and network management 
++	  features that "portable" vendor supplied sk98lin driver does.
++
++	  This driver supports adapters based on the original Yukon chipset:
++	  Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
++	  Linksys EG1032/EG1064, 3Com 3C940/3C940B, SysKonnect SK-9871/9872.
++
++	  It does not support the newer Yukon2 chipset: a separate driver,
++	  sky2, is provided for Yukon2-based adapters.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called skge.  This is recommended.
++
++config SKGE_DEBUG
++       bool "Debugging interface"
++       depends on SKGE && DEBUG_FS
++       help
++	 This option adds the ability to dump driver state for debugging.
++	 The file /sys/kernel/debug/skge/ethX displays the state of the internal
++	 transmit and receive rings.
++
++	 If unsure, say N.
++
++config SKY2
++	tristate "SysKonnect Yukon2 support"
++	depends on PCI
++	select CRC32
++	---help---
++	  This driver supports Gigabit Ethernet adapters based on the
++	  Marvell Yukon 2 chipset:
++	  Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
++	  88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21
++
++	  There is companion driver for the older Marvell Yukon and
++	  Genesis based adapters: skge.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called sky2.  This is recommended.
++
++config SKY2_DEBUG
++       bool "Debugging interface"
++       depends on SKY2 && DEBUG_FS
++       help
++	 This option adds the ability to dump driver state for debugging.
++	 The file /sys/kernel/debug/sky2/ethX displays the state of the internal
++	 transmit and receive rings.
++
++	 If unsure, say N.
++
++config VIA_VELOCITY
++	tristate "VIA Velocity support"
++	depends on PCI
++	select CRC32
++	select CRC_CCITT
++	select MII
++	help
++	  If you have a VIA "Velocity" based network card say Y here.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called via-velocity.
++
++config TIGON3
++	tristate "Broadcom Tigon3 support"
++	depends on PCI
++	select PHYLIB
++	help
++	  This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called tg3.  This is recommended.
++
++config BNX2
++	tristate "Broadcom NetXtremeII support"
++	depends on PCI
++	select CRC32
++	select FW_LOADER
++	help
++	  This driver supports Broadcom NetXtremeII gigabit Ethernet cards.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called bnx2.  This is recommended.
++
++config CNIC
++	tristate "Broadcom CNIC support"
++	depends on PCI
++	select BNX2
++	select UIO
++	help
++	  This driver supports offload features of Broadcom NetXtremeII
++	  gigabit Ethernet cards.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called cnic.  This is recommended.
++
++config SPIDER_NET
++	tristate "Spider Gigabit Ethernet driver"
++	depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB)
++	select FW_LOADER
++	help
++	  This driver supports the Gigabit Ethernet chips present on the
++	  Cell Processor-Based Blades from IBM.
++
++config TSI108_ETH
++	   tristate "Tundra TSI108 gigabit Ethernet support"
++	   depends on TSI108_BRIDGE
++	   help
++	     This driver supports Tundra TSI108 gigabit Ethernet ports.
++	     To compile this driver as a module, choose M here: the module
++	     will be called tsi108_eth.
++
++config GELIC_NET
++	tristate "PS3 Gigabit Ethernet driver"
++	depends on PPC_PS3
++	select PS3_SYS_MANAGER
++	help
++	  This driver supports the network device on the PS3 game
++	  console.  This driver has built-in support for Ethernet.
++
++	  To compile this driver as a module, choose M here: the
++	  module will be called ps3_gelic.
++
++config GELIC_WIRELESS
++	bool "PS3 Wireless support"
++	depends on WLAN
++	depends on GELIC_NET
++	select WIRELESS_EXT
++	help
++	  This option adds the support for the wireless feature of PS3.
++	  If you have the wireless-less model of PS3 or have no plan to
++	  use wireless feature, disabling this option saves memory.  As
++	  the driver automatically distinguishes the models, you can
++	  safely enable this option even if you have a wireless-less model.
++
++config FSL_PQ_MDIO
++	tristate "Freescale PQ MDIO"
++	depends on FSL_SOC
++	select PHYLIB
++	help
++	  This driver supports the MDIO bus used by the gianfar and UCC drivers.
++
++config GIANFAR
++	tristate "Gianfar Ethernet"
++	depends on FSL_SOC
++	select FSL_PQ_MDIO
++	select PHYLIB
++	select CRC32
++	help
++	  This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
++	  and MPC86xx family of chips, and the FEC on the 8540.
++
++config UCC_GETH
++	tristate "Freescale QE Gigabit Ethernet"
++	depends on QUICC_ENGINE
++	select FSL_PQ_MDIO
++	select PHYLIB
++	help
++	  This driver supports the Gigabit Ethernet mode of the QUICC Engine,
++	  which is available on some Freescale SOCs.
++
++config UGETH_TX_ON_DEMAND
++	bool "Transmit on Demand support"
++	depends on UCC_GETH
++
++config MV643XX_ETH
++	tristate "Marvell Discovery (643XX) and Orion ethernet support"
++	depends on MV64X60 || PPC32 || PLAT_ORION
++	select INET_LRO
++	select PHYLIB
++	help
++	  This driver supports the gigabit ethernet MACs in the
++	  Marvell Discovery PPC/MIPS chipset family (MV643XX) and
++	  in the Marvell Orion ARM SoC family.
++
++	  Some boards that use the Discovery chipset are the Momenco
++	  Ocelot C and Jaguar ATX and Pegasos II.
++
++config XILINX_LL_TEMAC
++	tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
++	depends on PPC || MICROBLAZE
++	select PHYLIB
++	help
++	  This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
++	  core used in Xilinx Spartan and Virtex FPGAs
++
++config QLA3XXX
++	tristate "QLogic QLA3XXX Network Driver Support"
++	depends on PCI
++	help
++	  This driver supports QLogic ISP3XXX gigabit Ethernet cards.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called qla3xxx.
++
++config ATL1
++	tristate "Atheros/Attansic L1 Gigabit Ethernet support"
++	depends on PCI
++	select CRC32
++	select MII
++	help
++	  This driver supports the Atheros/Attansic L1 gigabit ethernet
++	  adapter.
++
++	  To compile this driver as a module, choose M here.  The module
++	  will be called atl1.
++
++config ATL1E
++	tristate "Atheros L1E Gigabit Ethernet support (EXPERIMENTAL)"
++	depends on PCI && EXPERIMENTAL
++	select CRC32
++	select MII
++	help
++	  This driver supports the Atheros L1E gigabit ethernet adapter.
++
++	  To compile this driver as a module, choose M here.  The module
++	  will be called atl1e.
++
++config ATL1C
++	tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)"
++	depends on PCI && EXPERIMENTAL
++	select CRC32
++	select MII
++	help
++	  This driver supports the Atheros L1C gigabit ethernet adapter.
++
++	  To compile this driver as a module, choose M here.  The module
++	  will be called atl1c.
++
++config JME
++	tristate "JMicron(R) PCI-Express Gigabit Ethernet support"
++	depends on PCI
++	select CRC32
++	select MII
++	---help---
++	  This driver supports the PCI-Express gigabit ethernet adapters
++	  based on JMicron JMC250 chipset.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called jme.
++
++config S6GMAC
++	tristate "S6105 GMAC ethernet support"
++	depends on XTENSA_VARIANT_S6000
++	select PHYLIB
++	help
++	  This driver supports the on chip ethernet device on the
++	  S6105 xtensa processor.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called s6gmac.
++
++source "drivers/net/stmmac/Kconfig"
++
++endif # NETDEV_1000
++
++#
++#	10 Gigabit Ethernet
++#
++
++menuconfig NETDEV_10000
++	bool "Ethernet (10000 Mbit)"
++	depends on !UML
++	default y
++	---help---
++	  Say Y here to get to see options for 10 Gigabit Ethernet drivers.
++	  This option alone does not add any kernel code.
++
++	  If you say N, all options in this submenu will be skipped and disabled.
++
++if NETDEV_10000
++
++config MDIO
++	tristate
++
++config CHELSIO_T1
++        tristate "Chelsio 10Gb Ethernet support"
++        depends on PCI
++	select CRC32
++	select MDIO
++        help
++          This driver supports Chelsio gigabit and 10-gigabit
++          Ethernet cards. More information about adapter features and
++	  performance tuning is in <file:Documentation/networking/cxgb.txt>.
++
++          For general information about Chelsio and our products, visit
++          our website at <http://www.chelsio.com>.
++
++          For customer support, please visit our customer support page at
++          <http://www.chelsio.com/support.htm>.
++
++          Please send feedback to <linux-bugs@chelsio.com>.
++
++          To compile this driver as a module, choose M here: the module
++          will be called cxgb.
++
++config CHELSIO_T1_1G
++        bool "Chelsio gigabit Ethernet support"
++        depends on CHELSIO_T1
++        help
++          Enables support for Chelsio's gigabit Ethernet PCI cards.  If you
++          are using only 10G cards say 'N' here.
++
++config CHELSIO_T3_DEPENDS
++	tristate
++	depends on PCI && INET
++	default y
++
++config CHELSIO_T3
++	tristate "Chelsio Communications T3 10Gb Ethernet support"
++	depends on CHELSIO_T3_DEPENDS
++	select FW_LOADER
++	select MDIO
++	help
++	  This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
++	  adapters.
++
++	  For general information about Chelsio and our products, visit
++	  our website at <http://www.chelsio.com>.
++
++	  For customer support, please visit our customer support page at
++	  <http://www.chelsio.com/support.htm>.
++
++	  Please send feedback to <linux-bugs@chelsio.com>.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called cxgb3.
++
++config CHELSIO_T4_DEPENDS
++	tristate
++	depends on PCI && INET
++	default y
++
++config CHELSIO_T4
++	tristate "Chelsio Communications T4 Ethernet support"
++	depends on CHELSIO_T4_DEPENDS
++	select FW_LOADER
++	select MDIO
++	help
++	  This driver supports Chelsio T4-based gigabit and 10Gb Ethernet
++	  adapters.
++
++	  For general information about Chelsio and our products, visit
++	  our website at <http://www.chelsio.com>.
++
++	  For customer support, please visit our customer support page at
++	  <http://www.chelsio.com/support.htm>.
++
++	  Please send feedback to <linux-bugs@chelsio.com>.
++
++	  To compile this driver as a module choose M here; the module
++	  will be called cxgb4.
++
++config EHEA
++	tristate "eHEA Ethernet support"
++	depends on IBMEBUS && INET && SPARSEMEM
++	select INET_LRO
++	---help---
++	  This driver supports the IBM pSeries eHEA ethernet adapter.
++
++	  To compile the driver as a module, choose M here. The module
++	  will be called ehea.
++
++config ENIC
++	tristate "Cisco VIC Ethernet NIC Support"
++	depends on PCI && INET
++	select INET_LRO
++	help
++	  This enables the support for the Cisco VIC Ethernet card.
++
++config IXGBE
++	tristate "Intel(R) 10GbE PCI Express adapters support"
++	depends on PCI && INET
++	select MDIO
++	---help---
++	  This driver supports Intel(R) 10GbE PCI Express family of
++	  adapters.  For more information on how to identify your adapter, go
++	  to the Adapter & Driver ID Guide at:
++
++	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
++
++	  For general information and support, go to the Intel support
++	  website at:
++
++	  <http://support.intel.com>
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ixgbe.
++
++config IXGBE_DCA
++	bool "Direct Cache Access (DCA) Support"
++	default y
++	depends on IXGBE && DCA && !(IXGBE=y && DCA=m)
++	---help---
++	  Say Y here if you want to use Direct Cache Access (DCA) in the
++	  driver.  DCA is a method for warming the CPU cache before data
++	  is used, with the intent of lessening the impact of cache misses.
++
++config IXGBE_DCB
++	bool "Data Center Bridging (DCB) Support"
++	default n
++	depends on IXGBE && DCB
++	---help---
++	  Say Y here if you want to use Data Center Bridging (DCB) in the
++	  driver.
++
++	  If unsure, say N.
++
++config IXGBEVF
++       tristate "Intel(R) 82599 Virtual Function Ethernet support"
++       depends on PCI_MSI
++       ---help---
++         This driver supports Intel(R) 82599 virtual functions.  For more
++         information on how to identify your adapter, go to the Adapter &
++         Driver ID Guide at:
++
++         <http://support.intel.com/support/network/sb/CS-008441.htm>
++
++         For general information and support, go to the Intel support
++         website at:
++
++         <http://support.intel.com>
++
++         More specific information on configuring the driver is in
++         <file:Documentation/networking/ixgbevf.txt>.
++
++         To compile this driver as a module, choose M here. The module
++         will be called ixgbevf.  MSI-X interrupt support is required
++         for this driver to work correctly.
++
++config IXGB
++	tristate "Intel(R) PRO/10GbE support"
++	depends on PCI
++	---help---
++	  This driver supports Intel(R) PRO/10GbE family of adapters for
++	  PCI-X type cards. For PCI-E type cards, use the "ixgbe" driver
++	  instead. For more information on how to identify your adapter, go
++	  to the Adapter & Driver ID Guide at:
++
++	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
++
++	  For general information and support, go to the Intel support
++	  website at:
++
++	  <http://support.intel.com>
++
++	  More specific information on configuring the driver is in 
++	  <file:Documentation/networking/ixgb.txt>.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called ixgb.
++
++config S2IO
++	tristate "S2IO 10Gbe XFrame NIC"
++	depends on PCI
++	---help---
++	  This driver supports the 10Gbe XFrame NIC of S2IO. 
++	  More specific information on configuring the driver is in 
++	  <file:Documentation/networking/s2io.txt>.
++
++config VXGE
++	tristate "Neterion X3100 Series 10GbE PCIe Server Adapter"
++	depends on PCI && INET
++	---help---
++	  This driver supports Neterion Inc's X3100 Series 10 GbE PCIe
++	  I/O Virtualized Server Adapter.
++	  More specific information on configuring the driver is in
++	  <file:Documentation/networking/vxge.txt>.
++
++config VXGE_DEBUG_TRACE_ALL
++	bool "Enabling All Debug trace statments in driver"
++	default n
++	depends on VXGE
++	---help---
++	  Say Y here if you want to enabling all the debug trace statements in
++	  driver. By  default only few debug trace statements are enabled.
++
++config MYRI10GE
++	tristate "Myricom Myri-10G Ethernet support"
++	depends on PCI && INET
++	select FW_LOADER
++	select CRC32
++	select INET_LRO
++	---help---
++	  This driver supports Myricom Myri-10G Dual Protocol interface in
++	  Ethernet mode. If the eeprom on your board is not recent enough,
++	  you will need a newer firmware image.
++	  You may get this image or more information, at:
++
++	  <http://www.myri.com/scs/download-Myri10GE.html>
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called myri10ge.
++
++config MYRI10GE_DCA
++	bool "Direct Cache Access (DCA) Support"
++	default y
++	depends on MYRI10GE && DCA && !(MYRI10GE=y && DCA=m)
++	---help---
++	  Say Y here if you want to use Direct Cache Access (DCA) in the
++	  driver.  DCA is a method for warming the CPU cache before data
++	  is used, with the intent of lessening the impact of cache misses.
++
++config NETXEN_NIC
++	tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC"
++	depends on PCI
++	select FW_LOADER
++	help
++	  This enables the support for NetXen's Gigabit Ethernet card.
++
++config NIU
++	tristate "Sun Neptune 10Gbit Ethernet support"
++	depends on PCI
++	select CRC32
++	help
++	  This enables support for cards based upon Sun's
++	  Neptune chipset.
++
++config PASEMI_MAC
++	tristate "PA Semi 1/10Gbit MAC"
++	depends on PPC_PASEMI && PCI
++	select PHYLIB
++	select INET_LRO
++	help
++	  This driver supports the on-chip 1/10Gbit Ethernet controller on
++	  PA Semi's PWRficient line of chips.
++
++config MLX4_EN
++	tristate "Mellanox Technologies 10Gbit Ethernet support"
++	depends on PCI && INET
++	select MLX4_CORE
++	select INET_LRO
++	help
++	  This driver supports Mellanox Technologies ConnectX Ethernet
++	  devices.
++
++config MLX4_CORE
++	tristate
++	depends on PCI
++	default n
++
++config MLX4_DEBUG
++	bool "Verbose debugging output" if (MLX4_CORE && EMBEDDED)
++	depends on MLX4_CORE
++	default y
++	---help---
++	  This option causes debugging code to be compiled into the
++	  mlx4_core driver.  The output can be turned on via the
++	  debug_level module parameter (which can also be set after
++	  the driver is loaded through sysfs).
++
++config TEHUTI
++	tristate "Tehuti Networks 10G Ethernet"
++	depends on PCI
++	help
++	  Tehuti Networks 10G Ethernet NIC
++
++config BNX2X
++	tristate "Broadcom NetXtremeII 10Gb support"
++	depends on PCI
++	select FW_LOADER
++	select ZLIB_INFLATE
++	select LIBCRC32C
++	select MDIO
++	help
++	  This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
++	  To compile this driver as a module, choose M here: the module
++	  will be called bnx2x.  This is recommended.
++
++config QLCNIC
++	tristate "QLOGIC QLCNIC 1/10Gb Converged Ethernet NIC Support"
++	depends on PCI
++	select FW_LOADER
++	help
++	  This driver supports QLogic QLE8240 and QLE8242 Converged Ethernet
++	  devices.
++
++config QLGE
++	tristate "QLogic QLGE 10Gb Ethernet Driver Support"
++	depends on PCI
++	help
++	  This driver supports QLogic ISP8XXX 10Gb Ethernet cards.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called qlge.
++
++source "drivers/net/sfc/Kconfig"
++
++source "drivers/net/benet/Kconfig"
++
++endif # NETDEV_10000
++
++source "drivers/net/tokenring/Kconfig"
++
++source "drivers/net/wireless/Kconfig"
++
++source "drivers/net/wimax/Kconfig"
++
++source "drivers/net/usb/Kconfig"
++
++source "drivers/net/pcmcia/Kconfig"
++
++source "drivers/net/wan/Kconfig"
++
++source "drivers/atm/Kconfig"
++
++source "drivers/ieee802154/Kconfig"
++
++source "drivers/s390/net/Kconfig"
++
++source "drivers/net/caif/Kconfig"
++
++config XEN_NETDEV_FRONTEND
++	tristate "Xen network device frontend driver"
++	depends on XEN
++	default y
++	help
++	  The network device frontend driver allows the kernel to
++	  access network devices exported exported by a virtual
++	  machine containing a physical network device driver. The
++	  frontend driver is intended for unprivileged guest domains;
++	  if you are compiling a kernel for a Xen guest, you almost
++	  certainly want to enable this.
++
++config ISERIES_VETH
++	tristate "iSeries Virtual Ethernet driver support"
++	depends on PPC_ISERIES
++
++config RIONET
++	tristate "RapidIO Ethernet over messaging driver support"
++	depends on RAPIDIO
++
++config RIONET_TX_SIZE
++	int "Number of outbound queue entries"
++	depends on RIONET
++	default "128"
++
++config RIONET_RX_SIZE
++	int "Number of inbound queue entries"
++	depends on RIONET
++	default "128"
++
++config FDDI
++	tristate "FDDI driver support"
++	depends on (PCI || EISA || TC)
++	help
++	  Fiber Distributed Data Interface is a high speed local area network
++	  design; essentially a replacement for high speed Ethernet. FDDI can
++	  run over copper or fiber. If you are connected to such a network and
++	  want a driver for the FDDI card in your computer, say Y here (and
++	  then also Y to the driver for your FDDI card, below). Most people
++	  will say N.
++
++config DEFXX
++	tristate "Digital DEFTA/DEFEA/DEFPA adapter support"
++	depends on FDDI && (PCI || EISA || TC)
++	---help---
++	  This is support for the DIGITAL series of TURBOchannel (DEFTA),
++	  EISA (DEFEA) and PCI (DEFPA) controllers which can connect you
++	  to a local FDDI network.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called defxx.  If unsure, say N.
++
++config DEFXX_MMIO
++	bool
++	prompt "Use MMIO instead of PIO" if PCI || EISA
++	depends on DEFXX
++	default n if PCI || EISA
++	default y
++	---help---
++	  This instructs the driver to use EISA or PCI memory-mapped I/O
++	  (MMIO) as appropriate instead of programmed I/O ports (PIO).
++	  Enabling this gives an improvement in processing time in parts
++	  of the driver, but it may cause problems with EISA (DEFEA)
++	  adapters.  TURBOchannel does not have the concept of I/O ports,
++	  so MMIO is always used for these (DEFTA) adapters.
++
++	  If unsure, say N.
++
++config SKFP
++	tristate "SysKonnect FDDI PCI support"
++	depends on FDDI && PCI
++	select BITREVERSE
++	---help---
++	  Say Y here if you have a SysKonnect FDDI PCI adapter.
++	  The following adapters are supported by this driver:
++	  - SK-5521 (SK-NET FDDI-UP)
++	  - SK-5522 (SK-NET FDDI-UP DAS)
++	  - SK-5541 (SK-NET FDDI-FP)
++	  - SK-5543 (SK-NET FDDI-LP)
++	  - SK-5544 (SK-NET FDDI-LP DAS)
++	  - SK-5821 (SK-NET FDDI-UP64)
++	  - SK-5822 (SK-NET FDDI-UP64 DAS)
++	  - SK-5841 (SK-NET FDDI-FP64)
++	  - SK-5843 (SK-NET FDDI-LP64)
++	  - SK-5844 (SK-NET FDDI-LP64 DAS)
++	  - Netelligent 100 FDDI DAS Fibre SC
++	  - Netelligent 100 FDDI SAS Fibre SC
++	  - Netelligent 100 FDDI DAS UTP
++	  - Netelligent 100 FDDI SAS UTP
++	  - Netelligent 100 FDDI SAS Fibre MIC
++
++	  Read <file:Documentation/networking/skfp.txt> for information about
++	  the driver.
++
++	  Questions concerning this driver can be addressed to:
++	  <linux@syskonnect.de>
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called skfp.  This is recommended.
++
++config HIPPI
++	bool "HIPPI driver support (EXPERIMENTAL)"
++	depends on EXPERIMENTAL && INET && PCI
++	help
++	  HIgh Performance Parallel Interface (HIPPI) is a 800Mbit/sec and
++	  1600Mbit/sec dual-simplex switched or point-to-point network. HIPPI
++	  can run over copper (25m) or fiber (300m on multi-mode or 10km on
++	  single-mode). HIPPI networks are commonly used for clusters and to
++	  connect to super computers. If you are connected to a HIPPI network
++	  and have a HIPPI network card in your computer that you want to use
++	  under Linux, say Y here (you must also remember to enable the driver
++	  for your HIPPI card below). Most people will say N here.
++
++config ROADRUNNER
++	tristate "Essential RoadRunner HIPPI PCI adapter support (EXPERIMENTAL)"
++	depends on HIPPI && PCI
++	help
++	  Say Y here if this is your PCI HIPPI network card.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called rrunner.  If unsure, say N.
++
++config ROADRUNNER_LARGE_RINGS
++	bool "Use large TX/RX rings (EXPERIMENTAL)"
++	depends on ROADRUNNER
++	help
++	  If you say Y here, the RoadRunner driver will preallocate up to 2 MB
++	  of additional memory to allow for fastest operation, both for
++	  transmitting and receiving. This memory cannot be used by any other
++	  kernel code or by user space programs. Say Y here only if you have
++	  the memory.
++
++config PLIP
++	tristate "PLIP (parallel port) support"
++	depends on PARPORT
++	---help---
++	  PLIP (Parallel Line Internet Protocol) is used to create a
++	  reasonably fast mini network consisting of two (or, rarely, more)
++	  local machines.  A PLIP link from a Linux box is a popular means to
++	  install a Linux distribution on a machine which doesn't have a
++	  CD-ROM drive (a minimal system has to be transferred with floppies
++	  first). The kernels on both machines need to have this PLIP option
++	  enabled for this to work.
++
++	  The PLIP driver has two modes, mode 0 and mode 1.  The parallel
++	  ports (the connectors at the computers with 25 holes) are connected
++	  with "null printer" or "Turbo Laplink" cables which can transmit 4
++	  bits at a time (mode 0) or with special PLIP cables, to be used on
++	  bidirectional parallel ports only, which can transmit 8 bits at a
++	  time (mode 1); you can find the wiring of these cables in
++	  <file:Documentation/networking/PLIP.txt>.  The cables can be up to
++	  15m long.  Mode 0 works also if one of the machines runs DOS/Windows
++	  and has some PLIP software installed, e.g. the Crynwr PLIP packet
++	  driver (<http://oak.oakland.edu/simtel.net/msdos/pktdrvr-pre.html>)
++	  and winsock or NCSA's telnet.
++
++	  If you want to use PLIP, say Y and read the PLIP mini-HOWTO as well
++	  as the NET-3-HOWTO, both available from
++	  <http://www.tldp.org/docs.html#howto>.  Note that the PLIP
++	  protocol has been changed and this PLIP driver won't work together
++	  with the PLIP support in Linux versions 1.0.x.  This option enlarges
++	  your kernel by about 8 KB.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called plip. If unsure, say Y or M, in case you buy
++	  a laptop later.
++
++config PPP
++	tristate "PPP (point-to-point protocol) support"
++	select SLHC
++	---help---
++	  PPP (Point to Point Protocol) is a newer and better SLIP.  It serves
++	  the same purpose: sending Internet traffic over telephone (and other
++	  serial) lines.  Ask your access provider if they support it, because
++	  otherwise you can't use it; most Internet access providers these
++	  days support PPP rather than SLIP.
++
++	  To use PPP, you need an additional program called pppd as described
++	  in the PPP-HOWTO, available at
++	  <http://www.tldp.org/docs.html#howto>.  Make sure that you have
++	  the version of pppd recommended in <file:Documentation/Changes>.
++	  The PPP option enlarges your kernel by about 16 KB.
++
++	  There are actually two versions of PPP: the traditional PPP for
++	  asynchronous lines, such as regular analog phone lines, and
++	  synchronous PPP which can be used over digital ISDN lines for
++	  example.  If you want to use PPP over phone lines or other
++	  asynchronous serial lines, you need to say Y (or M) here and also to
++	  the next option, "PPP support for async serial ports".  For PPP over
++	  synchronous lines, you should say Y (or M) here and to "Support
++	  synchronous PPP", below.
++
++	  If you said Y to "Version information on all symbols" above, then
++	  you cannot compile the PPP driver into the kernel; you can then only
++	  compile it as a module. To compile this driver as a module, choose M
++	  here. The module will be called ppp_generic.
++
++config PPP_MULTILINK
++	bool "PPP multilink support (EXPERIMENTAL)"
++	depends on PPP && EXPERIMENTAL
++	help
++	  PPP multilink is a protocol (defined in RFC 1990) which allows you
++	  to combine several (logical or physical) lines into one logical PPP
++	  connection, so that you can utilize your full bandwidth.
++
++	  This has to be supported at the other end as well and you need a
++	  version of the pppd daemon which understands the multilink protocol.
++
++	  If unsure, say N.
++
++config PPP_FILTER
++	bool "PPP filtering"
++	depends on PPP
++	help
++	  Say Y here if you want to be able to filter the packets passing over
++	  PPP interfaces.  This allows you to control which packets count as
++	  activity (i.e. which packets will reset the idle timer or bring up
++	  a demand-dialed link) and which packets are to be dropped entirely.
++	  You need to say Y here if you wish to use the pass-filter and
++	  active-filter options to pppd.
++
++	  If unsure, say N.
++
++config PPP_ASYNC
++	tristate "PPP support for async serial ports"
++	depends on PPP
++	select CRC_CCITT
++	---help---
++	  Say Y (or M) here if you want to be able to use PPP over standard
++	  asynchronous serial ports, such as COM1 or COM2 on a PC.  If you use
++	  a modem (not a synchronous or ISDN modem) to contact your ISP, you
++	  need this option.
++
++	  To compile this driver as a module, choose M here.
++
++	  If unsure, say Y.
++
++config PPP_SYNC_TTY
++	tristate "PPP support for sync tty ports"
++	depends on PPP
++	help
++	  Say Y (or M) here if you want to be able to use PPP over synchronous
++	  (HDLC) tty devices, such as the SyncLink adapter. These devices
++	  are often used for high-speed leased lines like T1/E1.
++
++	  To compile this driver as a module, choose M here.
++
++config PPP_DEFLATE
++	tristate "PPP Deflate compression"
++	depends on PPP
++	select ZLIB_INFLATE
++	select ZLIB_DEFLATE
++	---help---
++	  Support for the Deflate compression method for PPP, which uses the
++	  Deflate algorithm (the same algorithm that gzip uses) to compress
++	  each PPP packet before it is sent over the wire.  The machine at the
++	  other end of the PPP link (usually your ISP) has to support the
++	  Deflate compression method as well for this to be useful.  Even if
++	  they don't support it, it is safe to say Y here.
++
++	  To compile this driver as a module, choose M here.
++
++config PPP_BSDCOMP
++	tristate "PPP BSD-Compress compression"
++	depends on PPP
++	---help---
++	  Support for the BSD-Compress compression method for PPP, which uses
++	  the LZW compression method to compress each PPP packet before it is
++	  sent over the wire. The machine at the other end of the PPP link
++	  (usually your ISP) has to support the BSD-Compress compression
++	  method as well for this to be useful. Even if they don't support it,
++	  it is safe to say Y here.
++
++	  The PPP Deflate compression method ("PPP Deflate compression",
++	  above) is preferable to BSD-Compress, because it compresses better
++	  and is patent-free.
++
++	  Note that the BSD compression code will always be compiled as a
++	  module; it is called bsd_comp and will show up in the directory
++	  modules once you have said "make modules". If unsure, say N.
++
++config PPP_MPPE
++       tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
++       depends on PPP && EXPERIMENTAL
++       select CRYPTO
++       select CRYPTO_SHA1
++       select CRYPTO_ARC4
++       select CRYPTO_ECB
++       ---help---
++         Support for the MPPE Encryption protocol, as employed by the
++	 Microsoft Point-to-Point Tunneling Protocol.
++
++	 See http://pptpclient.sourceforge.net/ for information on
++	 configuring PPTP clients and servers to utilize this method.
++
++config PPPOE
++	tristate "PPP over Ethernet (EXPERIMENTAL)"
++	depends on EXPERIMENTAL && PPP
++	help
++	  Support for PPP over Ethernet.
++
++	  This driver requires the latest version of pppd from the CVS
++	  repository at cvs.samba.org.  Alternatively, see the 
++	  RoaringPenguin package (<http://www.roaringpenguin.com/pppoe>)
++	  which contains instruction on how to use this driver (under 
++	  the heading "Kernel mode PPPoE").
++
++config PPPOATM
++	tristate "PPP over ATM"
++	depends on ATM && PPP
++	help
++	  Support PPP (Point to Point Protocol) encapsulated in ATM frames.
++	  This implementation does not yet comply with section 8 of RFC2364,
++	  which can lead to bad results if the ATM peer loses state and
++	  changes its encapsulation unilaterally.
++
++config PPPOL2TP
++	tristate "PPP over L2TP (EXPERIMENTAL)"
++	depends on EXPERIMENTAL && L2TP && PPP
++	help
++	  Support for PPP-over-L2TP socket family. L2TP is a protocol
++	  used by ISPs and enterprises to tunnel PPP traffic over UDP
++	  tunnels. L2TP is replacing PPTP for VPN uses.
++
++config SLIP
++	tristate "SLIP (serial line) support"
++	---help---
++	  Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to
++	  connect to your Internet service provider or to connect to some
++	  other local Unix box or if you want to configure your Linux box as a
++	  Slip/CSlip server for other people to dial in. SLIP (Serial Line
++	  Internet Protocol) is a protocol used to send Internet traffic over
++	  serial connections such as telephone lines or null modem cables;
++	  nowadays, the protocol PPP is more commonly used for this same
++	  purpose.
++
++	  Normally, your access provider has to support SLIP in order for you
++	  to be able to use it, but there is now a SLIP emulator called SLiRP
++	  around (available from
++	  <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which
++	  allows you to use SLIP over a regular dial up shell connection. If
++	  you plan to use SLiRP, make sure to say Y to CSLIP, below. The
++	  NET-3-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>, explains how to
++	  configure SLIP. Note that you don't need this option if you just
++	  want to run term (term is a program which gives you almost full
++	  Internet connectivity if you have a regular dial up shell account on
++	  some Internet connected Unix computer. Read
++	  <http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>). SLIP
++	  support will enlarge your kernel by about 4 KB. If unsure, say N.
++
++	  To compile this driver as a module, choose M here. The module
++	  will be called slip.
++
++config SLIP_COMPRESSED
++	bool "CSLIP compressed headers"
++	depends on SLIP
++	select SLHC
++	---help---
++	  This protocol is faster than SLIP because it uses compression on the
++	  TCP/IP headers (not on the data itself), but it has to be supported
++	  on both ends. Ask your access provider if you are not sure and
++	  answer Y, just in case. You will still be able to use plain SLIP. If
++	  you plan to use SLiRP, the SLIP emulator (available from
++	  <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which
++	  allows you to use SLIP over a regular dial up shell connection, you
++	  definitely want to say Y here. The NET-3-HOWTO, available from
++	  <http://www.tldp.org/docs.html#howto>, explains how to configure
++	  CSLIP. This won't enlarge your kernel.
++
++config SLHC
++	tristate
++	help
++	  This option enables Van Jacobsen serial line header compression
++	  routines.
++
++config SLIP_SMART
++	bool "Keepalive and linefill"
++	depends on SLIP
++	help
++	  Adds additional capabilities to the SLIP driver to support the
++	  RELCOM line fill and keepalive monitoring. Ideal on poor quality
++	  analogue lines.
++
++config SLIP_MODE_SLIP6
++	bool "Six bit SLIP encapsulation"
++	depends on SLIP
++	help
++	  Just occasionally you may need to run IP over hostile serial
++	  networks that don't pass all control characters or are only seven
++	  bit. Saying Y here adds an extra mode you can use with SLIP:
++	  "slip6". In this mode, SLIP will only send normal ASCII symbols over
++	  the serial device. Naturally, this has to be supported at the other
++	  end of the link as well. It's good enough, for example, to run IP
++	  over the async ports of a Camtec JNT Pad. If unsure, say N.
++
++config NET_FC
++	bool "Fibre Channel driver support"
++	depends on SCSI && PCI
++	help
++	  Fibre Channel is a high speed serial protocol mainly used to connect
++	  large storage devices to the computer; it is compatible with and
++	  intended to replace SCSI.
++
++	  If you intend to use Fibre Channel, you need to have a Fibre channel
++	  adaptor card in your computer; say Y here and to the driver for your
++	  adaptor below. You also should have said Y to "SCSI support" and
++	  "SCSI generic support".
++
++config NETCONSOLE
++	tristate "Network console logging support"
++	---help---
++	If you want to log kernel messages over the network, enable this.
++	See <file:Documentation/networking/netconsole.txt> for details.
++
++config NETCONSOLE_DYNAMIC
++	bool "Dynamic reconfiguration of logging targets"
++	depends on NETCONSOLE && SYSFS
++	select CONFIGFS_FS
++	help
++	  This option enables the ability to dynamically reconfigure target
++	  parameters (interface, IP addresses, port numbers, MAC addresses)
++	  at runtime through a userspace interface exported using configfs.
++	  See <file:Documentation/networking/netconsole.txt> for details.
++
++config NETPOLL
++	def_bool NETCONSOLE
++
++config NETPOLL_TRAP
++	bool "Netpoll traffic trapping"
++	default n
++	depends on NETPOLL
++
++config NET_POLL_CONTROLLER
++	def_bool NETPOLL
++
++config VIRTIO_NET
++	tristate "Virtio network driver (EXPERIMENTAL)"
++	depends on EXPERIMENTAL && VIRTIO
++	---help---
++	  This is the virtual network driver for virtio.  It can be used with
++          lguest or QEMU based VMMs (like KVM or Xen).  Say Y or M.
++
++config VMXNET3
++       tristate "VMware VMXNET3 ethernet driver"
++       depends on PCI && INET
++       help
++         This driver supports VMware's vmxnet3 virtual ethernet NIC.
++         To compile this driver as a module, choose M here: the
++         module will be called vmxnet3.
++
++endif # NETDEVICES
+diff -rupN linux-2.6.35.11/drivers/net/Makefile linux-2.6.35.11-ts7500/drivers/net/Makefile
+--- linux-2.6.35.11/drivers/net/Makefile	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -8,6 +8,9 @@ obj-$(CONFIG_PHYLIB) += phy/
+ 
+ obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
+ 
++obj-$(CONFIG_FAST_BRIDGE) += fast_bridge.o
++obj-$(CONFIG_STAR_GSW) += str9100/
++obj-$(CONFIG_STAR_NIC) += str8100/
+ obj-$(CONFIG_E1000) += e1000/
+ obj-$(CONFIG_E1000E) += e1000e/
+ obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
+diff -rupN linux-2.6.35.11/drivers/net/str8100/Kconfig linux-2.6.35.11-ts7500/drivers/net/str8100/Kconfig
+--- linux-2.6.35.11/drivers/net/str8100/Kconfig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str8100/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,28 @@
++menu "CNS2100 NIC support"
++	depends on ARCH_STR8100 && (NET_ETHERNET || NETDEV_1000)
++
++config STAR_NIC
++	tristate "CNS2100 NIC driver support"
++	help
++
++choice 
++	depends on STAR_NIC 
++        prompt "PHY Driver"
++        default STR_NIC_PHY_VSC8201
++          
++config STAR_NIC_PHY_INTERNAL_PHY
++        bool "Internal 10/100 PHY"
++
++config STAR_NIC_PHY_VSC8601
++        bool "Vitesse 8601"
++        
++config STAR_NIC_PHY_IP101A
++        bool "ICPlus IP101A"
++
++config STAR_NIC_PHY_IP1001
++		bool "ICPlus IP1001"
++          
++endchoice
++
++endmenu
++
+diff -rupN linux-2.6.35.11/drivers/net/str8100/Makefile linux-2.6.35.11-ts7500/drivers/net/str8100/Makefile
+--- linux-2.6.35.11/drivers/net/str8100/Makefile	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str8100/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,34 @@
++################################################################################
++#
++# 
++# Copyright(c) 2005 -  Star semiconduction. All rights reserved.
++# 
++# This program is free software; you can redistribute it and/or modify it 
++# under the terms of the GNU General Public License as published by the Free 
++# Software Foundation; either version 2 of the License, or (at your option) 
++# any later version.
++# 
++# This program is distributed in the hope that it will be useful, but WITHOUT 
++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
++# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
++# more details.
++# 
++# You should have received a copy of the GNU General Public License along with
++# this program; if not, write to the Free Software Foundation, Inc., 59 
++# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++# 
++# The full GNU General Public License is included in this distribution in the
++# file called LICENSE.
++# 
++# Contact Information:
++# Star semiconduction Linux Support <support@starsemi.com>
++#
++################################################################################
++
++#
++# Makefile for the Star GSW ethernet driver
++#
++
++obj-$(CONFIG_STAR_NIC) += star_nic_module.o
++star_nic_module-objs := star_nic.o
++
+diff -rupN linux-2.6.35.11/drivers/net/str8100/star_nic.c linux-2.6.35.11-ts7500/drivers/net/str8100/star_nic.c
+--- linux-2.6.35.11/drivers/net/str8100/star_nic.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str8100/star_nic.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,3070 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/bootmem.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/interrupt.h>
++#include <linux/ptrace.h>
++#include <linux/ioport.h>
++#include <linux/in.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++#include <asm/bitops.h>
++#include <asm/irq.h>		// 2006.03.22 richliu add list include file
++#include <asm/io.h>
++#include <asm/hardware.h>
++#include <linux/pci.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/ip.h>
++#include <linux/if_ether.h>
++#include <linux/icmp.h>
++#include <linux/udp.h>
++#include <linux/tcp.h>
++#include <linux/if_arp.h>
++#include <net/arp.h>
++
++#include <asm/arch/star_nic.h>
++
++#ifdef CONFIG_PM
++#include <linux/suspend.h>
++#endif
++
++#if 1
++#define DBG_PRINT printk
++#else
++#define DBG_PRINT(arg...)
++#endif
++
++#if 0
++#define DO_PRINT printk
++#define STAR_NIC_PRINT_ISR_STATUS
++#else
++#define DO_PRINT(arg...)
++#endif /* __DEBUG_PRINT_OUT */
++
++// VSC8601 and WavePlus Phy are the same
++#define STAR_NIC_PHY_ADDR	0
++
++#define CONFIG_STAR_NIC_NAPI
++//#define FREE_TX_SKB_MULTI		// FIXME: define this will cause samba fail
++
++#define STAR_NIC_TX_HW_CHECKSUM
++#define STAR_NIC_RX_HW_CHECKSUM
++
++#define STAR_NIC_SG
++
++#if defined(STAR_NIC_SG) && !defined(STAR_NIC_TX_HW_CHECKSUM)
++#define STAR_NIC_TX_HW_CHECKSUM
++#endif
++
++#define STAR_NIC_STATUS_ISR
++#define STAR_NIC_RXQF_ISR
++
++//#ifndef CONFIG_STAR_NIC_NAPI
++#define STAR_NIC_DELAYED_INTERRUPT
++//#endif
++
++#define MAX_PEND_INT_CNT	0x20
++#define MAX_PEND_TIME		0x20
++
++//#ifdef CONFIG_STAR_NIC_PHY_VSC8601
++//#define CONFIG_STAR_JUMBO
++//#endif
++//#define CONFIG_STAR_JUMBO
++#ifdef CONFIG_STAR_JUMBO
++#define MAX_PACKET_LEN		(2038)
++//#define MAX_PACKET_LEN		(9038)
++#else
++#define MAX_PACKET_LEN		(1536)
++#endif
++/* This constant(PKT_MIN_SIZE) can be replaced with ETH_ZLEN defined in
++ * include/linux/if_ether.h */
++#define PKT_MIN_SIZE		60
++
++//#define STAR_NIC_TIMER
++
++/* 
++ * Maximum Transmit/Receive Frame Descriptors for NIC's MAC frame
++ */
++#ifdef FREE_TX_SKB_MULTI
++#define STAR_NIC_MAX_TFD_NUM	48
++#define STAR_NIC_MAX_RFD_NUM	256
++#else
++#define STAR_NIC_MAX_TFD_NUM	48		// FIXME: original 64 will cause UDP fail
++#define STAR_NIC_MAX_RFD_NUM	64
++#endif
++
++
++#define LAN_PORT 1
++
++typedef struct
++{
++	u32		mib_rx_ok_pkt;
++	u32		mib_rx_ok_byte;
++	u32		mib_rx_runt;
++	u32		mib_rx_over_size;
++	u32		mib_rx_no_buffer_drop;
++	u32		mib_rx_crc_err;
++	u32		mib_rx_arl_drop;
++	u32		mib_rx_myvid_drop;
++	u32		mib_rx_csum_err;
++	u32		mib_rx_pause_frame;
++	u32		mib_tx_ok_pkt;
++	u32		mib_tx_ok_byte;
++	u32		mib_tx_pause_frame;
++} mib_info_t;
++
++/* store this information for the driver.. */
++struct star_nic_private {
++	struct napi_struct      napi;
++	struct net_device       *dev;
++	struct net_device_stats stats;
++	spinlock_t lock;
++	int dev_index;
++	u8 phy_addr;
++	u16 phy_id;
++	mib_info_t mib_info;
++};
++
++/*
++ * Network Driver, Receive/Send and Initial Buffer Function
++ */
++typedef struct {
++	// 1st 32Bits
++	u32 data_ptr;
++
++	// 2nd  32Bits
++	u32 length:16;
++	u32 reserved0:7;
++	u32 tco:1;
++	u32 uco:1;
++	u32 ico:1;
++	u32 insv:1;
++	u32 intr:1;
++	u32 ls:1;
++	u32 fs:1;
++	u32 eor:1;
++	u32 cown:1;
++
++	// 3rd 32Bits
++	u32 vid:12;
++	u32 cfi:1;
++	u32 pri:3;
++	u32 epid:16;
++
++	// 4th 32Bits
++	u32 reserved1;
++} __attribute__((packed)) STAR_NIC_TXDESC;
++
++typedef struct {
++	// 1st 32Bits
++	u32 data_ptr;
++
++	// 2nd  32Bits
++	u32 length:16;
++	u32 l4f:1;
++	u32 ipf:1;
++	u32 prot:2;
++	u32 vted:1;
++	u32 mymac:1;
++	u32 hhit:1;
++	u32 rmc:1;
++	u32 crce:1;
++	u32 osize:1;
++	u32 reserved0:2;
++	u32 ls:1;
++	u32 fs:1;
++	u32 eor:1;
++	u32 cown:1;
++
++	// 3rd 32Bits
++	u32 vid:12;
++	u32 cfi:1;
++	u32 pri:3;
++	u32 epid:16;
++
++	// 4th 32Bits
++	u32 reserved1;
++} __attribute__((packed)) STAR_NIC_RXDESC;
++
++/* 
++ * Transmit Frame Descriptor Ring for TFDS
++ */
++typedef struct {
++	u32			phy_addr;
++	STAR_NIC_TXDESC		*vir_addr;
++	u32			cur_index; // TX's current will point to Free Descriptors
++#if defined(FREE_TX_SKB_MULTI) || defined(STAR_NIC_TIMER)
++	u32			to_free_index;
++#endif
++	struct sk_buff		*skb_ptr[STAR_NIC_MAX_TFD_NUM]; // TX's sk_buff ptr
++} TXRING_INFO;
++
++/* 
++ * Receive Frame Descriptor Ring for RFDS
++ */
++typedef struct {
++	u32			phy_addr;
++	STAR_NIC_RXDESC		*vir_addr;
++	u32			cur_index;
++	struct sk_buff		*skb_ptr[STAR_NIC_MAX_RFD_NUM];	// RX's sk_buff ptr
++} RXRING_INFO;
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,32)
++#define IRQ_RETURN void
++#define IRQ_HANDLED 
++static const char star_nic_driver_version[] =
++	"Star NIC Driver(for Linux Kernel 2.4) - Star Semiconductor\n";
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++#define IRQ_RETURN irqreturn_t
++static const char star_nic_driver_version[] =
++	"Star NIC Driver(for Linux Kernel 2.6) - Star Semiconductor\n";
++#endif
++
++//========================================================
++#ifdef CONFIG_STAR_NIC_PHY_INTERNAL_PHY
++#define FE_PHY_LED_MODE (0x1 << 12)
++#define CONFIG_INTERNEL_PHY_PATCH
++#endif
++
++#ifdef CONFIG_INTERNEL_PHY_PATCH
++#define INTERNAL_PHY_PATCH_CHECKCNT	16
++#define INTERNAL_PHY_PATCH_CHECK_PERIOD	1000 //ms
++static struct timer_list internal_phy_timer;
++static void internal_phy_patch_check(int);
++static void internal_phy_update(unsigned long data);
++#endif
++//========================================================
++
++extern void fa_dma_inv_range(unsigned long s, unsigned long e);
++extern void fa_dma_clean_range(unsigned long s, unsigned long e);
++
++#define increase_cyclic(var, limit) {\
++				var++; \
++				if (var>=limit) var=0;\
++			}
++
++//static struct net_device *CUR_NAPI_DEV;
++static struct net_device *STAR_NIC_LAN_DEV;
++
++static int install_isr_account = 0;
++static int is_qf = 0; // determine queue full state
++
++static spinlock_t star_nic_send_lock;
++
++static TXRING_INFO txring;
++static RXRING_INFO rxring;
++
++static struct proc_dir_entry *star_nic_proc_entry;
++
++static u8 default_mac_addr[] = { 0x08, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e };
++
++typedef struct
++{   
++	u32 vid;	//0~4095
++	u32 control;	//ENABLE or DISABLE
++} my_vlan_entry_t;
++
++static my_vlan_entry_t my_vlan_id[4] =
++{
++	{ 2, 0},	//value for my_vid0
++	{ 2, 1},	//value for my_vid1
++	{ 1, 1},	//value for my_vid2
++	{ 1, 0}		//value for my_vid3
++};
++
++
++#ifdef CONFIG_STAR_NIC_NAPI
++static void star_nic_receive_packet(int mode, int *work_done, int work_to_do);
++#else
++static void star_nic_receive_packet(int mode);
++#endif
++
++static void star_nic_phy_powerdown(struct net_device *dev);
++static void star_nic_phy_powerup(struct net_device *dev);
++
++#ifdef STAR_NIC_TIMER
++static struct timer_list star_nic_timer;
++static void star_nic_timer_func(unsigned long data)
++{
++	int i;
++	int txsd_index;
++	int txsd_current;
++	int skb_free_count = 0;
++	STAR_NIC_TXDESC volatile *txdesc_ptr;
++	unsigned long flags;
++
++	local_irq_save(flags);
++	HAL_NIC_READ_TXSD(txsd_current);
++	txsd_index = (txsd_current - (u32)txring.phy_addr) >> 4;
++	if (txsd_index > txring.to_free_index) {
++		skb_free_count = txsd_index - txring.to_free_index;
++	} else if (txsd_index <= txring.to_free_index) {
++		skb_free_count = STAR_NIC_MAX_TFD_NUM + txsd_index - txring.to_free_index;
++	}
++	for (i = 0; i < skb_free_count; i++) {
++		txdesc_ptr = txring.vir_addr + txring.to_free_index;
++		if (txdesc_ptr->cown == 0) {
++			break;
++		}
++		if (txring.skb_ptr[txring.to_free_index]) {
++			dev_kfree_skb_any(txring.skb_ptr[txring.to_free_index]);
++			txring.skb_ptr[txring.to_free_index] = NULL;
++		}
++		txring.to_free_index++;
++		if (txring.to_free_index == STAR_NIC_MAX_TFD_NUM) {
++			txring.to_free_index = 0;
++		}
++	}
++	local_irq_restore(flags);
++}
++#endif
++
++#if 0
++#define between(x, start, end) ((x)>=(start) && (x)<=(end))
++static void print_packet(unsigned char *data, int len) 
++{
++	int i, j;
++
++	printk("packet length: %d%s:\n", len, len>100?"(only show the first 100 bytes)":"");
++	if (len > 100) {
++		len = 100;
++	}
++	for (i = 0; len;) {
++		if (len >=16) {
++			for (j=0;j<16;j++) {
++				printk("%02x ", data[i++]);
++			}
++			printk("| ");
++			i -= 16;
++			for(j=0;j<16;j++) {
++				if (between(data[i], 0x21, 0x7e) ) {
++					printk("%c", data[i++]);
++				} else {
++					printk(".");
++					i++;
++				}
++			}
++			printk("\n");
++			len -= 16;
++		} else {
++			/* last line */
++			for (j = 0; j < len; j++) {
++				printk("%02x ", data[i++]);
++			}
++			for (;j < 16; j++) {
++				printk("   ");
++			}
++			printk("| ");
++			i -= len;
++			for (j = 0;j < len; j++) {
++				if (between(data[i], 0x21, 0x7e)) {
++					printk("%c", data[i++]);
++				} else {
++					printk(".");
++					i++;
++				}
++			}
++			for (; j < 16; j++) {
++				printk(" ");
++			}
++			printk("\n");
++			len = 0;
++		}
++	}
++
++	return;
++}
++#endif /* Disable function print_packet */ 
++
++#ifdef STAR_NIC_DEBUG
++static void star_nic_show_format_reg(u32 val)
++{
++	int i;
++
++	for (i = 31; i >= 0; i--) {
++		if (val & ((unsigned long)1 << i)) {
++			printk("[%02d:1] ", i);
++		} else {
++			printk("[%02d:0] ", i);
++		}
++		if ((i % 8) == 0) {
++			printk("\n");
++		}
++	}
++	printk("==================================================================\n");
++}
++
++static void star_nic_show_reg(void)
++{
++	u32 reg_val;
++
++	printk("\n");
++
++	reg_val = NIC_MEM_MAP_VALUE(0x000);
++	printk("NIC REG OFF 0x000: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x004);
++	printk("NIC REG OFF 0x004: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x008);
++	printk("NIC REG OFF 0x008: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x00C);
++	printk("NIC REG OFF 0x00C: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x010);
++	printk("NIC REG OFF 0x010: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x014);
++	printk("NIC REG OFF 0x014: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x018);
++	printk("NIC REG OFF 0x018: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x01C);
++	printk("NIC REG OFF 0x01C: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x020);
++	printk("NIC REG OFF 0x020: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x024);
++	printk("NIC REG OFF 0x024: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x028);
++	printk("NIC REG OFF 0x028: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x030);
++	printk("NIC REG OFF 0x030: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x034);
++	printk("NIC REG OFF 0x034: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x038);
++	printk("NIC REG OFF 0x038: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x03C);
++	printk("NIC REG OFF 0x03C: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x040);
++	printk("NIC REG OFF 0x040: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x044);
++	printk("NIC REG OFF 0x044: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x048);
++	printk("NIC REG OFF 0x048: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x04C);
++	printk("NIC REG OFF 0x04C: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x050);
++	printk("NIC REG OFF 0x050: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x054);
++	printk("NIC REG OFF 0x054: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x058);
++	printk("NIC REG OFF 0x058: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++
++	reg_val = NIC_MEM_MAP_VALUE(0x05C);
++	printk("NIC REG OFF 0x05C: 0x%08x\n", reg_val);
++	star_nic_show_format_reg(reg_val);
++}
++#endif
++
++static void star_nic_mib_reset(void)
++{
++	u32 v;
++	unsigned long flags;
++
++	local_irq_save(flags);
++	v = NIC_MIB_RX_OK_PKT_CNTR;
++	v = NIC_MIB_RX_OK_BYTE_CNTR;
++	v = NIC_MIB_RX_RUNT_BYTE_CNTR;
++	v = NIC_MIB_RX_OSIZE_DROP_PKT_CNTR;
++	v = NIC_MIB_RX_NO_BUF_DROP_PKT_CNTR;
++	v = NIC_MIB_RX_CRC_ERR_PKT_CNTR;
++	v = NIC_MIB_RX_ARL_DROP_PKT_CNTR;
++	v = NIC_MIB_MYVLANID_MISMATCH_DROP_PKT_CNTR;
++	v = NIC_MIB_RX_CHKSUM_ERR_PKT_CNTR;
++	v = NIC_MIB_RX_PAUSE_FRAME_PKT_CNTR;
++	v = NIC_MIB_TX_OK_PKT_CNTR;
++	v = NIC_MIB_TX_OK_BYTE_CNTR;
++	v = NIC_MIB_TX_PAUSE_FRAME_CNTR;
++	local_irq_restore(flags);
++}
++
++static void star_nic_mib_read(struct net_device *dev)
++{
++	struct star_nic_private *priv = netdev_priv(dev);
++	unsigned long flags;
++
++	local_irq_save(flags);
++	priv->mib_info.mib_rx_ok_pkt		+= NIC_MIB_RX_OK_PKT_CNTR;
++	priv->mib_info.mib_rx_ok_byte		+= NIC_MIB_RX_OK_BYTE_CNTR;
++	priv->mib_info.mib_rx_runt		+= NIC_MIB_RX_RUNT_BYTE_CNTR;
++	priv->mib_info.mib_rx_over_size		+= NIC_MIB_RX_OSIZE_DROP_PKT_CNTR;
++	priv->mib_info.mib_rx_no_buffer_drop	+= NIC_MIB_RX_NO_BUF_DROP_PKT_CNTR;
++	priv->mib_info.mib_rx_crc_err		+= NIC_MIB_RX_CRC_ERR_PKT_CNTR;
++	priv->mib_info.mib_rx_arl_drop		+= NIC_MIB_RX_ARL_DROP_PKT_CNTR;
++	priv->mib_info.mib_rx_myvid_drop	+= NIC_MIB_MYVLANID_MISMATCH_DROP_PKT_CNTR;
++	priv->mib_info.mib_rx_csum_err		+= NIC_MIB_RX_CHKSUM_ERR_PKT_CNTR;
++	priv->mib_info.mib_rx_pause_frame	+= NIC_MIB_RX_PAUSE_FRAME_PKT_CNTR;
++	priv->mib_info.mib_tx_ok_pkt		+= NIC_MIB_TX_OK_PKT_CNTR;
++	priv->mib_info.mib_tx_ok_byte		+= NIC_MIB_TX_OK_BYTE_CNTR;
++	priv->mib_info.mib_tx_pause_frame	+= NIC_MIB_TX_PAUSE_FRAME_CNTR;
++	local_irq_restore(flags);
++}
++
++static int star_nic_write_phy(u8 phy_addr, u8 phy_reg, u16 write_data)
++{
++	int i;
++
++	if (phy_addr > 31) {
++		return 0;
++	}
++
++	//clear previous rw_ok status
++	NIC_PHY_CONTROL_REG0 = (0x1 << 15);
++ 
++	NIC_PHY_CONTROL_REG0 = ((phy_addr & 0x1F) |   
++		((phy_reg & 0x1F) << 8) |
++		(0x1 << 13) |
++		((write_data & 0xFFFF) << 16));
++
++	for (i = 0; i < 10000; i++) {
++		// if write command completed
++		if ((NIC_PHY_CONTROL_REG0) & (0x1 << 15)) {
++			// clear the rw_ok status, and clear other bits value
++			NIC_PHY_CONTROL_REG0 = (0x1 << 15);
++			return (0);    /* for ok indication */
++		}
++		udelay(1000);
++	}
++
++	printk("star_nic_write_phy() failed!! phy_addr:0x%x phy_reg:0x%x write_data:0x%x\n",
++		phy_addr, phy_reg, write_data);
++	return (-1);    /* for failure indication */
++}
++
++static int star_nic_read_phy(u8 phy_addr, u8 phy_reg, u16 *read_data)
++{
++	u32 status;
++	int i;
++
++	if (phy_addr > 31) {
++		return 0;
++	}
++
++	// clear previous rw_ok status
++	NIC_PHY_CONTROL_REG0 = (0x1 << 15);
++
++	NIC_PHY_CONTROL_REG0 = ((phy_addr & 0x1F) | 
++		((phy_reg & 0x1F) << 8) | 
++		(0x1 << 14));    
++
++	for (i = 0; i < 10000; i++) {
++		status = NIC_PHY_CONTROL_REG0;
++		if (status & (0x1 << 15)) {
++			// clear the rw_ok status, and clear other bits value
++			NIC_PHY_CONTROL_REG0 = (0x1 << 15);
++			*read_data = (u16)((status >> 16) & 0xFFFF);
++			return (0);    /* for ok indication */
++		}
++		udelay(1000);
++	}
++
++	printk("star_nic_read_phy() failed!! phy_addr:0x%x phy_reg:0x%x\n",
++		phy_addr, phy_reg);
++	return (-1);    /* for failure indication */
++}
++
++static int star_nic_dma_config(struct net_device *dev)
++{
++	u32 dma_config = 0;
++
++	dma_config = NIC_DMA_CONFIG_REG;
++
++#if 1
++	/* Config TX DMA */ 
++	dma_config &=  ~(0x3 << 6); //TX auto polling :1  us
++	//dma_config |=  (0x1 << 6); //TX auto polling :10 us
++	dma_config |=  (0x2 << 6); //TX auto polling :100us
++	//dma_config |=  (0x3 << 6); //TX auto polling :1000us
++	dma_config |=  (0x1 << 5); //TX auto polling C-bit enable
++	dma_config &=  ~(0x1 << 4); //TX can transmit packets,No suspend
++#endif
++
++#if 1
++	/* Config RX DMA */
++	dma_config &=  ~(0x3 << 2); //RX auto polling :1  us
++	//dma_config |=  (0x1 << 2); //RX auto polling :10 us
++	dma_config |=  (0x2 << 2); //RX auto polling :100us
++	//dma_config |=  (0x3 << 2); //RX auto polling :1000us
++	dma_config |=  (0x1 << 1); //RX auto polling C-bit enable
++	dma_config &=  ~0x1; //RX can receive packets, No suspend
++#endif
++
++	// 4N+2(for Linux)
++	dma_config &= ~(0x1 << 16);
++	// 4N
++	//dma_config |= (0x1 << 16);
++
++	NIC_DMA_CONFIG_REG = dma_config;
++
++	return 0;
++}
++
++static int star_nic_mac_config(struct net_device *dev)
++{
++	u32 mac_config;
++
++	mac_config = NIC_MAC_CONTROL_REG;
++
++#ifdef STAR_NIC_TX_HW_CHECKSUM
++	// Tx ChkSum offload On: TCP/UDP/IP
++	mac_config |= (0x1 << 26);
++#else
++	// Tx ChkSum offload Off: TCP/UDP/IP
++	mac_config &= ~(0x1 << 26);
++#endif
++
++#ifdef STAR_NIC_RX_HW_CHECKSUM
++	// Rx ChkSum offload On: TCP/UDP/IP
++	mac_config |= (0x1 << 25);
++#else
++	// Rx ChkSum offload Off: TCP/UDP/IP
++	mac_config &= ~(0x1 << 25);
++#endif
++
++	mac_config |= (0x1 << 24);	// Accept CSUM error pkt
++	//mac_config &= ~(0x1 << 24);	// Discard CSUM error pkt
++
++	//mac_config |= (0x1 << 23);	// IST Enable
++	mac_config &= ~(0x1 << 23);	// IST disable
++
++	mac_config |= (0x1 << 22);	// Strip vlan tag
++	//mac_config &= ~(0x1 << 22);	// Keep vlan tag
++
++	mac_config |= (0x1 << 21);	// Accept CRC error pkt
++	//mac_config &= ~(0x1 << 21);	// Disacrd CRC error pkt
++
++	mac_config |= (0x1 << 20);	// CRC strip
++	//mac_config &= ~(0x1 << 20);	// Keep CRC
++
++#ifdef CONFIG_STAR_JUMBO
++	mac_config |= (0x1 << 18);	// Accept oversize pkt
++#else
++	mac_config &= ~(0x1 << 18);	// Discard oversize pkt
++#endif
++
++	mac_config &= ~(0x3 << 16);	// clear, set 1518
++
++#ifdef CONFIG_STAR_JUMBO
++	mac_config |= (0x3 << 16);	//set reserved, for jumbo frame
++#else
++	mac_config |= (0x2 << 16);	// 1536
++	//mac_config |= (0x1 << 16);	// 1522
++#endif
++
++	// IPG
++	mac_config |= (0x1f << 10);
++
++	// Do not skip 16 consecutive collisions pkt
++	mac_config |= (0x1 << 9);	// allow to re-tx
++	//mac_config &= ~(0x1 << 9);	// drop pkt
++
++	mac_config |= (0x1 << 8);	// Fast retry
++	//mac_config &= ~(0x1 << 8);	// standard
++
++	NIC_MAC_CONTROL_REG = mac_config;
++
++	return 0;
++}
++
++static int star_nic_fc_config(struct net_device *dev)
++{
++	u32 fc_config;
++
++	fc_config = NIC_FLOW_CONTROL_CONFIG_REG;
++
++	// Send pause on frame threshold
++	fc_config &= ~(0xfff << 16);	// Clear
++	fc_config |= (0x360 << 16);	// Set
++
++	//fc_config |= (0x1 << 8);	// Enable UC_PAUSE
++	fc_config &= ~(0x1 << 8);	// Disable UC_PAUSE
++
++	fc_config |= (0x1 << 7);	// Enable Half Duplex backpressure
++	//fc_config &= ~(0x1 << 7);	// Disable Half Duplex backpressure
++
++    	//fc_config |= (0x1 << 6);	// CRS-based BP
++	fc_config &= ~(0x1 << 6);	// Collision-based BP
++
++	//fc_config |= (0x1 << 5);	// Enable max BP collision
++	fc_config &= ~(0x1 << 5);	// Disable max BP collision
++
++	// max BP collision count
++	fc_config &= ~(0x1f);		// Clear
++	fc_config |= (0xc);		// Set
++
++	NIC_FLOW_CONTROL_CONFIG_REG = fc_config;
++
++	return 0;
++}
++
++static int star_nic_phy_config(struct net_device *dev)
++{
++	struct star_nic_private *priv = netdev_priv(dev);
++	u32 phy_config = NIC_PHY_CONTROL_REG1;
++#ifdef CONFIG_STAR_NIC_PHY_VSC8601
++	u32 phy_addr=0;
++#endif /* CONFIG_STAR_NIC_PHY_VSC8601 */
++	//int i;
++
++#ifdef CONFIG_STAR_NIC_PHY_INTERNAL_PHY 
++	printk("Star Internal PHY\n");
++
++#if 0
++	{
++		u16 phy_data;
++		// restart the internal phy
++		star_nic_write_phy(STAR_NIC_PHY_ADDR, 0, 0x8000);
++		while (1) {
++			star_nic_read_phy(STAR_NIC_PHY_ADDR, 0, &phy_data);
++			if ( (phy_data&0x8000) ==0x0000) { // phy now at normal mode
++				break;
++			}
++		}
++	}
++#endif
++
++	priv->phy_addr = STAR_NIC_PHY_ADDR;
++	// set phy addr for auto-polling
++	phy_config |= (priv->phy_addr & 0x1f) << 24;
++
++	// set internal phy mode
++	// internel 10/100 phy
++	phy_config |= 0x1 << 18;
++
++	// MII
++	phy_config &= ~(0x1 << 17);
++
++	// MAC mode
++	phy_config &= ~(0x1 << 16);
++
++	// config PHY LED bit[13:12]
++	star_nic_read_phy(priv->phy_addr, 31, (u16 *)(&phy_config));
++	phy_config &= ~(0x3 << 12); // clear LED control
++	phy_config |= FE_PHY_LED_MODE;
++	star_nic_write_phy(priv->phy_addr, 31, phy_config);
++#endif
++#ifdef CONFIG_STAR_NIC_PHY_VSC8601
++	u16 phy_data;
++
++	printk("VSC8601 Chip\n");
++
++	// phy addr for auto-polling
++	phy_config |= ((phy_addr & 0x1f) << 24);
++
++	// set external phy mode
++	phy_config &= ~(0x1 << 18);
++
++	// set RGMII
++	phy_config |= (0x1 << 17);
++
++	// set MII interface
++	phy_config &= ~(0x1 << 16);
++
++	NIC_PHY_CONTROL_REG1 = phy_config;
++//=========================================================
++
++	priv->phy_addr = STAR_NIC_PHY_ADDR;
++	// set phy addr for auto-polling
++	phy_config |= (priv->phy_addr & 0x1f) << 24;
++
++	// set external phy mode
++	// MII/RGMII interface
++	phy_config &= ~(0x1 << 18);
++
++	// RGMII
++	phy_config |= (0x1 << 17);
++
++	// MAC mode
++	phy_config &= ~(0x1 << 16);
++
++	star_nic_read_phy(priv->phy_addr, 3, &phy_data);
++	if ((phy_data & 0x000f) == 0x0000) { // type A chip
++		u16 tmp16;
++
++		printk("VSC8601 Type A Chip\n");
++		star_nic_write_phy(priv->phy_addr, 31, 0x52B5);
++		star_nic_write_phy(priv->phy_addr, 16, 0xAF8A);
++
++		phy_data = 0x0;
++		star_nic_read_phy(priv->phy_addr, 18, &tmp16);
++		phy_data |= (tmp16 & ~0x0);
++		star_nic_write_phy(priv->phy_addr, 18, phy_data);
++
++		phy_data = 0x0008;
++		star_nic_read_phy(priv->phy_addr, 17, &tmp16);
++		phy_data |= (tmp16 & ~0x000C);
++		star_nic_write_phy(priv->phy_addr, 17, phy_data);        	
++
++		star_nic_write_phy(priv->phy_addr, 16, 0x8F8A);        	
++
++		star_nic_write_phy(priv->phy_addr, 16, 0xAF86);        	
++
++		phy_data = 0x0008;
++		star_nic_read_phy(priv->phy_addr, 18, &tmp16);
++		phy_data |= (tmp16 & ~0x000C);
++		star_nic_write_phy(priv->phy_addr, 18, phy_data);        	
++
++		phy_data = 0x0;
++		star_nic_read_phy(priv->phy_addr, 17, &tmp16);
++		phy_data |= (tmp16 & ~0x0);
++		star_nic_write_phy(priv->phy_addr, 17, phy_data);        	
++
++		star_nic_write_phy(priv->phy_addr, 16, 0x8F8A);        	
++
++		star_nic_write_phy(priv->phy_addr, 16, 0xAF82);        	
++
++		phy_data = 0x0;
++		star_nic_read_phy(priv->phy_addr, 18, &tmp16);
++		phy_data |= (tmp16 & ~0x0);
++		star_nic_write_phy(priv->phy_addr, 18, phy_data);        	
++
++		phy_data = 0x0100;
++		star_nic_read_phy(priv->phy_addr, 17, &tmp16);
++		phy_data |= (tmp16 & ~0x0180);
++		star_nic_write_phy(priv->phy_addr, 17, phy_data);        	
++
++		star_nic_write_phy(priv->phy_addr, 16, 0x8F82);        	
++
++		star_nic_write_phy(priv->phy_addr, 31, 0x0);        	
++           
++		//Set port type: single port
++		star_nic_read_phy(priv->phy_addr, 9, &phy_data);        	
++		phy_data &= ~(0x1 << 10);
++		star_nic_write_phy(priv->phy_addr, 9, phy_data);        	
++	} else if ((phy_data & 0x000f) == 0x0001) { // type B chip
++		printk("VSC8601 Type B Chip\n");
++		star_nic_read_phy(priv->phy_addr, 23, &phy_data);
++		phy_data |= ( 0x1 << 8); //set RGMII timing skew
++		star_nic_write_phy(priv->phy_addr, 23, phy_data);
++	}
++
++	// change to extened registers
++	star_nic_write_phy(priv->phy_addr, 31, 0x0001);
++
++	star_nic_read_phy(priv->phy_addr, 28, &phy_data);
++	phy_data &= ~(0x3 << 14); // set RGMII TX timing skew
++	phy_data |= (0x3 << 14); // 2.0ns
++	phy_data &= ~(0x3 << 12); // set RGMII RX timing skew
++	phy_data |= (0x3 << 12); // 2.0ns
++	star_nic_write_phy(priv->phy_addr, 28, phy_data);
++
++	// change to normal registers
++	star_nic_write_phy(priv->phy_addr, 31, 0x0000);
++
++	// set TX and RX clock skew
++	//NIC_TEST_0_REG = (0x2 << 2) | (0x2 << 0);
++
++#endif
++
++#ifdef CONFIG_STAR_NIC_PHY_IP101A
++	// ICPlus IP101A
++	printk("ICPlus IP101A\n");
++	priv->phy_addr = 1;
++	// set phy addr for auto-polling
++	phy_config |= (priv->phy_addr & 0x1f) << 24;
++
++	// set external phy mode
++	// MII/RGMII interface
++	phy_config &= ~(0x1 << 18);
++
++	// MII
++	phy_config &= ~(0x1 << 17);
++
++	// MAC mode
++	phy_config &= ~(0x1 << 16);
++#endif
++
++/* robin 080102 				*/
++/* added ICPlus IP1001 support	*/
++#ifdef CONFIG_STAR_NIC_PHY_IP1001
++u16 phy_data;
++
++u32 phy_addr = 1;
++
++phy_config = NIC_PHY_CONTROL_REG1;
++
++	// set phy addr for auto-polling
++	phy_config |= ((phy_addr & 0x1f) << 24);
++
++	// set external phy mode
++	// MII/RGMII interface
++	phy_config &= ~(0x1 << 18);
++
++	// RGMII
++	phy_config |= (0x1 << 17);
++
++	// MAC mode
++	phy_config &= ~(0x1 << 16);
++
++ NIC_PHY_CONTROL_REG1 = phy_config;
++    star_nic_read_phy(phy_addr,2,&phy_data);
++    //printf("\n phy.reg2=0x%04x",phy_data);
++	
++#if 1//set AN capability
++
++
++    star_nic_read_phy(phy_addr,4,&phy_data);
++
++    phy_data &= ~(0xf<<5);//clear
++    phy_data |= (0x1<<5); //10Half
++    phy_data |= (0x1<<6); //10Full
++    phy_data |= (0x1<<7); //100Half
++    phy_data |= (0x1<<8); //100Full
++//    phy_data &= ~(0x1<<10); //FC off
++    phy_data |= (0x1<<10); //FC on
++    star_nic_write_phy(phy_addr,4,phy_data);
++
++
++    star_nic_read_phy(phy_addr,9,&phy_data);
++
++    phy_data |= (0x1<<9); //1000Full on
++
++    phy_data &= ~(0x1<<10); 
++
++    phy_data |= (0x1<<12); 
++
++    star_nic_write_phy(phy_addr,9,phy_data);
++
++
++
++
++    star_nic_read_phy(phy_addr,16,&phy_data);
++
++    phy_data &= ~(0x1<<11); //Smart function off
++
++    phy_data |=  (0x1<<0); //TX delay
++
++    phy_data |=  (0x1<<1); //RX delay
++
++    star_nic_write_phy(phy_addr,16,phy_data);
++
++    star_nic_read_phy(phy_addr,16,&phy_data);
++    //printf("\n phy.reg16=0x%04x",phy_data);
++
++
++//    Hal_Nic_Read_PHY(NIC_PHY_ADDRESS,20,&phy_data);
++//
++//    phy_data &= ~(0x1<<2); 
++//
++//    phy_data |=  (0x1<<9); 
++//    Hal_Nic_Write_PHY(NIC_PHY_ADDRESS,20,phy_data);
++
++
++
++
++    star_nic_read_phy(phy_addr,0,&phy_data);
++    phy_data |= (0x1<<9); //re-AN
++    star_nic_write_phy(phy_addr,0,phy_data);
++
++
++    star_nic_read_phy(phy_addr,9,&phy_data);
++    //printf("\n phy.reg9=0x%04x",phy_data);
++
++  
++#endif	
++#endif // CONFIG_STAR_NIC_PHY_IP1001
++/* robin 080102 - end of modification */
++
++
++
++	phy_config |= (0x1 << 8); // AN On
++	//phy_config &= ~(0x1 << 8); // AN off
++
++	if (!((phy_config >> 8) & 0x1)) { // AN disbale
++		// Force to FullDuplex mode
++		phy_config &= ~(0x1 << 11); // Half
++
++		// Force to 100Mbps mode
++		phy_config &= ~(0x3 << 9); // clear to 10M
++		phy_config |= (0x1 << 9); // set to 100M
++	}
++
++	// Force TX FlowCtrl On,in 1000M
++	phy_config |= (0x1 << 13);
++
++	// Force TX FlowCtrl On, in 10/100M
++	phy_config |= (0x1 << 12);
++
++	// Enable MII auto polling
++	phy_config &= ~(0x1 << 7); // auto-polling enable
++	//phy_config |= (0x1 << 7); // auto-polling disable
++
++	NIC_PHY_CONTROL_REG1 = phy_config;
++#if 1
++	star_nic_phy_powerdown(dev);
++#endif
++
++	return 0;
++}
++
++static int star_nic_vlan_config(struct net_device *dev)
++{
++	u32 vlan_id;
++
++	//1.Setup MyVLAN ID0_1
++	vlan_id  = 0; //clear
++	vlan_id |= (my_vlan_id[0].vid & 0x0fff);
++	vlan_id |= ((my_vlan_id[1].vid & 0x0fff) << 16);
++	NIC_MY_VLANID_0_1 = vlan_id;
++
++	//2.Setup MyVLAN ID2_3
++	vlan_id  = 0; //clear
++	vlan_id |= (my_vlan_id[2].vid & 0x0fff);
++	vlan_id |= ((my_vlan_id[3].vid & 0x0fff) << 16);
++	NIC_MY_VLANID_2_3 = vlan_id;
++
++	//3.Setup vlan_id control bits
++	NIC_MY_VLANID_CONTROL_REG = ( (my_vlan_id[0].control << 0) |
++		(my_vlan_id[1].control << 1) |
++		(my_vlan_id[2].control << 2) |
++		(my_vlan_id[3].control << 3) );
++
++	return 0;
++}
++
++static int star_nic_arl_config(struct net_device *dev)
++{
++	u32 arl_config;
++
++	arl_config = NIC_ARL_CONFIG_REG;
++	arl_config |= (0x1 << 4); // Misc Mode ON
++	//arl_config &= ~(0x1 << 4); // Misc Mode Off
++	arl_config |= (0x1 << 3); // My MAC only enable
++	arl_config &= ~(0x1 << 2); // Learn SA On
++	arl_config &= ~(0x1 << 1); // Forward MC to CPU
++	arl_config &= ~(0x1); // Hash direct mode
++	NIC_ARL_CONFIG_REG = arl_config;
++
++	return 0;
++}
++
++#if 0
++static void star_nic_interrupt_disable(void)
++{
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_STATUS_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_TXTC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_TXQE_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++}
++#endif /* Disable function star_nic_interrupt_disable */
++
++static void star_nic_interrupt_enable(void)
++{
++#ifdef STAR_NIC_STATUS_ISR
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_STATUS_BIT_INDEX);
++#endif
++	
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++
++#ifdef STAR_NIC_RXQF_ISR
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++#endif
++}
++
++#if 0
++static int star_nic_show_rxdesc(char *page)
++{
++	int i;
++	int num = 0;
++	u32 rxsd_current;
++	int rxsd_index;
++	STAR_NIC_RXDESC volatile *rxdesc_ptr = rxring.vir_addr;
++
++	HAL_NIC_READ_RXSD(rxsd_current);
++	rxsd_index = (rxsd_current - (u32)rxring.phy_addr) >> 4;
++
++	num += sprintf(page + num, "rxring.cur_index: %d\n", rxring.cur_index);
++	num += sprintf(page + num, "rxsd_index:       %d\n", rxsd_index);
++
++	for (i = 0; i < STAR_NIC_MAX_RFD_NUM; i++) {
++		num += sprintf(page + num, "rxring[%02d].cown ==> %d\n", i, rxdesc_ptr->cown);
++		rxdesc_ptr++;
++	}
++
++	return num;
++}
++#endif /* Disable function star_nic_show_rxdesc */
++
++#if 0
++static int star_nic_show_txdesc(char *page)
++{
++	int i;
++	int num = 0;
++	u32 txsd_current;
++	int txsd_index;
++	STAR_NIC_TXDESC volatile *txdesc_ptr = txring.vir_addr;
++
++	HAL_NIC_READ_TXSD(txsd_current);
++	txsd_index = (txsd_current - (u32)txring.phy_addr) >> 4;
++
++	num += sprintf(page + num, "txring.cur_index: %d\n", txring.cur_index);
++	num += sprintf(page + num, "txsd_index:       %d\n", txsd_index);
++
++	for (i = 0; i < STAR_NIC_MAX_TFD_NUM; i++) {
++		num += sprintf(page + num, "txring[%02d].cown ==> %d\n", i, txdesc_ptr->cown);
++		txdesc_ptr++;
++	}
++
++	return num;
++}
++#endif /* star_nic_show_txdesc */
++
++static int star_nic_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
++{
++	struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++	int num = 0;
++
++	star_nic_mib_read(STAR_NIC_LAN_DEV);
++	num += sprintf(page + num, "mib_rx_ok_pkt          %08d\n", priv->mib_info.mib_rx_ok_pkt);
++	num += sprintf(page + num, "mib_rx_ok_byte         %08d\n", priv->mib_info.mib_rx_ok_byte);
++	num += sprintf(page + num, "mib_rx_runt            %08d\n", priv->mib_info.mib_rx_runt);
++	num += sprintf(page + num, "mib_rx_over_size       %08d\n", priv->mib_info.mib_rx_over_size);
++	num += sprintf(page + num, "mib_rx_no_buffer_drop  %08d\n", priv->mib_info.mib_rx_no_buffer_drop);
++	num += sprintf(page + num, "mib_rx_crc_err         %08d\n", priv->mib_info.mib_rx_crc_err);
++	num += sprintf(page + num, "mib_rx_arl_drop        %08d\n", priv->mib_info.mib_rx_arl_drop);
++	num += sprintf(page + num, "mib_rx_myvid_drop      %08d\n", priv->mib_info.mib_rx_myvid_drop);
++	num += sprintf(page + num, "mib_rx_csum_err        %08d\n", priv->mib_info.mib_rx_csum_err);
++	num += sprintf(page + num, "mib_rx_pause_frame     %08d\n", priv->mib_info.mib_rx_pause_frame);
++	num += sprintf(page + num, "mib_tx_ok_pkt          %08d\n", priv->mib_info.mib_tx_ok_pkt);
++	num += sprintf(page + num, "mib_tx_ok_byte         %08d\n", priv->mib_info.mib_tx_ok_byte);
++	num += sprintf(page + num, "mib_tx_pause_frame     %08d\n", priv->mib_info.mib_tx_pause_frame);
++
++	//num += star_nic_show_rxdesc(page + num);
++	//num += star_nic_show_txdesc(page + num);
++
++	return num;
++}
++
++
++static int
++star_nic_write_proc(struct file *file, const char __user *buffer,
++	unsigned long count, void *data)
++{
++	char *str;
++	char *cmd;
++
++	if (count > 0) {
++		str = (char *)buffer,
++		cmd = strsep(&str, "\t \n");
++		if (!cmd) goto err_out;
++		if (strcmp(cmd, "clear") == 0) {
++			struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++
++			star_nic_mib_read(STAR_NIC_LAN_DEV);
++			memset(&priv->mib_info,0,sizeof(priv->mib_info));
++
++		//} else if (strcmp(cmd, "write") == 0) {
++		} else {
++			goto err_out;
++		}
++	}
++
++	return count;
++
++err_out:
++	return -EFAULT;
++}
++
++static void star_nic_phy_powerdown(struct net_device *dev)
++{
++	struct star_nic_private *priv = netdev_priv(dev);
++	u16 phy_data = 0;
++	// power down the PHY
++	star_nic_read_phy(priv->phy_addr, 0, &phy_data);
++	phy_data |= (0x1 << 11);
++	star_nic_write_phy(priv->phy_addr, 0, phy_data);
++
++	// set hight
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++	// set low
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << 15);
++}
++
++static void star_nic_phy_powerup(struct net_device *dev)
++{
++	struct star_nic_private *priv = netdev_priv(dev);
++	u16 phy_data = 0;
++	// power up the PHY
++	star_nic_read_phy(priv->phy_addr, 0, &phy_data);
++	phy_data &= ~(0x1 << 11);
++	star_nic_write_phy(priv->phy_addr, 0, phy_data);
++
++	// set hight
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++}
++
++static void star_nic_enable(struct net_device *dev)
++{
++#if 0
++	// enable NIC clock
++	HAL_PWRMGT_ENABLE_NIC_CLOCK();
++	NIC_MAC_CONTROL_REG &= ~((u32)0x3 << 30);
++	udelay(100);
++#endif
++
++	star_nic_interrupt_enable();
++	HAL_NIC_RX_DMA_START();
++#if 1
++	star_nic_phy_powerup(dev);
++#endif
++#ifdef CONFIG_INTERNEL_PHY_PATCH
++	printk("%s: starting patch check.\n", __FUNCTION__);
++	internal_phy_patch_check(1);
++	mod_timer(&internal_phy_timer, jiffies + INTERNAL_PHY_PATCH_CHECK_PERIOD / 10);
++#endif
++
++}
++
++static void star_nic_shutdown(struct net_device *dev)
++{
++	if (install_isr_account == 0) {
++		DBG_PRINT("disable port 0\n");
++		HAL_NIC_RX_DMA_STOP();
++		HAL_NIC_TX_DMA_STOP();
++#if 0
++		NIC_MAC_CONTROL_REG |= ((u32)0x1 << 31);
++		while (!(NIC_MAC_CONTROL_REG & (0x1 << 29))) {
++			udelay(1000);
++		}
++		HAL_PWRMGT_DISABLE_NIC_CLOCK();
++		NIC_MAC_CONTROL_REG |= (0x1 <<29);
++#endif
++#ifdef CONFIG_INTERNEL_PHY_PATCH
++	printk("%s: stoping patch check.\n", __FUNCTION__);
++	del_timer_sync(&internal_phy_timer);
++#endif
++	}
++}
++
++IRQ_RETURN star_nic_receive_isr(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++#ifdef CONFIG_STAR_NIC_NAPI
++	if (!test_bit(5, &STAR_NIC_LAN_DEV->state)) 
++	  napi_schedule(&priv->napi);
++#else
++#ifndef CONFIG_VIC_INTERRUPT
++	// TODO: mask interrupt
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_RXRC_BIT_INDEX);
++#endif
++	// MASK Interrupt
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++
++	star_nic_receive_packet(0); // Receive Once
++
++	// TODO: unmask interrupt
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++#endif
++
++	return IRQ_HANDLED;
++}
++
++#ifdef STAR_NIC_RXQF_ISR
++IRQ_RETURN star_nic_rxqf_isr(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++#ifndef CONFIG_VIC_INTERRUPT
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_RXQF_BIT_INDEX);
++#endif
++#ifdef CONFIG_STAR_NIC_NAPI
++	// because in normal state, fsql only invoke once and set_bit is atomic function.
++	// so I don't mask it.
++	set_bit(0, (unsigned long *)&is_qf);
++	if (!test_bit(5, &STAR_NIC_LAN_DEV->state)) 
++	  napi_schedule(&priv->napi);
++#else
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++	
++	star_nic_receive_packet(1); // Receive at Queue Full Mode
++
++	// TODO: unmask interrupt
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++#endif
++
++	return IRQ_HANDLED;
++}
++#endif
++
++#ifdef CONFIG_PM
++int inline str8100_nic_resume();
++int inline str8100_nic_suspend(suspend_state_t state);
++#endif
++
++#ifdef STAR_NIC_STATUS_ISR
++
++IRQ_RETURN star_nic_status_isr(int irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 int_status;
++#ifdef CONFIG_PM
++	extern int nic_suspended;
++	u32 nic_suspended_tmp=nic_suspended;
++#endif
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_STATUS_BIT_INDEX);
++	HAL_NIC_READ_INTERRUPT_STATUS(int_status);
++
++	//printk("%s: NIC status:%08X \n",__FUNCTION__, int_status);
++
++	if (int_status & 0x8) {
++		star_nic_mib_read((struct net_device *)STAR_NIC_LAN_DEV);
++	}
++
++#ifdef CONFIG_PM
++	if ((int_status & 0x10)&&nic_suspended_tmp) {
++//		printk("W\n");
++		str8100_nic_resume();
++	}
++#endif
++	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCES(int_status);
++#ifdef CONFIG_PM
++	if ((int_status & 0x10)&&nic_suspended_tmp) {
++		str8100_nic_suspend(0);
++	}
++#endif
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_NIC_STATUS_BIT_INDEX);
++
++	return IRQ_HANDLED;
++}
++#endif // STAR_NIC_STATUS_ISR
++
++static int star_nic_uninstall_isr(struct net_device *dev)
++{
++	--install_isr_account;
++
++	if (install_isr_account == 0) {
++		printk("star nic uninstall isr\n");
++		free_irq(INTC_NIC_RXRC_BIT_INDEX, STAR_NIC_LAN_DEV);
++
++#ifdef STAR_NIC_RXQF_ISR
++		free_irq(INTC_NIC_RXQF_BIT_INDEX, STAR_NIC_LAN_DEV);
++#endif
++
++#ifdef STAR_NIC_STATUS_ISR
++		free_irq(INTC_NIC_STATUS_BIT_INDEX, STAR_NIC_LAN_DEV);
++#endif
++	}
++
++	return 0;
++}
++
++static int star_nic_install_isr(struct net_device *dev)
++{
++	int retval;
++
++	if (install_isr_account == 0) {
++#ifdef STAR_NIC_DELAYED_INTERRUPT
++		NIC_DELAYED_INT_CONFIG_REG = (1 << 16) | ((MAX_PEND_INT_CNT & 0xFF) << 8) | (MAX_PEND_TIME & 0xFF);
++#endif
++		retval = request_irq(INTC_NIC_RXRC_BIT_INDEX, &star_nic_receive_isr, IRQF_SHARED, "NIC RXRC INT", STAR_NIC_LAN_DEV);
++
++		if (retval) {
++			DO_PRINT("%s: unable to get IRQ %d (irqval=%d).\n", "NIC RXRC INT", INTC_NIC_RXRC_BIT_INDEX, retval);
++			return 1;
++		}
++
++#ifdef STAR_NIC_RXQF_ISR
++		/*  QUEUE full interrupt handler */
++		retval = request_irq(INTC_NIC_RXQF_BIT_INDEX, &star_nic_rxqf_isr, IRQF_SHARED, "NIC RXQF INT", STAR_NIC_LAN_DEV);
++
++		if (retval) {
++			DO_PRINT("%s: unable to get IRQ %d (irqval=%d).\n", "NIC RXQF INT", INTC_NIC_RXQF_BIT_INDEX, retval);
++			return 2;
++		}
++#endif	
++
++#ifdef STAR_NIC_STATUS_ISR
++		/*  NIC Status interrupt handler */
++		retval = request_irq(INTC_NIC_STATUS_BIT_INDEX, &star_nic_status_isr, IRQF_SHARED, "NIC STATUS", STAR_NIC_LAN_DEV);
++
++		if (retval) {
++			DO_PRINT("%s: unable to get IRQ %d (irqval=%d).\n", "NIC STATUS INT", INTC_NIC_STATUS_BIT_INDEX, retval);
++			return 3;
++		}
++		//HAL_NIC_ENABLE_ALL_INTERRUPT_STATUS_SOURCES();
++		HAL_NIC_DISABLE_ALL_INTERRUPT_STATUS_SOURCES();
++		//Enable NIC Status Interrupt: MIB counter th (3)
++		HAL_NIC_ENABLE_INTERRUPT_STATUS_SOURCE_BIT(3);
++
++#endif
++	} // end if(install_isr_account == 0)
++
++	++install_isr_account;
++
++	return 0;
++}
++
++static int star_nic_lan_open(struct net_device *dev)
++{
++	DBG_PRINT("%s:star_nic_lan_open\n", dev->name);
++
++#ifdef MODULE
++	MOD_INC_USE_COUNT;
++#endif
++
++	//CUR_NAPI_DEV = dev;
++	//
++	struct star_nic_private *priv = netdev_priv(dev);
++	napi_enable(&priv->napi);
++
++	netif_start_queue(dev);
++
++	star_nic_install_isr(dev);
++
++	star_nic_enable(dev);
++
++	return 0;
++}
++
++static struct net_device_stats *star_nic_get_stats(struct net_device *dev)
++{
++	struct star_nic_private *priv = netdev_priv(dev);
++
++	return &priv->stats;
++}
++
++static void star_nic_timeout(struct net_device *dev)
++{
++	DBG_PRINT("%s:star_nic_timeout\n", dev->name);
++	netif_wake_queue(dev);
++	dev->trans_start = jiffies;
++}
++
++static int star_nic_close(struct net_device *dev)
++{
++#if 1
++	star_nic_phy_powerdown(dev);
++#endif
++	star_nic_uninstall_isr(dev);
++
++/* plany add 20080904 */
++#ifdef CONFIG_STAR_NIC_NAPI
++	struct star_nic_private *priv = netdev_priv(dev);
++	napi_disable(&priv->napi);
++#endif
++	netif_stop_queue(dev);
++	star_nic_shutdown(dev);
++
++#ifdef MODULE
++	MOD_DEC_USE_COUNT;
++#endif
++
++	//CUR_NAPI_DEV = STAR_NIC_LAN_DEV;
++
++	return 0;
++}
++
++static inline struct sk_buff *star_nic_alloc_skb(void)
++{
++	struct sk_buff *skb;
++
++	skb = dev_alloc_skb(MAX_PACKET_LEN + 2);
++
++	if (unlikely(!skb)) {
++		printk("\n dev_alloc_skb fail!! while allocate RFD ring !!\n");
++		return NULL;
++	}
++
++	/* Make buffer alignment 2 beyond a 16 byte boundary
++	 * this will result in a 16 byte aligned IP header after
++	 * the 14 byte MAC header is removed
++	 */
++	skb_reserve(skb, 2);	/* 16 bit alignment */
++
++	return skb;
++}
++
++static void __init star_nic_buffer_free(void)
++{
++	int i;
++
++	if (rxring.vir_addr) {
++		for (i = 0; i < STAR_NIC_MAX_RFD_NUM; i++) {
++			if (rxring.skb_ptr[i]) {
++				dev_kfree_skb(rxring.skb_ptr[i]);
++			}
++		}
++		dma_free_coherent(NULL, STAR_NIC_MAX_RFD_NUM * sizeof(STAR_NIC_RXDESC), rxring.vir_addr, rxring.phy_addr);
++		memset((void *)&rxring, 0, STAR_NIC_MAX_RFD_NUM * sizeof(STAR_NIC_RXDESC));
++	}
++
++	if (txring.vir_addr) {
++		dma_free_coherent(NULL, STAR_NIC_MAX_TFD_NUM * sizeof(STAR_NIC_TXDESC), txring.vir_addr, txring.phy_addr);
++		memset((void *)&txring, 0, STAR_NIC_MAX_TFD_NUM * sizeof(STAR_NIC_TXDESC));
++	}
++}
++
++static int __init star_nic_buffer_alloc(void)
++{
++	STAR_NIC_RXDESC	volatile *rxdesc_ptr;
++	STAR_NIC_TXDESC	volatile *txdesc_ptr;
++	struct sk_buff	*skb_ptr;
++	int err;
++	int i;
++
++	rxring.vir_addr = dma_alloc_coherent(NULL, STAR_NIC_MAX_RFD_NUM * sizeof(STAR_NIC_RXDESC), &rxring.phy_addr, GFP_KERNEL);
++	if (!rxring.vir_addr) {
++		printk("\n ERROR: Allocate RFD Failed\n");
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++	txring.vir_addr = dma_alloc_coherent(NULL, STAR_NIC_MAX_TFD_NUM * sizeof(STAR_NIC_TXDESC), &txring.phy_addr, GFP_KERNEL);
++	if (!txring.vir_addr) {
++		printk("\n ERROR: Allocate TFD Failed\n");
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++	// Clean RX Memory
++	memset((void *)rxring.vir_addr, 0, STAR_NIC_MAX_RFD_NUM * sizeof(STAR_NIC_RXDESC));
++	DBG_PRINT("    rxring.vir_addr=0x%08X rxring.phy_addr=0x%08X\n", (u32)rxring.vir_addr, (u32)rxring.phy_addr);
++	rxring.cur_index = 0;	// Set cur_index Point to Zero
++	rxdesc_ptr = rxring.vir_addr;
++	for (i = 0; i < STAR_NIC_MAX_RFD_NUM; i++, rxdesc_ptr++) {
++		if (i == (STAR_NIC_MAX_RFD_NUM - 1)) { 
++			rxdesc_ptr->eor = 1;	// End bit == 0;
++		}
++		skb_ptr = star_nic_alloc_skb();
++		if (!skb_ptr) {
++			printk("ERROR: Allocate skb Failed!\n");
++			err = -ENOMEM;
++			goto err_out;
++		}
++		// Trans Packet from Virtual Memory to Physical Memory
++		rxring.skb_ptr[i]	= skb_ptr;
++		rxdesc_ptr->data_ptr	= (u32)virt_to_phys(skb_ptr->data);
++		rxdesc_ptr->length	= MAX_PACKET_LEN;
++	}
++
++	// Clean TX Memory
++	memset((void *)txring.vir_addr, 0, STAR_NIC_MAX_TFD_NUM * sizeof(STAR_NIC_TXDESC));
++	DBG_PRINT("    txring.vir_addr=0x%08X txring.phy_addr=0x%08X\n", (u32)txring.vir_addr, (u32)txring.phy_addr);
++	txring.cur_index = 0;	// Set cur_index Point to Zero
++	txdesc_ptr = txring.vir_addr;
++	for (i = 0; i < STAR_NIC_MAX_TFD_NUM; i++, txdesc_ptr++) {
++		if (i == (STAR_NIC_MAX_TFD_NUM - 1)) { 
++			txdesc_ptr->eor = 1;	// End of Ring ==1
++		}
++		txdesc_ptr->cown = 1;	// TX Ring , Cown == 1
++
++#ifdef STAR_NIC_TX_HW_CHECKSUM
++		// Enable Checksum
++		txdesc_ptr->ico		= 1;
++		txdesc_ptr->uco		= 1;
++		txdesc_ptr->tco		= 1;
++#else
++		txdesc_ptr->ico		= 0;
++		txdesc_ptr->uco		= 0;
++		txdesc_ptr->tco		= 0;
++#endif
++		txring.skb_ptr[i] 	= NULL;	// clear txring.skb_ptr
++	}
++
++	return 0;
++
++err_out:
++	star_nic_buffer_free();
++	return err;
++}
++
++
++#ifdef CONFIG_STAR_JUMBO
++#define MINIMUM_ETHERNET_FRAME_SIZE	64
++#define MAX_JUMBO_FRAME_SIZE		2036
++#define ENET_HEADER_SIZE			14
++#define ETHERNET_FCS_SIZE			4
++#define ETHERNET_VLAN_SIZE			4
++#define NET_IP_ALIGN				2
++static int
++str8100_change_mtu(struct net_device *netdev, int new_mtu)
++{
++printk("%s: new_mtu=%d\n",__FUNCTION__,new_mtu);
++	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE+ETHERNET_VLAN_SIZE;
++	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
++	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
++		printk("%s: Invalid MTU setting (%d)\n",__FUNCTION__,new_mtu);
++		return -EINVAL;
++	}
++	netdev->mtu = new_mtu;
++
++//	star_nic_buffer_free();
++//	star_nic_buffer_alloc();
++
++//	if (netif_running(netdev))
++//		e1000_reinit_locked(adapter);
++
++	return 0;
++
++}
++#endif
++
++#ifdef CONFIG_STAR_NIC_NAPI
++#if 1
++static int star_nic_poll(struct napi_struct *napi, int budget)
++{
++	struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++        int work_done = 0;
++        int work_to_do = budget;
++
++	star_nic_receive_packet(0, &work_done, work_to_do);
++
++        budget -= work_done;
++
++        /* if no Tx and not enough Rx work done, exit the polling mode */
++        if (work_done) {
++                if (test_bit(0, (unsigned long *)&is_qf) == 1) { // queue full
++                        clear_bit(0, (unsigned long *)&is_qf);
++                        HAL_NIC_RX_DMA_START();
++                        return 1;
++                }
++        } else {
++		napi_complete(&priv->napi);
++#ifdef CONFIG_STAR_NIC_NAPI_MASK_IRQ
++		enable_irq(INTC_NIC_RXRC_BIT_INDEX);
++#endif
++                return 0;
++        }
++
++        return work_done;
++}
++#else
++static int star_nic_poll(struct net_device *netdev, int *budget)
++{
++	struct star_nic_private *priv = netdev_priv(STAR_NIC_LAN_DEV);
++	int work_done = 0;
++	int work_to_do = min(*budget, netdev->quota); // where is min define
++
++	star_nic_receive_packet(0, &work_done, work_to_do);
++
++	*budget -= work_done;
++	netdev->quota -= work_done;
++
++	/* if no Tx and not enough Rx work done, exit the polling mode */
++	if (work_done) {
++		if (test_bit(0, (unsigned long *)&is_qf) == 1) { // queue full
++			clear_bit(0, (unsigned long *)&is_qf);
++			HAL_NIC_RX_DMA_START();
++			return 1;
++		}
++	} else {
++		napi_complete(&priv->napi);
++#ifdef CONFIG_STAR_NIC_NAPI_MASK_IRQ
++		enable_irq(INTC_NIC_RXRC_BIT_INDEX);
++#endif
++		return 0;
++	}
++	return 1;
++}
++#endif
++#endif
++
++static int star_nic_get_rfd_buff(int index)
++{
++	struct star_nic_private *priv;
++	STAR_NIC_RXDESC volatile *rxdesc_ptr;
++	struct sk_buff *skb_ptr;
++	unsigned char *data;
++	int len;
++
++	//TODO: get rxdesc ptr
++	rxdesc_ptr = rxring.vir_addr + index;
++	skb_ptr = rxring.skb_ptr[index];
++#ifdef CONFIG_STAR_JUMBO
++	if (rxdesc_ptr->fs != 1 || rxdesc_ptr->ls != 1) {
++		goto freepacket;
++	}
++#endif
++	len = rxdesc_ptr->length;
++
++	//dma_cache_maintenance(skb_ptr->data, len, PCI_DMA_FROMDEVICE);
++	fa_dma_inv_range(skb_ptr->data, (unsigned long)skb_ptr->data + len);
++
++	data = skb_put(skb_ptr, len);
++
++	skb_ptr->dev = STAR_NIC_LAN_DEV;
++
++	priv = netdev_priv(skb_ptr->dev);
++
++#ifdef STAR_NIC_RX_HW_CHECKSUM
++	if (rxdesc_ptr->ipf == 1 || rxdesc_ptr->l4f == 1) {
++		if (rxdesc_ptr->prot != 0x11) {
++			skb_ptr->ip_summed = CHECKSUM_NONE;
++		} else {
++			// CheckSum Fail
++			priv->stats.rx_errors++;
++			goto freepacket;
++		}
++	} else {
++			skb_ptr->ip_summed = CHECKSUM_UNNECESSARY;
++	}
++#else
++	skb_ptr->ip_summed = CHECKSUM_NONE;
++#endif
++
++	// this line must, if no, packet will not send to network layer
++	skb_ptr->protocol = eth_type_trans(skb_ptr, skb_ptr->dev);
++
++	priv->stats.rx_packets++;
++	priv->stats.rx_bytes += len;
++	skb_ptr->dev->last_rx = jiffies;
++
++	// if netif_rx any package, will let this driver core dump.
++#ifdef CONFIG_STAR_NIC_NAPI
++	netif_receive_skb(skb_ptr);
++#else
++	netif_rx(skb_ptr);
++#endif
++
++	return 0;
++
++freepacket:
++	dev_kfree_skb_any(skb_ptr);
++	return 0;
++}
++
++#ifdef CONFIG_STAR_NIC_NAPI
++void star_nic_receive_packet(int mode, int *work_done, int work_to_do)
++#else
++void star_nic_receive_packet(int mode)
++#endif
++{
++	int rxsd_index;
++	u32 rxsd_current;
++	STAR_NIC_RXDESC volatile *rxdesc_ptr = rxring.vir_addr + rxring.cur_index;
++	struct sk_buff *skb_ptr;
++#ifndef CONFIG_STAR_NIC_NAPI
++	int rxqf = 0; // Queue Full Mode =0
++#endif
++	int i, rxcount = 0;
++	HAL_NIC_READ_RXSD(rxsd_current);
++	rxsd_index = (rxsd_current - (u32)rxring.phy_addr) >> 4;
++
++	if (rxsd_index > rxring.cur_index) {
++		rxcount = rxsd_index - rxring.cur_index;
++	} else if (rxsd_index < rxring.cur_index) {
++		rxcount = (STAR_NIC_MAX_RFD_NUM - rxring.cur_index) + rxsd_index;
++	} else {
++		if (rxdesc_ptr->cown == 0) {
++			goto receive_packet_exit;
++		} else {
++			// Queue Full
++#ifndef CONFIG_STAR_NIC_NAPI
++			rxqf = 1;
++#endif
++			rxcount = STAR_NIC_MAX_RFD_NUM;
++		}
++	}
++
++#ifndef CONFIG_STAR_NIC_NAPI
++	if (mode == 1) {
++		rxqf = 1;
++		rxcount = STAR_NIC_MAX_RFD_NUM;
++	}
++#endif
++
++	for (i = 0; i < rxcount; i++) {
++#ifdef CONFIG_STAR_NIC_NAPI
++		if (*work_done >= work_to_do)
++			break;
++		++(*work_done);
++#endif
++		if (rxdesc_ptr->cown != 0) {
++			// Alloc New skb_buff 
++			skb_ptr = star_nic_alloc_skb();
++			// Check skb_buff
++			if (skb_ptr != NULL) {
++				star_nic_get_rfd_buff(rxring.cur_index);
++				rxring.skb_ptr[rxring.cur_index] = skb_ptr;
++				rxdesc_ptr->data_ptr	= (u32)virt_to_phys(skb_ptr->data);
++				rxdesc_ptr->length	= MAX_PACKET_LEN;	
++				rxdesc_ptr->cown	= 0; // set cbit to 0 for CPU Transfer	
++			} else {
++				// TODO:
++				// I will add dev->lp.stats->rx_dropped, it will effect the performance
++				DBG_PRINT("%s: Alloc sk_buff fail, reuse the buffer\n", __FUNCTION__);
++				rxdesc_ptr->cown	= 0; // set cbit to 0 for CPU Transfer	
++				return;
++			}
++		} else {
++			//printk("[KC_DEBUG] star_nic_receive_packet() encounter COWN==0 BUG\n");
++		}
++
++		if (rxring.cur_index == (STAR_NIC_MAX_RFD_NUM - 1)) {
++			rxring.cur_index	= 0;
++			rxdesc_ptr		= rxring.vir_addr;
++		} else {
++			rxring.cur_index++;
++			rxdesc_ptr++;
++		}
++	}
++
++#ifndef CONFIG_STAR_NIC_NAPI
++	if (rxqf) {
++		rxring.cur_index = rxsd_index;
++		mb();
++		HAL_NIC_RX_DMA_START();
++	}
++#endif
++
++receive_packet_exit:
++	return;
++}
++
++#ifdef FREE_TX_SKB_MULTI
++#define FREE_TX_SKB_MULTI_MAX   16
++#define MAX_TX_SKB_FREE_NUM     FREE_TX_SKB_MULTI_MAX + MAX_SKB_FRAGS
++#endif
++
++#define FIX_NFS
++static int star_nic_send_packet(struct sk_buff *skb, struct net_device *dev)
++{
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	struct star_nic_private *priv = netdev_priv(dev);
++	STAR_NIC_TXDESC volatile *txdesc_ptr;
++	unsigned long flags;
++
++#ifdef FREE_TX_SKB_MULTI
++	int i;
++	int tssd_index;
++	int tssd_current;
++	int skb_free_count = 0;
++	struct sk_buff *skb_free[MAX_TX_SKB_FREE_NUM];
++#endif
++
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	int org_index;
++	int cur_index;
++
++
++	unsigned int f;
++	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
++	unsigned int len = skb->len - skb->data_len;
++	int padding_size = ETH_ZLEN - len;
++	unsigned int offset;
++
++
++#ifndef FREE_TX_SKB_MULTI
++	int skb_free_count = 0;
++	struct sk_buff *skb_free[MAX_SKB_FRAGS];
++#endif
++#else
++#ifndef FREE_TX_SKB_MULTI
++	struct sk_buff *skb_free;
++#endif
++#endif
++
++	spin_lock_irqsave(&star_nic_send_lock, flags);
++
++#ifdef FREE_TX_SKB_MULTI
++		int count = 0;
++
++		for (i = 0; i < FREE_TX_SKB_MULTI_MAX; i++) {
++			txdesc_ptr = txring.vir_addr + txring.to_free_index;
++			if (txdesc_ptr->cown == 0) {
++				break;
++			}
++			if (txring.skb_ptr[txring.to_free_index]) {
++				skb_free[count++] = txring.skb_ptr[txring.to_free_index];
++				txring.skb_ptr[txring.to_free_index] = NULL;
++			}
++
++			increase_cyclic(txring.to_free_index, STAR_NIC_MAX_TFD_NUM);
++
++			if (count == FREE_TX_SKB_MULTI_MAX) {
++				break;
++			}
++		}
++		skb_free_count = count;
++#endif
++
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	org_index = txring.cur_index;
++	cur_index = txring.cur_index;
++	for (f = 0; f < (nr_frags + 1); f++) {
++		txdesc_ptr = txring.vir_addr + cur_index;
++
++		if (txdesc_ptr->cown == 0) {
++			spin_unlock_irqrestore(&star_nic_send_lock, flags);
++#ifdef FREE_TX_SKB_MULTI
++			for (i = 0; i < skb_free_count; i++) {
++				dev_kfree_skb(skb_free[i]);
++			}
++#endif
++			/* Not enough tx buffer, re-queue the skb.             */
++			return NETDEV_TX_BUSY;
++		}
++
++		if (txring.skb_ptr[cur_index]) {
++			skb_free[skb_free_count++] = txring.skb_ptr[cur_index];
++		}
++
++#if defined(FREE_TX_SKB_MULTI) || defined(STAR_NIC_TIMER)
++		if(cur_index==txring.to_free_index)
++			increase_cyclic(txring.to_free_index, STAR_NIC_MAX_TFD_NUM);
++#endif
++
++		if (f == 0) {
++			txdesc_ptr->fs		= 1;
++		} else {
++			txdesc_ptr->fs		= 0;
++		}
++		if (f == nr_frags) {
++			txdesc_ptr->ls		= 1;
++		} else {
++			txdesc_ptr->ls		= 0;
++		}
++
++		increase_cyclic(cur_index, STAR_NIC_MAX_TFD_NUM);
++	}
++
++	txdesc_ptr = (txring.vir_addr + txring.cur_index);
++	txdesc_ptr->data_ptr			= virt_to_phys(skb->data);
++
++	if ((nr_frags == 0) && (len < PKT_MIN_SIZE)) {
++		txdesc_ptr->length		= PKT_MIN_SIZE;
++		memset(skb->data + len, 0x00, PKT_MIN_SIZE - len);
++	} else {
++		txdesc_ptr->length		= len;
++	}
++
++	if (nr_frags) {
++		txring.skb_ptr[txring.cur_index]	= NULL;
++	} else {
++		txring.skb_ptr[txring.cur_index]	= skb;
++	}
++	//dma_cache_maintenance(skb->data, txdesc_ptr->length, PCI_DMA_TODEVICE);
++	fa_dma_clean_range(skb->data, (unsigned long)skb->data + txdesc_ptr->length);
++
++	increase_cyclic(txring.cur_index, STAR_NIC_MAX_TFD_NUM);
++
++	for (f = 0; f < nr_frags; f++) {
++		struct skb_frag_struct *frag; 
++		txdesc_ptr = txring.vir_addr + txring.cur_index;
++		frag = &skb_shinfo(skb)->frags[f]; 
++#if 1
++		padding_size -= frag->size;
++
++		//txdesc_ptr->data_ptr = virt_to_phys(page_address(frag->page) + frag->page_offset);
++		txdesc_ptr->data_ptr = virt_to_phys(sg_virt(frag));
++		txdesc_ptr->length = frag->size;
++#else
++		len = frag->size; 
++		//offset = frag->page_offset; 
++
++		//txdesc_ptr->data_ptr = virt_to_phys(page_address(frag->page) + offset);
++		txdesc_ptr->data_ptr = virt_to_phys(sg_virt(frag));
++		txdesc_ptr->length = len;
++#endif // FIX_NFS
++
++		if (f == (nr_frags - 1)) {
++			txring.skb_ptr[txring.cur_index] = skb;
++		} else {
++			txring.skb_ptr[txring.cur_index] = NULL;
++		}
++		//dma_cache_maint(page_address(frag->page) + offset, txdesc_ptr->length, PCI_DMA_TODEVICE);
++		// dma_cache_maintenance(sg_virt(frag), txdesc_ptr->length, PCI_DMA_TODEVICE);
++		fa_dma_clean_range(sg_virt(frag), (unsigned long)sg_virt(frag)+txdesc_ptr->length);
++
++		increase_cyclic(txring.cur_index, STAR_NIC_MAX_TFD_NUM);
++		
++		if (padding_size > 0)
++		/* Padding zero to the end of packet to meet minimum 
++		 * packet size requirement.                       */
++			txdesc_ptr->length += padding_size;
++	}
++
++	for (f = 0; f < (nr_frags + 1); f++) {
++		txdesc_ptr = txring.vir_addr + org_index;
++		txdesc_ptr->cown = 0;
++		org_index++;
++		if (org_index == STAR_NIC_MAX_TFD_NUM) {
++			org_index = 0;
++		}
++	}
++
++
++
++#else
++	txdesc_ptr = txring.vir_addr + txring.cur_index;
++
++	if (txdesc_ptr->cown == 0) { // This TFD is busy
++		spin_unlock_irqrestore(&star_nic_send_lock, flags);
++		// re-queue the skb
++		return 1;
++	}
++
++#ifndef FREE_TX_SKB_MULTI
++	if (txring.skb_ptr[txring.cur_index]) {
++		// MUST TODO: Free skbuff
++		skb_free = txring.skb_ptr[txring.cur_index];
++	}
++#endif
++
++	txdesc_ptr->fs		= 1;
++	txdesc_ptr->ls		= 1;
++
++	txring.skb_ptr[txring.cur_index]	= skb;
++	txdesc_ptr->data_ptr			= virt_to_phys(skb->data);
++	if (skb->len < PKT_MIN_SIZE) {
++		txdesc_ptr->length		= PKT_MIN_SIZE;
++		memset(skb->data + skb->len, 0x00, PKT_MIN_SIZE - skb->len);
++	} else {
++		txdesc_ptr->length		= skb->len;
++	}
++
++	//dma_cache_maintenance(skb->data, txdesc_ptr->length, PCI_DMA_TODEVICE);
++	fa_dma_clean_range(skb->data, (unsigned long)skb->data+txdesc_ptr->length);
++
++	increase_cyclic(txring.cur_index, STAR_NIC_MAX_TFD_NUM);
++
++	txdesc_ptr->cown	= 0;
++#endif
++
++	mb();
++	HAL_NIC_TX_DMA_START();
++
++	priv->stats.tx_packets++;
++	priv->stats.tx_bytes += skb->len;
++	dev->trans_start = jiffies;
++
++	spin_unlock_irqrestore(&star_nic_send_lock, flags);
++
++#ifdef FREE_TX_SKB_MULTI
++	for (i = 0; i < skb_free_count; i++) {
++		dev_kfree_skb(skb_free[i]);
++	}
++#else
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	for (f = 0; f < skb_free_count; f++) {
++		dev_kfree_skb(skb_free[f]);
++	}
++#else
++	if (skb_free) {
++		dev_kfree_skb(skb_free);
++	}
++#endif
++#endif
++
++	return NETDEV_TX_OK;
++
++#else
++	struct star_nic_private *priv = netdev_priv(dev);
++	STAR_NIC_TXDESC volatile *txdesc_ptr = (txring.vir_addr + txring.cur_index);
++	struct sk_buff *skb_free = NULL;
++	unsigned long flags;
++
++	spin_lock_irqsave(&star_nic_send_lock, flags);
++
++	if (txdesc_ptr->cown == 0) { // This TFD is busy
++		spin_unlock_irqrestore(&star_nic_send_lock, flags);
++		// re-queue the skb
++		return NETDEV_TX_BUSY;
++	}
++
++	if (txdesc_ptr->data_ptr != 0) {
++		// MUST TODO: Free skbuff
++		skb_free = txring.skb_ptr[txring.cur_index];
++#ifdef STAR_NIC_TIMER
++		txring.to_free_index = txring.cur_index + 1;
++		if (txring.to_free_index == STAR_NIC_MAX_TFD_NUM) {
++			txring.to_free_index = 0;
++		}
++#endif
++	}
++
++#ifdef STAR_NIC_TX_HW_CHECKSUM
++	if (skb->protocol == __constant_htons(ETH_P_IP)) {
++		if (skb->nh.iph->protocol == IPPROTO_UDP) {
++			txdesc_ptr->uco = 1;
++			txdesc_ptr->tco = 0;
++			//printk("[KC DEBUG] UDP PACKET\n");
++		} else if (skb->nh.iph->protocol == IPPROTO_TCP) {
++			txdesc_ptr->uco = 0;
++			txdesc_ptr->tco = 1;
++			//printk("[KC DEBUG] TCP PACKET\n");
++		} else {
++			txdesc_ptr->uco = 0;
++			txdesc_ptr->tco = 0;
++			//printk("[KC DEBUG] NOT TCP&UDP PACKET\n");
++		}
++	} else {
++#if 0
++		if (skb->protocol == __constant_htons(ETH_P_ARP)) {
++			printk("[KC DEBUG] ARP PACKET\n");
++		} else {
++			printk("[KC DEBUG] NOT IP PACKET\n");
++		}
++#endif
++		txdesc_ptr->ico = 0;
++		txdesc_ptr->uco = 0;
++		txdesc_ptr->tco = 0;
++	}
++#endif
++
++	txring.skb_ptr[txring.cur_index]	= skb;
++	txdesc_ptr->data_ptr			= virt_to_phys(skb->data);
++	if (skb->len < PKT_MIN_SIZE) {
++		txdesc_ptr->length		= PKT_MIN_SIZE;
++		memset(skb->data + skb->len, 0x00, PKT_MIN_SIZE - skb->len);
++	} else {
++		txdesc_ptr->length		= skb->len;
++	}
++
++	//dma_cache_maintenance(skb->data, txdesc_ptr->length, PCI_DMA_TODEVICE);
++	fa_dma_clean_range(skb->data, (unsigned long)skb->data+txdesc_ptr->length);
++
++	txdesc_ptr->fs		= 1;
++	txdesc_ptr->ls		= 1;
++	// Wake interrupt
++	txdesc_ptr->intr	= 0;
++	txdesc_ptr->cown	= 0;
++
++	mb();
++	HAL_NIC_TX_DMA_START();
++
++	priv->stats.tx_packets++;
++	priv->stats.tx_bytes += skb->len;
++	dev->trans_start = jiffies;
++
++	if (txring.cur_index == (STAR_NIC_MAX_TFD_NUM - 1)) {
++		txring.cur_index = 0;
++	} else {
++		txring.cur_index++;
++	}
++
++	spin_unlock_irqrestore(&star_nic_send_lock, flags);
++	if (skb_free) {
++		dev_kfree_skb(skb_free);
++	}
++
++#ifdef STAR_NIC_TIMER
++	mod_timer(&star_nic_timer, jiffies + 10);
++#endif
++	return NETDEV_TX_OK;
++#endif
++}
++
++static void star_nic_set_mac_addr(struct net_device *dev, const char *mac_addr)
++{
++	memcpy(dev->dev_addr, mac_addr, 6);
++
++	NIC_MY_MAC_HIGH_BYTE_REG =
++	       	(mac_addr[0] << 8) |
++		 mac_addr[1];
++
++	NIC_MY_MAC_LOW_BYTE_REG =
++	       	(mac_addr[2] << 24) |
++		(mac_addr[3] << 16) |
++		(mac_addr[4] << 8)  |
++		(mac_addr[5]);
++
++	printk("MAC Addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
++		mac_addr[0],
++		mac_addr[1],
++		mac_addr[2],
++		mac_addr[3],
++		mac_addr[4],
++		mac_addr[5]);
++}
++
++static int star_nic_set_lan_mac_addr(struct net_device *dev, void *addr)
++{
++	struct sockaddr *sock_addr = addr;
++	struct star_nic_private *priv = netdev_priv(dev);
++
++	spin_lock_irq(&priv->lock);
++	star_nic_set_mac_addr(dev, sock_addr->sa_data);
++	spin_unlock_irq(&priv->lock);
++
++	return 0;
++}
++
++
++#ifdef CONFIG_PM
++static int nic_suspended=0;
++void inline str8100_wol_enter(){
++
++	//stop tx dma
++	HAL_NIC_TX_DMA_STOP();
++	//Enable Internal Loopback mode
++	NIC_TEST_1_REG|=(0x1<<18);
++
++	//WoL
++	NIC_MAC_CONTROL_REG |= (0x1 << 30); //assert WoL bit
++
++
++	while (!((NIC_MAC_CONTROL_REG>>29)&0x1)){
++		udelay(500);
++		NIC_MAC_CONTROL_REG |= (0x1 << 30); //assert WoL bit
++		NIC_MAC_CONTROL_REG &= ~(0x1 << 30); //de-assert WoL bit
++		NIC_MAC_CONTROL_REG |= (0x1 << 30); //assert WoL bit
++		udelay(500);
++
++//		if((NIC_TEST_1_REG&(0x1fff))!=4096){
++//printk("%.8x\n",NIC_TEST_1_REG);
++			u32 test=0;
++			test=test=NIC_TEST_1_REG;
++//		}
++	}
++	//Disable Internal Loopback mode
++	NIC_TEST_1_REG&=~(0x1<<18);
++
++	//Enable Magic packet received of Nic status Int	
++	HAL_NIC_ENABLE_INTERRUPT_STATUS_SOURCE_BIT(4);
++
++	NIC_MAC_CONTROL_REG |= (0x1 <<29);//write "1" clear
++	HAL_PWRMGT_DISABLE_NIC_CLOCK();
++}
++
++void inline str8100_wol_exit(){
++	HAL_NIC_DISABLE_INTERRUPT_STATUS_SOURCE_BIT(4);
++	HAL_PWRMGT_ENABLE_NIC_CLOCK();
++	NIC_MAC_CONTROL_REG &= ~(0x1 << 30); //de-assert power down bit
++
++	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCES((0x1<<4));
++	HAL_NIC_TX_DMA_START();
++}
++
++int inline str8100_nic_suspend(suspend_state_t state)
++{
++	if(!netif_running(STAR_NIC_LAN_DEV)) return 0;
++	nic_suspended=1;
++
++#ifdef CONFIG_PM_DEBUG
++	printk("%s:\n",__FUNCTION__);
++#endif
++	netif_device_detach(STAR_NIC_LAN_DEV);
++/*
++	if (netif_running(STAR_NIC_LAN_DEV)) {
++		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
++		e1000_down(adapter);
++	}
++*/
++	str8100_wol_enter();
++	return 0;
++}
++int inline str8100_nic_resume()
++{
++	//Waked
++	if(!nic_suspended) return 0;
++	nic_suspended=0;
++#ifdef CONFIG_PM_DEBUG
++	printk("%s:\n",__FUNCTION__);
++#endif
++/*	if (netif_running(STAR_NIC_LAN_DEV))
++		e1000_up(adapter);
++*/
++	netif_device_attach(STAR_NIC_LAN_DEV);
++
++	str8100_wol_exit();	
++
++	return 0;
++}
++#endif
++
++static int star_nic_init(struct net_device *dev)
++{
++#if 1
++	// set hight
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++	// set low
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << 15);
++	// set high
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++#endif
++
++#if 1
++	// set NIC clock to 67.5MHz
++	PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 7);
++#else
++	// set NIC clock to 125MHz
++	PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x1 << 7);
++#endif
++
++	// enable NIC clock
++	HAL_PWRMGT_ENABLE_NIC_CLOCK();
++	//NIC_MAC_CONTROL_REG = 0x00527C00;
++	udelay(100);
++
++	// Configure GPIO for NIC MDC/MDIO pins
++	HAL_MISC_ENABLE_MDC_MDIO_PINS();
++	HAL_MISC_ENABLE_NIC_COL_PINS();
++#ifdef CONFIG_STAR_NIC_PHY_INTERNAL_PHY
++	MISC_GPIOA_PIN_ENABLE_REG |= (0x7 << 22);
++	MISC_FAST_ETHERNET_PHY_CONFIG_REG |=  (FE_PHY_LED_MODE >> 12) & 0x3;
++
++	// set hight
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++	// set low
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << 15);
++	// set high
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 15);
++#else
++	//Enable GPIO for NIC LED
++	HAL_MISC_ENABLE_LED012_PINS();
++#endif
++
++	// disable all interrupt status sources
++	HAL_NIC_DISABLE_ALL_INTERRUPT_STATUS_SOURCES();
++
++	// clear previous interrupt sources
++	HAL_NIC_CLEAR_ALL_INTERRUPT_STATUS_SOURCES();
++
++	// disable all DMA-related interrupt sources
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_TXTC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_TXQE_BIT_INDEX);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_NIC_RXQF_BIT_INDEX);
++
++	// clear previous interrupt sources
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_TXTC_BIT_INDEX);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_RXRC_BIT_INDEX);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_TXQE_BIT_INDEX);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_NIC_RXQF_BIT_INDEX);
++
++	HAL_NIC_TX_DMA_STOP();
++	HAL_NIC_RX_DMA_STOP();
++
++	if (star_nic_buffer_alloc() != 0) {
++		return -1;
++	}
++	star_nic_mac_config(dev);
++	star_nic_fc_config(dev);
++
++	if (star_nic_phy_config(dev) != 0) {
++		star_nic_buffer_free();
++		return -1;
++	}
++
++	star_nic_vlan_config(dev);
++	star_nic_arl_config(dev);
++
++	/* MAC address is already in MAC registers from TS-BOOTROM */
++	default_mac_addr[0] = NIC_MY_MAC_HIGH_BYTE_REG >> 8;
++	default_mac_addr[1] = NIC_MY_MAC_HIGH_BYTE_REG;
++	default_mac_addr[2] = NIC_MY_MAC_LOW_BYTE_REG >> 24;
++	default_mac_addr[3] = NIC_MY_MAC_LOW_BYTE_REG >> 16;
++	default_mac_addr[4] = NIC_MY_MAC_LOW_BYTE_REG >> 8;
++	default_mac_addr[5] = NIC_MY_MAC_LOW_BYTE_REG;
++
++	star_nic_set_mac_addr(dev, default_mac_addr);
++	star_nic_mib_reset();
++
++	*(u32 volatile *)(SYSVA_MISC_BASE_ADDR+0x0c) = 0x00000125;    //0x00000105 pb0_nic
++
++	HAL_NIC_WRITE_TXSD(txring.phy_addr);
++	HAL_NIC_WRITE_TX_BASE(txring.phy_addr);
++	HAL_NIC_WRITE_RXSD(rxring.phy_addr);
++	HAL_NIC_WRITE_RX_BASE(rxring.phy_addr);
++
++	star_nic_dma_config(dev);
++
++	return 0;
++}
++
++static void set_multicast_list(struct net_device *dev) {
++}
++
++static const struct net_device_ops star_ops = {
++        .ndo_open               = star_nic_lan_open,
++        .ndo_stop               = star_nic_close,
++        .ndo_start_xmit         = star_nic_send_packet,
++        .ndo_get_stats          = star_nic_get_stats,
++        .ndo_set_multicast_list = set_multicast_list,
++        .ndo_tx_timeout         = star_nic_timeout,
++        .ndo_change_mtu         = eth_change_mtu,
++        .ndo_set_mac_address    = star_nic_set_lan_mac_addr,
++        .ndo_validate_addr      = eth_validate_addr,
++};
++
++static int __init star_nic_probe(int port_type)
++{
++	struct net_device *netdev;
++	struct star_nic_private *priv;
++	int err;
++
++	netdev = alloc_etherdev(sizeof(struct star_nic_private));
++	if (!netdev) {
++		err = -ENOMEM;
++		goto err_alloc_etherdev;
++	}
++
++	priv = netdev_priv(netdev);
++	memset(priv, 0, sizeof(struct star_nic_private));
++	spin_lock_init(&priv->lock);
++
++	netdev->base_addr		= SYSVA_NIC_BASE_ADDR;
++	netdev->netdev_ops = &star_ops;
++
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	netdev->features                = NETIF_F_IP_CSUM | NETIF_F_SG;
++#elif defined(STAR_NIC_TX_HW_CHECKSUM)
++	netdev->features                = NETIF_F_IP_CSUM;
++#endif
++#ifdef CONFIG_STAR_NIC_NAPI
++	netif_napi_add(netdev, &priv->napi, star_nic_poll, 64);
++#else
++	netdev->poll			= star_nic_poll;
++	netdev->weight			= 64;
++#endif
++	priv->dev_index			= LAN_PORT;
++
++#ifdef CONFIG_STAR_JUMBO
++	#error fix me
++	netdev->change_mtu = &str8100_change_mtu;
++#endif
++
++	err = register_netdev(netdev);
++	if (err) {
++		goto err_register_netdev;
++	}
++
++	//SET_MODULE_OWNER(netdev);
++
++	STAR_NIC_LAN_DEV = netdev;
++
++	if ((err = star_nic_init(netdev))) {
++		goto err_nic_init;
++	}
++
++	return 0;
++
++err_register_netdev:
++	free_netdev(netdev);
++	return err;
++
++err_nic_init:
++	unregister_netdev(netdev);
++	return err;
++
++err_alloc_etherdev:
++	return err;
++}
++
++static int __init star_nic_lan_init(void)
++{
++	return star_nic_probe(LAN_PORT);
++}
++
++static int __init star_nic_proc_init(void)
++{
++	star_nic_proc_entry = create_proc_entry("str8100/nic", S_IFREG | S_IRUGO, NULL);
++	if (star_nic_proc_entry) {
++		star_nic_proc_entry->read_proc = star_nic_read_proc;
++		star_nic_proc_entry->write_proc = star_nic_write_proc;
++	}
++
++	return 0;
++}
++
++static int __init star_nic_init_module(void)
++{
++	int err = 0;
++
++	printk(KERN_INFO "%s", star_nic_driver_version);
++	spin_lock_init(&star_nic_send_lock);
++	err = star_nic_lan_init();
++	if (err != 0) {
++		return err;
++	}
++	star_nic_proc_init();
++
++	printk("\n");
++#ifdef CONFIG_INTERNEL_PHY_PATCH
++	printk("%s: internal phy patch included.\n",__FUNCTION__);
++	//str813x_internal_phy_proc_init();
++#elif defined(CONFIG_STAR_NIC_PHY_INTERNAL_PHY)
++	printk("%s: internal phy used but no patch included.\n",__FUNCTION__);
++#endif
++#if defined(STAR_NIC_TX_HW_CHECKSUM) && defined(MAX_SKB_FRAGS) && defined(STAR_NIC_SG)
++	printk("%s: scatter/gather enabled.\n",__FUNCTION__);
++#else
++	printk("%s: scatter/gather disabled.\n",__FUNCTION__);
++#endif
++	printk("\n");
++
++#ifdef STAR_NIC_TIMER
++	init_timer(&star_nic_timer);
++	star_nic_timer.function = &star_nic_timer_func;
++	star_nic_timer.data = (unsigned long)NULL;
++#endif
++
++	return 0;
++}
++
++module_init(star_nic_init_module);
++
++//========================================================
++#ifdef CONFIG_INTERNEL_PHY_PATCH
++
++static void (*phy_statemachine)(int, int, int);
++
++#define ETH3220_PHY_MON_PERIOD INTERNAL_PHY_PATCH_CHECK_PERIOD
++
++/*===================================================================================*/
++/*  phy monitor state  */
++#define NUM_PHY 1
++#define PHY_STATE_INIT					0
++#define LINK_DOWN_POSITIVE				1
++#define WAIT_LINK_UP_POSITIVE				2
++#define LINK_UP_POSITIVE				3
++#define WAIT_BYPASS_LINK_UP_POSITIVE			4
++#define BYPASS_AND_LINK_UP_POSITIVE			5
++#define LINK_UP_8101_POSITIVE				6
++#define WAIT_8101_LINK_UP_POSITIVE			7
++
++#define PHY_STATE_LAST					(WAIT_8101_LINK_UP_POSITIVE+1)
++/*===================================================================================*/
++/*  time setting  */
++#define WAIT_BYPASS_LINK_UP_POSITIVE_TIMEOUT		5000	/*  5000 ms  */
++#define WAIT_BYPASS_LINK_UP_NEGATIVE_TIMEOUT		5000	/*  5000 ms  */
++#define LINK_DOWN_ABILITY_DETECT_TIMEOUT		5000	/*  5000 ms  */
++#define DETECT_8101_PERIOD				7000	/*  7000 ms  */
++#define WAIT_8101_LINK_UP_TIMEOUT			3000	/*  3000 ms  */
++
++#define MAX_PHY_PORT					1
++#define DEFAULT_AGC_TRAIN				16
++#define MAX_AGC_TRAIN					16	//train 16 times
++static int agc_train_num = DEFAULT_AGC_TRAIN;
++u32 port_displaybuf[NUM_PHY][MAX_AGC_TRAIN + 1] = {{0}};
++
++static int cuv[3][3] = {
++	{1, 1, 4},
++	{1, 1, 0},
++	{1, 1, -4}};
++static u32 link_status_old = 0;
++//static int agc_th[2] = {0x18, 0x28}; /* To be deleted */
++//static u32 phy_mon_timer; /* To be deleted */
++//static u32 current_agc = 0;   //0:Not patch, 1:patch
++/*===================================================================================*/
++
++typedef struct eth3220_phy_s {
++	u16 state;
++	u16 linkdown_cnt;
++	u32 state_time;
++	u32 timer;
++} eth3220_phy_t;
++
++#define DEBUG_PHY_STATE_TRANSITION			1
++#if DEBUG_PHY_STATE_TRANSITION
++/*  show state transition of debug phy port.
++ *  -1 for all ports
++ *  -2 for disable all ports
++ *  0 - 4 for each port  */
++static int debug_phy_port = -2;
++static char *phystate_name[] = {
++	"init",			/*  PHY_STATE_INIT  */
++	"ldp",			/*  LINK_DOWN_POSITIVE  */
++	"wait_lup",		/*  WAIT_LINK_UP_POSITIVE  */
++	"lup",			/*  LINK_UP_POSITIVE  */
++	"wait_bp_lup",		/*  WAIT_BYPASS_LINK_UP_POSITIVE  */
++	"bp_lup",		/*  BYPASS_AND_LINK_UP_POSITIVE  */
++	"8101_lup",		/*  LINK_UP_8101_POSITIVE  */
++	"wait_8101_lup",	/*  WAIT_8101_LINK_UP_POSITIVE  */
++	"err",
++};
++#endif  /*  DEBUG_PHY_STATE_TRANSITION  */
++static eth3220_phy_t phy[5] = { {PHY_STATE_INIT, 0, 0, 0},
++				{PHY_STATE_INIT, 0, 0, 0},
++				{PHY_STATE_INIT, 0, 0, 0},
++				{PHY_STATE_INIT, 0, 0, 0},
++				{PHY_STATE_INIT, 0, 0, 0}};
++
++static u16 long_cable_global_reg[32]={
++0x0000,0x19a0,0x1d00,0x0e80,0x0f60,0x07c0,0x07e0,0x03e0,
++0x0000,0x0000,0x0000,0x2000,0x8250,0x1700,0x0000,0x0000,
++0x0000,0x0000,0x0000,0x0000,0x0000,0x204b,0x01c2,0x0000,
++0x0000,0x0000,0x0fff,0x4100,0x9319,0x0021,0x0034,0x270a|FE_PHY_LED_MODE
++};
++
++static u16 long_cable_local_reg[32]={
++0x3100,0x786d,0x01c1,0xca51,0x05e1,0x45e1,0x0003,0x001c,
++0x2000,0x9828,0xf3c4,0x400c,0xf8ff,0x6940,0xb906,0x503c,
++0x8000,0x297a,0x1010,0x5010,0x6ae1,0x7c73,0x783c,0xfbdf,
++0x2080,0x3244,0x1301,0x1a80,0x8e8f,0x8000,0x9c29,0xa70a|FE_PHY_LED_MODE
++};
++
++static void internal_phy_update(unsigned long data)
++{
++	internal_phy_patch_check(0);
++	mod_timer(&internal_phy_timer, jiffies + INTERNAL_PHY_PATCH_CHECK_PERIOD / 10);
++}
++
++static struct timer_list internal_phy_timer =
++	TIMER_INITIALIZER(internal_phy_update, 0, 0);
++
++/*=============================================================*
++ *  eth3220ac_rt8101_phy_setting
++ *=============================================================*/
++static  void eth3220ac_rt8101_phy_setting(int port)
++{
++	star_nic_write_phy(port, 12, 0x18ff);
++	star_nic_write_phy(port, 18, 0x6400);
++}
++
++static void eth3220ac_release_bpf(int port)
++{
++	star_nic_write_phy(port, 18, 0x6210);
++}
++
++static  void eth3220ac_def_bpf(int port)
++{
++	star_nic_write_phy(port, 18, 0x6bff);
++}
++
++static  void eth3220ac_def_linkdown_setting(int port)
++{
++	star_nic_write_phy(port, 13, 0xe901);
++	star_nic_write_phy(port, 14, 0xa3c6);
++}
++
++static  void eth3220ac_def_linkup_setting(int port)
++{
++	star_nic_write_phy(port, 13, 0x6901);
++	star_nic_write_phy(port, 14, 0xa286);
++}
++
++/*=============================================================*
++ *  eth3220ac_link_agc:
++ *=============================================================*/
++static int eth3220ac_link_agc(int port, int speed)
++{
++	u16 reg;
++	u32 agc_data = 0;
++	u32 short_cable;
++	int i, jj;
++
++	/* if speed = 100MHz, then continue */
++	if (speed == 0)
++		return 0;
++
++	short_cable = 0;
++	jj = 0;
++	for (i=0; i < agc_train_num; i++) {
++		star_nic_read_phy(port, 15, &reg);
++		reg &= 0x7f;
++		if (reg <= 0x12) {
++			short_cable = 1;
++			jj++;
++			agc_data += (u32)reg;
++		}
++	}
++	if (short_cable) {
++		agc_data = (agc_data / jj) + 4;
++	} else {
++		agc_data = (cuv[2][0] * agc_data) / cuv[2][1] / agc_train_num - 4;
++	}
++
++	/*  Fix AGC  */
++	agc_data = 0xd0 | (agc_data << 9);
++	star_nic_write_phy(port, 15, agc_data);
++	udelay(1000);
++	star_nic_read_phy(port, 15, &reg);
++	reg &= ~(0x1 << 7);
++	star_nic_write_phy(port, 15, reg);
++
++	return 0;
++}
++
++/*=============================================================*
++ *  eth3220ac_unlink_agc:
++ *=============================================================*/
++static void eth3220ac_unlink_agc(int port)
++{
++	// start AGC adaptive
++	star_nic_write_phy(port, 15, 0xa050);
++}
++
++/*=============================================================*
++ *  eth3220ac_rt8100_check
++ *=============================================================*/
++static int eth3220ac_rt8100_check(int port)
++{
++	u16 reg, reg2;
++
++	/* Read reg27 (error register) */
++	star_nic_read_phy(port, 27, &reg);
++	/* if error exists, set Bypass Filter enable */
++	if ((reg & 0xfffc)) {
++                star_nic_read_phy(port, 15, &reg);	
++                star_nic_read_phy(port, 27, &reg2);	
++		if (( reg2 & 0xfffc) && (((reg >> 9) & 0xff) < 0x1c)) {
++			printk("8100 pos err\n");
++			/* Bypass agcgain disable */
++			star_nic_write_phy(port, 15, (reg & (~(0x1 << 7))));
++			
++			/* repeat counts when reaching threshold error */
++			star_nic_write_phy(port, 13, 0x4940);
++			
++			/* Speed up AN speed && compensate threshold phase error */
++			star_nic_write_phy(port, 14, 0xa306);
++			
++			/* Bypass Filter enable */
++                        star_nic_read_phy(port, 18, &reg2);	
++
++			star_nic_write_phy(port, 18, (reg | 0x400));
++			
++			/* restart AN */
++			star_nic_write_phy(port, 0, 0x3300);
++			return 1;
++		}
++	}
++	return 0;
++}
++
++
++/*=============================================================*
++ *  eth3220ac_rt8100_linkdown
++ *=============================================================*/
++static void eth3220ac_rt8100_linkdown(int port)
++{
++	u16 reg;
++	
++	/* Bypass Filter disable */
++	star_nic_read_phy(port, 18, &reg);	
++	star_nic_write_phy(port, 18, (reg & (~(0x1 << 10))));
++	eth3220ac_def_linkdown_setting(port);
++}
++
++static void eth3220ac_normal_phy_setting(int port)
++{
++	star_nic_write_phy(port, 12, 0xd8ff);
++	eth3220ac_def_bpf(port);
++}
++
++/*=============================================================*
++ *  wp3220ac_phystate
++ *=============================================================*/
++static void wp3220ac_phystate(int port, int link, int speed)
++{
++	int next_state;
++	u16 reg, reg2;	
++
++	phy[port].timer += ETH3220_PHY_MON_PERIOD;
++	
++	if (link) {
++		/*  Link up state  */
++		switch(phy[port].state) {
++		case LINK_UP_POSITIVE:
++			next_state = eth3220ac_rt8100_check(port) ?
++				WAIT_BYPASS_LINK_UP_POSITIVE :
++				LINK_UP_POSITIVE;
++			break;
++			
++		case PHY_STATE_INIT:
++		case WAIT_LINK_UP_POSITIVE:
++		case LINK_DOWN_POSITIVE:
++			next_state = LINK_UP_POSITIVE;
++			eth3220ac_def_linkup_setting(port);
++			eth3220ac_link_agc(port, speed);
++			eth3220ac_release_bpf(port);
++			break;
++			
++		case WAIT_BYPASS_LINK_UP_POSITIVE:
++		case BYPASS_AND_LINK_UP_POSITIVE:
++			next_state = BYPASS_AND_LINK_UP_POSITIVE;
++			break;
++			
++		case WAIT_8101_LINK_UP_POSITIVE:
++			next_state = LINK_UP_8101_POSITIVE;
++			eth3220ac_link_agc(port, speed);
++			star_nic_write_phy(port, 12, 0x98ff);
++			break;
++			
++		case LINK_UP_8101_POSITIVE:
++			next_state = LINK_UP_8101_POSITIVE;
++			break;
++			
++		default:
++			next_state = LINK_UP_POSITIVE;
++			eth3220ac_def_linkup_setting(port);
++			eth3220ac_link_agc(port, speed);
++		}
++	} else {
++		/*  Link down state  */
++		switch(phy[port].state) {
++		case LINK_DOWN_POSITIVE:
++                        star_nic_read_phy(port, 5, &reg);	
++                        star_nic_read_phy(port, 28, &reg2);	
++			/* AN Link Partner Ability Register or NLP */
++			if (reg || (reg2 & 0x100))
++				next_state = WAIT_LINK_UP_POSITIVE;
++			else
++				next_state = LINK_DOWN_POSITIVE;
++			break;
++			
++		case WAIT_LINK_UP_POSITIVE:
++			if (phy[port].state_time > LINK_DOWN_ABILITY_DETECT_TIMEOUT)
++				next_state = LINK_DOWN_POSITIVE;
++			else
++				next_state = WAIT_LINK_UP_POSITIVE;
++			break;
++			
++		case WAIT_BYPASS_LINK_UP_POSITIVE:
++			/* set timeout = 5 sec */
++			if (phy[port].state_time > WAIT_BYPASS_LINK_UP_POSITIVE_TIMEOUT) {
++				next_state = LINK_DOWN_POSITIVE;
++				/* Bypass Filter disable */
++				eth3220ac_rt8100_linkdown(port);
++				eth3220ac_def_bpf(port);
++			} else {
++				next_state = WAIT_BYPASS_LINK_UP_POSITIVE;
++			}
++			break;
++			
++		case BYPASS_AND_LINK_UP_POSITIVE:
++			next_state = LINK_DOWN_POSITIVE;
++			eth3220ac_rt8100_linkdown(port);
++			eth3220ac_def_bpf(port);
++			break;
++			
++		case WAIT_8101_LINK_UP_POSITIVE:
++			if (phy[port].state_time > WAIT_8101_LINK_UP_TIMEOUT) {
++				next_state = LINK_DOWN_POSITIVE;
++				eth3220ac_normal_phy_setting(port);
++				eth3220ac_def_linkdown_setting(port);
++			} else {
++				next_state = WAIT_8101_LINK_UP_POSITIVE;
++			}
++			break;
++			
++		case LINK_UP_POSITIVE:
++			eth3220ac_unlink_agc(port);
++			eth3220ac_def_linkdown_setting(port);
++			eth3220ac_def_bpf(port);
++			if (phy[port].timer > DETECT_8101_PERIOD) {
++				next_state = LINK_DOWN_POSITIVE;
++				phy[port].timer = 0;
++				phy[port].linkdown_cnt = 1;
++			} else {
++				if (++phy[port].linkdown_cnt > 2) {
++					next_state = WAIT_8101_LINK_UP_POSITIVE;
++					eth3220ac_rt8101_phy_setting(port);
++				} else {
++					next_state = LINK_DOWN_POSITIVE;
++				}
++			}
++			break;
++			
++		case LINK_UP_8101_POSITIVE:
++			eth3220ac_normal_phy_setting(port);
++			/*  fall down to phy normal state  */
++		case PHY_STATE_INIT:
++			eth3220ac_def_linkdown_setting(port);
++			eth3220ac_unlink_agc(port);
++		default:
++			next_state = LINK_DOWN_POSITIVE;
++		}
++	}
++	
++	if (phy[port].state != next_state) {
++		phy[port].state_time = 0;
++#if DEBUG_PHY_STATE_TRANSITION
++		if (debug_phy_port == -1 || port == debug_phy_port)
++		{
++			if ((phy[port].state < PHY_STATE_LAST) && (next_state < PHY_STATE_LAST))
++			{
++				printk("p%d: %s->%s, %d, %d\n", port, phystate_name[phy[port].state],
++					phystate_name[next_state], phy[port].timer, phy[port].linkdown_cnt);
++			}
++			else
++			{
++				printk("p%d: %d->%d\n", port, phy[port].state, next_state);
++			}
++		}
++#endif   /*  DEBUG_PHY_STATE_TRANSITION  */
++	} else {
++		phy[port].state_time += ETH3220_PHY_MON_PERIOD;
++	}
++	phy[port].state = next_state;
++}
++
++/*=============================================================*
++ *  eth3220_phyinit:
++ *=============================================================*/
++static void eth3220ac_10m_agc(void)
++{
++	/* Force 10M AGC = 2c globally */
++	star_nic_write_phy(0, 31, 0x2f1a);
++	star_nic_write_phy(0, 12, 0x112c);
++	star_nic_write_phy(0, 13, 0x2e21);
++	star_nic_write_phy(0, 31, 0xaf1a);
++}
++
++static void eth3220ac_dfe_init(void)
++{
++	int i;
++
++	star_nic_write_phy(0, 31, 0x2f1a);
++	for (i=0; i <= 7; i++)
++		star_nic_write_phy(0, i, 0);
++	star_nic_write_phy(0, 11, 0x0b50);
++	star_nic_write_phy(0, 31, 0xaf1a);
++}
++
++static void eth3220ac_phy_cdr_training_init(void)
++{
++	int volatile i;
++
++	/* Force all port in 10M FD mode */
++	for (i=0; i < NUM_PHY; i++)
++		star_nic_write_phy(i, 0, 0x100);
++	
++	/* Global setting */
++	star_nic_write_phy(0, 31, 0x2f1a);
++	star_nic_write_phy(0, 29, 0x5021);
++        udelay(2000); //2ms, wait > 1 ms
++	star_nic_write_phy(0, 29, 0x4021);
++        udelay(2000); //2ms, wait > 1 ms
++	star_nic_write_phy(0, 31, 0xaf1a);
++
++	/* Enable phy AN */
++	for (i=0; i < NUM_PHY; i++)
++		star_nic_write_phy(i, 0, 0x3100);	
++}
++
++static void eth3220_phyinit(void)
++{
++	eth3220ac_10m_agc();
++	eth3220ac_dfe_init();
++	eth3220ac_phy_cdr_training_init();
++}
++
++static void eth3220_phycfg(int phyaddr)
++{
++	eth3220ac_def_linkdown_setting(phyaddr);
++	eth3220ac_normal_phy_setting(phyaddr);
++	star_nic_write_phy(phyaddr, 9, 0x7f);
++}
++
++static void internal_phy_patch_check(int init)
++{
++	u32 short_cable_agc_detect_count;
++	u32 link_status = 0, link_speed;
++	u32 ii, jj;
++	u16 phy_data;
++	u16 phy_data2;
++
++	star_nic_read_phy(STAR_NIC_PHY_ADDR, 1, &phy_data);
++	udelay(100);
++	star_nic_read_phy(STAR_NIC_PHY_ADDR, 1, &phy_data2);
++	if (((phy_data & 0x0004) != 0x0004) && ((phy_data2 & 0x0004) != 0x0004)) { // link down
++		short_cable_agc_detect_count = 0;
++		for (jj = 0; jj < INTERNAL_PHY_PATCH_CHECKCNT; jj++) {
++			star_nic_read_phy(STAR_NIC_PHY_ADDR, 15, &phy_data);
++			udelay(1000);
++			if (((phy_data) & 0x7F) <= 0x12) { // short cable
++				short_cable_agc_detect_count++;
++				break;
++			}
++		}
++		if (short_cable_agc_detect_count) { // short cable
++			phy_statemachine = wp3220ac_phystate;
++			eth3220_phyinit();
++			star_nic_read_phy(STAR_NIC_PHY_ADDR, 1, &phy_data);
++			if (phy_data & 0x0040) { // link up
++				link_status = 1;
++			}
++			if ((NIC_MAC_CONTROL_REG & 0xC) == 0x4) { // 100Mbps
++				link_speed = 1;
++			} else {
++				link_speed = 0;
++			}
++			link_status_old = link_status;
++			for (ii = 0; ii < MAX_PHY_PORT; link_status >>= 1, ii++) {
++				eth3220_phycfg(ii);
++#if 0
++				if (phy_statemachine != NULL)
++					(*phy_statemachine)(ii, link_status & 1, link_speed & 1);
++#endif
++			}
++		} else { // long cable
++			// set to global domain
++			star_nic_write_phy(NIC_PHY_ADDRESS, 31, 0x2f1a);
++			for (ii = 0; ii < 32; ii++) {
++				star_nic_write_phy(NIC_PHY_ADDRESS, ii, long_cable_global_reg[ii]);
++			}
++			// set to local domain
++			star_nic_write_phy(NIC_PHY_ADDRESS, 31, 0xaf1a);
++			for (ii = 0; ii < 32; ii++) {
++				star_nic_write_phy(NIC_PHY_ADDRESS, ii, long_cable_local_reg[ii]);
++			}
++		}
++	}
++}
++
++#endif
++//========================================================
+diff -rupN linux-2.6.35.11/drivers/net/str9100/dorado2.h linux-2.6.35.11-ts7500/drivers/net/str9100/dorado2.h
+--- linux-2.6.35.11/drivers/net/str9100/dorado2.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/dorado2.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,223 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef  DORADO2_H
++#define  DORADO2_H
++
++#include <linux/types.h>
++
++// this configure is for star dorado2
++
++// add by descent 2006/07/10
++#define DORADO2
++
++// add by KC 2006/09/07
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++// if no VSC8201 on MAC PORT1, we need to define this
++// if VSC8201 is present, mark it
++//#define DORADO2_PCI_FASTPATH_MAC_PORT1_LOOPBACK
++#endif
++
++#ifdef DORADO2
++// init phy or switch chip
++#define INIT_PORT0_PHY star_gsw_config_VSC7385();
++#ifdef DORADO2_PCI_FASTPATH_MAC_PORT1_LOOPBACK
++#define INIT_PORT1_PHY star_gsw_config_mac_port1_loopback();
++#else
++#define INIT_PORT1_PHY star_gsw_config_VSC8201(1,1);
++#endif
++//#define INIT_PORT1_PHY 
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC init_packet_forward(1);
++//#define INIT_PORT1_MAC 
++
++#define PORT0_LINK_DOWN disable_AN(0, 0);
++#define PORT0_LINK_UP disable_AN(0, 1);
++
++#ifdef DORADO2_PCI_FASTPATH_MAC_PORT1_LOOPBACK
++#define PORT1_LINK_DOWN
++#define PORT1_LINK_UP
++#else
++#define PORT1_LINK_DOWN std_phy_power_down(1, 1);
++#define PORT1_LINK_UP std_phy_power_down(1, 0);
++#endif
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 star_gsw_probe(WAN_PORT);
++#define CREATE_NET_DEV2 star_gsw_probe(EWC_PORT);
++//#define CREATE_NET_DEV2 
++
++#define CONFIG_STR9100_PORT_BASE
++#define CONFIG_STR9100_VLAN_BASE
++//#define CONFIG_HAVE_VLAN_TAG
++
++// for port base, port base max is 2 port.
++// use in star_gsw_get_rfd_buff().
++// if a port no used, define to "0;"
++// NET_DEV0 : rx->sp 0 (port 0)
++#define NET_DEV0 0
++// NET_DEV1 : rx->sp 1 (port 1)
++#define NET_DEV1 STAR_GSW_EWC_DEV
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT -1
++#define PORT_BASE_PMAP_WAN_PORT -1
++#define PORT_BASE_PMAP_EWC_PORT 2 // 2 port 1
++
++#define MODEL "DORADO2"
++
++// OPEN_PORT0 include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_EWC_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[2].vlan_mac, 6);\
++		PRINT_INFO("open mac port1\n"); \
++		mac_port_config = GSW_MAC_PORT_1_CONFIG; \
++		/* disable port 1 */  \
++		mac_port_config &= (~(0x1 << 18)); \
++		GSW_MAC_PORT_1_CONFIG = mac_port_config; \
++		PORT1_LINK_UP \
++	} \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		if (dev == STAR_GSW_LAN_DEV) \
++			memcpy(dev->dev_addr, star_gsw_info.vlan[1].vlan_mac, 6);\
++		if (dev == STAR_GSW_WAN_DEV) \
++			memcpy(dev->dev_addr, star_gsw_info.vlan[0].vlan_mac, 6);\
++		/* rc_port is a reference count variable. */ \
++	        if (rc_port == 0) {\
++        		PRINT_INFO("open mac port 0\n");\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* enable port 0 */ \
++		        mac_port_config &= (~(0x1 << 18));\
++               		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++			PORT0_LINK_UP\
++	        }\
++	        else{\
++      			PRINT_INFO("port 0 already open\n");\
++	        }\
++		++rc_port;\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_EWC_DEV) { \
++		PRINT_INFO("close mac port1\n"); \
++		PORT1_LINK_DOWN \
++		mac_port_config = GSW_MAC_PORT_1_CONFIG; \
++		/* disable port 1 */  \
++		mac_port_config |= ((0x1 << 18)); \
++		GSW_MAC_PORT_1_CONFIG = mac_port_config; \
++	} \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		--rc_port;\
++		/* rc_port is a reference count variable. */ \
++	        if (rc_port == 0) {\
++        		PRINT_INFO("close mac port 0\n");\
++			PORT0_LINK_DOWN\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* disable port 0 */ \
++		        mac_port_config |= ((0x1 << 18));\
++               		 GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	        }\
++	        else {\
++      			PRINT_INFO("a live net device\n");\
++	        }\
++	} \
++}
++
++
++
++#define VLAN0_VID			(0x2)
++#define VLAN1_VID			(0x1)
++#define VLAN2_VID			(0x3)
++#define VLAN3_VID			(0x4)
++#define VLAN4_VID			(0x5)
++#define VLAN5_VID			(0x6)
++#define VLAN6_VID			(0x7)
++#define VLAN7_VID			(0x8)
++
++#define VLAN0_GROUP			(PORT0 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(PORT1 | CPU_PORT)
++#define VLAN3_GROUP			(PORT1 | CPU_PORT)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(PORT1 | CPU_PORT)
++
++
++#ifdef CONFIG_HAVE_VLAN_TAG
++
++#define VLAN0_VLAN_TAG			(5)	// cpu port and mac 0 port
++#define VLAN1_VLAN_TAG			(5)	// cpu port and mac 0 port
++
++#else
++#define VLAN0_VLAN_TAG			(1)	// only mac 0 port
++#define VLAN1_VLAN_TAG			(1)	// only mac 0 port
++#endif
++
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++
++/* wan eth1 */
++static u8 my_vlan0_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x50};
++
++/* lan eth 0*/
++static u8 my_vlan1_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x60};
++
++/* cpu */
++static u8 my_vlan2_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x22};
++
++/* ewc  */
++static u8 my_vlan3_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x23};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 1
++#define WAN_GID 0
++
++
++#endif //DORADO2
++
++
++
++
++#endif
+diff -rupN linux-2.6.35.11/drivers/net/str9100/dorado.h linux-2.6.35.11-ts7500/drivers/net/str9100/dorado.h
+--- linux-2.6.35.11/drivers/net/str9100/dorado.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/dorado.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,188 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef  DORADO_H
++#define  DORADO_H
++
++int disable_AN(int port, int y);
++// this configure is for star dorado2
++
++// add by descent 2006/07/10
++#define DORADO
++#ifdef DORADO
++// init phy or switch chip
++#define INIT_PORT0_PHY star_gsw_config_VSC7385();
++#define INIT_PORT1_PHY 
++//#define INIT_PORT1_PHY 
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC 
++//#define INIT_PORT1_MAC 
++
++#define PORT0_LINK_DOWN disable_AN(0, 0);
++#define PORT0_LINK_UP disable_AN(0, 1);
++
++#define PORT1_LINK_DOWN 
++#define PORT1_LINK_UP 
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 star_gsw_probe(WAN_PORT);
++#define CREATE_NET_DEV2 
++//#define CREATE_NET_DEV2 
++
++#undef CONFIG_STR9100_PORT_BASE
++#define CONFIG_STR9100_VLAN_BASE
++#undef CONFIG_HAVE_VLAN_TAG
++
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT INVALID_PORT_BASE_PMAP_PORT
++#define PORT_BASE_PMAP_WAN_PORT INVALID_PORT_BASE_PMAP_PORT
++#define PORT_BASE_PMAP_EWC_PORT INVALID_PORT_BASE_PMAP_PORT
++
++#define MODEL "DORADO"
++
++// OPEN_PORT0 include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		if (dev == STAR_GSW_LAN_DEV) { \
++			/*printk("STAR_GSW_LAN_DEV\n"); */ \
++			/*memcpy(dev->dev_addr, star_gsw_info.vlan[LAN_GID].vlan_mac, 6);*/ \
++		} \
++		if (dev == STAR_GSW_WAN_DEV) { \
++			/* printk("STAR_GSW_WAN_DEV\n"); */ \
++			/*memcpy(dev->dev_addr, star_gsw_info.vlan[WAN_GID].vlan_mac, 6);*/ \
++		} \
++		/* rc_port is a reference count variable. */ \
++	        if (rc_port == 0) {\
++        		PRINT_INFO("open mac port 0\n");\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* enable port 0 */ \
++		        mac_port_config &= (~(0x1 << 18));\
++               		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++			PORT0_LINK_UP\
++	        }\
++	        else{\
++      			PRINT_INFO("port 0 already open\n");\
++	        }\
++		++rc_port;\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		/* rc_port is a reference count variable. */ \
++		--rc_port;\
++	        if (rc_port == 0) {\
++        		PRINT_INFO("close mac port 0\n");\
++			PORT0_LINK_DOWN\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* disable port 0 */ \
++		        mac_port_config |= ((0x1 << 18));\
++               		 GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	        }\
++	        else {\
++      			PRINT_INFO("a live net device\n");\
++	        }\
++	} \
++}
++
++
++
++// the vlan past waht vlan tag value
++#define VLAN0_VID			(0x2) // wan
++#define VLAN1_VID			(0x1) // lan
++#define VLAN2_VID			(0x3)
++#define VLAN3_VID			(0x4)
++#define VLAN4_VID			(0x5)
++#define VLAN5_VID			(0x6)
++#define VLAN6_VID			(0x7)
++#define VLAN7_VID			(0x8)
++
++// the vlan include ports
++#define VLAN0_GROUP			(PORT0 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(0)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++
++
++#ifdef CONFIG_HAVE_VLAN_TAG
++
++// the vlan which ports will past vlan tags.
++#define VLAN0_VLAN_TAG			(5)	// cpu port and mac 0 port
++#define VLAN1_VLAN_TAG			(5)	// cpu port and mac 0 port
++
++#else
++#define VLAN0_VLAN_TAG			(1)	// only mac 0 port
++#define VLAN1_VLAN_TAG			(1)	// only mac 0 port
++#endif
++
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++
++/* wan eth1 */
++static u8 my_vlan0_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x50};
++
++/* lan eth 0*/
++static u8 my_vlan1_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x60};
++
++/* cpu */
++static u8 my_vlan2_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x22};
++
++/* ewc  */
++static u8 my_vlan3_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x23};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 1
++#define WAN_GID 0
++
++
++#endif //DORADO
++
++
++
++
++#endif
+diff -rupN linux-2.6.35.11/drivers/net/str9100/Kconfig linux-2.6.35.11-ts7500/drivers/net/str9100/Kconfig
+--- linux-2.6.35.11/drivers/net/str9100/Kconfig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,45 @@
++menu "CNS1100 Gigabit Switch support"
++	depends on ARCH_STR9100
++
++config STAR_GSW
++	tristate "CNS1100 Gigabit Switch driver support"
++
++config STR9100_SHNAT
++	bool "CNS1100 Smart HNAT Support"
++	depends on STAR_GSW
++	help
++	  Add STAR Smart HNAT support function in kernel
++
++config STAR9100_SHNAT_PCI_FASTPATH
++	bool "FastPath(From PCI to WAN) Support"
++	depends on STR9100_SHNAT
++	help
++	  Add FastPath Support for Smart HNAT.
++
++choice
++	prompt "CNS1100 Board"
++	depends on STAR_GSW
++	default DORADO
++
++config DORADO
++	bool "Dorado"
++
++config DORADO2
++	bool "Dorado2"
++
++config VIRGO
++	bool "Virgo"
++
++config VELA
++	bool "Vela"
++
++config LIBRA
++	bool "Libra"
++
++config LEO
++	bool "Leo"
++
++endchoice
++
++endmenu
++
+diff -rupN linux-2.6.35.11/drivers/net/str9100/leo.h linux-2.6.35.11-ts7500/drivers/net/str9100/leo.h
+--- linux-2.6.35.11/drivers/net/str9100/leo.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/leo.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,152 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef LEO_H
++#define LEO_H
++
++// add by descent 2006/07/10
++#define LEO
++#ifdef LEO
++// init phy or switch chip
++#define INIT_PORT0_PHY star_gsw_config_VSC8201(0,0);
++#define INIT_PORT1_PHY 
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC disable_AN(1, 1);
++// if no disable_AN port 1, maybe get link up/down (change link state)
++
++#define PORT0_LINK_DOWN std_phy_power_down(0,1);
++#define PORT0_LINK_UP std_phy_power_down(0,0);
++
++#define PORT1_LINK_DOWN 
++#define PORT1_LINK_UP 
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 
++#define CREATE_NET_DEV2
++
++
++#define CONFIG_STR9100_PORT_BASE
++#undef CONFIG_STR9100_VLAN_BASE
++#undef CONFIG_HAVE_VLAN_TAG
++
++// for port base, port base max is 2 port.
++// NET_DEV0 : rx->sp 0 (port 0)
++#define NET_DEV0 STAR_GSW_LAN_DEV
++// NET_DEV1 : rx->sp 1 (port 1)
++#define NET_DEV1 0
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT PORT0
++#define PORT_BASE_PMAP_WAN_PORT INVALID_PORT_BASE_PMAP_PORT
++#define PORT_BASE_PMAP_EWC_PORT INVALID_PORT_BASE_PMAP_PORT
++
++#define MODEL "LEO"
++
++// OPEN_PORT0 include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[1].vlan_mac, 6);\
++       		PRINT_INFO("open mac port 0\n");\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* enable port 0 */ \
++	        mac_port_config &= (~(0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++		PORT0_LINK_UP\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++       		PRINT_INFO("close mac port 0\n");\
++		PORT0_LINK_DOWN\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* disable port 0 */ \
++	        mac_port_config |= ((0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	} \
++}
++
++
++#define VLAN0_VID			(0x111)
++#define VLAN1_VID			(0x222)
++#define VLAN2_VID			(0x333)
++#define VLAN3_VID			(0x444)
++#define VLAN4_VID			(0x555)
++#define VLAN5_VID			(0x666)
++#define VLAN6_VID			(0x777)
++#define VLAN7_VID			(0x888)
++
++
++#define VLAN0_GROUP			(CPU_PORT | PORT0)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++//#define VLAN0_GROUP                     (PORT0 | PORT1 | CPU_PORT)
++//#define VLAN1_GROUP                     (PORT0 | CPU_PORT)
++//#define VLAN2_GROUP                     (PORT1 | CPU_PORT)
++#define VLAN2_GROUP			(0)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++
++#define VLAN0_VLAN_TAG			(0)
++#define VLAN1_VLAN_TAG			(0)
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++//#define PORT0_PVID			(VLAN0_GROUP_ID)
++//#define PORT1_PVID			(VLAN2_GROUP_ID)
++//#define CPU_PORT_PVID			(VLAN1_GROUP_ID)
++
++static u8 my_vlan0_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x12};
++static u8 my_vlan1_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x22};
++static u8 my_vlan2_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x32};
++static u8 my_vlan3_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x42};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 0
++#define WAN_GID 2
++
++
++#endif // LEO
++
++#endif
+diff -rupN linux-2.6.35.11/drivers/net/str9100/libra.h linux-2.6.35.11-ts7500/drivers/net/str9100/libra.h
+--- linux-2.6.35.11/drivers/net/str9100/libra.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/libra.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,184 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef  LIBRA_H
++#define  LIBRA_H
++
++// this configure is for star LIBRA
++
++// add by descent 2006/07/10
++#define LIBRA
++#ifdef LIBRA
++// init phy or switch chip
++#define INIT_PORT0_PHY configure_icplus_175c_phy();
++#define INIT_PORT1_PHY 
++//#define INIT_PORT1_PHY 
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC 
++//#define INIT_PORT1_MAC 
++
++#define PORT0_LINK_DOWN icp_175c_all_phy_power_down(1);
++#define PORT0_LINK_UP icp_175c_all_phy_power_down(0);
++
++#define PORT1_LINK_DOWN 
++#define PORT1_LINK_UP 
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 star_gsw_probe(WAN_PORT);
++#define CREATE_NET_DEV2 
++//#define CREATE_NET_DEV2 
++
++#undef CONFIG_STR9100_PORT_BASE
++#define CONFIG_STR9100_VLAN_BASE
++#undef CONFIG_HAVE_VLAN_TAG
++#define CONFIG_HAVE_VLAN_TAG
++
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT INVALID_PORT_BASE_PMAP_PORT
++#define PORT_BASE_PMAP_WAN_PORT INVALID_PORT_BASE_PMAP_PORT
++#define PORT_BASE_PMAP_EWC_PORT INVALID_PORT_BASE_PMAP_PORT
++
++#define MODEL "LIBRA"
++
++// OPEN_PORT0 include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		if (dev == STAR_GSW_LAN_DEV) \
++			memcpy(dev->dev_addr, star_gsw_info.vlan[LAN_GID].vlan_mac, 6);\
++		if (dev == STAR_GSW_WAN_DEV) \
++			memcpy(dev->dev_addr, star_gsw_info.vlan[WAN_GID].vlan_mac, 6);\
++		/* rc_port is a reference count variable. */ \
++	        if (rc_port == 0) {\
++        		PRINT_INFO("open mac port 0\n");\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* enable port 0 */ \
++		        mac_port_config &= (~(0x1 << 18));\
++               		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++			PORT0_LINK_UP\
++	        }\
++	        else{\
++      			PRINT_INFO("port 0 already open\n");\
++	        }\
++		++rc_port;\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV || dev == STAR_GSW_WAN_DEV) { \
++		/* rc_port is a reference count variable. */ \
++		--rc_port;\
++	        if (rc_port == 0) {\
++        		PRINT_INFO("close mac port 0\n");\
++			PORT0_LINK_DOWN\
++		        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++               		/* disable port 0 */ \
++		        mac_port_config |= ((0x1 << 18));\
++               		 GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	        }\
++	        else {\
++      			PRINT_INFO("a live net device\n");\
++	        }\
++	} \
++}
++
++
++
++// the vlan past waht vlan tag value
++#define VLAN0_VID			(0x2) // wan
++#define VLAN1_VID			(0x1) // lan
++#define VLAN2_VID			(0x3)
++#define VLAN3_VID			(0x4)
++#define VLAN4_VID			(0x5)
++#define VLAN5_VID			(0x6)
++#define VLAN6_VID			(0x7)
++#define VLAN7_VID			(0x8)
++
++// the vlan include ports
++#define VLAN0_GROUP			(PORT0 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(0)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++
++
++#ifdef CONFIG_HAVE_VLAN_TAG
++
++// the vlan which ports will past vlan tags.
++#define VLAN0_VLAN_TAG			(5)	// cpu port and mac 0 port
++#define VLAN1_VLAN_TAG			(5)	// cpu port and mac 0 port
++
++#else
++#define VLAN0_VLAN_TAG			(1)	// only mac 0 port
++#define VLAN1_VLAN_TAG			(1)	// only mac 0 port
++#endif
++
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++
++/* wan eth1 */
++static u8 my_vlan0_mac[6] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x50};
++
++/* lan eth 0*/
++static u8 my_vlan1_mac[6] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x60};
++
++/* cpu */
++static u8 my_vlan2_mac[6] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x22};
++
++/* ewc  */
++static u8 my_vlan3_mac[6] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x23};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 1
++#define WAN_GID 0
++
++
++#endif //LIBRA
++
++
++
++
++#endif
+diff -rupN linux-2.6.35.11/drivers/net/str9100/Makefile linux-2.6.35.11-ts7500/drivers/net/str9100/Makefile
+--- linux-2.6.35.11/drivers/net/str9100/Makefile	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,38 @@
++################################################################################
++#
++# 
++# Copyright(c) 2005 -  Star semiconduction. All rights reserved.
++# 
++# This program is free software; you can redistribute it and/or modify it 
++# under the terms of the GNU General Public License as published by the Free 
++# Software Foundation; either version 2 of the License, or (at your option) 
++# any later version.
++# 
++# This program is distributed in the hope that it will be useful, but WITHOUT 
++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
++# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
++# more details.
++# 
++# You should have received a copy of the GNU General Public License along with
++# this program; if not, write to the Free Software Foundation, Inc., 59 
++# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++# 
++# The full GNU General Public License is included in this distribution in the
++# file called LICENSE.
++# 
++# Contact Information:
++# Star semiconduction Linux Support <support@starsemi.com>
++#
++################################################################################
++
++#
++# Makefile for the Star GSW ethernet driver
++#
++
++#obj-y :=
++#obj-m :=
++
++obj-$(CONFIG_STAR_GSW) += str9100.o
++str9100-objs := star_gsw_phy.o star_gsw.o
++
++#include $(TOPDIR)/Rules.make
+diff -rupN linux-2.6.35.11/drivers/net/str9100/star_gsw.c linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw.c
+--- linux-2.6.35.11/drivers/net/str9100/star_gsw.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,3421 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include "star_gsw.h"
++
++#ifdef LINUX24
++#include <asm/arch/str9100/star_tool.h>
++#include <asm/arch/str9100/star_misc.h>
++#endif
++
++#ifdef LINUX26
++#include <asm/arch/star_misc.h>
++#endif
++
++#if defined(LINUX24)
++#if defined(CONFIG_STAR9100_SHNAT_PCI_FASTPATH) 
++#include <linux/star9100/star9100_shnat.h>
++#include <linux/star9100/str9100_shnat_hook.h>
++#endif /* defined(CONFIG_STAR9100_SHNAT_PCI_FASTPATH) */
++#elif defined(LINUX26) /* defined(LINUX24) */
++#if defined(CONFIG_STR9100_SHNAT) 
++#include <linux/str9100/star9100_shnat.h>
++#include <linux/str9100/str9100_shnat_hook.h>
++#endif /* defined(CONFIG_STAR9100_SHNAT_PCI_FASTPATH) */
++#endif /* defined(LINUX24) */
++
++#if defined(LINUX24)
++#define IRQ_RETURN void
++#define IRQ_HANDLED 
++static const char star_gsw_driver_version[] =
++	"Star GSW Driver(for Linux Kernel 2.4) - Star Semiconductor\n";
++#elif defined(LINUX26)
++#define IRQ_RETURN irqreturn_t
++static const char star_gsw_driver_version[] =
++	"Star GSW Driver(for Linux Kernel 2.6) - Star Semiconductor\n";
++#endif
++
++
++#define DRV_VERSION "0.01"
++
++int all_netdevice=0;
++
++
++irqreturn_t star_gsw_receive_isr(int irq, void *dev_id, struct pt_regs *regs);
++//struct proc_dir_entry *str9100_gsw_procdir=0;
++static u32 max_pend_int_cnt=MAX_PEND_INT_CNT, max_pend_time=MAX_PEND_TIME;
++
++#define MIN_PACKET_LEN 60
++
++
++static struct net_device *STAR_GSW_LAN_DEV;
++static struct net_device *STAR_GSW_WAN_DEV;
++static struct net_device *STAR_GSW_EWC_DEV;
++
++static struct net_device *STAR_NAPI_DEV;
++
++#define NETDEV_SIZE 10
++static struct net_device *net_dev_array[NETDEV_SIZE];
++
++
++static int install_isr_account = 0;
++static int rc_port = 0; // rc mean reference counting, determine port open/close.
++static int fsrc_count = 0;
++static volatile unsigned long is_qf = 0; // determine queue full state
++
++gsw_info_t star_gsw_info;
++static spinlock_t star_gsw_send_lock;
++
++static TXRING_INFO txring;
++static RXRING_INFO rxring;
++
++static struct proc_dir_entry *star_gsw_proc_entry;
++
++#ifdef CONFIG_STAR_GSW_NAPI
++static void star_gsw_receive_packet(int mode, int *work_done, int work_to_do);
++#else
++static void star_gsw_receive_packet(int mode);
++#endif
++
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++void gsw_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
++void gsw_vlan_rx_register(struct net_device *dev, struct vlan_group *grp);
++#endif
++
++static int star_gsw_notify_reboot(struct notifier_block *nb, unsigned long event, void *ptr);
++
++static struct notifier_block star_gsw_notifier_reboot = {
++	.notifier_call	= star_gsw_notify_reboot,
++	.next		= NULL,
++	.priority	= 0
++};
++
++
++
++
++#ifdef STAR_GSW_TIMER
++static struct timer_list star_gsw_timer;
++static void star_gsw_timer_func(unsigned long data)
++{
++	int i;
++	int tssd_index;
++	int tssd_current;
++	int skb_free_count = 0;
++	STAR_GSW_TXDESC volatile *txdesc_ptr;
++	unsigned long flags;
++
++	local_irq_save(flags);
++	HAL_GSW_READ_TSSD(tssd_current);
++	tssd_index = (tssd_current - (u32)txring.phy_addr) >> 4;
++	if (tssd_index > txring.to_free_index) {
++		skb_free_count = tssd_index - txring.to_free_index;
++	} else if (tssd_index < txring.to_free_index) {
++		skb_free_count = STAR_GSW_MAX_TFD_NUM + tssd_index - txring.to_free_index;
++	}
++	for (i = 0; i < skb_free_count; i++) {
++		txdesc_ptr = txring.vir_addr + txring.to_free_index;
++		if (txdesc_ptr->cown == 0) {
++			break;
++		}
++		if (txring.skb_ptr[txring.to_free_index]) {
++			dev_kfree_skb_any(txring.skb_ptr[txring.to_free_index]);
++			txring.skb_ptr[txring.to_free_index] = NULL;
++		}
++		txring.to_free_index++;
++		if (txring.to_free_index == STAR_GSW_MAX_TFD_NUM) {
++			txring.to_free_index = 0;
++		}
++	}
++	local_irq_restore(flags);
++}
++#endif
++
++
++#define between(x, start, end) ((x)>=(start) && (x)<=(end))
++void print_packet(unsigned char *data, int len) 
++{
++    int i,j;
++
++    printk("packet length: %d%s:\n", len, len>128?"(only show the first 128 bytes)":"");
++    if(len > 128) {
++        len = 128;
++    }
++    for(i=0;len;) {
++        if(len >=16 ) {
++            for(j=0;j<16;j++) {
++                printk("%02x ", data[i++]);
++            }
++            printk("| ");
++
++            i -= 16;
++            for(j=0;j<16;j++) {
++                if( between(data[i], 0x21, 0x7e) ) {
++                    printk("%c", data[i++]);
++                }
++                else {
++                    printk(".");
++                    i++;
++                }
++            }
++            printk("\n");
++
++            len -= 16;
++        }
++        else {
++            /* last line */
++
++            for(j=0; j<len; j++) {
++                printk("%02x ", data[i++]);
++            }
++            for(;j<16;j++) {
++                printk("   ");
++            }
++            printk("| ");
++
++            i -= len;
++            for(j=0;j<len;j++) {
++                if( between(data[i], 0x21, 0x7e) ) {
++                    printk("%c", data[i++]);
++                }
++                else {
++                    printk(".");
++                    i++;
++                }
++            }
++            for(;j<16;j++) {
++                printk(" ");
++            }
++            printk("\n");
++
++            len = 0;
++        }
++    }
++    return;
++
++}
++
++// add by descent 2006/07/07
++void init_switch()
++{
++        u32 sw_config;
++
++        /*
++         * Configure GSW configuration
++         */
++        sw_config = GSW_SWITCH_CONFIG;
++
++#if 0
++        // orignal virgon configuration
++        // enable fast aging
++        sw_config |= (0xF);
++
++        // CRC stripping
++        sw_config |= (0x1 << 21);
++
++        // IVL learning
++        sw_config |= (0x1 << 22);
++        // HNAT disable
++        sw_config &= ~(0x1 << 23);
++
++        GSW_SWITCH_CONFIG = sw_config;
++
++        sw_config = GSW_SWITCH_CONFIG;
++#endif
++
++//#if 0
++        /* configure switch */
++        sw_config = GSW_SWITCH_CONFIG;
++
++        sw_config &= ~0xF;      /* disable aging */
++        sw_config |= 0x1;       /* disable aging */
++
++#ifdef JUMBO_ENABLE
++
++        // CRC stripping and GSW_CFG_MAX_LEN_JMBO
++        //sw_config |= (GSW_CFG_CRC_STRP | GSW_CFG_MAX_LEN_JMBO);
++        // CRC stripping and GSW_CFG_MAX_LEN_JMBO
++        sw_config |= ((0x1 << 21) | (0x3 << 4));
++	       
++#else
++        // CRC stripping and 1536 bytes
++        //sw_config |= (GSW_CFG_CRC_STRP | GSW_CFG_MAX_LEN_1536);
++	sw_config |= ((0x1 << 21) | (0x2 << 4));
++#endif
++
++        /* IVL */
++        //sw_config |= GSW_CFG_IVL;
++        sw_config |= (0x1 << 22);
++
++
++        /* disable HNAT */
++        //sw_config &= ~GSW_CFG_HNAT_EN;
++        sw_config &= ~(0x1 << 23);
++
++
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++	// PCI FASTPATH must enable firewall mode
++	sw_config |= (0x1 << 24);
++#endif
++
++        GSW_SWITCH_CONFIG = sw_config;
++//#endif
++}
++
++
++
++static int star_gsw_write_arl_table_entry(gsw_arl_table_entry_t *arl_table_entry)
++{
++	int i;
++
++	GSW_ARL_TABLE_ACCESS_CONTROL_0 = 0x0;
++	GSW_ARL_TABLE_ACCESS_CONTROL_1 = 0x0;
++	GSW_ARL_TABLE_ACCESS_CONTROL_2 = 0x0;
++
++	GSW_ARL_TABLE_ACCESS_CONTROL_1 = (((arl_table_entry->filter & 0x1) << 3) |
++		((arl_table_entry->vlan_mac & 0x1) << 4) |
++		((arl_table_entry->vlan_gid & 0x7) << 5) |
++		((arl_table_entry->age_field & 0x7) << 8) |
++		((arl_table_entry->port_map & 0x7) << 11) |
++		((arl_table_entry->mac_addr[0] & 0xFF) << 16) |
++		((arl_table_entry->mac_addr[1] & 0xFF) << 24));
++
++	GSW_ARL_TABLE_ACCESS_CONTROL_2 = (((arl_table_entry->mac_addr[2] & 0xFF) << 0) |
++		((arl_table_entry->mac_addr[3] & 0xFF) << 8) |
++		((arl_table_entry->mac_addr[4] & 0xFF) << 16) |
++		((arl_table_entry->mac_addr[5] & 0xFF) << 24));
++
++	// issue the write command
++	GSW_ARL_TABLE_ACCESS_CONTROL_0 = (0x1 << 3);
++
++	for (i = 0; i < 0x1000; i++) {
++		if (GSW_ARL_TABLE_ACCESS_CONTROL_1 & (0x1)) {
++			return (1);  // write OK
++		} else {
++			udelay(10);
++		}
++	}
++
++	return (0);  // write failed
++}
++
++static int star_gsw_config_cpu_port(void)
++{
++	gsw_arl_table_entry_t arl_table_entry;
++	u32 cpu_port_config;
++
++	/*
++	 * Write some default ARL table entries
++	 */
++	// default ARL entry for VLAN0
++	arl_table_entry.filter		= 0;
++	arl_table_entry.vlan_mac	= 1;	// the MAC in this table entry is MY VLAN MAC
++	arl_table_entry.vlan_gid	= star_gsw_info.vlan[0].vlan_gid;
++	arl_table_entry.age_field	= 0x7;	// static entry
++	arl_table_entry.port_map	= star_gsw_info.vlan[0].vlan_group;
++	memcpy(arl_table_entry.mac_addr, star_gsw_info.vlan[0].vlan_mac, 6);
++	if (!star_gsw_write_arl_table_entry(&arl_table_entry)) {
++		return 1;
++	}
++
++	// default ARL entry for VLAN1
++	arl_table_entry.filter		= 0;
++	arl_table_entry.vlan_mac	= 1;
++	arl_table_entry.vlan_gid	= star_gsw_info.vlan[1].vlan_gid;
++	arl_table_entry.age_field	= 0x7;
++	arl_table_entry.port_map	= star_gsw_info.vlan[1].vlan_group;
++	memcpy(arl_table_entry.mac_addr, star_gsw_info.vlan[1].vlan_mac, 6);
++	if (!star_gsw_write_arl_table_entry(&arl_table_entry)) {
++		return 1;
++	}
++
++	// default ARL entry for VLAN2
++	arl_table_entry.filter		= 0;
++	arl_table_entry.vlan_mac	= 1;
++	arl_table_entry.vlan_gid	= star_gsw_info.vlan[2].vlan_gid;
++	arl_table_entry.age_field	= 0x7;
++	arl_table_entry.port_map	= star_gsw_info.vlan[2].vlan_group;
++	memcpy(arl_table_entry.mac_addr, star_gsw_info.vlan[2].vlan_mac, 6);
++	if (!star_gsw_write_arl_table_entry(&arl_table_entry)) {
++		return 1;
++	}
++
++	// default ARL entry for VLAN3
++	arl_table_entry.filter		= 0;
++	arl_table_entry.vlan_mac	= 1;
++	arl_table_entry.vlan_gid	= star_gsw_info.vlan[3].vlan_gid;
++	arl_table_entry.age_field	= 0x7;
++	arl_table_entry.port_map	= star_gsw_info.vlan[3].vlan_group;
++	memcpy(arl_table_entry.mac_addr, star_gsw_info.vlan[3].vlan_mac, 6);
++	if (!star_gsw_write_arl_table_entry(&arl_table_entry)) {
++		return 1;
++	}
++
++	GSW_SET_PORT0_PVID(star_gsw_info.port[0].pvid);
++	GSW_SET_PORT1_PVID(star_gsw_info.port[1].pvid);
++	GSW_SET_CPU_PORT_PVID(star_gsw_info.port[2].pvid);
++
++	GSW_SET_VLAN_0_VID(star_gsw_info.vlan[0].vlan_vid);
++	GSW_SET_VLAN_1_VID(star_gsw_info.vlan[1].vlan_vid);
++	GSW_SET_VLAN_2_VID(star_gsw_info.vlan[2].vlan_vid);
++	GSW_SET_VLAN_3_VID(star_gsw_info.vlan[3].vlan_vid);
++	GSW_SET_VLAN_4_VID(star_gsw_info.vlan[4].vlan_vid);
++	GSW_SET_VLAN_5_VID(star_gsw_info.vlan[5].vlan_vid);
++	GSW_SET_VLAN_6_VID(star_gsw_info.vlan[6].vlan_vid);
++	GSW_SET_VLAN_7_VID(star_gsw_info.vlan[7].vlan_vid);
++
++	GSW_SET_VLAN_0_MEMBER(star_gsw_info.vlan[0].vlan_group);
++	GSW_SET_VLAN_1_MEMBER(star_gsw_info.vlan[1].vlan_group);
++	GSW_SET_VLAN_2_MEMBER(star_gsw_info.vlan[2].vlan_group);
++	GSW_SET_VLAN_3_MEMBER(star_gsw_info.vlan[3].vlan_group);
++	GSW_SET_VLAN_4_MEMBER(star_gsw_info.vlan[4].vlan_group);
++	GSW_SET_VLAN_5_MEMBER(star_gsw_info.vlan[5].vlan_group);
++	GSW_SET_VLAN_6_MEMBER(star_gsw_info.vlan[6].vlan_group);
++	GSW_SET_VLAN_7_MEMBER(star_gsw_info.vlan[7].vlan_group);
++
++	GSW_SET_VLAN_0_TAG(star_gsw_info.vlan[0].vlan_tag_flag);
++	GSW_SET_VLAN_1_TAG(star_gsw_info.vlan[1].vlan_tag_flag);
++	GSW_SET_VLAN_2_TAG(star_gsw_info.vlan[2].vlan_tag_flag);
++	GSW_SET_VLAN_3_TAG(star_gsw_info.vlan[3].vlan_tag_flag);
++	GSW_SET_VLAN_4_TAG(star_gsw_info.vlan[4].vlan_tag_flag);
++	GSW_SET_VLAN_5_TAG(star_gsw_info.vlan[5].vlan_tag_flag);
++	GSW_SET_VLAN_6_TAG(star_gsw_info.vlan[6].vlan_tag_flag);
++	GSW_SET_VLAN_7_TAG(star_gsw_info.vlan[7].vlan_tag_flag);
++
++	// disable all interrupt status sources
++	GSW_DISABLE_ALL_INTERRUPT_STATUS_SOURCES();
++
++	// clear previous interrupt sources
++	GSW_CLEAR_ALL_INTERRUPT_STATUS_SOURCES();
++
++	// disable all DMA-related interrupt sources
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_TSTC_BIT_INDEX);
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_FSRC_BIT_INDEX);
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_TSQE_BIT_INDEX);
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_FSQF_BIT_INDEX);
++
++	// clear previous interrupt sources
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_TSTC_BIT_INDEX);
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_FSRC_BIT_INDEX);
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_TSQE_BIT_INDEX);
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_FSQF_BIT_INDEX);
++
++	GSW_TS_DMA_STOP();
++	GSW_FS_DMA_STOP();
++
++	GSW_WRITE_TSSD(txring.phy_addr);
++	GSW_WRITE_TS_BASE(txring.phy_addr);
++	GSW_WRITE_FSSD(rxring.phy_addr);
++	GSW_WRITE_FS_BASE(rxring.phy_addr);
++
++	/*
++	 * Configure CPU port
++	 */
++	cpu_port_config = GSW_CPU_PORT_CONFIG;
++
++	//SA learning Disable 
++	cpu_port_config |= (0x1 << 19);
++
++	//offset 4N +2 
++	cpu_port_config &= ~(1 << 31);
++	//cpu_port_config |= (1 << 31);
++
++	/* enable the CPU port */
++	cpu_port_config &= ~(1 << 18);
++
++	GSW_CPU_PORT_CONFIG = cpu_port_config;
++
++	return 0;
++}
++
++static void star_gsw_interrupt_disable(void)
++{
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_STATUS_BIT_INDEX);
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_TSTC_BIT_INDEX);
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_FSRC_BIT_INDEX);
++}
++
++static void star_gsw_interrupt_enable(void)
++{
++	INTC_ENABLE_INTERRUPT_SOURCE(INTC_GSW_STATUS_BIT_INDEX);
++	// 20070321 
++	//INTC_ENABLE_INTERRUPT_SOURCE(INTC_GSW_TSTC_BIT_INDEX);
++	INTC_ENABLE_INTERRUPT_SOURCE(INTC_GSW_FSRC_BIT_INDEX);
++}
++
++static int star_gsw_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
++{
++#if 0
++	int num = 0;
++	int ad;
++	u32 port;
++	u32 fssd_current;
++	int fssd_index, rxcount;
++	STAR_GSW_RXDESC volatile *rxdesc_ptr = (rxring.vir_addr + rxring.cur_index);
++
++	GSW_READ_FSSD(fssd_current);
++	fssd_index = (fssd_current - (u32)rxring.phy_addr) >> 4;
++
++	if (fssd_index > rxring.cur_index) {
++		rxcount = fssd_index - rxring.cur_index;
++	} else if (fssd_index < rxring.cur_index) {
++		rxcount = (STAR_GSW_MAX_RFD_NUM - rxring.cur_index) + fssd_index;
++	} else {
++		if (rxdesc_ptr->cown == 0) {
++			//goto receive_packet_exit;
++			rxcount = -1;
++		} else {
++			// Queue Full
++			rxcount = STAR_GSW_MAX_RFD_NUM;
++		}
++	}
++
++	port = GSW_MAC_PORT_0_CONFIG;
++	num = sprintf(page, "\nStar Giga Bit Switch\n");
++#ifdef CONFIG_STAR_GSW_NAPI
++	num += sprintf(page + num, "Receive Method : NAPI\n");
++#else
++	num += sprintf(page + num, "Receive Method : General\n");
++#endif
++
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++	num += sprintf(page + num, "Support SHNAT PCI Fast PATH\n");
++#endif
++
++	HAL_MISC_ORION_ECO_AD(ad);
++	num += sprintf(page + num, "Orion Version: %s\n", ad==1?"AD":"AC");
++
++	num += sprintf(page + num, "GSW_DELAYED_INTERRUPT_CONFIG: %x\n", GSW_DELAYED_INTERRUPT_CONFIG);
++
++	num += sprintf(page + num, "GSW_VLAN_VID_0_1: %x\n", GSW_VLAN_VID_0_1);
++	num += sprintf(page + num, "GSW_VLAN_VID_2_3: %x\n", GSW_VLAN_VID_2_3);
++	num += sprintf(page + num, "GSW_VLAN_VID_4_5: %x\n", GSW_VLAN_VID_4_5);
++	num += sprintf(page + num, "GSW_VLAN_VID_6_7: %x\n", GSW_VLAN_VID_6_7);
++
++	num += sprintf(page + num, "STAR_GSW_LAN_DEV: %x\n", STAR_GSW_LAN_DEV);
++	num += sprintf(page + num, "STAR_GSW_WAN_DEV: %x\n", STAR_GSW_WAN_DEV);
++	num += sprintf(page + num, "GSW_VLAN_TAG_PORT_MAP: %x\n", GSW_VLAN_TAG_PORT_MAP);
++	num += sprintf(page + num, "GSW_SWITCH_CONFIG: %x \n", GSW_SWITCH_CONFIG);
++	//num += sprintf(page + num, "is_qf: %d \n", is_qf);
++	num += sprintf(page + num, "GSW_VLAN_VID_0_1: %08X \n", GSW_VLAN_VID_0_1);
++	num += sprintf(page + num, "VLAN0_VID: %d \n", VLAN0_VID);
++	num += sprintf(page + num, "VLAN1_VID: %d \n", VLAN1_VID);
++
++	num += sprintf(page + num, "GSW_QUEUE_STATUS_TEST_1  : %x \n", GSW_QUEUE_STATUS_TEST_1);
++	num += sprintf(page + num, "GW_GSW_MAX_RFD_NUM  : %d \n", STAR_GSW_MAX_RFD_NUM);
++	num += sprintf(page + num, "GW_GSW_MAX_TFD_NUM  : %d \n", STAR_GSW_MAX_TFD_NUM);
++	num += sprintf(page + num, "GSW_INTERRUPT_STATUS  : %x \n", GSW_INTERRUPT_STATUS);
++
++	num += sprintf(page + num, "MAC PORT 0   : %x \n", GSW_MAC_PORT_0_CONFIG);
++	if (port & (0x1 << 22))
++		num += sprintf(page + num, "  IVL: IVL\n");
++	else
++		num += sprintf(page + num, "  IVL: SVL\n");
++
++	port = GSW_MAC_PORT_1_CONFIG;
++	num += sprintf(page + num, "MAC PORT 1   : %x \n", GSW_MAC_PORT_1_CONFIG);
++	if (port & (0x1 << 22))
++		num += sprintf(page + num, "  IVL: IVL\n");
++	else
++		num += sprintf(page + num, "  IVL: SVL\n");
++
++	num += sprintf(page + num, " CPU PORT 1   : %x \n", GSW_CPU_PORT_CONFIG);
++
++	num += sprintf(page + num, "MODEL: %s\n", MODEL);
++#ifdef STAR_GSW_TX_HW_CHECKSUM
++	num += sprintf(page + num, "use TX hardware checksum\n");
++#endif
++#ifdef STAR_GSW_RX_HW_CHECKSUM
++	num += sprintf(page + num, "use RX hardware checksum\n");
++#endif
++
++#ifdef CONFIG_STR9100_VLAN_BASE
++	num += sprintf(page + num, "VLAN BASE\n");
++  #ifdef CONFIG_HAVE_VLAN_TAG
++	num += sprintf(page + num, "HAVE VLAN TAG\n");
++  #else
++	num += sprintf(page + num, "HAVE NO VLAN TAG\n");
++  #endif
++#endif
++
++#ifdef CONFIG_STR9100_PORT_BASE
++	num += sprintf(page + num, "PORT BASE\n");
++#endif
++
++// 20060922 descent
++#ifdef CONFIG_NIC_MODE
++	num += sprintf(page + num, "NIC MODE ON\n");
++#else
++	num += sprintf(page + num, "NIC MODE OFF\n");
++#endif
++// 20060922 descent end
++
++#ifdef STAR_GSW_SG
++	num += sprintf(page + num, "scatter gather on\n");
++#else
++	num += sprintf(page + num, "scatter gather off\n");
++#endif
++
++#ifdef FREE_TX_SKB_MULTI
++	num += sprintf(page + num, "FREE_TX_SKB_MULTI on\n");
++#else
++	num += sprintf(page + num, "FREE_TX_SKB_MULTI off\n");
++#endif
++
++#ifdef STAR_GSW_TIMER
++	num += sprintf(page + num, "STAR_GSW_TIMER on\n");
++#else
++	num += sprintf(page + num, "STAR_GSW_TIMER off\n");
++#endif
++
++
++#if 0
++	num += sprintf(page + num, "  lan (eth0) mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
++			star_gsw_info.vlan[1].vlan_mac[0],
++			star_gsw_info.vlan[1].vlan_mac[1],
++			star_gsw_info.vlan[1].vlan_mac[2],
++			star_gsw_info.vlan[1].vlan_mac[3],
++			star_gsw_info.vlan[1].vlan_mac[4],
++			star_gsw_info.vlan[1].vlan_mac[5]);
++	num += sprintf(page + num, "  wan (eth1) mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
++			star_gsw_info.vlan[0].vlan_mac[0],
++			star_gsw_info.vlan[0].vlan_mac[1],
++			star_gsw_info.vlan[0].vlan_mac[2],
++			star_gsw_info.vlan[0].vlan_mac[3],
++			star_gsw_info.vlan[0].vlan_mac[4],
++			star_gsw_info.vlan[0].vlan_mac[5]);
++#endif
++
++	return num;
++
++#endif
++
++
++	int num = 0;
++	u32 port=0;
++	const char *STR_ENABLE="Enable";
++	const char *STR_DISABLE="Disable";
++
++
++	num  = sprintf(page, "Star STR9100 Gigabit Switch Driver Information \n");
++
++	num += sprintf(page + num, "%s\n", star_gsw_driver_version);
++	num += sprintf(page + num, "Demo Board Name: %s\n", MODEL);
++#ifdef CONFIG_STAR_GSW_NAPI
++	num += sprintf(page + num, "NAPI Function : %s\n", STR_ENABLE);
++#else
++	num += sprintf(page + num, "NAPI Function : %s\n", STR_DISABLE);
++#endif
++
++	port = GSW_SWITCH_CONFIG;
++	if (port & (0x1 << 22))
++		num += sprintf(page + num, "Independent VLAN Learning(IVL) Enable\n");
++	else
++		num += sprintf(page + num, "Share VLAN Learning (SVL) Enable\n");
++
++#ifdef CONFIG_STR9100_VLAN_BASE
++	num += sprintf(page + num, "Support Tag Base VLAN , Receive packet ");
++  #ifdef CONFIG_HAVE_VLAN_TAG
++	num += sprintf(page + num, "with vlan tag\n");
++  #else
++	num += sprintf(page + num, "without vlan tag\n");
++  #endif
++#endif
++
++#ifdef CONFIG_STR9100_PORT_BASE
++	num += sprintf(page + num, "Support Port Base VLAN\n");
++#endif
++
++
++	num += sprintf(page + num, "Max Receive Ring Buffer:  %02d \n", STAR_GSW_MAX_RFD_NUM );
++	num += sprintf(page + num, "Max Send Ring Buffer:     %02d\n",  STAR_GSW_MAX_TFD_NUM );
++#ifdef STAR_GSW_TX_HW_CHECKSUM
++	num += sprintf(page + num, "TX Hardware checksum:     %s \n", STR_ENABLE);
++#else
++	num += sprintf(page + num, "TX Hardware checksum:     %s \n", STR_DISABLE);
++#endif
++#ifdef STAR_GSW_RX_HW_CHECKSUM
++	num += sprintf(page + num, "Rx Hardware checksum:     %s\n", STR_ENABLE );
++#else
++	num += sprintf(page + num, "Rx Hardware checksum:     %s\n", STR_DISABLE );
++#endif
++
++#ifndef STAR_GSW_DELAYED_INTERRUPT
++	// Disable Delayed Interrupt
++	num += sprintf(page + num, "Delay Interrupt %s\n",STR_DISABLE);
++#else
++	num += sprintf(page + num, "Delay Interrupt %s , Max Pending Interrupt Count: %d , Max Pending Timer : %d \n",
++		       STR_ENABLE, MAX_PEND_INT_CNT, MAX_PEND_TIME);
++#endif
++	num += sprintf(page + num, "Group VID Info: GVID0_VID:%02X   GVID1_VID: %02X   GVID2_VID:%02X   GVID3_VID: %02X \n", 
++				GSW_VLAN_VID_0_1&0xFFF, (GSW_VLAN_VID_0_1>>12)&0xFFF,
++				GSW_VLAN_VID_2_3&0xFFF, (GSW_VLAN_VID_2_3>>12)&0xFFF);
++
++	
++	num += sprintf(page + num, "                GVID4_VID:%02X   GVID5_VID: %02X   GVID6_VID:%02X   GVID7_VID: %02X \n", 
++				GSW_VLAN_VID_4_5&0xFFF, (GSW_VLAN_VID_4_5>>12)&0xFFF,
++				GSW_VLAN_VID_6_7&0xFFF, (GSW_VLAN_VID_6_7>>12)&0xFFF);
++
++
++	num += sprintf(page + num, "Int. Buffer free pages count : %x(%d)\n", 
++				   GSW_QUEUE_STATUS_TEST_1&0xFF,GSW_QUEUE_STATUS_TEST_1&0xFF);
++	num += sprintf(page + num, "Interrupt Status    : %x (Clean After Read)\n", GSW_INTERRUPT_STATUS);
++	GSW_INTERRUPT_STATUS= GSW_INTERRUPT_STATUS;
++
++	num += sprintf(page + num, "Switch Register: %x \n", GSW_SWITCH_CONFIG);
++	num += sprintf(page + num, "MAC0 REG: %x (%s:%s,%s,%s,%s)\n", GSW_MAC_PORT_0_CONFIG,
++			(GSW_MAC_PORT_0_CONFIG&(0x1<<18))==0?"Port Enable":"Port Disable",
++			(GSW_MAC_PORT_0_CONFIG&(0x1<<7))!=0?"AN Enable":"AN Disable",
++			(GSW_MAC_PORT_0_CONFIG&(0x11<<2))!=0x10?"1000Mbps":"10/100Mbps",
++			(GSW_MAC_PORT_0_CONFIG&(0x1<<4))==0x0?"Half Duplex":"Full Duplex",
++			(GSW_MAC_PORT_0_CONFIG&(0x1))!=0?"Link Up":"Link Down"
++			);
++	num += sprintf(page + num, "MAC1 REG: %x (%s:%s,%s,%s,%s)\n", GSW_MAC_PORT_1_CONFIG,
++			(GSW_MAC_PORT_0_CONFIG&(0x1<<18))==0?"Port Enable":"Port Disable",
++			(GSW_MAC_PORT_0_CONFIG&(0x1<<7))!=0?"AN Enable":"AN Disable",
++			(GSW_MAC_PORT_0_CONFIG&(0x11<<2))!=0x10?"1000Mbps":"10/100Mbps",
++			(GSW_MAC_PORT_0_CONFIG&(0x1<<4))==0x0?"Half Duplex":"Full Duplex",
++			(GSW_MAC_PORT_0_CONFIG&(0x1))!=0?"Link Up":"Link Down"
++			);
++
++	num += sprintf(page + num, "CPU  REG: %x \n", GSW_CPU_PORT_CONFIG);
++	num += sprintf(page + num, "GSW_BIST_RESULT_TEST_0: %x\n", GSW_BIST_RESULT_TEST_0);
++#ifdef CONFIG_STR9100_VLAN_BASE
++	num += sprintf(page + num, "VLAN BASE\n");
++  #ifdef CONFIG_HAVE_VLAN_TAG
++	num += sprintf(page + num, "HAVE VLAN TAG\n");
++  #else
++	num += sprintf(page + num, "HAVE NO VLAN TAG\n");
++  #endif
++#endif
++
++#ifdef CONFIG_STR9100_PORT_BASE
++	num += sprintf(page + num, "PORT BASE\n");
++#endif
++
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++	num += sprintf(page + num, "8021Q support\n");
++#else
++	num += sprintf(page + num, "no 8021Q support\n");
++#endif
++
++#ifdef STAR_GSW_SG
++	num += sprintf(page + num, "Scatter Gather on\n");
++#else
++	num += sprintf(page + num, "Scatter Gather off\n");
++#endif
++
++#ifdef FREE_TX_SKB_MULTI
++	num += sprintf(page + num, "FREE_TX_SKB_MULTI on\n");
++#else
++	num += sprintf(page + num, "FREE_TX_SKB_MULTI off\n");
++#endif
++
++#ifdef STAR_GSW_TIMER
++	num += sprintf(page + num, "STAR_GSW_TIMER on\n");
++#else
++	num += sprintf(page + num, "STAR_GSW_TIMER off\n");
++#endif
++
++	num += sprintf(page + num, "all_netdevice: %d\n", all_netdevice);
++
++	return num;
++}
++
++int star_gsw_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
++{
++
++// 20061103 descent
++#ifdef CONFIG_CONF_VID
++	char *str, *pos;
++	u16 gid, vid;
++
++	str=buffer;
++
++	if (count)
++	{
++		//simple_strtol();
++		//printk("input str: %s\n", buffer);
++
++		// skip blank
++		while (*str==' ')
++		{
++			++str;
++		}
++		pos = strstr(str, " ");
++		if (pos)
++		{
++			*pos='\0';
++			//printk("str : %s\n", str);
++			gid=simple_strtol(str, NULL, 10);
++			//printk("gid : %d\n", gid);
++		}
++
++		str=(++pos);
++
++		// skip blank
++		while (*str==' ')
++		{
++			++str;
++		}
++
++		//pos = strstr(str, " ");
++		//if (pos)
++		{
++			//*pos='\0';
++			//printk("str : %s\n", str);
++			vid=simple_strtol(str, NULL, 10);
++			//printk("vid : %d\n", vid);
++		}
++		star_gsw_info.vlan[gid].vlan_vid=vid;
++		switch (gid)
++		{
++			case 0:
++			{
++				GSW_SET_VLAN_0_VID(vid);
++				break;
++			}
++			case 1:
++			{
++				GSW_SET_VLAN_1_VID(vid);
++				break;
++			}
++			case 2:
++			{
++				GSW_SET_VLAN_2_VID(vid);
++				break;
++			}
++			case 3:
++			{
++				GSW_SET_VLAN_3_VID(vid);
++				break;
++			}
++			case 4:
++			{
++				GSW_SET_VLAN_4_VID(vid);
++				break;
++			}
++			case 5:
++			{
++				GSW_SET_VLAN_5_VID(vid);
++				break;
++			}
++			case 6:
++			{
++				GSW_SET_VLAN_6_VID(vid);
++				break;
++			}
++			case 7:
++			{
++				GSW_SET_VLAN_7_VID(vid);
++				break;
++			}
++		}
++
++
++
++		printk("GSW_VLAN_VID_0_1: %x\n", GSW_VLAN_VID_0_1);
++		printk("GSW_VLAN_VID_2_3: %x\n", GSW_VLAN_VID_2_3);
++		printk("GSW_VLAN_VID_4_5: %x\n", GSW_VLAN_VID_4_5);
++		printk("GSW_VLAN_VID_6_7: %x\n", GSW_VLAN_VID_6_7);
++	}
++
++#endif
++// 20061103 descent end
++
++// 20060922 descent
++#ifdef CONFIG_NIC_MODE
++       	u32 sw_config = GSW_SWITCH_CONFIG;
++
++	// NIC mode on
++	if (count && buffer[0]=='1') {
++		sw_config |= (1 << 30);
++
++		star_gsw_info.vlan[0].vlan_tag_flag	= 0;
++		star_gsw_info.vlan[1].vlan_tag_flag	= 0;
++
++		printk("NIC mode on\n");
++	}
++
++	// NIC mode off
++	if (count && buffer[0]=='0') {
++		sw_config &= ~(1 << 30);
++
++		star_gsw_info.vlan[0].vlan_tag_flag	= VLAN0_VLAN_TAG;
++		star_gsw_info.vlan[1].vlan_tag_flag	= VLAN1_VLAN_TAG;
++
++		printk("NIC mode off\n");
++	}
++	GSW_SET_VLAN_0_TAG(star_gsw_info.vlan[0].vlan_tag_flag);
++	GSW_SET_VLAN_1_TAG(star_gsw_info.vlan[1].vlan_tag_flag);
++
++       	GSW_SWITCH_CONFIG = sw_config;
++#endif
++// 20060922 descent end
++
++#ifdef CHANGE_DELAY_INT
++	int i=0, j=0;
++	int c=count;
++	char *str=buffer;
++	char str_num[5];
++	unsigned long n[2];
++	int index=0;
++	const char cmd_on[]="delay_int_on";
++	const char cmd_off[]="delay_int_off";
++
++	while(*str==' ') {
++		++str;
++		--c;
++	}
++	PDEBUG("count: %d\n", count);
++	PDEBUG("c: %d\n", c);
++	if (strncmp(cmd_on, str, strlen(cmd_on))==0) {
++		PDEBUG("delay int on\n");
++		GSW_DELAYED_INTERRUPT_CONFIG |= (1 << 16) ;
++		return count;
++	}
++	if (strncmp(cmd_off, str, strlen(cmd_off))==0) {
++		PDEBUG("delay int off \n");
++		GSW_DELAYED_INTERRUPT_CONFIG &= (~(0x1 << 16));
++		return count;
++	}
++	for (i=0, j=0 ; i < c; ++i){
++		if ( ('0' <= str[i] && str[i] <= '9') || ('a' <= str[i] && str[i] <= 'f') || ('A' <= str[i] && str[i] <= 'F'))
++			str[j++]=str[i];
++		else
++		{
++			str[j++]=0;
++			n[index]=simple_strtoul(str, NULL, 16);
++			PDEBUG("n: %x\n", n[index]);
++			++index;
++			PDEBUG("str: %s\n", str);
++			j=0;
++		}
++	}
++	//if (count && buffer[0]=='0')
++	max_pend_int_cnt=n[0];
++	max_pend_time=n[1];
++#ifdef STAR_GSW_DELAYED_INTERRUPT
++	GSW_DELAYED_INTERRUPT_CONFIG = (1 << 16) | (max_pend_int_cnt << 8) | (max_pend_time);
++#endif
++
++#endif
++
++// add by descent, 2006/07/04
++// ADJUSTMENT TX RX SKEW
++#ifdef ADJUSTMENT_TX_RX_SKEW
++	// adjust MAC port 0/1 RX/TX clock skew
++	if (count && buffer[0]=='0')
++	{
++		printk("port 1 tx skew 0 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 30);
++		GSW_BIST_RESULT_TEST_0 |= (0x0 << 30);
++
++	}
++	if (count && buffer[0]=='1')
++	{
++		printk("port 1 tx skew 1.5 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 30);
++		GSW_BIST_RESULT_TEST_0 |= (0x1 << 30);
++	}
++	if (count && buffer[0]=='2')
++	{
++		printk("port 1 tx skew 2.0 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 30);
++		GSW_BIST_RESULT_TEST_0 |= (0x2 << 30);
++	}
++	if (count && buffer[0]=='3')
++	{
++		printk("port 1 tx skew 2.5 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 30);
++		GSW_BIST_RESULT_TEST_0 |= (0x3 << 30);
++	}
++
++
++
++	if (count && buffer[0]=='4')
++	{
++		printk("port 1 rx skew 0 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 28);
++		GSW_BIST_RESULT_TEST_0 |= (0x0 << 28);
++	}
++	if (count && buffer[0]=='5')
++	{
++		printk("port 1 rx skew 1.5 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 28);
++		GSW_BIST_RESULT_TEST_0 |= (0x1 << 28);
++	}
++	if (count && buffer[0]=='6')
++	{
++		printk("port 1 rx skew 2.0 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 28);
++		GSW_BIST_RESULT_TEST_0 |= (0x2 << 28);
++	}
++	if (count && buffer[0]=='7')
++	{
++		printk("port 1 rx skew 2.5 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 28);
++		GSW_BIST_RESULT_TEST_0 |= (0x3 << 28);
++	}
++
++
++	if (count && buffer[0]=='8')
++	{
++		printk("port 0 tx skew 0 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 26);
++		GSW_BIST_RESULT_TEST_0 |= (0x0 << 26);
++	}
++	if (count && buffer[0]=='9')
++	{
++		printk("port 0 tx skew 1.5 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 26);
++		GSW_BIST_RESULT_TEST_0 |= (0x1 << 26);
++	}
++	if (count && buffer[0]=='a')
++	{
++		printk("port 0 tx skew 2.0 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 26);
++		GSW_BIST_RESULT_TEST_0 |= (0x2 << 26);
++	}
++	if (count && buffer[0]=='b')
++	{
++		printk("port 0 tx skew 2.5 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 26);
++		GSW_BIST_RESULT_TEST_0 |= (0x3 << 26);
++	}
++
++
++	if (count && buffer[0]=='c')
++	{
++		printk("port 0 rx skew 0 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 24);
++		GSW_BIST_RESULT_TEST_0 |= (0x0 << 24);
++	}
++	if (count && buffer[0]=='d')
++	{
++		printk("port 0 rx skew 1.5 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 24);
++		GSW_BIST_RESULT_TEST_0 |= (0x1 << 24);
++	}
++	if (count && buffer[0]=='e')
++	{
++		printk("port 0 rx skew 2.0 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 24);
++		GSW_BIST_RESULT_TEST_0 |= (0x2 << 24);
++	}
++	if (count && buffer[0]=='f')
++	{
++		printk("port 0 rx skew 2.5 ns\n");
++                GSW_BIST_RESULT_TEST_0 &= ~(0x3 << 24);
++		GSW_BIST_RESULT_TEST_0 |= (0x3 << 24);
++	}
++
++	printk("GSW_BIST_RESULT_TEST_0: %x\n", GSW_BIST_RESULT_TEST_0);
++#endif
++
++#ifdef STR9100_GSW_FAST_AGE_OUT_
++	{
++	// 00:02:A5:BE:59:AA
++	u8 src_mac[6] = {0x00, 0x02, 0xa5, 0xbe, 0x59, 0xaa};
++	int vlan_gid=1; // lan
++
++	printk("src mac = %x:%x:%x:%x:%x:%x\n", *src_mac,*(src_mac+1), *(src_mac+2), *(src_mac+3), *(src_mac+4), *(src_mac+5));
++	printk("vlan_gid : %d\n", vlan_gid);
++	if (star_gsw_search_arl_table(src_mac, vlan_gid))
++	{
++		printk("find it\n");
++	}
++	else
++	{
++		printk("not found\n");
++	}
++
++	}
++
++	{
++	// 00:02:A5:BE:59:AA
++	u8 src_mac[6] = {0x00, 0x02, 0xa5, 0xbe, 0x59, 0x99};
++	int vlan_gid=1; // lan
++
++	printk("src mac = %x:%x:%x:%x:%x:%x\n", *src_mac,*(src_mac+1), *(src_mac+2), *(src_mac+3), *(src_mac+4), *(src_mac+5));
++	printk("vlan_gid : %d\n", vlan_gid);
++	if (star_gsw_search_arl_table(src_mac, vlan_gid))
++	{
++		printk("find it\n");
++	}
++	else
++	{
++		printk("not found\n");
++	}
++	}
++#endif
++	return count;
++}
++
++
++static void star_gsw_enable(struct net_device *dev)
++{
++	GSW_FS_DMA_START();
++	star_gsw_interrupt_enable();
++}
++
++
++static void star_gsw_shutdown(struct net_device *dev)
++{
++}
++
++inline int star_gsw_search_arl_table(u8 *mac, u32 vlan_gid)
++{
++	volatile u32 lookup_result;
++
++	GSW_ARL_TABLE_ACCESS_CONTROL_0 = 0x0;
++	GSW_ARL_TABLE_ACCESS_CONTROL_1 = 0x0;
++	GSW_ARL_TABLE_ACCESS_CONTROL_2 = 0x0;
++
++	GSW_ARL_TABLE_ACCESS_CONTROL_2 =
++		(((mac[2] & 0xFF) << 0)	|
++		((mac[3] & 0xFF) << 8)	|
++		((mac[4] & 0xFF) << 16)	|
++		((mac[5] & 0xFF) << 24));
++
++	GSW_ARL_TABLE_ACCESS_CONTROL_1 =
++		((vlan_gid << 5)	|
++		((mac[0] & 0xFF) << 16)	|
++		((mac[1] & 0xFF) << 24) );
++
++	GSW_ARL_TABLE_ACCESS_CONTROL_0 = (0x1 << 2);
++
++	do {
++		lookup_result = GSW_ARL_TABLE_ACCESS_CONTROL_1;
++		// still search, bit2 and bit0
++	} while ((lookup_result & 0x5) == 0); 
++
++	if (lookup_result & (0x1 << 2)) {
++		return 1;
++	} else {
++		return 0; // not found
++	}
++}
++
++// add by descent 2006/07/03
++// del arl entry
++int star_gsw_del_arl_table(u8 *mac, u32 vlan_gid)
++{
++	volatile u32 age_field=0; // invalid mean erase this entry
++	volatile u32 port_map=star_gsw_info.vlan[0].vlan_group; // invalid mean erase this entry
++	volatile u32 result;
++	
++	GSW_ARL_TABLE_ACCESS_CONTROL_1 = 0x0;
++	GSW_ARL_TABLE_ACCESS_CONTROL_2 = 0x0;
++
++	GSW_ARL_TABLE_ACCESS_CONTROL_1 = ( ((vlan_gid & 0x7) << 5) |
++                                           ((age_field & 0x7) << 8 ) | 
++                                           ((port_map & 0x7) << 11 ) | 
++                                           ((mac[0] & 0xFF) << 16) |
++                                           ((mac[1] & 0xFF) << 24) );
++
++	GSW_ARL_TABLE_ACCESS_CONTROL_2 = ( ((mac[2] & 0xFF) << 0)  |
++                                           ((mac[3] & 0xFF) << 8)  |
++                                           ((mac[4] & 0xFF) << 16) |
++                                           ((mac[5] & 0xFF) << 24));
++
++
++	GSW_ARL_TABLE_ACCESS_CONTROL_0 = 0x8; // write command
++	do
++	{
++		result=GSW_ARL_TABLE_ACCESS_CONTROL_1;
++	}while((result & 0x1)==0); 
++
++	return 0;
++}
++
++void star_gsw_hnat_write_vlan_src_mac(u8 index, u8 *vlan_src_mac)
++{
++	switch (index) {
++	case 0:
++		GSW_HNAT_SOURCE_MAC_0_HIGH = (vlan_src_mac[0] << 8) |
++			(vlan_src_mac[1] << 0);
++
++		GSW_HNAT_SOURCE_MAC_0_LOW = (vlan_src_mac[2] << 24) |
++			(vlan_src_mac[3] << 16) |
++			(vlan_src_mac[4] << 8) |
++			(vlan_src_mac[5] << 0);
++		break;
++
++	case 1:
++		GSW_HNAT_SOURCE_MAC_1_HIGH = (vlan_src_mac[0] << 8) |
++			(vlan_src_mac[1] << 0);
++
++		GSW_HNAT_SOURCE_MAC_1_LOW = (vlan_src_mac[2] << 24) |
++			(vlan_src_mac[3] << 16) |
++			(vlan_src_mac[4] << 8) |
++			(vlan_src_mac[5] << 0);
++		break;
++
++	case 2:
++		GSW_HNAT_SOURCE_MAC_2_HIGH = (vlan_src_mac[0] << 8) |
++			(vlan_src_mac[1] << 0);
++
++		GSW_HNAT_SOURCE_MAC_2_LOW = (vlan_src_mac[2] << 24) |
++			(vlan_src_mac[3] << 16) |
++			(vlan_src_mac[4] << 8) |
++			(vlan_src_mac[5] << 0);
++		break;
++
++	case 3:
++		GSW_HNAT_SOURCE_MAC_3_HIGH = (vlan_src_mac[0] << 8) |
++			(vlan_src_mac[1] << 0);
++
++		GSW_HNAT_SOURCE_MAC_3_LOW = (vlan_src_mac[2] << 24) |
++			(vlan_src_mac[3] << 16) |
++			(vlan_src_mac[4] << 8) |
++			(vlan_src_mac[5] << 0);
++		break;
++
++	case 4:
++		GSW_HNAT_SOURCE_MAC_4_HIGH = (vlan_src_mac[0] << 8) |
++			(vlan_src_mac[1] << 0);
++
++		GSW_HNAT_SOURCE_MAC_4_LOW = (vlan_src_mac[2] << 24) |
++			(vlan_src_mac[3] << 16) |
++			(vlan_src_mac[4] << 8) |
++			(vlan_src_mac[5] << 0);
++		break;
++
++	case 5:
++		GSW_HNAT_SOURCE_MAC_5_HIGH = (vlan_src_mac[0] << 8) |
++			(vlan_src_mac[1] << 0);
++
++		GSW_HNAT_SOURCE_MAC_5_LOW = (vlan_src_mac[2] << 24) |
++			(vlan_src_mac[3] << 16) |
++			(vlan_src_mac[4] << 8) |
++			(vlan_src_mac[5] << 0);
++		break;
++
++	case 6:
++		GSW_HNAT_SOURCE_MAC_6_HIGH = (vlan_src_mac[0] << 8) |
++			(vlan_src_mac[1] << 0);
++
++		GSW_HNAT_SOURCE_MAC_6_LOW = (vlan_src_mac[2] << 24) |
++			(vlan_src_mac[3] << 16) |
++			(vlan_src_mac[4] << 8) |
++			(vlan_src_mac[5] << 0);
++		break;
++
++	case 7:
++		GSW_HNAT_SOURCE_MAC_7_HIGH = (vlan_src_mac[0] << 8) |
++			(vlan_src_mac[1] << 0);
++
++		GSW_HNAT_SOURCE_MAC_7_LOW = (vlan_src_mac[2] << 24) |
++			(vlan_src_mac[3] << 16) |
++			(vlan_src_mac[4] << 8) |
++			(vlan_src_mac[5] << 0);
++		break;
++
++	default:
++		break;
++	}
++}
++
++static int star_gsw_hnat_setup_vlan_src_mac(void)
++{
++	star_gsw_hnat_write_vlan_src_mac(0, star_gsw_info.vlan[0].vlan_mac);
++	star_gsw_hnat_write_vlan_src_mac(1, star_gsw_info.vlan[1].vlan_mac);
++	star_gsw_hnat_write_vlan_src_mac(2, star_gsw_info.vlan[2].vlan_mac);
++	star_gsw_hnat_write_vlan_src_mac(3, star_gsw_info.vlan[3].vlan_mac);
++
++	return 0;
++}
++
++static void star_gsw_vlan_init(void)
++{
++	star_gsw_info.vlan[0].vlan_gid		= VLAN0_GROUP_ID;
++	star_gsw_info.vlan[0].vlan_vid		= VLAN0_VID;
++	star_gsw_info.vlan[0].vlan_group	= VLAN0_GROUP;
++	star_gsw_info.vlan[0].vlan_tag_flag	= VLAN0_VLAN_TAG;
++
++	// store My VLAN0 MAC
++	memcpy(star_gsw_info.vlan[0].vlan_mac, my_vlan0_mac, 6);
++
++	star_gsw_info.vlan[1].vlan_gid		= VLAN1_GROUP_ID;
++	star_gsw_info.vlan[1].vlan_vid		= VLAN1_VID;
++	star_gsw_info.vlan[1].vlan_group	= VLAN1_GROUP;
++	star_gsw_info.vlan[1].vlan_tag_flag	= VLAN1_VLAN_TAG;
++
++	// store My VLAN1 MAC
++	memcpy(star_gsw_info.vlan[1].vlan_mac, my_vlan1_mac, 6);
++
++	star_gsw_info.vlan[2].vlan_gid		= VLAN2_GROUP_ID;
++	star_gsw_info.vlan[2].vlan_vid		= VLAN2_VID;
++	star_gsw_info.vlan[2].vlan_group	= VLAN2_GROUP;
++	star_gsw_info.vlan[2].vlan_tag_flag	= VLAN2_VLAN_TAG;
++
++	// store My VLAN2 MAC
++	memcpy(star_gsw_info.vlan[2].vlan_mac, my_vlan2_mac, 6);
++
++	star_gsw_info.vlan[3].vlan_gid		= VLAN3_GROUP_ID;
++	star_gsw_info.vlan[3].vlan_vid		= VLAN3_VID;
++	star_gsw_info.vlan[3].vlan_group	= VLAN3_GROUP;
++	star_gsw_info.vlan[3].vlan_tag_flag	= VLAN3_VLAN_TAG;
++
++	// store My VLAN3 MAC
++	memcpy(star_gsw_info.vlan[3].vlan_mac, my_vlan3_mac, 6);
++
++	star_gsw_info.vlan[4].vlan_gid		= VLAN4_GROUP_ID;
++	star_gsw_info.vlan[4].vlan_vid		= VLAN4_VID;
++	star_gsw_info.vlan[4].vlan_group	= VLAN4_GROUP;
++	star_gsw_info.vlan[4].vlan_tag_flag	= VLAN4_VLAN_TAG;
++
++	star_gsw_info.vlan[5].vlan_gid		= VLAN5_GROUP_ID;
++	star_gsw_info.vlan[5].vlan_vid		= VLAN5_VID;
++	star_gsw_info.vlan[5].vlan_group	= VLAN5_GROUP;
++	star_gsw_info.vlan[5].vlan_tag_flag	= VLAN5_VLAN_TAG;
++
++	star_gsw_info.vlan[6].vlan_gid		= VLAN6_GROUP_ID;
++	star_gsw_info.vlan[6].vlan_vid		= VLAN6_VID;
++	star_gsw_info.vlan[6].vlan_group	= VLAN6_GROUP;
++	star_gsw_info.vlan[6].vlan_tag_flag	= VLAN6_VLAN_TAG; 
++
++	star_gsw_info.vlan[7].vlan_gid		= VLAN7_GROUP_ID;
++	star_gsw_info.vlan[7].vlan_vid		= VLAN7_VID;
++	star_gsw_info.vlan[7].vlan_group	= VLAN7_GROUP;
++	star_gsw_info.vlan[7].vlan_tag_flag	= VLAN7_VLAN_TAG;
++
++	star_gsw_info.port[0].pvid		= PORT0_PVID;
++	star_gsw_info.port[0].config_flag	= 0;
++	star_gsw_info.port[0].status_flag	= 0;
++
++	star_gsw_info.port[1].pvid		= PORT1_PVID;
++	star_gsw_info.port[1].config_flag	= 0;
++	star_gsw_info.port[1].status_flag	= 0;
++
++	star_gsw_info.port[2].pvid		= CPU_PORT_PVID;
++	star_gsw_info.port[2].config_flag	= 0;
++	star_gsw_info.port[2].status_flag	= 0;   
++}
++
++irqreturn_t star_gsw_receive_isr(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct star_gsw_private *priv = netdev_priv(STAR_NAPI_DEV);
++
++
++#ifdef CONFIG_STAR_GSW_NAPI
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_FSRC_BIT_INDEX);
++	disable_irq(INTC_GSW_FSRC_BIT_INDEX);
++
++
++        if (likely(netif_rx_schedule_prep(STAR_NAPI_DEV,&priv->napi))) {
++                __netif_rx_schedule(STAR_NAPI_DEV,&priv->napi);
++	} else {
++                enable_irq(INTC_GSW_FSRC_BIT_INDEX);
++        }
++
++#if 0
++	CUR_NAPI_DEV=STAR_GSW_WAN_DEV;
++
++	if (CUR_NAPI_DEV && netif_running(CUR_NAPI_DEV)) {
++		if (likely(netif_rx_schedule_prep(CUR_NAPI_DEV))) {
++			__netif_rx_schedule(CUR_NAPI_DEV);
++		} else {
++			PDEBUG("lan driver bug! interrupt while in poll\n");
++		}
++	}
++	else
++	{
++		CUR_NAPI_DEV=STAR_GSW_LAN_DEV;
++		if (CUR_NAPI_DEV && netif_running(CUR_NAPI_DEV)) {
++			if (likely(netif_rx_schedule_prep(CUR_NAPI_DEV))) {
++				__netif_rx_schedule(CUR_NAPI_DEV);
++			} else {
++				PDEBUG("lan driver bug! interrupt while in poll\n");
++			}
++		}
++		else
++		{
++			CUR_NAPI_DEV=STAR_GSW_EWC_DEV;
++			if (CUR_NAPI_DEV && netif_running(CUR_NAPI_DEV)) {
++				if (likely(netif_rx_schedule_prep(CUR_NAPI_DEV))) {
++					__netif_rx_schedule(CUR_NAPI_DEV);
++				} else {
++					PDEBUG("lan driver bug! interrupt while in poll\n");
++				}
++			}
++
++		}
++	}
++#endif
++#else
++	// TODO: mask interrupt
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_FSRC_BIT_INDEX);
++	// MASK Interrupt
++	INTC_INTERRUPT_MASK |= (0x1 << INTC_GSW_FSRC_BIT_INDEX);
++	INTC_INTERRUPT_MASK |= (0x1 << INTC_GSW_FSQF_BIT_INDEX);
++	++fsrc_count;
++	star_gsw_receive_packet(0); // Receive Once
++	// TODO: unmask interrupt
++	INTC_INTERRUPT_MASK &= ~(0x1 << INTC_GSW_FSRC_BIT_INDEX);
++	INTC_INTERRUPT_MASK &= ~(0x1 << INTC_GSW_FSQF_BIT_INDEX);
++#endif
++
++	return IRQ_HANDLED;
++}
++
++
++#ifdef STAR_GSW_FSQF_ISR
++IRQ_RETURN star_gsw_fsqf_isr(int irq, void *dev_id, struct pt_regs *regs)
++{
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_FSQF_BIT_INDEX);
++#ifdef CONFIG_STAR_GSW_NAPI
++	// because in normal state, fsql only invoke once and set_bit is atomic function.
++	// so I don't mask it.
++	set_bit(0, &is_qf);
++#else
++	INTC_INTERRUPT_MASK |= (0x1 << INTC_GSW_FSRC_BIT_INDEX);
++	INTC_INTERRUPT_MASK |= (0x1 << INTC_GSW_FSQF_BIT_INDEX);
++
++	star_gsw_receive_packet(1); // Receive at Queue Full Mode
++
++	// TODO: unmask interrupt
++	INTC_INTERRUPT_MASK &= ~(0x1 << INTC_GSW_FSRC_BIT_INDEX);
++	INTC_INTERRUPT_MASK &= ~(0x1 << INTC_GSW_FSQF_BIT_INDEX);
++	//INTC_INTERRUPT_MASK &= (0x0 << INTC_GSW_FSRC_BIT_INDEX);
++	//INTC_INTERRUPT_MASK &= (0x0 << INTC_GSW_FSQF_BIT_INDEX);
++#endif
++
++	return IRQ_HANDLED;
++}
++#endif
++
++#ifdef STAR_GSW_STATUS_ISR
++static char *star_gsw_status_tbl[] = {
++	"\nGlobal threshold reached and Port 0 queue threshold reached.\n",
++	"\nGlobal threshold reached and Port 1 queue threshold reached.\n",
++	"\nGlobal threshold reached and CPU port queue threshold reached.\n",
++	"\nGlobal threshold reached and HNAT queue threshold reached.\n",
++	"\nGlobal threshold reached.\n",
++	"\nAll pages of packet buffer are used.\n",
++	"\nPort change link state.\n",
++	"\nPort 0 received intruder packets.\n",
++	"\nPort 1 received intruder packets.\n",
++	"\n",
++	"\nPort 0 received packets with unknown VLAN.\n",
++	"\nPort 1 received packets with unknown VLAN.\n",
++	"\nPort CPU received packets with unknown VLAN.\n",
++	"\n",
++	"\n",
++	"\n",
++	"\nDrop by no free links(Port 0).\n",
++	"\nDrop by broadcast storm(Port 0).\n",
++	"\nDrop by rx packet error(Port 0).\n",
++	"\nDrop by backpressure(Port 0).\n",
++	"\nDrop by no destination(Port 0).\n",
++	"\nDrop by reserved MC packets(Port 0).\n",
++	"\nDrop by local traffic(Port 0).\n",
++	"\nDrop by ingress check(Port 0).\n",
++	"\nDrop by no free links(Port 1).\n",
++	"\nDrop by broadcast storm(Port 1).\n",
++	"\nDrop by rx packet error(Port 1).\n",
++	"\nDrop by backpressure(Port 1).\n",
++	"\nDrop by no destination(Port 1).\n",
++	"\nDrop by reserved MC packets(Port 1).\n",
++	"\nDrop by local traffic(Port 1).\n",
++	"\nDrop by ingress checki(Port 1).\n",
++};
++
++IRQ_RETURN star_gsw_status_isr(int irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 int_status;
++	u32 i;
++
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_STATUS_BIT_INDEX);
++
++	GSW_READ_INTERRUPT_STATUS(int_status);
++
++	PDEBUG("\n status:%08X \n",int_status);
++	PDEBUG("\n GSW_MAC_PORT_0_CONFIG:%08X\n",GSW_MAC_PORT_0_CONFIG);
++	PDEBUG("\n GSW_MAC_PORT_1_CONFIG:%08X\n",GSW_MAC_PORT_1_CONFIG);
++
++	for (i = 0; i < 32; i++) {
++		if (int_status & (1 << i)) {
++			PRINT_INFO(star_gsw_status_tbl[i]);
++		}
++	}
++
++	GSW_CLEAR_INTERRUPT_STATUS_SOURCES(int_status);
++
++	INTC_ENABLE_INTERRUPT_SOURCE(INTC_GSW_STATUS_BIT_INDEX);
++
++	return IRQ_HANDLED;
++
++}
++#endif // STAR_GSW_STATUS_ISR
++
++static int star_gsw_uninstall_isr(struct net_device *dev)
++{
++	--install_isr_account;
++	if (install_isr_account == 0) {
++		PDEBUG("star gsw uninstall isr\n");
++		free_irq(INTC_GSW_FSRC_BIT_INDEX, STAR_GSW_LAN_DEV);
++
++#ifdef STAR_GSW_FSQF_ISR
++		free_irq(INTC_GSW_FSQF_BIT_INDEX, STAR_GSW_LAN_DEV);
++#endif
++
++#ifdef STAR_GSW_STATUS_ISR
++		free_irq(INTC_GSW_STATUS_BIT_INDEX, STAR_GSW_LAN_DEV);
++#endif
++
++
++#ifdef CONFIG_STAR_GSW_NAPI
++{
++	struct star_gsw_private *sp = netdev_priv(STAR_NAPI_DEV);
++
++	napi_disable(&sp->napi);
++	netif_stop_queue(STAR_NAPI_DEV);
++}
++#endif
++
++	}
++
++	return 0;
++}
++
++static int star_gsw_install_isr(struct net_device *dev)
++{
++	int retval;
++
++	
++	if (install_isr_account == 0) {
++#ifdef STAR_GSW_DELAYED_INTERRUPT
++		GSW_DELAYED_INTERRUPT_CONFIG = (1 << 16) | (max_pend_int_cnt << 8) | (max_pend_time);
++#endif
++#ifdef STAR_GSW_STATUS_ISR
++		str9100_set_interrupt_trigger(INTC_GSW_STATUS_BIT_INDEX, INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH);
++#endif
++		str9100_set_interrupt_trigger((u32)INTC_GSW_FSRC_BIT_INDEX, (u32)INTC_EDGE_TRIGGER, (u32)INTC_RISING_EDGE);
++#ifdef STAR_GSW_FSQF_ISR
++		str9100_set_interrupt_trigger(INTC_GSW_FSQF_BIT_INDEX, INTC_EDGE_TRIGGER, INTC_RISING_EDGE);
++#endif
++
++
++		retval = request_irq(INTC_GSW_FSRC_BIT_INDEX, &star_gsw_receive_isr, IRQF_SHARED, "GSW FSRC INT", STAR_GSW_LAN_DEV);
++
++		if (retval) {
++			PRINT_INFO("%s: unable to get IRQ %d (irqval=%d).\n", "GSW FSRC INT", INTC_GSW_FSRC_BIT_INDEX, retval);
++			return 1;
++		}
++
++#ifdef STAR_GSW_FSQF_ISR
++		/*  QUEUE full interrupt handler */
++		retval = request_irq(INTC_GSW_FSQF_BIT_INDEX, &star_gsw_fsqf_isr, IRQF_SHARED, "GSW FSQF INT", STAR_GSW_LAN_DEV);
++
++		if (retval) {
++			PRINT_INFO("%s: unable to get IRQ %d (irqval=%d).\n", "GSW FSQF INT", INTC_GSW_FSQF_BIT_INDEX, retval);
++			return 2;
++		}
++#endif	
++
++#ifdef STAR_GSW_STATUS_ISR
++		/*  GSW Status interrupt handler */
++		retval = request_irq(INTC_GSW_STATUS_BIT_INDEX, &star_gsw_status_isr, IRQF_SHARED, "GSW STATUS", STAR_GSW_LAN_DEV);
++
++		if (retval) {
++			PRINT_INFO("%s: unable to get IRQ %d (irqval=%d).\n", "GSW STATUS INT", INTC_GSW_STATUS_BIT_INDEX, retval);
++			return 3;
++		}
++		GSW_ENABLE_ALL_INTERRUPT_STATUS_SOURCES();
++#endif
++
++#ifdef CONFIG_STAR_GSW_NAPI
++{
++	struct star_gsw_private *sp = netdev_priv(STAR_NAPI_DEV);    
++        napi_enable(&sp->napi);
++        netif_start_queue(STAR_NAPI_DEV);
++}
++#endif
++	} // end if(install_isr_account == 0)
++
++	++install_isr_account;
++
++	return 0;
++}
++
++// add by descent 2006/07/12
++void enable_cpu_port(int y)
++{
++	u32 cpu_port_config;
++	cpu_port_config = GSW_CPU_PORT_CONFIG;		
++	if (y==1) // enable CPU
++		cpu_port_config &= ~(0x1 << 18);
++	if (y==0) // disable CPU
++		cpu_port_config |= (0x1 << 18);
++	GSW_CPU_PORT_CONFIG = cpu_port_config;
++}
++
++static int star_gsw_open(struct net_device *dev)
++{
++
++
++	OPEN_PORT(dev)
++	enable_cpu_port(1);
++	//memcpy(dev->dev_addr, star_gsw_info.vlan[1].vlan_mac, 6);
++
++	star_gsw_hnat_setup_vlan_src_mac();
++
++#if 0
++#ifdef MODULE
++	MOD_INC_USE_COUNT;
++#endif
++#endif
++
++
++
++	//CUR_NAPI_DEV = dev;
++
++	star_gsw_enable(dev);
++
++	netif_start_queue(dev);
++
++	GSW_ENABLE_ALL_INTERRUPT_STATUS_SOURCES();
++
++	star_gsw_install_isr(dev);
++
++	return 0;
++}
++
++
++
++static struct net_device_stats *star_gsw_get_stats(struct net_device *dev)
++{
++	struct star_gsw_private *priv = netdev_priv(dev);
++
++	return &priv->stats;
++}
++
++static void star_gsw_timeout(struct net_device *dev)
++{
++	PRINT_INFO("%s:star_gsw_timeout\n", dev->name);
++	star_gsw_enable(dev);
++	netif_wake_queue(dev);
++	dev->trans_start = jiffies;
++}
++
++
++
++static int star_gsw_close(struct net_device *dev)
++{
++	star_gsw_uninstall_isr(dev);
++	//star_gsw_shutdown(dev);
++
++	//CLOSE_PORT0
++	//CLOSE_PORT1
++	CLOSE_PORT(dev)
++
++#if 0
++#ifdef MODULE
++	MOD_DEC_USE_COUNT;
++#endif
++#endif
++
++#if 0
++	if (dev == STAR_GSW_WAN_DEV) {
++		CUR_NAPI_DEV = STAR_GSW_LAN_DEV;
++	} else if (dev == STAR_GSW_LAN_DEV) {
++		CUR_NAPI_DEV = STAR_GSW_WAN_DEV;
++	} else if (dev == STAR_GSW_EWC_DEV) {
++		CUR_NAPI_DEV = STAR_GSW_LAN_DEV;
++	}
++	//} // if (dev == STAR_GSW_LAN_DEV)
++#endif
++
++	//phy_power_down_ptr(1,1);
++	return 0;
++}
++
++static inline struct sk_buff *star_gsw_alloc_skb(void)
++{
++	struct sk_buff *skb;
++
++	skb = dev_alloc_skb(MAX_PACKET_LEN + 2);
++
++	if (unlikely(!skb)) {
++		PDEBUG("\n dev_alloc_skb fail!! while allocate RFD ring !!\n");
++		return NULL;
++	}
++
++
++	/* Make buffer alignment 2 beyond a 16 byte boundary
++	 * this will result in a 16 byte aligned IP header after
++	 * the 14 byte MAC header is removed
++	 */
++	
++	skb_reserve(skb, 2);	/* 16 bit alignment, 4N + 2 mode */
++
++	return skb;
++}
++
++static void star_gsw_buffer_free(void)
++{
++	int i;
++
++	if (rxring.vir_addr) {
++		for (i = 0; i < STAR_GSW_MAX_RFD_NUM; i++) {
++			if (rxring.skb_ptr[i]) {
++				dev_kfree_skb(rxring.skb_ptr[i]);
++			}
++		}
++		dma_free_coherent(NULL, STAR_GSW_MAX_RFD_NUM * sizeof(STAR_GSW_RXDESC), rxring.vir_addr, rxring.phy_addr);
++	}
++
++	if (txring.vir_addr) {
++		dma_free_coherent(NULL, STAR_GSW_MAX_TFD_NUM * sizeof(STAR_GSW_TXDESC), txring.vir_addr, txring.phy_addr);
++	}
++}
++
++static int __init star_gsw_buffer_alloc(void)
++{
++	STAR_GSW_RXDESC	volatile *rxdesc_ptr;
++	STAR_GSW_TXDESC	volatile *txdesc_ptr;
++	struct sk_buff	*skb_ptr;
++	int err;
++	int i;
++
++	rxring.vir_addr = dma_alloc_coherent(NULL, STAR_GSW_MAX_RFD_NUM * sizeof(STAR_GSW_RXDESC), &rxring.phy_addr, GFP_KERNEL);
++	if (!rxring.vir_addr) {
++		PDEBUG("\n ERROR: Allocate RFD Failed\n");
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++	txring.vir_addr = dma_alloc_coherent(NULL, STAR_GSW_MAX_TFD_NUM * sizeof(STAR_GSW_TXDESC), &txring.phy_addr, GFP_KERNEL);
++	if (!txring.vir_addr) {
++		PDEBUG("\n ERROR: Allocate TFD Failed\n");
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++	// Clean RX Memory
++	memset((void *)rxring.vir_addr, 0, STAR_GSW_MAX_RFD_NUM * sizeof(STAR_GSW_RXDESC));
++	PDEBUG("    rxring.vir_addr=0x%08X rxring.phy_addr=0x%08X\n", (u32)rxring.vir_addr, (u32)rxring.phy_addr);
++	rxring.cur_index = 0;	// Set cur_index Point to Zero
++	rxdesc_ptr = rxring.vir_addr;
++	for (i = 0; i < STAR_GSW_MAX_RFD_NUM; i++, rxdesc_ptr++) {
++		if (i == (STAR_GSW_MAX_RFD_NUM - 1)) { 
++			rxdesc_ptr->eor = 1;	// End bit == 0;
++		}
++		skb_ptr = star_gsw_alloc_skb();
++		if (!skb_ptr) {
++			PDEBUG("ERROR: Allocate skb Failed!\n");
++			err = -ENOMEM;
++			goto err_out;
++		}
++		// Trans Packet from Virtual Memory to Physical Memory
++		rxring.skb_ptr[i]	= skb_ptr;
++		rxdesc_ptr->data_ptr	= (u32)virt_to_phys(skb_ptr->data);
++		rxdesc_ptr->length	= MAX_PACKET_LEN;
++	}
++
++	// Clean TX Memory
++	memset((void *)txring.vir_addr, 0, STAR_GSW_MAX_TFD_NUM * sizeof(STAR_GSW_TXDESC));
++	PDEBUG("    txring.vir_addr=0x%08X txring.phy_addr=0x%08X\n", (u32)txring.vir_addr, (u32)txring.phy_addr);
++	txring.cur_index = 0;	// Set cur_index Point to Zero
++	txdesc_ptr = txring.vir_addr;
++	for (i = 0; i < STAR_GSW_MAX_TFD_NUM; i++, txdesc_ptr++) {
++		if (i == (STAR_GSW_MAX_TFD_NUM - 1)) { 
++			txdesc_ptr->eor = 1;	// End of Ring ==1
++		}
++		txdesc_ptr->cown = 1;	// TX Ring , Cown == 1
++
++#ifdef STAR_GSW_TX_HW_CHECKSUM
++		// Enable Checksum
++		txdesc_ptr->ico		= 0;
++		txdesc_ptr->uco		= 1;
++		txdesc_ptr->tco		= 1;
++#else
++		txdesc_ptr->ico		= 0;
++		txdesc_ptr->uco		= 0;
++		txdesc_ptr->tco		= 0;
++#endif
++		txring.skb_ptr[i] 	= NULL;	// clear txring.skb_ptr
++	}
++
++	return 0;
++
++err_out:
++	star_gsw_buffer_free();
++	return err;
++}
++
++#ifdef CONFIG_STAR_GSW_NAPI
++
++#if 0
++static int star_gsw_poll(struct net_device *netdev, int *budget)
++{
++	int work_done = 0;
++	int work_to_do = min(*budget, netdev->quota); // where is min define
++
++	star_gsw_receive_packet(0, &work_done, work_to_do);
++
++	*budget -= work_done;
++	netdev->quota -= work_done;
++
++        if (work_done) {
++                if (is_qf) {
++                        is_qf = 0;
++                        HAL_GSW_FS_DMA_START();
++                        return 1;
++                }
++        }
++        else {
++                netif_rx_complete(&STAR_NAPI_DEV);
++                enable_irq(INTC_GSW_FSRC_BIT_INDEX);
++                return 0;
++        }
++
++
++	return 1;
++}
++#else
++
++static int star_gsw_poll(struct napi_struct *napi, int budget)
++{
++
++	struct star_gsw_private *sp = container_of(napi, struct star_gsw_private, napi);
++	int work_done = 0;
++	int work_to_do = budget; // where is min define
++
++	star_gsw_receive_packet(0, &work_done, work_to_do);
++
++	budget -= work_done;
++
++        if (work_done) {
++			if (test_bit(0, (unsigned long *)&is_qf) == 1){
++				clear_bit(0, (unsigned long *)&is_qf);
++                HAL_GSW_FS_DMA_START();
++                return 1;
++            }
++        }
++        else {
++            netif_rx_complete(STAR_NAPI_DEV, &sp->napi);
++            enable_irq(INTC_GSW_FSRC_BIT_INDEX);
++            return 0;
++        }
++
++
++	return 1;
++}
++#endif
++
++
++#ifdef LINUX26_
++#ifdef CONFIG_CPU_ISPAD_ENABLE
++__attribute__((section(".ispad")))
++#endif
++
++static int star_gsw_poll(struct napi_struct *napi, int budget)
++{
++
++	struct star_gsw_private *sp = container_of(napi, struct star_gsw_private, napi);
++	int work_done = 0;
++	int work_to_do = budget; // where is min define
++
++	star_gsw_receive_packet(0, &work_done, work_to_do);
++
++	budget -= work_done;
++
++        if (work_done) {
++			if (test_bit(0, (unsigned long *)&is_qf) == 1){
++				clear_bit(0, (unsigned long *)&is_qf);
++                HAL_GSW_FS_DMA_START();
++                return 1;
++            }
++        }
++        else {
++            netif_rx_complete(STAR_NAPI_DEV, &sp->napi);
++            enable_irq(INTC_GSW_FSRC_BIT_INDEX);
++            return 0;
++        }
++
++
++	return 1;
++}
++#endif // LINUX26
++
++
++
++
++
++#endif // CONFIG_STAR_GSW_NAPI
++
++static int star_gsw_get_rfd_buff(int index)
++{
++	struct star_gsw_private *priv;
++	STAR_GSW_RXDESC volatile *rxdesc_ptr;
++	struct sk_buff *skb_ptr;
++	unsigned char *data;
++	int len;
++#ifdef CONFIG_STR9100_VLAN_BASE
++	u32 vlan_gid = 0;
++	u8 *src_mac;
++#endif
++
++	rxdesc_ptr = rxring.vir_addr + index;
++	skb_ptr = rxring.skb_ptr[index];
++	len = rxdesc_ptr->length;
++
++	dma_cache_maint(skb_ptr->data, len, PCI_DMA_FROMDEVICE);
++
++#ifdef CONFIG_STR9100_PORT_BASE
++	if (rxdesc_ptr->sp == 0) {
++		/*
++		 * Note this packet is from GSW Port 0, and the device index of GSW Port 0 is 1
++		 * Note the device index = 0 is for internal loopback device
++		 */
++		//skb_ptr->dev = STAR_GSW_LAN_DEV;
++		skb_ptr->dev = NET_DEV0;
++		if (skb_ptr->dev)
++			goto determine_dev_ok;
++	} else {
++		// Note this packet is from GSW Port 1, and the device index of GSW Port 1 is 2
++		//skb_ptr->dev = STAR_GSW_WAN_DEV;
++		skb_ptr->dev = NET_DEV1;
++		if (skb_ptr->dev)
++			goto determine_dev_ok;
++	}
++
++#endif /* CONFIG_STR9100_PORT_BASE */
++
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++	if (rxdesc_ptr->hr == 0x27 && star9100_shnat_hook_ready) {
++		if(star9100_shnat_pci_fp_getdev_hook(skb_ptr)){
++			skb_put(skb_ptr, len);
++
++#if CONFIG_HAVE_VLAN_TAG
++	#define PPPOE_ID_1_LOC 16
++	#define PPPOE_ID_2_LOC 17
++#else
++	#define PPPOE_ID_1_LOC 12
++	#define PPPOE_ID_2_LOC 13
++#endif
++
++			if (skb_ptr->data[PPPOE_ID_1_LOC] == 0x88 && skb_ptr->data[PPPOE_ID_2_LOC]==0x64) { // pppoe session 
++				/* Remove PPPoE Header */
++                memmove(skb_ptr->data+8, skb_ptr->data, 12); 
++                skb_ptr->data+=8; 
++                skb_ptr->len-=8; 
++                skb_ptr->data[PPPOE_ID_1_LOC]=0x08; 
++                skb_ptr->data[PPPOE_ID_2_LOC]=0x0; 
++       		 } else { 
++				/* Remove VLAN Tag */
++#ifdef CONFIG_HAVE_VLAN_TAG
++				memmove(skb_ptr->data + 4, skb_ptr->data, 12);
++				skb_ptr->len-=4;
++				skb_ptr->data+=4;
++#endif
++			} 
++			skb_ptr->dev->hard_start_xmit(skb_ptr, skb_ptr->dev);
++			return 0;
++			}
++	}
++#endif /* CONFIG_STAR9100_SHNAT_PCI_FASTPATH */
++
++RECV_PACKET:
++
++#ifdef CONFIG_STR9100_VLAN_BASE
++
++#ifdef CONFIG_HAVE_VLAN_TAG
++
++
++// 20060922 descent
++	{ // NIC MODE off
++
++		const char lan_tag[]={0x81, 0x00, 0x00, 0x01};
++		const char wan_tag[]={0x81, 0x00, 0x00, 0x02};
++
++
++
++		if (memcmp(skb_ptr->data+12, lan_tag,4)==0) {
++			//printk("lan dev\n");
++			skb_ptr->dev = STAR_GSW_LAN_DEV;
++		} else if (memcmp(skb_ptr->data+12, wan_tag,4)==0) {
++			//printk("wan dev\n");
++			skb_ptr->dev = STAR_GSW_WAN_DEV;
++		} else {
++			PDEBUG("no vlan tag\n");
++			//print_packet(skb_ptr->data, 32);
++			goto freepacket;
++
++		}
++// 20070503 descent
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++		// let 8021Q to determine vlan tag
++#else  /* defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) */
++		memmove(skb_ptr->data + 4, skb_ptr->data, 12);
++		//skb_ptr->data += 4; 
++		skb_reserve(skb_ptr, 4);
++		len -= 4; // minus 4 byte vlan tag
++#endif /* defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) */
++
++#else  /* CONFIG_HAVE_VLAN_TAG */
++	
++// 20060922 descent
++#ifdef CONFIG_NIC_MODE
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++// do nothing
++#else // defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++	// if NIC MODE on
++        if ( ((GSW_SWITCH_CONFIG >> 30) & 0x1) ==1){
++		const char lan_tag[]={0x81, 0x00, 0x00, 0x01};
++		const char wan_tag[]={0x81, 0x00, 0x00, 0x02};
++
++		//printk("NIC mode on\n");
++		if (memcmp(skb_ptr->data+12, lan_tag,4)==0) {
++			//printk("lan dev\n");
++			skb_ptr->dev = STAR_GSW_LAN_DEV;
++		} else if (memcmp(skb_ptr->data+12, wan_tag,4)==0) {
++			//printk("wan dev\n");
++			skb_ptr->dev = STAR_GSW_WAN_DEV;
++		} else {
++			//printk("no vlan tag\n");
++			//print_packet(skb_ptr->data, 32);
++			goto freepacket;
++
++		}
++
++		memmove(skb_ptr->data + 4, skb_ptr->data, 12);
++		skb_ptr->data += 4; 
++		goto determine_dev_ok;
++
++	}
++#endif // defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++#endif
++// 20060922 descent end
++
++	src_mac = skb_ptr->data + 6; // get source mac address
++
++	// use gid and source mac to serarch arl table
++	vlan_gid = 1; // lan
++	if (star_gsw_search_arl_table(src_mac, vlan_gid)) {
++		//printk("STAR_GSW_LAN_DEV\n");
++		skb_ptr->dev = STAR_GSW_LAN_DEV;
++		#ifdef STR9100_GSW_FAST_AGE_OUT
++		star_gsw_del_arl_table(src_mac, vlan_gid);
++		#endif
++		goto determine_dev_ok;
++	} else {
++		vlan_gid = 0; // wan
++		if (star_gsw_search_arl_table(src_mac, vlan_gid)) {
++			//printk("STAR_GSW_WAN_DEV\n");
++			skb_ptr->dev = STAR_GSW_WAN_DEV;
++			#ifdef STR9100_GSW_FAST_AGE_OUT
++			star_gsw_del_arl_table(src_mac, vlan_gid);
++			#endif
++			goto determine_dev_ok;
++		} else {
++			PDEBUG("not determine come from lan or wan\n"); // should not go here
++			PDEBUG("not determine come from lan or wan\n"); // should not go here
++			goto freepacket;
++		}
++	}
++
++#endif // CONFIG_HAVE_VLAN_TAG
++
++#endif /* CONFIG_STR9100_VLAN_BASE */
++
++
++determine_dev_ok:
++	skb_put(skb_ptr, len);
++
++
++
++	if (skb_ptr->dev!=NULL) {
++		priv = netdev_priv(skb_ptr->dev);
++	}
++	else{
++		PDEBUG("skb_ptr->dev==NULL\n");
++		//goto freepacket;
++	}
++
++#ifdef STAR_GSW_RX_HW_CHECKSUM
++	if (rxdesc_ptr->ipf == 1 || rxdesc_ptr->l4f == 1) {
++		if (rxdesc_ptr->prot != 0x11) {
++			skb_ptr->ip_summed = CHECKSUM_NONE;
++		} else {
++			// CheckSum Fail
++			priv->stats.rx_errors++;
++			goto freepacket;
++		}
++	} else {
++			skb_ptr->ip_summed = CHECKSUM_UNNECESSARY;
++	}
++#else
++	skb_ptr->ip_summed = CHECKSUM_NONE;
++#endif
++
++	// this line must, if no, packet will not send to network layer
++	skb_ptr->protocol = eth_type_trans(skb_ptr, skb_ptr->dev);
++	//skb_ptr->protocol = htons(ETH_P_8021Q);
++
++#ifndef CONFIG_STAR_GSW_BRIDGE
++	// send any packet in bridge mode
++	/*
++	 * This is illegality packet so drop it.
++	*/
++	if (skb_ptr->protocol == htons(ETH_P_802_2)) {
++		PDEBUG("ETH_P_802_2\n");
++		goto freepacket;
++	}
++#endif
++
++	priv->stats.rx_packets++;
++	priv->stats.rx_bytes += len;
++	skb_ptr->dev->last_rx = jiffies;
++
++
++	//PRINT_PACKET(skb_ptr->data, 32, "RX")
++
++	// if netif_rx any package, will let this driver core dump.
++#ifdef CONFIG_STAR_GSW_NAPI
++	netif_receive_skb(skb_ptr);
++#else
++	netif_rx(skb_ptr);
++#endif
++
++	return 0;
++
++freepacket:
++	dev_kfree_skb_any(skb_ptr);
++	return 0;
++}
++
++#ifdef CONFIG_STAR_GSW_NAPI
++void star_gsw_receive_packet(int mode, int *work_done, int work_to_do)
++#else
++void star_gsw_receive_packet(int mode)
++#endif
++{
++	int fssd_index;
++	int fssd_current;
++	STAR_GSW_RXDESC volatile *rxdesc_ptr = rxring.vir_addr + rxring.cur_index;
++	struct sk_buff *skb_ptr;
++#ifndef CONFIG_STAR_GSW_NAPI
++	int fsqf = 0; // Queue Full Mode =0
++#endif
++	int i, rxcount = 0;
++	GSW_READ_FSSD(fssd_current);
++	fssd_index = (fssd_current - (u32)rxring.phy_addr) >> 4;
++
++	if (fssd_index > rxring.cur_index) {
++		rxcount = fssd_index - rxring.cur_index;
++	} else if (fssd_index < rxring.cur_index) {
++		rxcount = (STAR_GSW_MAX_RFD_NUM - rxring.cur_index) + fssd_index;
++	} else {
++		if (rxdesc_ptr->cown == 0) {
++			goto receive_packet_exit;
++		} else {
++			// Queue Full
++#ifndef CONFIG_STAR_GSW_NAPI
++			fsqf = 1;
++#endif
++			rxcount = STAR_GSW_MAX_RFD_NUM;
++			//set_bit(0, &is_qf);
++		}
++	}
++
++#ifndef CONFIG_STAR_GSW_NAPI
++	if (mode == 1) {
++		fsqf = 1;
++		rxcount = STAR_GSW_MAX_RFD_NUM;
++	}
++#endif
++
++	for (i = 0; i < rxcount; i++) {
++#ifdef CONFIG_STAR_GSW_NAPI
++		if (*work_done >= work_to_do)
++			break;
++		++(*work_done);
++#endif
++		if (rxdesc_ptr->cown != 0) {
++			// Alloc New skb_buff 
++			skb_ptr = star_gsw_alloc_skb();
++			// Check skb_buff
++			if (skb_ptr != NULL) {
++				star_gsw_get_rfd_buff(rxring.cur_index);
++				rxring.skb_ptr[rxring.cur_index] = skb_ptr;
++				rxdesc_ptr->data_ptr	= (u32)virt_to_phys(skb_ptr->data);
++				rxdesc_ptr->length	= MAX_PACKET_LEN;	
++				rxdesc_ptr->cown	= 0; // set cbit to 0 for CPU Transfer	
++			} else {
++				// TODO:
++				// I will add dev->lp.stats->rx_dropped, it will effect the performance
++				PDEBUG("%s: Alloc sk_buff fail, reuse the buffer\n", __FUNCTION__);
++				rxdesc_ptr->cown	= 0; // set cbit to 0 for CPU Transfer	
++				return;
++			}
++		}
++
++		if (rxring.cur_index == (STAR_GSW_MAX_RFD_NUM - 1)) {
++			rxring.cur_index	= 0;
++			rxdesc_ptr		= rxring.vir_addr;
++		} else {
++			rxring.cur_index++;
++			rxdesc_ptr++;
++		}
++	}
++
++#ifndef CONFIG_STAR_GSW_NAPI
++	if (fsqf) {
++		rxring.cur_index = fssd_index;
++		mb();
++		GSW_FS_DMA_START();
++	}
++#endif
++
++receive_packet_exit:
++	return;
++}
++
++#ifdef FREE_TX_SKB_MULTI
++#define MAX_TX_SKB_FREE_NUM     16
++#endif
++
++
++static int star_gsw_send_packet(struct sk_buff *skb, struct net_device *dev)
++{
++	struct star_gsw_private *priv = netdev_priv(dev);
++	STAR_GSW_TXDESC volatile *txdesc_ptr;
++	unsigned long flags;
++	u16 vlan_tag;
++
++#ifdef FREE_TX_SKB_MULTI
++	int i;
++	int tssd_index;
++	int tssd_current;
++	int skb_free_count = 0;
++	struct sk_buff *skb_free[MAX_TX_SKB_FREE_NUM];
++#endif
++
++
++#if defined(MAX_SKB_FRAGS) && defined(STAR_GSW_SG)
++	int org_index;
++	int cur_index;
++
++	unsigned int f;
++	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
++	unsigned int len = skb->len - skb->data_len;
++	unsigned int offset;
++
++#ifndef FREE_TX_SKB_MULTI
++	int skb_free_count = 0;
++	struct sk_buff *skb_free[MAX_SKB_FRAGS];
++#endif
++#else /* defined(MAX_SKB_FRAGS) && defined(STAR_GSW_SG) */
++#ifndef FREE_TX_SKB_MULTI
++	struct sk_buff *skb_free = NULL;
++#endif
++#endif /* defined(MAX_SKB_FRAGS) && defined(STAR_GSW_SG) */
++
++	HAL_GSW_TS_DMA_STOP();
++	spin_lock_irqsave(&star_gsw_send_lock, flags);
++
++#ifdef FREE_TX_SKB_MULTI
++	HAL_GSW_READ_TSSD(tssd_current);
++	tssd_index = (tssd_current - (u32)txring.phy_addr) >> 4;
++
++	if (tssd_index > txring.to_free_index) {
++		skb_free_count = tssd_index - txring.to_free_index;
++	} else if (tssd_index < txring.to_free_index) {
++		skb_free_count = STAR_GSW_MAX_TFD_NUM + tssd_index - txring.to_free_index;
++	}
++
++	if (skb_free_count >= MAX_TX_SKB_FREE_NUM) {
++		int count = 0;
++		for (i = 0; i < skb_free_count; i++) {
++			txdesc_ptr = txring.vir_addr + txring.to_free_index;
++			if (txdesc_ptr->cown == 0) {
++				break;
++			}
++			if (txring.skb_ptr[txring.to_free_index]) {
++				skb_free[count++] = txring.skb_ptr[txring.to_free_index];
++				txring.skb_ptr[txring.to_free_index] = NULL;
++			}
++			txring.to_free_index++;
++			if (txring.to_free_index == STAR_GSW_MAX_TFD_NUM) {
++				txring.to_free_index = 0;
++			}
++			if (count == MAX_TX_SKB_FREE_NUM) {
++				break;
++			}
++		}
++		skb_free_count = count;
++	} else {
++		skb_free_count = 0;
++	}
++#endif
++
++
++
++#if defined(MAX_SKB_FRAGS) && defined(STAR_GSW_SG)
++	org_index = txring.cur_index;
++	cur_index = txring.cur_index;
++	//printk("nr_frags: %d\n", nr_frags);
++	for (f = 0; f < (nr_frags + 1); f++) {
++		txdesc_ptr = txring.vir_addr + cur_index;
++
++		if (txdesc_ptr->cown == 0) {
++			spin_unlock_irqrestore(&star_gsw_send_lock, flags);
++			// re-queue the skb
++			return 1;
++		}
++
++#ifndef FREE_TX_SKB_MULTI
++		if (txring.skb_ptr[cur_index]) {
++			skb_free[skb_free_count++] = txring.skb_ptr[cur_index];
++#ifdef STAR_GSW_TIMER
++			txring.to_free_index = cur_index + 1;
++			if (txring.to_free_index == STAR_GSW_MAX_TFD_NUM) {
++				txring.to_free_index = 0;
++			}
++#endif
++		}
++#endif
++
++		if (f == 0) {
++			txdesc_ptr->fs		= 1;
++		} else {
++			txdesc_ptr->fs		= 0;
++		}
++		if (f == nr_frags) {
++			txdesc_ptr->ls		= 1;
++		} else {
++			txdesc_ptr->ls		= 0;
++		}
++
++#if 0
++		if (skb->protocol == __constant_htons(ETH_P_IP)) {
++			txdesc_ptr->ico = 1;
++			if (skb->nh.iph->protocol == IPPROTO_UDP) {
++				txdesc_ptr->uco = 1;
++				txdesc_ptr->tco = 0;
++			} else if (skb->nh.iph->protocol == IPPROTO_TCP) {
++				txdesc_ptr->uco = 0;
++				txdesc_ptr->tco = 1;
++			} else {
++				txdesc_ptr->uco = 0;
++				txdesc_ptr->tco = 0;
++			}
++		} else {
++			txdesc_ptr->ico = 0;
++			txdesc_ptr->uco = 0;
++			txdesc_ptr->tco = 0;
++		}
++#endif
++
++		txdesc_ptr->interrupt = 0;
++		txdesc_ptr->fr = 1;
++
++
++
++#ifdef CONFIG_STR9100_VLAN_BASE
++		if (priv->pmap==-1) {
++			txdesc_ptr->insv	= 1;
++			txdesc_ptr->pmap	= 1; // MAC0
++			if (dev == STAR_GSW_WAN_DEV) {
++				txdesc_ptr->vid	= VLAN0_GROUP_ID; 
++			} else {
++				txdesc_ptr->vid	= VLAN1_GROUP_ID; 
++			}
++		}
++#endif // CONFIG_STR9100_VLAN_BASE
++
++#ifdef CONFIG_STR9100_PORT_BASE
++		if (priv->pmap != -1) {
++			txdesc_ptr->insv	= 0;
++			txdesc_ptr->pmap	= priv->pmap;
++		}
++#endif
++
++		cur_index++;
++		if (cur_index == STAR_GSW_MAX_TFD_NUM) {
++			cur_index = 0;
++		}
++	} // end for (f = 0; f < (nr_frags + 1); f++) 
++
++	txdesc_ptr = (txring.vir_addr + txring.cur_index);
++	txdesc_ptr->data_ptr			= virt_to_phys(skb->data);
++	if ((nr_frags == 0) && (len < MIN_PACKET_LEN)) {
++		txdesc_ptr->length		= MIN_PACKET_LEN;
++		memset(skb->data + len, 0x00, MIN_PACKET_LEN - len);
++	} else {
++		txdesc_ptr->length		= len;
++	}
++	if (nr_frags) {
++		txring.skb_ptr[txring.cur_index]	= NULL;
++	} else {
++		txring.skb_ptr[txring.cur_index]	= skb;
++	}
++	dma_cache_maint(skb->data, txdesc_ptr->length, PCI_DMA_TODEVICE);
++
++#if 0
++	printk("txdesc_ptr : %x\n", txdesc_ptr);
++	printk("txdesc_ptr->length: %d\n", txdesc_ptr->length);
++	printk("txdesc_ptr->insv : %d\n", txdesc_ptr->insv);
++	printk("txdesc_ptr->pmap : %d\n", txdesc_ptr->pmap);
++	printk("txdesc_ptr->vid : %d\n", txdesc_ptr->vid);
++#endif
++
++	txring.cur_index++;
++	if (txring.cur_index == STAR_GSW_MAX_TFD_NUM) {
++		txring.cur_index = 0;
++	}
++
++	for (f = 0; f < nr_frags; f++) {
++		struct skb_frag_struct *frag; 
++		txdesc_ptr = txring.vir_addr + txring.cur_index;
++		frag = &skb_shinfo(skb)->frags[f]; 
++		len = frag->size; 
++		offset = frag->page_offset; 
++
++		txdesc_ptr->data_ptr		= virt_to_phys(page_address(frag->page) + offset);
++		txdesc_ptr->length		= len;
++		if (f == (nr_frags - 1)) {
++			txring.skb_ptr[txring.cur_index] = skb;
++		} else {
++			txring.skb_ptr[txring.cur_index] = NULL;
++		}
++		dma_cache_maint(page_address(frag->page) + offset, txdesc_ptr->length, PCI_DMA_TODEVICE);
++
++		txring.cur_index++;
++		if (txring.cur_index == STAR_GSW_MAX_TFD_NUM) {
++			txring.cur_index = 0;
++		}
++	}
++
++	for (f = 0; f < (nr_frags + 1); f++) {
++		txdesc_ptr = txring.vir_addr + org_index;
++
++		txdesc_ptr->cown = 0;
++
++		org_index++;
++		if (org_index == STAR_GSW_MAX_TFD_NUM) {
++			org_index = 0;
++		}
++	}
++
++#else // defined(MAX_SKB_FRAGS) && defined(STAR_GSW_SG)
++	txdesc_ptr = txring.vir_addr + txring.cur_index;
++
++
++	if (txdesc_ptr->cown == 0) { // This TFD is busy
++		spin_unlock_irqrestore(&star_gsw_send_lock, flags);
++		// re-queue the skb
++		return 1;
++	}
++
++	if (txdesc_ptr->data_ptr != 0) {
++		// MUST TODO: Free skbuff
++		dev_kfree_skb_any(txring.skb_ptr[txring.cur_index]);
++	}
++
++	/* clean dcache range  in order that data synchronization*/
++	txring.skb_ptr[txring.cur_index]	= skb;
++	txdesc_ptr->data_ptr			= virt_to_phys(skb->data);
++
++        if (skb->len < MIN_PACKET_LEN) {
++                txdesc_ptr->length              = MIN_PACKET_LEN;
++                memset(skb->data + skb->len, 0x00, MIN_PACKET_LEN - skb->len);
++        } else {
++                txdesc_ptr->length              = skb->len;
++        }
++
++ 
++
++        /* clean dcache range  in order that data synchronization*/
++        dma_cache_maint(skb->data, txdesc_ptr->length, PCI_DMA_TODEVICE);
++
++
++	// 20060922 descent
++	// if NIC MODE on
++	#ifdef CONFIG_NIC_MODE
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++	// do nothing
++#else
++        if ( ((GSW_SWITCH_CONFIG >> 30) & 0x1) ==1){
++		const char lan_tag[]={0x81, 0x00, 0x00, 0x01};
++		const char wan_tag[]={0x81, 0x00, 0x00, 0x02};
++		unsigned char	data; /* Data head pointer */
++
++		// insert vlan tag and move other byte to back
++		memmove(skb->data+16, skb->data + 12, skb->len-12);
++		skb->len+=4;
++
++                txdesc_ptr->length = skb->len;
++
++		if (dev == STAR_GSW_LAN_DEV) {
++			memcpy(skb->data+12, lan_tag, 4);
++		}
++		if (dev == STAR_GSW_WAN_DEV) {
++			memcpy(skb->data+12, wan_tag, 4);
++		}
++        	dma_cache_maint(skb->data, txdesc_ptr->length, PCI_DMA_TODEVICE);
++	}
++#endif //defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++	#endif // ifdef CONFIG_NIC_MODE
++	// 20060922 descent end
++
++	/*
++	* Basically, according to the result of the search of the destination 
++	* address in the routing table, the specific network interface will be 
++	* correctly selected
++	* According to the device entry index value, we can know the packet will 
++	* be destined for LAN port (port 0) or WAN port (port 1)
++	*
++	* Note:
++	* device entry index = 0 means local loopback network interface
++	* device entry index = 1 means GSW port 0 for LAN port network interface
++	* device entry index = 2 means GSW port 1 for WAN port network interface
++	* and also note:
++	* Force Route Port Map = 1 : GSW port 0
++	*                      = 2 : GSW port 1
++	*                      = 4 : GSW CPU port 
++	*/     
++
++
++	PDEBUG("\n00 priv->pmap: %d\n", priv->pmap);
++
++
++#ifdef CONFIG_STR9100_VLAN_BASE
++	PDEBUG("CONFIG_STR9100_VLAN_BASE\n");
++
++
++
++	if (priv->pmap==-1)
++	{
++		// 20060922 descent
++		// if NIC MODE on
++		#ifdef CONFIG_NIC_MODE
++       		if ( ((GSW_SWITCH_CONFIG >> 30) & 0x1) ==1)
++		{
++			txdesc_ptr->insv	= 0;
++		}
++		else
++		#endif
++		// 20060922 descent end
++		{
++			txdesc_ptr->insv	= 1;
++		}
++
++
++		PDEBUG("txdesc_ptr->insv	= 1;\n");
++
++
++
++
++		txdesc_ptr->pmap	= 1; // MAC0
++
++
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++	// let 8021Q insert vlan tag
++	// so insv set to 0
++	txdesc_ptr->insv	= 0;
++	#if 0
++        if (priv->vlgrp && vlan_tx_tag_present(skb)) {
++                //vlan_tag = cpu_to_be16(vlan_tx_tag_get(skb));
++                //vlan_tag = ntohl(vlan_tx_tag_get(skb));
++                //vlan_tag = (vlan_tx_tag_get(skb));
++                vlan_tag = cpu_to_le16(vlan_tx_tag_get(skb));
++		//printk("vlan_tag : %x\n", vlan_tag);
++		if (vlan_tag == 1) {
++			txdesc_ptr->vid	= VLAN1_GROUP_ID; // lan
++		}
++		if (vlan_tag == 2) {
++			txdesc_ptr->vid	= VLAN0_GROUP_ID; // wan
++		}
++	}
++	#endif
++#else // #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++
++
++
++		PDEBUG("txdesc_ptr->pmap = 1\n");
++		if (dev == STAR_GSW_WAN_DEV) {
++			txdesc_ptr->vid	= VLAN0_GROUP_ID; 
++			PDEBUG("VLAN0_GROUP_ID: %d\n", VLAN0_GROUP_ID);
++		} else {
++			txdesc_ptr->vid	= VLAN1_GROUP_ID; 
++			PDEBUG("VLAN1_GROUP_ID: %d\n", VLAN1_GROUP_ID);
++		}
++
++#endif // end #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++
++	}
++
++#endif // CONFIG_STR9100_VLAN_BASE
++
++#ifdef CONFIG_STR9100_PORT_BASE
++	if (priv->pmap != -1)
++	{
++		txdesc_ptr->insv	= 0;
++		PDEBUG("txdesc_ptr->insv        = 0;\n");
++		txdesc_ptr->pmap	= priv->pmap;
++		PDEBUG("txdesc_ptr->pmap	= priv->pmap;\n");
++	}
++	PDEBUG("CONFIG_STR9100_PORT_BASE\n");
++#endif
++	PDEBUG("txdesc_ptr->pmap: %d\n", txdesc_ptr->pmap);
++
++	txdesc_ptr->fr		= 1;
++
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++	if (star9100_shnat_pci_fp_forward_skb_ptr == 0) 
++		goto SEND_PACKET;
++	if(priv->pmap == PORT_BASE_PMAP_TUN_PORT){
++
++		struct iphdr *iph = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
++		star9100_arp_table volatile *arp_table;
++		u32			fp_gvid = 0;
++
++		arp_table = star9100_shnat_getarptable_hook(iph->saddr);
++		if(arp_table != NULL){
++			fp_gvid = arp_table->unused &= 0x7; 
++		}
++#if 0
++	   printk("[SEND PACKET] FP Path send_packet\n");
++#endif
++	   txdesc_ptr->fr = 0;
++	   txdesc_ptr->insv  = 1;
++	   txdesc_ptr->vid = fp_gvid;
++#if 0
++	   print_packet(skb->data,128);
++#endif
++	}
++#endif /*  CONFIG_STAR9100_SHNAT_PCI_FASTPATH */
++
++SEND_PACKET:
++
++	txdesc_ptr->fs		= 1;
++	txdesc_ptr->ls		= 1;
++	// Wake interrupt
++	txdesc_ptr->interrupt	= 0;
++	txdesc_ptr->cown	= 0;
++
++
++	if (txring.cur_index == (STAR_GSW_MAX_TFD_NUM - 1)) {
++		txring.cur_index = 0;
++	} else {
++		txring.cur_index++;
++	}
++	
++
++#endif // defined(MAX_SKB_FRAGS) && defined(STAR_GSW_SG)
++	mb();
++	GSW_TS_DMA_START();
++
++
++	priv->stats.tx_packets++;
++	priv->stats.tx_bytes += skb->len;
++	dev->trans_start = jiffies;
++
++sendpacket_exit:
++	spin_unlock_irqrestore(&star_gsw_send_lock, flags);
++
++#ifdef FREE_TX_SKB_MULTI
++	for (i = 0; i < skb_free_count; i++) {
++		dev_kfree_skb(skb_free[i]);
++	}
++#else
++#if defined(MAX_SKB_FRAGS) && defined(STAR_GSW_SG)
++	for (f = 0; f < skb_free_count; f++) {
++		dev_kfree_skb(skb_free[f]);
++	}
++#else
++	if (skb_free) {
++		dev_kfree_skb(skb_free);
++	}
++#endif
++#endif
++
++#ifdef STAR_GSW_TIMER
++	mod_timer(&star_gsw_timer, jiffies + 10);
++#endif
++
++
++
++
++	return 0;
++}
++
++// modify parameter type by descent.
++// move dev->dev_addr to set mac function.
++static void star_gsw_set_mac_addr(int index, struct net_device *dev, void *addr)
++{
++	const char *mac = ((struct sockaddr *)addr)->sa_data;
++	int mac_len = dev->addr_len;
++	gsw_arl_table_entry_t arl_table_entry;
++
++	memcpy(dev->dev_addr, mac, 6);
++
++	//printk("addr: %x:%x:%x:%x:%x:%x\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
++
++	// erase old mac
++	arl_table_entry.filter		= 0;
++	arl_table_entry.vlan_mac	= 1;
++	arl_table_entry.vlan_gid	= star_gsw_info.vlan[index].vlan_gid;
++	arl_table_entry.age_field	= 0x0; // invalid mean erase this entry
++	arl_table_entry.port_map	= star_gsw_info.vlan[index].vlan_group;
++	memcpy(arl_table_entry.mac_addr, star_gsw_info.vlan[index].vlan_mac, 6);
++	star_gsw_write_arl_table_entry(&arl_table_entry);
++
++	// copy new mac to star_gsw_info
++	memcpy(star_gsw_info.vlan[index].vlan_mac, mac, mac_len);
++	arl_table_entry.filter		= 0;
++	arl_table_entry.vlan_mac	= 1;
++	arl_table_entry.vlan_gid	= star_gsw_info.vlan[index].vlan_gid;
++	arl_table_entry.age_field	= 0x7;
++	arl_table_entry.port_map	= star_gsw_info.vlan[index].vlan_group;
++	memcpy(arl_table_entry.mac_addr, star_gsw_info.vlan[index].vlan_mac, 6);
++	star_gsw_write_arl_table_entry(&arl_table_entry);
++}
++
++#if 0
++static void star_gsw_set_mac_addr(int index, const char *mac, int mac_len)
++{
++	gsw_arl_table_entry_t arl_table_entry;
++
++	// erase old mac
++	arl_table_entry.filter		= 0;
++	arl_table_entry.vlan_mac	= 1;
++	arl_table_entry.vlan_gid	= star_gsw_info.vlan[index].vlan_gid;
++	arl_table_entry.age_field	= 0x0; // invalid mean erase this entry
++	arl_table_entry.port_map	= star_gsw_info.vlan[index].vlan_group;
++	memcpy(arl_table_entry.mac_addr, star_gsw_info.vlan[index].vlan_mac, 6);
++	star_gsw_write_arl_table_entry(&arl_table_entry);
++
++	// copy new mac to star_gsw_info
++	memcpy(star_gsw_info.vlan[index].vlan_mac, mac, mac_len);
++	arl_table_entry.filter		= 0;
++	arl_table_entry.vlan_mac	= 1;
++	arl_table_entry.vlan_gid	= star_gsw_info.vlan[index].vlan_gid;
++	arl_table_entry.age_field	= 0x7;
++	arl_table_entry.port_map	= star_gsw_info.vlan[index].vlan_group;
++	memcpy(arl_table_entry.mac_addr, star_gsw_info.vlan[index].vlan_mac, 6);
++	star_gsw_write_arl_table_entry(&arl_table_entry);
++}
++#endif
++
++
++static int star_gsw_set_lan_mac_addr(struct net_device *dev, void *addr)
++{
++	struct sockaddr *sock_addr = addr;
++	struct star_gsw_private *priv = netdev_priv(dev);
++
++	spin_lock_irq(&priv->lock);
++	star_gsw_set_mac_addr(LAN_GID, dev, addr);
++	//star_gsw_set_mac_addr(LAN_GID, sock_addr->sa_data, dev->addr_len);
++	//star_gsw_set_mac_addr(0, sock_addr->sa_data, dev->addr_len);
++	spin_unlock_irq(&priv->lock);
++
++	return 0;
++}
++
++static int star_gsw_set_wan_mac_addr(struct net_device *dev, void *addr)
++{
++	struct sockaddr *sock_addr = addr;
++	struct star_gsw_private *priv = netdev_priv(dev);
++
++	spin_lock_irq(&priv->lock);
++	star_gsw_set_mac_addr(WAN_GID, dev, addr);
++	spin_unlock_irq(&priv->lock);
++
++	return 0;
++}
++
++// current dorado2 use this function
++static int star_gsw_set_ewc_mac_addr(struct net_device *dev, void *addr)
++{
++	struct sockaddr *sock_addr = addr;
++	struct star_gsw_private *priv = netdev_priv(dev);
++
++	spin_lock_irq(&priv->lock);
++	//star_gsw_set_mac_addr(2, sock_addr->sa_data, dev->addr_len);
++	star_gsw_set_mac_addr(2, dev, addr);
++	spin_unlock_irq(&priv->lock);
++
++	return 0;
++}
++
++static void __init star_gsw_hw_init(void)
++{
++	u32 mac_port_config;
++	int i;
++	u32 cfg_reg = 0;
++
++	cfg_reg = PWRMGT_SOFTWARE_RESET_CONTROL;
++	// set reset bit to HIGH active;
++	cfg_reg |=0x10;
++	PWRMGT_SOFTWARE_RESET_CONTROL = cfg_reg;
++
++	//pulse delay
++	udelay(100);
++
++	// set reset bit to LOW active;
++	cfg_reg &=~0x10;
++	PWRMGT_SOFTWARE_RESET_CONTROL = cfg_reg;
++
++	//pulse delay
++	udelay(100);
++
++	// set reset bit to HIGH active;
++	cfg_reg |= 0x10;
++	PWRMGT_SOFTWARE_RESET_CONTROL = cfg_reg; 
++
++	for (i = 0; i < 1000; i++) {
++		cfg_reg = GSW_BIST_RESULT_TEST_0;
++		if ((cfg_reg & BIT(17))) {
++			break;
++		} else {
++			udelay(10);
++		}
++	}
++	// Set to defaule value
++	GSW_SWITCH_CONFIG = 0x007AA7A1;
++
++	// Set Mac port 0 to default value
++	GSW_MAC_PORT_0_CONFIG = 0x00423D80;
++
++	// Set Mac port 1 to default value
++	GSW_MAC_PORT_1_CONFIG = 0x00423D80;
++
++	// Set CPU port to default Value
++	GSW_CPU_PORT_CONFIG = 0x004C0000;
++
++	// Disable Port 0
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++	mac_port_config |= ((0x1 << 18)); 
++	GSW_MAC_PORT_0_CONFIG = mac_port_config; 
++
++	// Disable Port 1
++	mac_port_config = GSW_MAC_PORT_1_CONFIG;
++	mac_port_config |= ((0x1 << 18)); 
++	GSW_MAC_PORT_1_CONFIG = mac_port_config; 
++}
++
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++static int tundev_close(struct net_device *dev){
++	netif_stop_queue(dev);
++	printk("Close Orion Fast Path Tunnel Device \n");
++	return 0;
++}
++static int tundev_open(struct net_device *dev){
++	netif_start_queue(dev);
++	printk("Open Orion Fast Path Tunnel Device \n");
++	return 0;
++}
++static void tundev_init(struct net_device *dev){
++	return;
++}
++static int __init star_gsw_probe_tun(void){
++	struct net_device *netdev;
++	struct star_gsw_private *priv;
++	int err=0;
++
++	//netdev = alloc_netdev(sizeof(struct star_gsw_private),"fp",tundev_init);
++	netdev = alloc_etherdev(sizeof(struct star_gsw_private));
++	if (!netdev) {
++		err = -ENOMEM;
++		goto progend;
++	}
++
++	sprintf(netdev->name,"fp"); // force name
++
++	priv = netdev_priv(netdev);
++	memset(priv, 0, sizeof(struct star_gsw_private));
++	spin_lock_init(&priv->lock);
++
++	//netdev->base_addr			= IO_ADDRESS(GSW_BASE_ADDR);
++	netdev->base_addr			= 0;
++	netdev->stop				= tundev_close;
++	netdev->hard_start_xmit		= star_gsw_send_packet;
++	netdev->open				= tundev_open;
++        netdev->do_ioctl = gsw_do_ioctl;
++
++	//netdev->set_mac_address		= star_gsw_set_lan_mac_addr;
++
++	netdev->features			= NETIF_F_NO_CSUM;
++	netdev->hard_header			= NULL;
++	netdev->rebuild_header 		= NULL;
++	netdev->hard_header_cache	= NULL;
++	netdev->header_cache_update = NULL;
++	netdev->hard_header_parse   = NULL;
++	netdev->flags				= 0; // Don't need any flags
++	priv->pmap			= PORT_BASE_PMAP_TUN_PORT;
++
++
++
++	err = register_netdev(netdev);
++	if (err) {
++		free_netdev(netdev);
++		err = -ENOMEM;
++	}
++
++progend:
++	return err;
++}
++#endif
++
++
++static int __init star_gsw_probe(int port_type)
++{
++	struct net_device *netdev;
++	struct star_gsw_private *priv;
++	int err;
++        struct sockaddr sock_addr;
++
++
++	netdev = alloc_etherdev(sizeof(struct star_gsw_private));
++	if (!netdev) {
++		err = -ENOMEM;
++		goto err_alloc_etherdev;
++	}
++
++	SET_NETDEV_DEV(netdev, NULL);
++
++	priv = netdev_priv(netdev);
++	memset(priv, 0, sizeof(struct star_gsw_private));
++	spin_lock_init(&priv->lock);
++
++
++	//netdev->base_addr		= IO_ADDRESS(GSW_BASE_ADDR);
++	netdev->base_addr		= 0;
++	netdev->open			= star_gsw_open;
++	netdev->stop			= star_gsw_close;
++	netdev->hard_start_xmit		= star_gsw_send_packet;
++	netdev->tx_timeout		= star_gsw_timeout;
++	netdev->get_stats		= star_gsw_get_stats;
++#if defined(MAX_SKB_FRAGS) && defined(STAR_GSW_SG)
++	netdev->features		= NETIF_F_IP_CSUM | NETIF_F_SG;
++#elif defined(STAR_GSW_TX_HW_CHECKSUM)
++	netdev->features		= NETIF_F_IP_CSUM;
++#endif
++
++#ifdef CONFIG_STAR_GSW_NAPI
++	netif_napi_add(netdev, &priv->napi, star_gsw_poll, 64);
++#endif
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++	// do not let 8021Q module insert vlan tag
++	// can use the snippet code to get vlan tage
++	// if (priv->vlgrp && vlan_tx_tag_present(skb)) {
++	//   vlan_tag = cpu_to_be16(vlan_tx_tag_get(skb));
++        //netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
++        netdev->features |= NETIF_F_HW_VLAN_RX; // remove NETIF_F_HW_VLAN_TX flag that 8021Q module to insert vlan tag.
++
++        netdev->vlan_rx_register = gsw_vlan_rx_register;
++        netdev->vlan_rx_kill_vid = gsw_vlan_rx_kill_vid;
++#endif
++
++
++
++	switch (port_type) {
++	case LAN_PORT:
++		netdev->set_mac_address	= star_gsw_set_lan_mac_addr;
++	        memcpy(sock_addr.sa_data, star_gsw_info.vlan[LAN_GID].vlan_mac, 6);
++	        star_gsw_set_lan_mac_addr(netdev, &sock_addr);
++		//priv->pmap		= PMAP_PORT0;
++		//priv->pmap		= PORT_BASE_PORT0;
++		priv->pmap		= PORT_BASE_PMAP_LAN_PORT;
++		break;
++
++	case WAN_PORT:
++		//netdev->open		= star_gsw_wan_open;
++		netdev->set_mac_address	= star_gsw_set_wan_mac_addr;
++	        memcpy(sock_addr.sa_data, star_gsw_info.vlan[WAN_GID].vlan_mac, 6);
++	        star_gsw_set_wan_mac_addr(netdev, &sock_addr);
++		//priv->pmap		= PMAP_PORT1;
++		priv->pmap		= PORT_BASE_PMAP_WAN_PORT;
++		break;
++
++	case EWC_PORT:
++		//netdev->open		= star_gsw_ewc_open;
++		netdev->set_mac_address	= star_gsw_set_ewc_mac_addr;
++	        //memcpy(sock_addr.sa_data, star_gsw_info.vlan[WAN_GID].vlan_mac, 6);
++		//priv->pmap		= PMAP_PORT1;
++		priv->pmap		= PORT_BASE_PMAP_EWC_PORT;
++		break;
++
++	default:
++		break;
++	}
++
++	err = register_netdev(netdev);
++	if (err) {
++        printk("Register network dev :%s failed \n", netdev->name);
++		goto err_register_netdev;
++	}
++
++
++
++	switch (port_type) {
++	case LAN_PORT:
++		STAR_GSW_LAN_DEV = netdev;
++		break;
++
++	case WAN_PORT:
++		STAR_GSW_WAN_DEV = netdev;
++
++
++		break;
++
++	case EWC_PORT:
++		PDEBUG("create ewc port\n");
++		STAR_GSW_EWC_DEV = netdev;
++		break;
++
++	default:
++		break;
++	}
++
++#if 0 
++	if (net_dev_array[0] == 0) {
++		net_dev_array[0] = netdev;
++	}
++#endif
++	++all_netdevice;
++	return 0;
++
++err_register_netdev:
++	free_netdev(netdev);
++
++err_alloc_etherdev:
++	return err;
++}
++
++#ifdef LINUX26
++extern struct proc_dir_entry *str9100_proc_dir;
++static int __init star_gsw_proc_init(void)
++{
++        star_gsw_proc_entry = create_proc_entry("gsw", S_IFREG | S_IRUGO, str9100_proc_dir);
++        if (star_gsw_proc_entry) {
++                star_gsw_proc_entry->read_proc = star_gsw_read_proc;
++                star_gsw_proc_entry->write_proc = star_gsw_write_proc;
++        }
++        return 1;
++}
++#endif
++
++
++#ifdef LINUX24
++static int __init star_gsw_proc_init(void)
++{
++	struct proc_dir_entry *procdir=0;
++
++	const char proc_str[]="str9100";
++
++	//str9100_gsw_procdir=proc_mkdir(proc_str, NULL);
++	
++        procdir=create_proc_str9100(PROC_STR);
++
++        if (procdir)
++        {
++		star_gsw_proc_entry = create_proc_entry("gsw", S_IFREG | S_IRUGO, procdir);
++		if (star_gsw_proc_entry) {
++			star_gsw_proc_entry->read_proc = star_gsw_read_proc;
++			star_gsw_proc_entry->write_proc = star_gsw_write_proc;
++		}
++		return 1;
++        }
++	else
++		return -1;
++	
++
++
++}
++#endif
++
++static int star_gsw_notify_reboot(struct notifier_block *nb, unsigned long event, void *ptr)
++{
++	u32 mac_port_config;
++
++	/* stop the DMA engine */
++	GSW_TS_DMA_STOP();
++	GSW_FS_DMA_STOP();
++
++	// disable Port 0
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++	mac_port_config |= ((0x1 << 18)); 
++	GSW_MAC_PORT_0_CONFIG = mac_port_config; 
++
++	// disable Port 1
++	mac_port_config = GSW_MAC_PORT_1_CONFIG;
++	mac_port_config |= ((0x1 << 18)); 
++	GSW_MAC_PORT_1_CONFIG = mac_port_config; 
++
++	// disable all interrupt status sources
++	GSW_DISABLE_ALL_INTERRUPT_STATUS_SOURCES();
++
++	// clear previous interrupt sources
++	GSW_CLEAR_ALL_INTERRUPT_STATUS_SOURCES();
++
++	// disable all DMA-related interrupt sources
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_TSTC_BIT_INDEX);
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_FSRC_BIT_INDEX);
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_TSQE_BIT_INDEX);
++	INTC_DISABLE_INTERRUPT_SOURCE(INTC_GSW_FSQF_BIT_INDEX);
++
++	// clear previous interrupt sources
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_TSTC_BIT_INDEX);
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_FSRC_BIT_INDEX);
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_TSQE_BIT_INDEX);
++	INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_FSQF_BIT_INDEX);
++
++	return NOTIFY_DONE;
++}
++
++
++
++
++
++static int __init star_gsw_init_module(void)
++{
++	int err = 0;
++	u8 mac_num[6]; // get from flash
++
++	spin_lock_init(&star_gsw_send_lock);
++
++
++//#define CONFIG_GET_FLASH_MAC
++#ifdef CONFIG_GET_FLASH_MAC
++	char *mac_addr;
++
++	PRINT_INFO(KERN_INFO "%s", star_gsw_driver_version);
++	mac_addr=get_flash_env("ethaddr");
++	if (mac_addr)
++	{
++		printk("mac addr: %s\n", mac_addr);
++		printk("mac len: %d\n", strlen(mac_addr) );
++
++	}
++	sscanf(mac_addr ,"%x:%x:%x:%x:%x:%x", (unsigned int *)&mac_num[0], (unsigned int *)&mac_num[1], (unsigned int *)&mac_num[2], (unsigned int *)&mac_num[3], (unsigned int *)&mac_num[4], (unsigned int *)&mac_num[5]);
++	printk("flash mac : %x:%x:%x:%x:%x:%x\n", *mac_num,*(mac_num+1),*(mac_num+2), *(mac_num+3), *(mac_num+4), *(mac_num+5) );
++
++
++	memcpy(my_vlan0_mac, mac_num, 6);
++	++mac_num[5];
++	memcpy(my_vlan1_mac, mac_num, 6);
++	++mac_num[5];
++	memcpy(my_vlan2_mac, mac_num, 6);
++	++mac_num[5];
++	memcpy(my_vlan3_mac, mac_num, 6);
++
++
++
++#endif
++
++
++
++	star_gsw_hw_init();
++	err = star_gsw_buffer_alloc();
++	if (err != 0) {
++		return err;
++	}
++	star_gsw_vlan_init();
++	star_gsw_config_cpu_port();
++	init_switch();
++
++//#if 0
++	CREATE_NET_DEV0 
++	CREATE_NET_DEV1
++	CREATE_NET_DEV2
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++	CREATE_NET_DEV_AD
++#endif
++
++	str9100_gsw_config_mac_port0();
++	str9100_gsw_config_mac_port1();
++
++#ifdef CONFIG_STAR_GSW_NAPI
++	{
++		struct star_gsw_private *priv;
++		STAR_NAPI_DEV = alloc_etherdev(sizeof(struct star_gsw_private));
++		if (!STAR_NAPI_DEV) {
++			printk("Cannot allocate NAPI virtual device \n");
++			BUG();
++		}
++
++		priv = netdev_priv(STAR_NAPI_DEV);
++		memset(priv, 0, sizeof(struct star_gsw_private));
++
++		netif_napi_add(STAR_NAPI_DEV, &priv->napi , star_gsw_poll, 64);
++        dev_hold(STAR_NAPI_DEV);
++        set_bit(__LINK_STATE_START, &STAR_NAPI_DEV->state);
++		}
++#endif
++//#endif
++
++#if 0
++	star_gsw_lan_init();
++
++#ifndef CONFIG_STAR_GSW_TYPE_9109
++	star_gsw_wan_init();
++#endif
++#ifdef CONFIG_STAR_GSW_TYPE_EWC
++	star_gsw_ewc_init();
++#endif
++#endif
++
++	star_gsw_proc_init();
++
++	register_reboot_notifier(&star_gsw_notifier_reboot);
++#ifdef STAR_GSW_TIMER
++        init_timer(&star_gsw_timer);
++        star_gsw_timer.function = &star_gsw_timer_func;
++        star_gsw_timer.data = (unsigned long)NULL;
++#endif
++
++
++	return 0;
++}
++
++static void __exit star_gsw_exit_module(void)
++{
++	int i=0;
++
++#if 1
++	for (i=0 ; i < all_netdevice ; ++i) {
++		char netdev_name[20];
++		struct net_device * netdev=0;
++
++		sprintf(netdev_name, "eth%d", i);
++		//printk("net_dev_array[0]: %x\n", net_dev_array[0]);
++		netdev=__dev_get_by_name(&init_net, netdev_name);
++		// if no unregister_netdev and free_netdev,
++		// after remove module, ifconfig will hang.
++		#if 1
++		if (netdev) {
++			unregister_netdev(netdev);
++			free_netdev(netdev);
++		}
++		#endif
++	}
++#endif
++
++#ifdef CONFIG_STAR_GSW_NAPI
++	free_netdev(STAR_NAPI_DEV);
++#endif
++
++#if 0
++	unregister_netdev(STAR_GSW_LAN_DEV);
++	free_netdev(STAR_GSW_LAN_DEV);
++
++	unregister_netdev(STAR_GSW_WAN_DEV);
++	free_netdev(STAR_GSW_WAN_DEV);
++#endif
++	//unregister_netdev(STAR_GSW_EWC_DEV);
++	//free_netdev(STAR_GSW_EWC_DEV);
++
++	unregister_reboot_notifier(&star_gsw_notifier_reboot);
++	star_gsw_buffer_free(); 
++}
++
++
++// this snippet code ref 8139cp.c
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++void gsw_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
++{
++        struct star_gsw_private *priv = netdev_priv(dev);
++        unsigned long flags;
++
++        spin_lock_irqsave(&priv->lock, flags);
++	printk("gsw_vlan_rx_register\n");
++        priv->vlgrp = grp;
++        spin_unlock_irqrestore(&priv->lock, flags);
++}
++
++void gsw_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
++{
++        struct star_gsw_private *priv = netdev_priv(dev);
++        unsigned long flags;
++
++        spin_lock_irqsave(&priv->lock, flags);
++        if (priv->vlgrp)
++                priv->vlgrp->vlan_devices[vid] = NULL;
++        spin_unlock_irqrestore(&priv->lock, flags);
++}
++
++#endif
++
++//#define CONFIG_SWITCH_IOCTL
++#ifdef CONFIG_SWITCH_IOCTL
++
++/* ADD MAC into ARL */
++/***
++ * add_mac_into_arl  -  add extra(without hnat support) my mac in ARL table.
++ * 
++ * INPUTS:
++ *        gid    -   vlan group (0-7)
++ *        mac    -   mac address
++ * 
++ * OUTPUTS:
++ *        None
++ * 
++ * RETURNS:
++ *        void
++ ***/
++int add_mac_into_arl(u16 gid, u8 *mac)
++{
++        gsw_arl_table_entry_t arl_table_entry;
++
++        arl_table_entry.filter          = 0;
++        arl_table_entry.vlan_mac        = 1;    // the MAC in this table entry is MY VLAN MAC 
++        arl_table_entry.vlan_gid        = gid;
++        arl_table_entry.age_field       = 0x7;  // static entry
++        arl_table_entry.port_map        = star_gsw_info.vlan[gid].vlan_group;
++        memcpy(arl_table_entry.mac_addr, mac, 6); 
++
++        if (!star_gsw_write_arl_table_entry(&arl_table_entry)) {
++                //DEBUG_MSG(WARNING_MSG, "star_gsw_write_arl_table_entry fail\n");
++                return 1;
++        }
++
++        return 0; 
++}
++
++/* DEL MAC from ARL*/
++//void del_my_vlan_mac_2argu(u8 gid, u8 *mac)
++/***
++ * star_gsw_del_arl_table - delete my mac from ARL table
++ * 
++ * INPUTS:
++ *        mac      - mac address
++ *        vlan_gid - gid value 
++ * 
++ * OUTPUTS:
++ *        None
++ * 
++ * RETURNS:
++ *        0		-   successful
++ *
++ ***/
++void del_mac_from_arl(u8 gid, u8 *mac)
++{
++    gsw_arl_table_entry_t arl_table_entry;
++
++    // erase old mac
++    arl_table_entry.filter        = 0;
++    arl_table_entry.vlan_mac    = 1;
++    //arl_table_entry.vlan_gid    = star_gsw_info.vlan[gid].vlan_gid;
++    arl_table_entry.vlan_gid    = gid;
++    arl_table_entry.age_field    = 0x0; // invalid mean erase this entry
++    arl_table_entry.port_map    = star_gsw_info.vlan[gid].vlan_group;
++    memcpy(arl_table_entry.mac_addr, mac, 6);
++    star_gsw_write_arl_table_entry(&arl_table_entry);
++}
++
++
++/***
++ * del_my_vlan_mac  -  delete my mac of default setting from ARL table.
++ * 
++ * INPUTS:
++ *        gid    -   vlan group (0-7)
++ * 
++ * OUTPUTS:
++ *        None
++ * 
++ * RETURNS:
++ *        void
++ ***/
++void del_my_vlan_mac(u8 gid)
++{
++    gsw_arl_table_entry_t arl_table_entry; 
++
++    // erase old mac
++    arl_table_entry.filter        = 0; 
++    arl_table_entry.vlan_mac    = 1;
++    arl_table_entry.vlan_gid    = gid;
++    arl_table_entry.age_field    = 0x0; // invalidate this entry 
++    arl_table_entry.port_map    = star_gsw_info.vlan[gid].vlan_group;
++    memcpy(arl_table_entry.mac_addr, star_gsw_info.vlan[gid].vlan_mac, 6);
++    star_gsw_write_arl_table_entry(&arl_table_entry);
++}
++
++/***
++ * config_my_vlan_mac  -  change my mac default setting, according to 
++ * gid and vid value.
++ * 
++ * INPUTS:
++ *        gid    -   vlan group (0-7)
++ *        vid    -   vlan id (12 bits)
++ *        mac    -   mac address
++ * 
++ * OUTPUTS:
++ *        None
++ * 
++ * RETURNS:
++ *        0  -  successful
++ *        1  -  fail
++ ***/
++int config_my_vlan_mac(u16 gid, u16 vid, u8 *mac)
++{
++	gsw_arl_table_entry_t arl_table_entry; 
++
++        star_gsw_info.vlan[gid].vlan_gid          = gid;
++        star_gsw_info.vlan[gid].vlan_vid          = vid;
++        star_gsw_info.vlan[gid].vlan_group        = (PORT0 | CPU_PORT); // this case always (PORT0 | CPU_PORT)
++        star_gsw_info.vlan[gid].vlan_tag_flag     = 0;
++        memcpy(star_gsw_info.vlan[gid].vlan_mac, mac, 6);
++
++
++
++	arl_table_entry.filter          = 0;
++        arl_table_entry.vlan_mac        = 1;    // the MAC in this table entry is MY VLAN MAC
++        arl_table_entry.vlan_gid        = star_gsw_info.vlan[gid].vlan_gid;
++        arl_table_entry.age_field       = 0x7;  // static entry
++        arl_table_entry.port_map        = star_gsw_info.vlan[gid].vlan_group;
++        memcpy(arl_table_entry.mac_addr, star_gsw_info.vlan[gid].vlan_mac, 6);
++
++        if (!star_gsw_write_arl_table_entry(&arl_table_entry)) {
++		//DEBUG_MSG(WARNING_MSG, "star_gsw_write_arl_table_entry fail\n");
++        	return 1;
++        }
++
++	return 0;
++}
++
++#endif // end CONFIG_SWITCH_IOCTL
++
++// reference e100.c
++static int gsw_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
++{
++	printk("gsw_do_ioctl\n");
++	return 0;
++}
++
++
++MODULE_AUTHOR("Star Corporation, <tech@starsemi.com>");
++MODULE_DESCRIPTION("Star Switch Driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_VERSION);
++
++
++
++module_init(star_gsw_init_module);
++module_exit(star_gsw_exit_module);
++
+diff -rupN linux-2.6.35.11/drivers/net/str9100/star_gsw_config.h linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_config.h
+--- linux-2.6.35.11/drivers/net/str9100/star_gsw_config.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_config.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,288 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __STAR_GSW_CONFIG_H__
++#define __STAR_GSW_CONFIG_H__
++
++
++// add by descent 2006/07/05
++// this debug macro reference linux device drivers, 2e
++
++
++// 20060922 descent
++// in dorado, if NIC mode on, and use ARL search, need enable STR9100_GSW_FAST_AGE_OUT
++// NIC mode is experiment, don't recommand use it.
++#define CONFIG_NIC_MODE
++
++// 20060922 descent end
++
++//#define STR9100_GSW_DEBUG
++
++
++#ifdef SHOW_DEBUG_MESSAGE
++
++#define NORMAL_MSG 1
++#define WARNING_MSG (1 << 1)
++#define CRITICAL_MSG (1 << 2)
++
++#define DEBUG_MSG(msg_level, fmt, args...)\
++{ \
++        int i=0; \
++\
++        for(i=0 ; i < 3 ; ++i) { \
++                if ((MSG_LEVEL & msg_level) >> i) \
++                        printk (KERN_INFO "*str9100_gsw_debug* " fmt, ## args); \
++        } \
++}
++
++#endif
++
++
++
++// direction is "TX" or "RX"
++#define PRINT_PACKET(data, len, direction) \
++{ \
++	printk(direction); \
++	print_packet(data, len); \
++}
++
++#undef PDEBUG
++  #ifdef STR9100_GSW_DEBUG
++    #ifdef __KERNEL__
++      #define PDEBUG(fmt, args...) printk (KERN_INFO "*str9100_gsw_debug* " fmt, ## args)
++      //#define PDEBUG printk 
++    #else
++      #define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
++    #endif // __KERNEL__
++  #else
++    #define PDEBUG(fmt, args...)
++  #endif
++
++#undef PDEBUGG
++#define PDEBUGG(fmt, args...)
++
++// 20061103 descent
++//#define CONFIG_CONF_VID
++// 20061103 descent end
++
++
++// modify by descent 2006/07/05
++// use for print needed message
++#if 1
++#define PRINT_INFO printk 
++#else
++#define PRINT_INFO(arg...)
++#endif
++
++
++#define CONFIG_STAR_GSW_NAPI
++
++// add by descent 2006/07/07
++// in star_gsw_get_rfd_buff
++// if define CONFIG_STAR_GSW_BRIDGE drop no packets
++// else drop invalid packets.
++
++
++#include <linux/config.h>
++#ifdef CONFIG_BRIDGE // reference linux config network bridge
++#define CONFIG_STAR_GSW_BRIDGE
++#endif
++
++// add by descent 2006/07/05
++// 1 mean rate controll on
++// 0 mean rate controll off
++#define STR9100_GSW_BROADCAST_RATE_CONTROL 0
++#define STR9100_GSW_MULTICAST_RATE_CONTROL 0
++#define STR9100_GSW_UNKNOW_PACKET_RATE_CONTROL 0
++
++// 1 mean forwarding off
++// 0 mean forwarding on
++#define STR9100_GSW_DISABLE_FORWARDING_BROADCAST_PACKET 0
++#define STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET 0
++#define STR9100_GSW_DISABLE_FORWARDING_UNKNOW_PACKET 0
++
++//#define STR9100_GSW_FAST_AGE_OUT
++
++#define STAR_GSW_TX_HW_CHECKSUM
++#define STAR_GSW_RX_HW_CHECKSUM
++
++
++//#define STAR_GSW_TIMER
++//#define FREE_TX_SKB_MULTI
++#define STAR_GSW_SG
++#if defined(STAR_GSW_SG) && !defined(STAR_GSW_TX_HW_CHECKSUM)
++#define STAR_GSW_TX_HW_CHECKSUM
++#endif
++
++
++//#define ADJUSTMENT_TX_RX_SKEW
++//#define STAR_GSW_STATUS_ISR
++#define STAR_GSW_FSQF_ISR
++
++
++// adjust MAX_PEND_INT_CNT and MAX_PEND_TIME at run time.
++//#define CHANGE_DELAY_INT
++
++#define STAR_GSW_DELAYED_INTERRUPT
++
++#define MAX_PEND_INT_CNT	0x06
++#define MAX_PEND_TIME		0x20
++
++/*
++ * This tag is for 9102 + 9109 Case only, and 9102's MAC0 Connect ot 9102's MAC1
++ */
++#ifdef CONFIG_STAR_GSW_TYPE_EWC
++#define CONFIG_STAR_GSW_TYPE_ONEARM "y"
++#undef CONFIG_SERCOMM_VSC7385
++#endif
++
++#if 0
++
++#define VLAN0_GROUP_ID			(0)
++#define VLAN1_GROUP_ID			(1)
++#define VLAN2_GROUP_ID			(2)
++#define VLAN3_GROUP_ID			(3)
++#define VLAN4_GROUP_ID			(4)
++#define VLAN5_GROUP_ID			(5)
++#define VLAN6_GROUP_ID			(6)
++#define VLAN7_GROUP_ID			(7)
++
++
++
++
++
++#ifdef CONFIG_STAR_GSW_TYPE_ONEARM
++#ifdef CONFIG_SERCOMM_VSC7385
++#define VLAN0_VID			(0x1)
++#define VLAN1_VID			(0x2)
++#define VLAN2_VID			(0x3)
++#define VLAN3_VID			(0x4)
++#define VLAN4_VID			(0x5)
++#define VLAN5_VID			(0x6)
++#define VLAN6_VID			(0x7)
++#define VLAN7_VID			(0x8)
++#else
++#define VLAN0_VID			(0x2)
++#define VLAN1_VID			(0x1)
++#define VLAN2_VID			(0x3)
++#define VLAN3_VID			(0x4)
++#define VLAN4_VID			(0x5)
++#define VLAN5_VID			(0x6)
++#define VLAN6_VID			(0x7)
++#define VLAN7_VID			(0x8)
++#endif
++#else
++#define VLAN0_VID			(0x111)
++#define VLAN1_VID			(0x222)
++#define VLAN2_VID			(0x333)
++#define VLAN3_VID			(0x444)
++#define VLAN4_VID			(0x555)
++#define VLAN5_VID			(0x666)
++#define VLAN6_VID			(0x777)
++#define VLAN7_VID			(0x888)
++#endif
++
++#define PORT0				(1 << 0)	/* bit map : bit 0 */
++#define PORT1				(1 << 1)	/* bit map : bit 1 */
++#define CPU_PORT			(1 << 2)	/* bit map : bit 2 */
++
++#ifdef CONFIG_STAR_GSW_TYPE_ONEARM
++#define VLAN0_GROUP			(PORT0 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#ifdef CONFIG_STAR_GSW_TYPE_EWC
++#define VLAN2_GROUP			(PORT1 | CPU_PORT)
++#define VLAN3_GROUP			(PORT1 | CPU_PORT)
++#else
++#define VLAN2_GROUP			(0)
++#define VLAN3_GROUP			(0)
++#endif
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#ifdef CONFIG_STAR_GSW_TYPE_EWC
++#define VLAN7_GROUP			(PORT1 | CPU_PORT)
++#else
++#define VLAN7_GROUP			(0)
++#endif
++
++#else
++#define VLAN0_GROUP			(PORT0 | PORT1 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(PORT1 | CPU_PORT)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++#endif
++
++#ifdef CONFIG_STAR_GSW_TYPE_ONEARM
++
++#ifdef CONFIG_HAVE_VLAN_TAG
++
++#define VLAN0_VLAN_TAG			(5)	// cpu port and mac 0 port
++#define VLAN1_VLAN_TAG			(5)	// cpu port and mac 0 port
++
++#else
++#define VLAN0_VLAN_TAG			(1)	// only mac 0 port
++#define VLAN1_VLAN_TAG			(1)	// only mac 0 port
++#endif
++
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#ifdef CONFIG_STAR_GSW_TYPE_EWC
++#define VLAN7_VLAN_TAG			(0)	// MAC1 don't need Tag
++#else
++#define VLAN7_VLAN_TAG			(0)
++#endif
++#else
++#define VLAN0_VLAN_TAG			(0)
++#define VLAN1_VLAN_TAG			(0)
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++#endif
++
++
++#define PORT0_PVID			(VLAN1_GROUP_ID)
++#define PORT1_PVID			(VLAN2_GROUP_ID)
++#define CPU_PORT_PVID			(VLAN0_GROUP_ID)
++
++#endif
++
++#define MAX_PACKET_LEN			(1536)
++
++/* 
++ * Maximum Transmit/Receive Frame Descriptors for GSW's MAC frame
++ * the value of tx/rx set to 40/48 is suggested.
++ */
++#define STAR_GSW_MAX_TFD_NUM		40
++#define STAR_GSW_MAX_RFD_NUM		48
++
++#endif /* __STAR_GSW_CONFIG_H__ */
+diff -rupN linux-2.6.35.11/drivers/net/str9100/star_gsw.h linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw.h
+--- linux-2.6.35.11/drivers/net/str9100/star_gsw.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,682 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef STAR_GSW_H
++#define STAR_GSW_H
++
++#include "star_gsw_phy.h"
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/bootmem.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/interrupt.h>
++#include <linux/ptrace.h>
++#include <linux/ioport.h>
++#include <linux/in.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++#include <linux/reboot.h>
++#include <asm/bitops.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <asm/hardware.h>
++#include <linux/pci.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/ip.h>
++#include <linux/if_ether.h>
++#include <linux/icmp.h>
++#include <linux/udp.h>
++#include <linux/tcp.h>
++#include <linux/if_arp.h>
++#include <net/arp.h>
++
++#if defined(LINUX24)
++#include <asm/arch/str9100/star_gsw.h>
++#include <asm/arch/str9100/star_gpio.h>
++#include <asm/arch/str9100/star_powermgt.h>
++#endif
++
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++#include <linux/if_vlan.h>
++#endif
++
++
++
++
++#include "star_gsw_config.h"
++
++#ifndef BIT
++#define BIT(x)		((1 << (x)))
++#endif
++
++#define LAN_PORT	1
++#define WAN_PORT	2
++#define EWC_PORT	3
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++
++#define TUN_PORT	4
++#define PMAP_TUN_PORT	8
++#define CREATE_NET_DEV_AD star_gsw_probe_tun();
++#define PORT_BASE_PMAP_TUN_PORT	PMAP_TUN_PORT
++#else
++#define CREATE_NET_DEV_AD
++#define PORT_BASE_PMAP_TUN_PORT
++#endif
++
++
++// add by descent 2006/07/10
++#define PMAP_PORT0	1
++#define PMAP_PORT1	2
++#define PMAP_CPU_PORT	4
++
++
++/*
++ * macro declarations
++ */
++#define GSW_SET_PORT0_PVID(port0_pvid) \
++{ \
++	((GSW_VLAN_PORT_PVID) &= (~(0x7 << 0))); \
++	((GSW_VLAN_PORT_PVID) |= ((port0_pvid) & 0x07)); \
++}
++
++#define GSW_SET_PORT1_PVID(port1_pvid) \
++{ \
++	((GSW_VLAN_PORT_PVID) &= (~(0x7 << 4))); \
++	((GSW_VLAN_PORT_PVID) |= (((port1_pvid) & 0x07) << 4)); \
++}
++
++#define GSW_SET_CPU_PORT_PVID(cpu_port_pvid) \
++{ \
++	((GSW_VLAN_PORT_PVID) &= (~(0x7 << 8))); \
++	((GSW_VLAN_PORT_PVID) |= (((cpu_port_pvid) & 0x07) << 8)); \
++}
++
++#define GSW_SET_VLAN_0_VID(vid) \
++{ \
++	((GSW_VLAN_VID_0_1) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_0_1) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_1_VID(vid) \
++{ \
++	((GSW_VLAN_VID_0_1) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_0_1) |= (((vid) & 0xFFF) << 12)); \
++}
++
++#define GSW_SET_VLAN_2_VID(vid) \
++{ \
++	((GSW_VLAN_VID_2_3) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_2_3) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_3_VID(vid) \
++{ \
++	((GSW_VLAN_VID_2_3) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_2_3) |= (((vid) & 0xFFF) << 12)); \
++}
++
++#define GSW_SET_VLAN_4_VID(vid) \
++{ \
++	((GSW_VLAN_VID_4_5) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_4_5) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_5_VID(vid) \
++{ \
++	((GSW_VLAN_VID_4_5) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_4_5) |= (((vid) & 0xFFF) << 12)); \
++}
++
++#define GSW_SET_VLAN_6_VID(vid) \
++{ \
++	((GSW_VLAN_VID_6_7) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_6_7) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_7_VID(vid) \
++{ \
++	((GSW_VLAN_VID_6_7) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_6_7) |= (((vid) & 0xFFF) << 12)); \
++}
++
++#define GSW_SET_VLAN_0_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 0))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 0)); \
++}
++
++#define GSW_SET_VLAN_1_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 3))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 3)); \
++}
++
++#define GSW_SET_VLAN_2_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 6))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 6)); \
++}
++
++#define GSW_SET_VLAN_3_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 9))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 9)); \
++}
++
++#define GSW_SET_VLAN_4_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 12))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 12)); \
++}
++
++#define GSW_SET_VLAN_5_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 15))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 15)); \
++}
++
++#define GSW_SET_VLAN_6_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 18))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 18)); \
++}
++
++#define GSW_SET_VLAN_7_MEMBER(vlan_member) \
++{ \
++	((GSW_VLAN_MEMBER_PORT_MAP) &= (~(0x7 << 21))); \
++	((GSW_VLAN_MEMBER_PORT_MAP) |= (((vlan_member) & 0x7) << 21)); \
++}
++
++#define GSW_SET_VLAN_0_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 0))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 0)); \
++}
++
++#define GSW_SET_VLAN_1_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 3))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 3)); \
++}
++
++#define GSW_SET_VLAN_2_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 6))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 6)); \
++}
++
++#define GSW_SET_VLAN_3_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 9))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 9)); \
++}
++
++#define GSW_SET_VLAN_4_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 12))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 12)); \
++}
++
++#define GSW_SET_VLAN_5_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 15))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 15)); \
++}
++
++#define GSW_SET_VLAN_6_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 18))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 18)); \
++}
++
++#define GSW_SET_VLAN_7_TAG(vlan_tag) \
++{ \
++	((GSW_VLAN_TAG_PORT_MAP) &= (~(0x7 << 21))); \
++	((GSW_VLAN_TAG_PORT_MAP) |= (((vlan_tag) & 0x7) << 21)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_0_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_0_1) &= (~(0xFFFF << 0))); \
++	((GSW_PPPOE_SESSION_ID_0_1) |= (((session_id) & 0xFFFF) << 0)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_1_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_0_1) &= (~(0xFFFF << 16))); \
++	((GSW_PPPOE_SESSION_ID_0_1) |= (((session_id) & 0xFFFF) << 16)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_2_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_2_3) &= (~(0xFFFF << 0))); \
++	((GSW_PPPOE_SESSION_ID_2_3) |= (((session_id) & 0xFFFF) << 0)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_3_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_2_3) &= (~(0xFFFF << 16))); \
++	((GSW_PPPOE_SESSION_ID_2_3) |= (((session_id) & 0xFFFF) << 16)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_4_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_4_5) &= (~(0xFFFF << 0))); \
++	((GSW_PPPOE_SESSION_ID_4_5) |= (((session_id) & 0xFFFF) << 0)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_5_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_4_5) &= (~(0xFFFF << 16))); \
++	((GSW_PPPOE_SESSION_ID_4_5) |= (((session_id) & 0xFFFF) << 16)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_6_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_6_7) &= (~(0xFFFF << 0))); \
++	((GSW_PPPOE_SESSION_ID_6_7) |= (((session_id) & 0xFFFF) << 0)); \
++}
++
++#define GSW_SET_PPPOE_SESSION_7_ID(session_id) \
++{ \
++	((GSW_PPPOE_SESSION_ID_6_7) &= (~(0xFFFF << 16))); \
++	((GSW_PPPOE_SESSION_ID_6_7) |= (((session_id) & 0xFFFF) << 16)); \
++}
++
++#define GSW_READ_INTERRUPT_STATUS(int_status) \
++	((int_status) = (GSW_INTERRUPT_STATUS))
++
++#define GSW_CLEAR_ALL_INTERRUPT_STATUS_SOURCES()\
++	((GSW_INTERRUPT_STATUS) = (0x00001FFF))
++
++#define GSW_CLEAR_INTERRUPT_STATUS_SOURCES(source) \
++	((GSW_INTERRUPT_STATUS) |= (source))
++
++#define GSW_CLEAR_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++	((GSW_INTERRUPT_STATUS) |= (1 << (source_bit_index)))
++
++#define GSW_DISABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++	((GSW_INTERRUPT_MASK) = (0x00001FFF))
++
++#define GSW_ENABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++	((GSW_INTERRUPT_MASK) = (0x00000000))
++
++#define GSW_DISABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++	((GSW_INTERRUPT_MASK) |= (1 << (source_bit_index)))
++
++#define GSW_ENABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++	((GSW_INTERRUPT_MASK) &= ~(1 << (source_bit_index)))
++
++#define GSW_TS_DMA_START() \
++	((GSW_TS_DMA_CONTROL) = (1))
++
++#define GSW_TS_DMA_STOP() \
++	((GSW_TS_DMA_CONTROL) = (0))
++
++#define GSW_READ_TS_DMA_STATE(state) \
++	((state) = (GSW_TS_DMA_CONTROL))
++
++#define GSW_FS_DMA_START() \
++	((GSW_FS_DMA_CONTROL) = (1))
++
++#define GSW_FS_DMA_STOP() \
++	((GSW_FS_DMA_CONTROL) = (0))
++
++#define GSW_WRITE_TSSD(tssd_value) \
++	((GSW_TS_DESCRIPTOR_POINTER) = (tssd_value))
++
++#define GSW_READ_TSSD(tssd_value) \
++	((tssd_value) = (GSW_TS_DESCRIPTOR_POINTER))
++
++#define GSW_WRITE_FSSD(fssd_value) \
++	((GSW_FS_DESCRIPTOR_POINTER) = (fssd_value))
++
++#define GSW_READ_FSSD(fssd_value) \
++	((fssd_value) = (GSW_FS_DESCRIPTOR_POINTER))
++
++#define GSW_WRITE_TS_BASE(ts_base_value) \
++	((GSW_TS_DESCRIPTOR_BASE_ADDR) = (ts_base_value))
++
++#define GSW_READ_TS_BASE(ts_base_value) \
++	((ts_base_value) = (GSW_TS_DESCRIPTOR_BASE_ADDR))
++
++#define GSW_WRITE_FS_BASE(fs_base_value) \
++	((GSW_FS_DESCRIPTOR_BASE_ADDR) = (fs_base_value))
++
++#define GSW_READ_FS_BASE(fs_base_value) \
++	((fs_base_value) = (GSW_FS_DESCRIPTOR_BASE_ADDR))
++
++/*
++ * HNAT macros defines
++ */
++#define GSW_WRITE_HNAT_CONFIGURATION(hnat_config) \
++	((GSW_HNAT_CONFIG) = (hnat_config))
++
++#define GSW_READ_HNAT_CONFIGURATION(hnat_config) \
++	((hnat_config) = (GSW_HNAT_CONFIG))
++
++#define GSW_WRITE_PRIVATE_IP_BASE(ip_base) \
++	((GSW_HNAT_PRIVATE_IP_BASE) = (ip_base & 0x000FFFFF))
++
++#define GSW_WRITE_HNAT_FW_RULE_START_INDEX(rule_start_index) \
++	((GSW_HNAT_FW_RULE_START_ADDR) = (rule_start_index & 0x1FF))
++
++#define GSW_WRITE_HNAT_FW_RULE_END_INDEX(rule_end_index) \
++	((GSW_HNAT_FW_RULE_END_ADDR) = (rule_end_index & 0x1FF))
++
++#define GSW_READ_HNAT_FW_RULE_START_INDEX(rule_start_index) \
++	((rule_start_index) = ((GSW_HNAT_FW_RULE_START_ADDR) & 0x1FF))
++
++#define GSW_READ_HNAT_FW_RULE_END_INDEX(rule_end_index) \
++	((rule_end_index) = ((GSW_HNAT_FW_RULE_END_ADDR) & 0x1FF))
++
++#define GSW_WRITE_HNAT_FL_RULE_START_INDEX(rule_start_index) \
++	((GSW_HNAT_FL_RULE_START_ADDR) = (rule_start_index & 0x1FF))
++
++#define GSW_WRITE_HNAT_FL_RULE_END_INDEX(rule_end_index) \
++	((GSW_HNAT_FL_RULE_END_ADDR) = (rule_end_index & 0x1FF))
++
++#define GSW_READ_HNAT_FL_RULE_START_INDEX(rule_start_index) \
++	((rule_start_index) = ((GSW_HNAT_FL_RULE_START_ADDR) & 0x1FF))
++
++#define GSW_READ_HNAT_FL_RULE_END_INDEX(rule_end_index) \
++	((rule_end_index) = ((GSW_HNAT_FL_RULE_END_ADDR) & 0x1FF))
++
++#define GSW_WRITE_HNAT_ALG_START_INDEX(rule_start_index) \
++	((GSW_HNAT_ALG_START_ADDR) = (rule_start_index & 0x1FF))
++
++#define GSW_WRITE_HNAT_ALG_END_INDEX(rule_end_index) \
++	((GSW_HNAT_ALG_END_ADDR) = (rule_end_index & 0x1FF))
++
++#define GSW_READ_HNAT_ALG_START_INDEX(rule_start_index) \
++	((rule_start_index) = ((GSW_HNAT_ALG_START_ADDR) & 0x1FF))
++
++#define GSW_READ_HNAT_ALG_END_INDEX(rule_end_index) \
++	((rule_end_index) = ((GSW_HNAT_ALG_END_ADDR) & 0x1FF))
++
++#define GSW_WRITE_HNAT_SIP_START_INDEX(rule_start_index) \
++	((GSW_HNAT_SIP_BASE_ADDR) = (rule_start_index & 0x1FF))
++
++#define GSW_READ_HNAT_SIP_START_INDEX(rule_start_index) \
++	((rule_start_index) = ((GSW_HNAT_SIP_BASE_ADDR) & 0x1FF))
++
++#define GSW_WRITE_HNAT_NAPT_BASE_ADDR(base_addr) \
++	((GSW_HNAT_NAPT_BASE_ADDR) = (base_addr))
++
++#define GSW_READ_HNAT_NAPT_BASE_ADDR(base_addr) \
++	((base_addr) = (GSW_HNAT_NAPT_BASE_ADDR))
++
++#define GSW_WRITE_HNAT_NAPT_PORT_BASE(port_base) \
++	((GSW_HNAT_NAPT_PORT_BASE) = (port_base & 0xFFFF))
++
++#define GSW_WRITE_HNAT_ARP_BASE_ADDR(base_addr) \
++	((GSW_HNAT_ARP_BASE_ADDR) = (base_addr))
++
++#define GSW_READ_HNAT_ARP_BASE_ADDR(base_addr) \
++	((base_addr) = (GSW_HNAT_ARP_BASE_ADDR))
++
++//---------------------------------------------------
++//      STAR9100   INTC  macro define
++//---------------------------------------------------
++/*
++ * macro declarations
++ */
++#define INTC_ENABLE_INTERRUPT_SOURCE(source_bit_index) \
++	(INTC_INTERRUPT_MASK) &= (~(1 << source_bit_index))
++
++#define INTC_DISABLE_INTERRUPT_SOURCE(source_bit_index) \
++	(INTC_INTERRUPT_MASK) |= ((1 << source_bit_index))
++
++#define INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(source_bit_index) \
++	(INTC_INTERRUPT_CLEAR_EDGE_TRIGGER) |= ((1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_EDGE_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_MODE) |= ((1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_LEVEL_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_MODE) &= (~(1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_RISING_EDGE_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_LEVEL) &= (~(1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_FALLING_EDGE_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_LEVEL) |= ((1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_ACTIVE_HIGH_LEVEL_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_LEVEL) &= (~(1 << source_bit_index))
++
++#define INTC_SET_INTERRUPT_ACTIVE_LOW_LEVEL_TRIGGER(source_bit_index) \
++	(INTC_INTERRUPT_TRIGGER_LEVEL) |= ((1 << source_bit_index))
++
++#define INTC_ASSIGN_INTERRUPT_TO_IRQ(source_bit_index) \
++	(INTC_FIQ_MODE_SELECT) &= (~(1 << source_bit_index))
++
++#define INTC_ASSIGN_INTERRUPT_TO_FIQ(source_bit_index) \
++	(INTC_FIQ_MODE_SELECT) |= ((1 << source_bit_index))
++
++/*-------------------------------------------------*/
++//                       PHY define
++/*-------------------------------------------------*/
++#define PHY_CONTROL_REG_ADDR		0x00
++#define PHY_STATUA_REG_ADDR		0x01
++#define PHY_ID1_REG_ADDR		0x02
++#define PHY_ID2_REG_ADDR		0x03
++#define PHY_AN_ADVERTISEMENT_REG_ADDR	0x04
++#define PHY_AN_REAMOTE_CAP_REG_ADDR	0x05
++#define PHY_RESERVED1_REG_ADDR		0x10
++#define PHY_RESERVED2_REG_ADDR		0x11
++#define PHY_CH_STATUS_OUTPUT_REG_ADDR	0x12
++#define PHY_RESERVED3_REG_ADDR		0x13
++#define PHY_RESERVED4_REG_ADDR		0x14
++
++#define PHY_LSI_L84225_ID1		0x0016
++#define PHY_LSI_L84225_ID2		0xF840	// 0xF870????
++
++//--------------------------------------------------------
++//         STAR9100 Hnat related define
++//--------------------------------------------------------
++/*Define for status print for Inerrrupt Status Register */
++#define INT_PORT0_Q_FULL		BIT(0)
++#define INT_PORT1_Q_FULL		BIT(1)
++#define INT_CPU_Q_FULL			BIT(2)
++#define INT_HNAT_Q_FULL			BIT(3)
++#define INT_GLOBAL_Q_FULL		BIT(4)
++#define INT_BUFFER_FULL			BIT(5)
++#define INT_PORT_STATUS_CHG		BIT(6)
++#define INT_INTRUDER0			BIT(7)
++#define INT_INTRUDER1			BIT(8)
++#define INT_CPU_HOLD			BIT(9)
++#define INT_PORT0_UNKNOWN_VLAN		BIT(10)
++#define INT_PORT1_UNKNOWN_VLAN		BIT(11)
++#define INT_CPU_UNKNOWN_VLAN		BIT(12)
++#define INT_PORT0_NO_LINK_DROP		BIT(16)
++#define INT_PORT0_BCS_DROP		BIT(17)
++#define INT_PORT0_RX_CRC_DROP		BIT(18)
++#define INT_PORT0_JAMED_DROP		BIT(19)
++#define INT_PORT0_QUEUE_DROP		BIT(20)
++#define INT_PORT0_RMC_DROP		BIT(21)
++#define INT_PORT0_LOCAL_DROP		BIT(22)
++#define INT_PORT0_INGRESS_DROP		BIT(23)
++#define INT_PORT1_NO_LINK_DROP		BIT(24)
++#define INT_PORT1_BCS_DROP		BIT(25)
++#define INT_PORT1_RX_CRC_DROP		BIT(26)
++#define INT_PORT1_JAMED_DROP		BIT(27)
++#define INT_PORT1_QUEUE_DROP		BIT(28)
++#define INT_PORT1_RMC_DROP		BIT(29)
++#define PORT1_LOCAL_DROP		BIT(30)
++#define PORT1_INGRESS_DROP		0x80000000
++
++#define MAX_VLAN_NUM			(8)
++#define MAX_PORT_NUM			(3)	/* including port 0, port 1, and CPU port */
++
++typedef struct _vlan_config_ {
++	u32	vlan_gid;	/* 3-bit VLAN group ID */
++	u32	vlan_vid;	/* 12-bit VLAN ID */
++	u32	vlan_group;	/* 3-bit VLAN group port map */
++	u32	vlan_tag_flag;	/* 3-bit VLAN tag port map */
++	u8	vlan_mac[6];
++	u8	pad[2];
++} vlan_config_t;
++
++typedef struct _port_config_ {
++	u32	pvid;	/* 3-bit Port PVID */
++	u32	config_flag;
++	u32	status_flag;
++} port_config_t;
++
++typedef struct _gsw_info_ {
++	vlan_config_t vlan[MAX_VLAN_NUM];
++	port_config_t port[MAX_PORT_NUM];
++} gsw_info_t;
++
++/* store this information for the driver.. */
++struct star_gsw_private {
++	struct net_device_stats stats;
++	spinlock_t lock;
++	/* Note:
++	 * device entry pmap = 0 means local loopback network interface
++	 * device entry pmap = 1 means GSW port 0 for LAN port network interface
++	 * device entry pmap = 2 means GSW port 1 for WAN port network interface
++	 * device entry pmap = 4 means GSW cpu port
++	 */
++	int pmap;
++	struct napi_struct  napi;
++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
++        struct vlan_group               *vlgrp;
++#endif
++
++};
++
++#define __REG(reg)	(*(u32 volatile *)(reg))
++
++/*
++ * Network Driver, Receive/Send and Initial Buffer Function
++ */
++typedef struct {
++	// 1st 32Bits
++	u32 data_ptr;
++
++	// 2nd  32Bits
++	u32 length:16;
++	u32 tco:1;
++	u32 uco:1;
++	u32 ico:1;
++	u32 pmap:3;
++	u32 fr:1;
++	u32 pri:3;
++	u32 fp:1;
++	u32 interrupt:1;
++	u32 ls:1;
++	u32 fs:1;
++	u32 eor:1;
++	u32 cown:1;
++
++	// 3rd 32Bits
++	u32 vid:3;
++	u32 insv:1;
++	u32 sid:3;
++	u32 inss:1;
++	u32 unused:24;
++
++	// 4th 32Bits
++	u32 unused2;
++
++} __attribute__((packed)) STAR_GSW_TXDESC;
++
++typedef struct {
++	// 1st 32Bits
++	u32 data_ptr;
++
++	// 2nd  32Bits
++	u32 length:16;
++	u32 l4f:1;
++	u32 ipf:1;
++	u32 prot:2;
++	u32 hr:6;
++	u32 sp:2;
++	u32 ls:1;
++	u32 fs:1;
++	u32 eor:1;
++	u32 cown:1;
++
++	// 3rd 32Bits
++	u32 unused;
++
++	// 4th 32Bits
++	u32 unused2;
++
++} __attribute__((packed)) STAR_GSW_RXDESC;
++
++/* 
++ * Transmit Frame Descriptor Ring for TFDS
++ */
++
++typedef struct {
++	u32			phy_addr;
++	STAR_GSW_TXDESC		*vir_addr;
++	unsigned int		cur_index; // TX's current will point to Free Descriptors
++	struct sk_buff		*skb_ptr[STAR_GSW_MAX_TFD_NUM]; // TX's sk_buff ptr
++#if defined(FREE_TX_SKB_MULTI) || defined(STAR_GSW_TIMER)
++        u32                     to_free_index;
++#endif
++
++} TXRING_INFO;
++/* 
++ * Receive Frame Descriptor Ring for RFDS
++ */
++
++typedef struct {
++	u32			phy_addr;
++	STAR_GSW_RXDESC		*vir_addr;
++	u32			cur_index;
++	struct sk_buff		*skb_ptr[STAR_GSW_MAX_RFD_NUM];	// RX's sk_buff ptr
++} RXRING_INFO;
++
++extern void str9100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++/*
++ * data structure defines
++ */
++typedef struct _gsw_arl_table_entry_
++{
++    u32    filter;
++    u32    vlan_mac;
++    u32    vlan_gid;
++    u32    age_field;
++    u32    port_map;
++    u8     mac_addr[6];
++    u8     pad[2];
++
++} gsw_arl_table_entry_t;
++
++#endif
++
+diff -rupN linux-2.6.35.11/drivers/net/str9100/star_gsw_phy.c linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_phy.c
+--- linux-2.6.35.11/drivers/net/str9100/star_gsw_phy.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_phy.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,1224 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include "star_gsw_phy.h"
++#include "star_gsw.h"
++#include "star_gsw_config.h"
++
++
++#if 0
++void init_switch()
++{
++        u32 sw_config;
++
++	PDEBUG("init_switch\n");
++        /*
++         * Configure GSW configuration
++         */
++        sw_config = GSW_SWITCH_CONFIG;
++
++#if 0
++        // orignal virgon configuration
++        // enable fast aging
++        sw_config |= (0xF);
++
++        // CRC stripping
++        sw_config |= (0x1 << 21);
++
++        // IVL learning
++        sw_config |= (0x1 << 22);
++
++        // HNAT disable
++        sw_config &= ~(0x1 << 23);
++
++        GSW_SWITCH_CONFIG = sw_config;
++
++        sw_config = GSW_SWITCH_CONFIG;
++#endif
++
++        /* configure switch */
++        sw_config = GSW_SWITCH_CONFIG;
++
++        sw_config &= ~0xF;      /* disable aging */
++        sw_config |= 0x1;       /* disable aging */
++
++#ifdef JUMBO_ENABLE
++
++        // CRC stripping and GSW_CFG_MAX_LEN_JMBO
++        sw_config |= (GSW_CFG_CRC_STRP | GSW_CFG_MAX_LEN_JMBO);
++#else
++        // CRC stripping and 1536 bytes
++        sw_config |= (GSW_CFG_CRC_STRP | GSW_CFG_MAX_LEN_1536);
++#endif
++
++        /* IVL */
++        sw_config |= GSW_CFG_IVL;
++
++        /* disable HNAT */
++        sw_config &= ~GSW_CFG_HNAT_EN;
++
++        GSW_SWITCH_CONFIG = sw_config;
++}
++#endif
++
++
++
++
++
++
++// add by descent 2006/07/05
++// for configure packet forward and rate control
++void init_packet_forward(int port)
++{
++	u32 mac_port_config;
++
++	PDEBUG("port%d configure\n", port);
++	if (port==0)
++		mac_port_config = GSW_MAC_PORT_0_CONFIG;
++	if (port==1)
++		mac_port_config = GSW_MAC_PORT_1_CONFIG;
++	if (STR9100_GSW_BROADCAST_RATE_CONTROL)
++		mac_port_config |=  (0x1 << 31); // STR9100_GSW_BROADCAST_RATE_CONTROLL on
++	else
++		mac_port_config &=  (~(0x1 << 31)); // STR9100_GSW_BROADCAST_RATE_CONTROLL off
++
++	if (STR9100_GSW_MULTICAST_RATE_CONTROL)
++		mac_port_config |=  (0x1 << 30); // STR9100_GSW_MULTICAST_RATE_CONTROLL on
++	else
++		mac_port_config &=  (~(0x1 << 30)); // STR9100_GSW_MULTICAST_RATE_CONTROLL off
++
++	if (STR9100_GSW_UNKNOW_PACKET_RATE_CONTROL)
++		mac_port_config |=  (0x1 << 29); // STR9100_GSW_UNKNOW_PACKET_RATE_CONTROLL on
++	else
++		mac_port_config &=  (~(0x1 << 29)); // STR9100_GSW_UNKNOW_PACKET_RATE_CONTROLL off
++
++
++	if (STR9100_GSW_DISABLE_FORWARDING_BROADCAST_PACKET)
++		mac_port_config |=  (0x1 << 27); // STR9100_GSW_DISABLE_FORWARDING_BROADCAST_PACKET on
++	else
++		mac_port_config &=  (~(0x1 << 27)); // STR9100_GSW_DISABLE_FORWARDING_BROADCAST_PACKET off
++
++	if(STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET)
++	{
++		mac_port_config |=  (0x1 << 26); // STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET on
++		PDEBUG("STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET on\n");
++	}
++	else
++	{
++		mac_port_config &=  (~(0x1 << 26)); // STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET off
++		PDEBUG("STR9100_GSW_DISABLE_FORWARDING_MULTICAST_PACKET off\n");
++	}
++
++	if(STR9100_GSW_DISABLE_FORWARDING_UNKNOW_PACKET)
++		mac_port_config |=  (0x1 << 25); // STR9100_GSW_DISABLE_FORWARDING_UNKNOW_PACKET on
++	else
++		mac_port_config &=  (~(0x1 << 25)); // STR9100_GSW_DISABLE_FORWARDING_UNKNOW_PACKET off
++
++	//GSW_MAC_PORT_0_CONFIG = mac_port_config;
++	if (port==0)
++		GSW_MAC_PORT_0_CONFIG = mac_port_config;
++	if (port==1)
++		GSW_MAC_PORT_1_CONFIG = mac_port_config;
++}
++
++static int star_gsw_set_phy_addr(u8 mac_port, u8 phy_addr)
++{
++	u32 status = 0;	/* for failure indication */
++
++	if ((mac_port > 1) || (phy_addr > 31)) {
++		return status;
++	}
++
++	if (mac_port == 0) {
++		GSW_PORT_MIRROR &= ~(0x3 << 0); /* clear bit[1:0] for PHY_ADDR[1:0] */
++		GSW_PORT_MIRROR &= ~(0x3 << 4); /* clear bit[5:4] for PHY_ADDR[3:2] */
++		GSW_QUEUE_STATUS_TEST_1 &= ~(0x1 << 25); /* clear bit[25] for PHY_ADDR[4] */
++		GSW_PORT_MIRROR |= (((phy_addr >> 0) & 0x3) << 0);
++		GSW_PORT_MIRROR |= (((phy_addr >> 2) & 0x3) << 4);
++		GSW_QUEUE_STATUS_TEST_1 |= (((phy_addr >> 4) & 0x1) << 25);
++		status = 1; /* for ok indication */
++	} else if (mac_port == 1) {
++		GSW_PORT_MIRROR &= ~(0x1 << 6); /* clear bit[6] for PHY_ADDR[0] */
++		GSW_PORT_MIRROR &= ~(0x7 << 8); /* clear bit[10:8] for PHY_ADDR[3:1] */
++		GSW_QUEUE_STATUS_TEST_1 &= ~(0x1 << 26); /* clear bit[26] for PHY_ADDR[4] */
++		GSW_PORT_MIRROR |= (((phy_addr >> 0) & 0x1) << 6);
++		GSW_PORT_MIRROR |= (((phy_addr >> 1) & 0x7) << 8);
++		GSW_QUEUE_STATUS_TEST_1 |= (((phy_addr >> 4) & 0x1) << 26);
++		status = 1; /* for ok indication */
++	}
++
++	return status;
++}
++
++static int star_gsw_read_phy(u8 phy_addr, u8 phy_reg, u16 *read_data)
++{
++	u32 status;
++	int i;
++
++	// clear previous rw_ok status
++	GSW_PHY_CONTROL = (0x1 << 15);
++
++        // 20061013 descent 
++	// for ORION EOC
++        GSW_QUEUE_STATUS_TEST_1 &= ~( 0XF << 16);
++
++        GSW_PHY_CONTROL   &= ~(0x1<<0);
++
++        GSW_QUEUE_STATUS_TEST_1 |= (((phy_addr >> 1) & 0xF) << 16);
++        // 20061013 descent end
++
++
++	GSW_PHY_CONTROL = ((phy_addr & 0x1) | ((phy_reg & 0x1F) << 8) | (0x1 << 14));
++
++	for (i = 0; i < 0x1000; i++) {
++		status = GSW_PHY_CONTROL;
++		if (status & (0x1 << 15)) {
++			// clear the rw_ok status, and clear other bits value
++			GSW_PHY_CONTROL = (0x1 << 15);
++			*read_data = (u16) ((status >> 16) & 0xFFFF);
++			return (1);
++		} else {
++			udelay(10);
++		}
++	}
++
++	return (0);
++}
++
++static int star_gsw_write_phy(u8 phy_addr, u8 phy_reg, u16 write_data)
++{
++	int i;
++
++	// clear previous rw_ok status
++	GSW_PHY_CONTROL = (0x1 << 15);
++
++        // 20061013 descent 
++	// for ORION EOC
++        GSW_QUEUE_STATUS_TEST_1 &= ~( 0XF << 16);
++
++        GSW_PHY_CONTROL   &= ~(0x1<<0);
++
++        GSW_QUEUE_STATUS_TEST_1 |= (((phy_addr >> 1) & 0xF) << 16);
++        // 20061013 descent end
++
++
++	GSW_PHY_CONTROL = ((phy_addr & 0x1) |
++		((phy_reg & 0x1F) << 8) |
++		(0x1 << 13) | ((write_data & 0xFFFF) << 16));
++
++	for (i = 0; i < 0x1000; i++) {
++		if ((GSW_PHY_CONTROL) & (0x1 << 15)) {
++			// clear the rw_ok status, and clear other bits value
++			GSW_PHY_CONTROL = (0x1 << 15);
++			return (1);
++		} else {
++			udelay(10);
++		}
++	}
++
++	return (0);
++}
++
++#ifdef DORADO2_PCI_FASTPATH_MAC_PORT1_LOOPBACK
++static int star_gsw_config_mac_port1_loopback(void)
++{
++	u32 mac_port_base;
++	u32 mac_port_config;
++	int i;
++
++	PRINT_INFO("\nconfigure mac port1 loopback\n");
++	
++	mac_port_base = GSW_PORT1_CFG_REG;
++
++	mac_port_config = __REG(mac_port_base);
++
++	// disable PHY's AN
++	mac_port_config &= ~(0x1 << 7);
++
++	// enable RGMII-PHY mode
++	mac_port_config |= (0x1 << 15);
++
++	// reversed RGMII mode
++	mac_port_config |= (0x1 << 14);
++
++	// enable GSW MAC port 0
++	mac_port_config &= ~(0x1 << 18);
++
++	__REG(mac_port_base) = mac_port_config;
++
++	// SA learning disable
++	mac_port_config |= (0x1 << 19);
++
++	// disable TX flow control
++	mac_port_config &= ~(0x1 << 12);
++
++	// disable RX flow control
++	mac_port_config &= ~(0x1 << 11);
++
++	// force duplex
++	mac_port_config |= (0x1 << 10);
++
++	// force speed at 1000Mbps
++	mac_port_config &= ~(0x3 << 8);
++	mac_port_config |= (0x2 << 8);
++
++	__REG(mac_port_base) = mac_port_config;
++
++	// adjust MAC port 1 RX/TX clock skew
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 28) | (0x3 << 30));
++	//GSW_BIST_RESULT_TEST_0 |= ((0x2 << 28) | (0x2 << 30));
++	GSW_BIST_RESULT_TEST_0 |= (0x2 << 30);
++
++	return 0;
++}
++#endif
++
++int VSC8201_phy_power_down(int phy_addr, int y)
++{
++	u16 phy_data = 0;
++	// power-down or up the PHY
++	star_gsw_read_phy(phy_addr, 0, &phy_data);
++	if (y==1) // down
++		phy_data |= (0x1 << 11);
++	if (y==0) // up
++		phy_data |= (~(0x1 << 11));
++	star_gsw_write_phy(phy_addr, 0, phy_data);
++	return 0;
++
++}
++
++static int star_gsw_config_VSC8201(u8 mac_port, u8 phy_addr)	// include cicada 8201
++{
++	u32 mac_port_base = 0;
++	u32 mac_port_config;
++	u16 phy_reg;
++	int i;
++
++	PRINT_INFO("\nconfigure VSC8201\n");
++	PDEBUG("mac port : %d phy addr : %d\n", mac_port, phy_addr);
++	/*
++	 * Configure MAC port 0
++	 * For Cicada CIS8201 single PHY
++	 */
++	if (mac_port == 0) {
++		PDEBUG("port 0\n");
++		mac_port_base = GSW_PORT0_CFG_REG;
++	}
++	if (mac_port == 1) {
++		PDEBUG("port 1\n");
++		mac_port_base = GSW_PORT1_CFG_REG;
++	}
++
++	star_gsw_set_phy_addr(mac_port, phy_addr);
++	//star_gsw_set_phy_addr(1, 1);
++
++	mac_port_config = __REG(mac_port_base);
++
++	// enable PHY's AN
++	mac_port_config |= (0x1 << 7);
++
++	// enable RGMII-PHY mode
++	mac_port_config |= (0x1 << 15);
++
++	// enable GSW MAC port 0
++	mac_port_config &= ~(0x1 << 18);
++
++	__REG(mac_port_base)=  mac_port_config;
++
++	/*
++	 * Configure Cicada's CIS8201 single PHY
++	 */
++	/* 2007.04.24 Richard.Liu Marked, we don't need VSC8201 lookback mode */
++#if 0
++#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++	/* near-end loopback mode */
++	star_gsw_read_phy(phy_addr, 0x0, &phy_reg);
++	phy_reg |= (0x1 << 14);
++	star_gsw_write_phy(phy_addr, 0x0, phy_reg);
++#endif
++#endif
++
++	star_gsw_read_phy(phy_addr, 0x1C, &phy_reg);
++
++	// configure SMI registers have higher priority over MODE/FRC_DPLX, and ANEG_DIS pins
++	phy_reg |= (0x1 << 2);
++
++	star_gsw_write_phy(phy_addr, 0x1C, phy_reg);
++
++	star_gsw_read_phy(phy_addr, 0x17, &phy_reg);
++
++	// enable RGMII MAC interface mode
++	phy_reg &= ~(0xF << 12);
++	phy_reg |= (0x1 << 12);
++
++	// enable RGMII I/O pins operating from 2.5V supply
++	phy_reg &= ~(0x7 << 9);
++	phy_reg |= (0x1 << 9);
++
++	star_gsw_write_phy(phy_addr, 0x17, phy_reg);
++
++	star_gsw_read_phy(phy_addr, 0x4, &phy_reg);
++
++	// Enable symmetric Pause capable
++	phy_reg |= (0x1 << 10);
++
++	star_gsw_write_phy(phy_addr, 0x4, phy_reg);
++
++	mac_port_config = __REG(mac_port_base);
++
++	/* 2007.04.24 Richard.Liu Marked, we don't need VSC8201 lookback mode */
++//#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++#if 0
++	// near-end loopback mode, must disable AN
++	mac_port_config &= ~(0x1 << 7);
++
++	// SA learning disable
++	mac_port_config |= (0x1 << 19);
++
++	// disable TX flow control
++	mac_port_config &= ~(0x1 << 12);
++
++	// disable RX flow control
++	mac_port_config &= ~(0x1 << 11);
++
++	// force duplex
++	mac_port_config |= (0x1 << 10);
++
++	// force speed at 1000Mpbs
++	mac_port_config &= ~(0x3 << 8);
++	mac_port_config |= (0x2 << 8);
++#else
++	// enable PHY's AN
++	mac_port_config |= (0x1 << 7);
++#endif
++
++	__REG(mac_port_base) = mac_port_config;
++
++	/*
++	 * Enable PHY1 AN restart bit to restart PHY1 AN
++	 */
++	star_gsw_read_phy(phy_addr, 0x0, &phy_reg);
++
++	phy_reg |= (0x1 << 9) | (0x1 << 12);
++
++	star_gsw_write_phy(phy_addr, 0x0, phy_reg);
++
++	/*
++	 * Polling until PHY0 AN restart is complete
++	 */
++	for (i = 0; i < 0x1000; i++) {
++		star_gsw_read_phy(phy_addr, 0x1, &phy_reg);
++
++		if ((phy_reg & (0x1 << 5)) && (phy_reg & (0x1 << 2))) {
++			printk("0x1 phy reg: %x\n", phy_reg);
++			break;
++		} else {
++			udelay(100);
++		}
++	}
++
++	mac_port_config = __REG(mac_port_base);
++
++	if (((mac_port_config & 0x1) == 0) || (mac_port_config & 0x2)) {
++		printk("Check MAC/PHY%s Link Status : DOWN!\n", (mac_port == 0 ? "0" : "1"));
++	} else {
++		printk("Check MAC/PHY%s Link Status : UP!\n", (mac_port == 0 ? "0" : "1"));
++		/*
++		 * There is a bug for CIS8201 PHY operating at 10H mode, and we use the following
++		 * code segment to work-around
++		 */
++		star_gsw_read_phy(phy_addr, 0x05, &phy_reg);
++
++		if ((phy_reg & (0x1 << 5)) && (!(phy_reg & (0x1 << 6))) && (!(phy_reg & (0x1 << 7))) && (!(phy_reg & (0x1 << 8)))) {	/* 10H,10F/100F/100H off */
++			star_gsw_read_phy(phy_addr, 0x0a, &phy_reg);
++
++			if ((!(phy_reg & (0x1 << 10))) && (!(phy_reg & (0x1 << 11)))) {	/* 1000F/1000H off */
++				star_gsw_read_phy(phy_addr, 0x16, &phy_reg);
++
++				phy_reg |= (0x1 << 13) | (0x1 << 15);	// disable "Link integrity check(B13)" & "Echo mode(B15)"
++
++				star_gsw_write_phy(phy_addr, 0x16, phy_reg);
++			}
++		}
++	}
++
++	if (mac_port == 0) {
++		// adjust MAC port 0 RX/TX clock skew
++		GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 24) | (0x3 << 26));
++		GSW_BIST_RESULT_TEST_0 |= ((0x2 << 24) | (0x2 << 26));
++	}
++
++	if (mac_port == 1) {
++		// adjust MAC port 1 RX/TX clock skew
++		GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 28) | (0x3 << 30));
++		GSW_BIST_RESULT_TEST_0 |= ((0x2 << 28) | (0x2 << 30));
++	}
++
++	return 0;
++}
++
++// add by descent 2006/07/10
++// port : 0 => port0 ; port : 1 => port1
++// y = 1 ; disable AN
++int disable_AN(int port, int y)
++{
++	u32 mac_port_config;
++	if (port==0)
++		mac_port_config = GSW_MAC_PORT_0_CONFIG;
++	if (port==1)
++		mac_port_config = GSW_MAC_PORT_1_CONFIG;
++	// disable PHY's AN
++	if (y==1)
++	{
++	  PDEBUG("disable AN\n");
++	  mac_port_config &= ~(0x1 << 7);
++	}
++
++	// enable PHY's AN
++	if (y==0)
++	{
++	  PDEBUG("enable AN\n");
++	  mac_port_config |= (0x1 << 7);
++	}
++
++	if (port==0)
++		GSW_MAC_PORT_0_CONFIG = mac_port_config;
++	if (port==1)
++		GSW_MAC_PORT_1_CONFIG = mac_port_config;
++	return 0;
++}
++
++int disable_AN_VSC7385(int y)
++{
++	u32 mac_port_config;
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++	// disable PHY's AN
++	if (y==1)
++	{
++	  PDEBUG("disable AN\n");
++	  mac_port_config &= ~(0x1 << 7);
++	}
++
++	// enable PHY's AN
++	if (y==0)
++	{
++	  PDEBUG("enable AN\n");
++	  mac_port_config |= (0x1 << 7);
++	}
++
++	GSW_MAC_PORT_0_CONFIG = mac_port_config;
++	return 0;
++}
++
++void star_gsw_config_VSC7385(void)
++{
++	u32 mac_port_config;
++
++
++	printk("\nconfigure VSC7385\n");
++	/*
++	 * Configure GSW's MAC port 0
++	 * For ASIX's 5-port GbE Switch setting
++	 * 1. No SMI (MDC/MDIO) connection between Orion's MAC port 0 and ASIX's MAC port 4
++	 * 2. Force Orion's MAC port 0 to be 1000Mbps, and full-duplex, and flow control on
++	 */
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++
++	// enable RGMII-PHY mode
++	mac_port_config |= (0x1 << 15);
++
++	// force speed = 1000Mbps
++	mac_port_config &= ~(0x3 << 8);
++	mac_port_config |= (0x2 << 8);
++
++	// force full-duplex
++	mac_port_config |= (0x1 << 10);
++
++	// force Tx/Rx flow-control on
++	mac_port_config |= (0x1 << 11) | (0x1 << 12);
++
++	GSW_MAC_PORT_0_CONFIG = mac_port_config;
++
++	udelay(1000);
++
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++	if (((mac_port_config & 0x1) == 0) || (mac_port_config & 0x2)) {
++		printk("Check MAC/PHY 0 Link Status : DOWN!\n");
++	} else {
++		printk("Check MAC/PHY 0 Link Status : UP!\n");
++	}
++
++	/* adjust MAC port 0 /RX/TX clock skew */
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 24) | (0x3 << 26));
++	GSW_BIST_RESULT_TEST_0 |= ((0x2 << 24) | (0x2 << 26));
++}
++
++
++
++void star_gsw_config_ASIX()
++{
++	u32 mac_port_config;
++
++	printk("configure port0 ASIX\n");
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++	//Disable AN
++	mac_port_config &= (~(0x1 << 7));
++
++	//force speed to 1000Mbps
++	mac_port_config &= (~(0x3 << 8));
++	mac_port_config |= (0x2 << 8);	//jacky
++
++	//force tx and rx follow control
++	mac_port_config |= (0x1 << 11) | (0x1 << 12);
++
++	//force full deplex
++	mac_port_config |= 0x1 << 10;
++
++	//RGMII ENABLR
++	mac_port_config |= 0x1 << 15;
++
++	GSW_MAC_PORT_0_CONFIG = mac_port_config;
++
++	udelay(1000);
++
++	/* adjust MAC port 0 RX/TX clock skew */
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 24) | (0x3 << 26));
++	GSW_BIST_RESULT_TEST_0 |= ((0x2 << 24) | (0x2 << 26));
++	
++	// configure MAC port 0 pad drive strength = 10/100 mode
++	*(u32 volatile *) (0xf770001C) |= (0x1 << 2);
++}
++
++
++
++// agere power down/up
++int AGERE_phy_power_down(int phy_addr, int y)
++{
++	u16 phy_data = 0;
++	// power-down or up the PHY
++	star_gsw_read_phy(phy_addr, 0, &phy_data);
++	if (y==1) // down
++		phy_data |= (0x1 << 11);
++	if (y==0) // up
++		phy_data &= (~(0x1 << 11));
++	star_gsw_write_phy(phy_addr, 0, phy_data);
++	return 0;
++}
++
++// add by descent 2006/07/31
++// standard phy register 0 and offset is 11 is power down
++int std_phy_power_down(int phy_addr, int y)
++{
++	u16 phy_data = 0;
++	// power-down or up the PHY
++	star_gsw_read_phy(phy_addr, 0, &phy_data);
++	if (y==1) // down
++		phy_data |= (0x1 << 11);
++	if (y==0) // up
++		phy_data &= (~(0x1 << 11));
++	star_gsw_write_phy(phy_addr, 0, phy_data);
++	return 0;
++}
++
++
++/*
++ *  AGERE PHY is attached to MAC PORT 1
++ * with phy_addr 1
++ */
++void star_gsw_config_AGERE()
++{
++	u32 mac_port_config;
++	u16 phy_data = 0;
++	int i;
++
++	printk("configure port1 AGERE\n");
++
++	/*
++	 * Configure MAC port 1
++	 * For Agere Systems's ET1011 single PHY
++	 */
++	mac_port_config = GSW_MAC_PORT_1_CONFIG;
++
++	// disable PHY's AN
++	mac_port_config &= ~(0x1 << 7);
++
++	// enable RGMII-PHY mode
++	mac_port_config |= (0x1 << 15);
++
++	GSW_MAC_PORT_1_CONFIG = mac_port_config;
++
++#if 1
++	/*
++	 * configure Agere's ET1011 Single PHY
++	 */
++	/* Configure Agere's ET1011 by Agere's programming note */
++	//1. power-down the PHY
++	star_gsw_read_phy(1, 0, &phy_data);
++	phy_data |= (0x1 << 11);
++	star_gsw_write_phy(1, 0, phy_data);
++
++	//2. Enable PHY programming mode
++	star_gsw_read_phy(1, 18, &phy_data);
++	phy_data |= (0x1 << 0);
++	phy_data |= (0x1 << 2);
++	star_gsw_write_phy(1, 18, phy_data);
++
++	//3.Perform some PHY register with the Agere-specfic value
++	star_gsw_write_phy(1, 16, 0x880e);
++	star_gsw_write_phy(1, 17, 0xb4d3);
++
++	star_gsw_write_phy(1, 16, 0x880f);
++	star_gsw_write_phy(1, 17, 0xb4d3);
++
++	star_gsw_write_phy(1, 16, 0x8810);
++	star_gsw_write_phy(1, 17, 0xb4d3);
++
++	star_gsw_write_phy(1, 16, 0x8817);
++	star_gsw_write_phy(1, 17, 0x1c00);
++
++	star_gsw_write_phy(1, 16, 0x8805);
++	star_gsw_write_phy(1, 17, 0xb03e);
++
++	star_gsw_write_phy(1, 16, 0x8806);
++	star_gsw_write_phy(1, 17, 0xb03e);
++
++	star_gsw_write_phy(1, 16, 0x8807);
++	star_gsw_write_phy(1, 17, 0xff00);
++
++	star_gsw_write_phy(1, 16, 0x8808);
++	star_gsw_write_phy(1, 17, 0xe110);
++
++	star_gsw_write_phy(1, 16, 0x300d);
++	star_gsw_write_phy(1, 17, 0x0001);
++
++	//4. Disable PHY programming mode
++	star_gsw_read_phy(1, 18, &phy_data);
++	phy_data &= ~(0x1 << 0);
++	phy_data &= ~(0x1 << 2);
++	star_gsw_write_phy(1, 18, phy_data);
++
++	//5. power-up the PHY
++	star_gsw_read_phy(1, 0, &phy_data);
++	phy_data &= ~(0x1 << 11);
++	star_gsw_write_phy(1, 0, phy_data);
++
++	star_gsw_read_phy(1, 22, &phy_data);
++
++	// enable RGMII MAC interface mode : RGMII/RMII (dll delay or trace delay) mode
++	phy_data &= ~(0x7 << 0);
++
++	// phy_data |= (0x6 << 0); // RGMII/RMII dll delay mode : not work!!
++	phy_data |= (0x4 << 0);	// RGMII/RMII trace delay mode
++
++	star_gsw_write_phy(1, 22, phy_data);
++#endif
++
++	mac_port_config = GSW_MAC_PORT_1_CONFIG;
++
++	// enable PHY's AN
++	mac_port_config |= (0x1 << 7);
++
++	GSW_MAC_PORT_1_CONFIG = mac_port_config;
++
++	/*
++	 * Enable flow-control on (Symmetric PAUSE frame)
++	 */
++	star_gsw_read_phy(1, 0x4, &phy_data);
++
++	phy_data |= (0x1 << 10);
++
++	star_gsw_write_phy(1, 0x4, phy_data);
++
++	/*
++	 * Enable PHY1 AN restart bit to restart PHY1 AN
++	 */
++	star_gsw_read_phy(1, 0x0, &phy_data);
++
++	phy_data |= (0x1 << 9) | (0x1 << 12);
++
++	star_gsw_write_phy(1, 0x0, phy_data);
++
++	/*
++	 * Polling until PHY1 AN restart is complete and PHY1 link status is UP
++	 */
++	for (i = 0; i < 0x2000; i++) {
++		star_gsw_read_phy(1, 0x1, &phy_data);
++		if ((phy_data & (0x1 << 5)) && (phy_data & (0x1 << 2))) {
++			break;
++		}
++	}
++
++	// adjust MAC port 1 RX/TX clock skew
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 28) | (0x3 << 30));
++	GSW_BIST_RESULT_TEST_0 |= ((0x2 << 28) | (0x3 << 30));
++
++	udelay(100);
++
++	mac_port_config = GSW_MAC_PORT_1_CONFIG;
++	if (!(mac_port_config & 0x1) || (mac_port_config & 0x2)) {
++		/*
++		 * Port 1 PHY link down or no TXC in Port 1
++		 */
++		PDEBUG("PHY1: Link Down, 0x%08x!\n", mac_port_config);
++		return;
++	}
++
++}
++
++
++
++int str9100_gsw_config_mac_port0()
++{
++        PDEBUG("str9100_gsw_config_mac_port0\n");
++        INIT_PORT0_PHY
++	INIT_PORT0_MAC
++        PORT0_LINK_DOWN
++        return 0;
++}
++
++int str9100_gsw_config_mac_port1()
++{
++        INIT_PORT1_PHY
++	INIT_PORT1_MAC
++        PORT1_LINK_DOWN
++        //PORT1_LINK_UP
++        return 0;
++}
++
++
++#define PHY_CONTROL_REG_ADDR 0x00
++#define PHY_AN_ADVERTISEMENT_REG_ADDR 0x04
++
++
++int icp_101a_init (int port)
++{
++	u32 mac_port_config;
++        u16 phy_data = 0;
++
++
++	PRINT_INFO("init IC+101A\n");
++
++	if (port == 0)		// port 0
++		mac_port_config = GSW_MAC_PORT_0_CONFIG;
++	if (port == 1)		// port 1
++		mac_port_config = GSW_MAC_PORT_1_CONFIG;
++
++	if (!(mac_port_config & (0x1 << 5))) {
++		if (!star_gsw_read_phy (port, PHY_AN_ADVERTISEMENT_REG_ADDR, &phy_data))
++	    	{
++			PDEBUG("\n PORT%d, enable local flow control capability Fail\n", port);
++			return (1);
++	    	}
++		else
++	    	{
++	      		// enable PAUSE frame capability
++			phy_data |= (0x1 << 10);
++
++	      		if (!star_gsw_write_phy (port, PHY_AN_ADVERTISEMENT_REG_ADDR, phy_data))
++			{
++				PDEBUG("\nPORT%d, enable PAUSE frame capability Fail\n", port);
++				return (1);
++			}
++	    	}
++	}
++
++
++	// restart PHY0 AN
++	if (!star_gsw_read_phy (port, PHY_CONTROL_REG_ADDR, &phy_data)) {
++		PDEBUG ("\n restart PHY%d AN Fail \n", port);
++		return (1);
++	}
++	else {
++		// enable PHY0 AN restart
++		phy_data |= (0x1 << 9);
++
++		if (!star_gsw_write_phy (port, PHY_CONTROL_REG_ADDR, phy_data)) {
++			PDEBUG ("\n  enable PHY0 AN restart \n");
++			return (1);
++		}
++	}
++
++
++
++	while (1)
++	{
++		PDEBUG ("\n Polling  PHY%d AN \n", port);
++		star_gsw_read_phy (port, PHY_CONTROL_REG_ADDR, &phy_data);
++
++		if (phy_data & (0x1 << 9)) {
++		  continue;
++		}
++		else {
++			PDEBUG ("\n PHY%d AN restart is complete \n", port);
++			break;
++		}
++	}
++
++	return 0;
++}
++
++#ifdef CONFIG_LIBRA
++void icp_175c_all_phy_power_down(int y)
++{
++	int i=0;
++
++	for (i=0 ; i < 5 ; ++i)
++		std_phy_power_down(i, y);
++
++}
++
++#define CONFIG_PORT0_5
++
++void configure_icplus_175c_phy(void)
++{
++	u32 volatile	II, jj;
++	u32 volatile	mac_port_config;
++	u16 volatile reg;
++	u32 volatile reg2;
++	int i=0;
++
++	//star_gsw_set_phy_addr(0, 0);
++	//star_gsw_set_phy_addr(1, 1);
++
++	printk("\n ICPLUS175C_PHY,enable PORT0 local flow control capability \n");
++	/* adjust MAC port 0 /RX/TX clock skew */
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 24) | (0x3 << 26));
++	GSW_BIST_RESULT_TEST_0 |= ((0x2 << 24) | (0x2 << 26));
++
++// 20061117 descent
++	// auto polling default phy address is 0
++	// so set phy address to not exist address to avoid auto polling
++	// in STAR library board if no these code, port 0 link state will get half duplex
++	// port 1-4 get full duplex
++        if (star_gsw_set_phy_addr(0, 15))
++                printk ("star_gsw_set_phy_addr(0,2) is successful\n");
++        else
++                printk ("star_gsw_set_phy_addr(0,2) is fail\n");
++
++        if (star_gsw_set_phy_addr(1, 16))
++                printk ("star_gsw_set_phy_addr(1,3) is successful\n");
++        else
++                printk ("star_gsw_set_phy_addr(1,3) is fail\n");
++
++
++
++	#if 0
++	// for PHY_AN_ADVERTISEMENT_REG_ADDR
++	// in this case needn't this code, only for reference
++		star_gsw_read_phy(i, 4, &phy_data);
++		phy_data |= (0x1 << 10);  // Enable PAUSE frame capability of PHY 0
++		phy_data |= (0x1 << 5) | (0x1 << 6) | (0x1 << 7) | (0x1 << 8);
++		star_gsw_write_phy(i, 4, phy_data);
++		star_gsw_read_phy(i, 0, &phy_data);
++		phy_data |= (0x1 << 9) | (0x1 << 12);  // Enable AN and Restart-AN
++		star_gsw_write_phy(i, 0, phy_data);
++	#endif
++// 20061117 descent end
++
++
++#if 0
++	for (i=0 ; i < 10; ++i)
++	{
++	  star_gsw_read_phy(i, 2, &reg);
++	  printk("addr: %d, phyid: %x\n", i, reg);
++	}
++
++
++
++
++	/*
++	 * Configure GSW's MAC port 0
++	 * For ASIX's 5-port GbE Switch setting
++	 * 1. No SMI (MDC/MDIO) connection between Orion's MAC port 0 and ASIX's MAC port 4
++	 * 2. Force Orion's MAC port 0 to be 1000Mbps, and full-duplex, and flow control on
++	 */
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++
++
++	// enable RGMII-PHY mode
++	mac_port_config &= ~(0x1 << 15);
++
++	// force speed = 100Mbps
++	mac_port_config &= ~(0x3 << 8);
++	mac_port_config |= (0x1 << 8);
++
++	// force full-duplex
++	mac_port_config |= (0x1 << 10);
++
++	// force Tx/Rx flow-control on
++	mac_port_config |= (0x1 << 11) | (0x1 << 12);
++
++	GSW_MAC_PORT_0_CONFIG = mac_port_config;
++	star_gsw_write_phy(29, 31, 0x175C);
++	//star_gsw_write_phy(30, 9, 0x1089);
++	star_gsw_write_phy(29, 23, 0x2);
++
++	star_gsw_write_phy(29, 24, 0x2);
++	star_gsw_write_phy(29, 25, 0x1);
++	star_gsw_write_phy(29, 26, 0x1);
++	star_gsw_write_phy(29, 27, 0x1);
++	star_gsw_write_phy(29, 28, 0x1);
++	star_gsw_write_phy(29, 29, 0x2);
++
++	star_gsw_write_phy(30, 1, (0x3e << 8) );
++	star_gsw_write_phy(30, 2, 0x21);
++	star_gsw_write_phy(30, 9, 0x80);
++
++	udelay(1000);
++
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++	if (((mac_port_config & 0x1) == 0) || (mac_port_config & 0x2)) {
++		printk("Check MAC/PHY 0 Link Status : DOWN!\n");
++	} else {
++		printk("Check MAC/PHY 0 Link Status : UP!\n");
++	}
++
++	/* adjust MAC port 0 /RX/TX clock skew */
++	GSW_BIST_RESULT_TEST_0 &= ~((0x3 << 24) | (0x3 << 26));
++	GSW_BIST_RESULT_TEST_0 |= ((0x2 << 24) | (0x2 << 26));
++
++
++#endif
++
++
++
++#if 1
++
++	
++#if 1
++	reg2 = __REG(PWR_PAD_DRV_REG);
++	PDEBUG("[PWR_PAD_DRV_REG = %x]\n", reg2);
++	reg2 = reg2 | 0x4;
++
++	__REG(PWR_PAD_DRV_REG) = reg2;
++
++	reg2 = __REG(PWR_PAD_DRV_REG);
++	PDEBUG("[PWR_PAD_DRV_REG = %x]\n", reg2);
++#endif
++	
++	star_gsw_write_phy(29, 31, 0x175C);
++	
++
++	star_gsw_read_phy(0, 2, &reg);
++	PDEBUG("[0,%d,%x]\n", 2, reg);
++	star_gsw_read_phy(29, 31, &reg);
++	PDEBUG("[29,%d,%x]\n", 31, reg);
++
++	star_gsw_write_phy(29, 23, 0x7C2);
++	star_gsw_write_phy(29, 24, 0x1);
++	star_gsw_write_phy(29, 25, 0x1);
++	star_gsw_write_phy(29, 26, 0x1);
++
++#ifdef CONFIG_PORT0_5
++	star_gsw_write_phy(29, 27, 0x1);
++#else
++	star_gsw_write_phy(29, 27, 0x2);
++#endif
++	star_gsw_write_phy(29, 28, 0x2);
++	star_gsw_write_phy(29, 30, 0x2);
++
++#ifdef CONFIG_PORT0_5
++	printk("CONFIG_PORT0_5\n");
++	star_gsw_write_phy(30, 1, 0x2f00);
++	star_gsw_write_phy(30, 2, 0x30);
++#else // port0_4
++	printk("not CONFIG_PORT0_5\n");
++
++
++        //star_gsw_write_phy(30, 1, 0x2f00);
++        star_gsw_write_phy(30, 1, 0x2700);
++        //star_gsw_write_phy(30, 2, 0x30);
++        star_gsw_write_phy(30, 2, 0x38);
++
++#endif
++
++
++	star_gsw_write_phy(30, 9, 0x80);
++
++// 20061115 descent
++// If no these code,
++// in STAR libra board, will get crc drop
++	// configure port 4 (MII 0)
++	// configure port 4 (MII 0)
++
++	// P4_FORCE
++	star_gsw_read_phy(29, 22, &reg);
++	reg |= (0x1 << 15);
++        star_gsw_write_phy(29, 22, reg);
++
++	
++	// MAC_X_EN, flow control enable of MII0 and MII2
++	star_gsw_read_phy(29, 18, &reg);
++	reg |= (0x1 << 10);
++        star_gsw_write_phy(29, 18, reg);
++
++
++	// P4_FORCE 100 Mbps
++	star_gsw_read_phy(29, 22, &reg);
++	reg |= (0x1 << 10);
++        star_gsw_write_phy(29, 22, reg);
++
++
++	// P4_FORCE_FULL duplex
++	star_gsw_read_phy(29, 22, &reg);
++	reg |= (0x1 << 5);
++        star_gsw_write_phy(29, 22, reg);
++
++// 20061115 descent end
++
++
++
++
++
++	
++	#if 0
++	// enable flow control
++	star_gsw_read_phy(29, 18, &reg);
++	reg |= (0x1 < 13);
++	star_gsw_write_phy(29, 18, reg);
++	star_gsw_read_phy(29, 18, &reg);
++	printk("[29,%d,%x]\n", 18, reg);
++	#endif
++#if 0
++	//star_gsw_read_phy(29, 23, &reg);
++	//reg = reg & 0xF800;
++	//reg = reg | 0x7C2;
++
++
++	star_gsw_write_phy(29, 24, 0x1);
++
++	star_gsw_read_phy(29, 24, &reg);
++	PDEBUG("[  29, 24, %x]\n", reg);
++
++	star_gsw_write_phy(29, 25, 0x2);
++	udelay(1000);
++
++	star_gsw_read_phy(29, 25, &reg);
++	PDEBUG("[  29, 25, %x]\n", reg);
++
++	star_gsw_write_phy(29, 26, 0x1);
++	star_gsw_write_phy(29, 27, 0x1);
++	star_gsw_write_phy(29, 28, 0x1);
++	star_gsw_write_phy(29, 30, 0x2);
++
++	// tag vlan mask
++
++	star_gsw_write_phy(30, 1, 0x3F3D);
++
++	star_gsw_write_phy(30, 2, 0x3F22);
++	star_gsw_write_phy(30, 9, 0x1089);
++	// star_gsw_write_phy(30, 1, 0x3D22);
++	// star_gsw_write_phy(30, 9, 0x028A);
++#endif
++
++#if 0
++
++	for(II=18;II<=30;II++)
++	{
++		star_gsw_read_phy(29, II, &reg);
++		PDEBUG("[29,%d,%x]\n", II, reg);
++	}
++
++	for(II=1;II<=10;II++)
++	{
++		star_gsw_read_phy(30, II, &reg);
++		PDEBUG("[30,%d,%x]\n", II, reg);
++	}
++
++#endif
++
++	mac_port_config = GSW_MAC_PORT_0_CONFIG;
++
++	// disable PHY's AN
++	mac_port_config &= ~(0x1 << 7);
++
++	// disable RGMII-PHY mode
++	mac_port_config &= ~(0x1 << 15);
++
++	// force speed = 100Mbps
++	mac_port_config &= ~(0x3 << 8);
++	mac_port_config |= (0x1 << 8);
++	
++	// force full-duplex
++	mac_port_config |= (0x1 << 10);
++
++	// force Tx/Rx flow-control on
++	mac_port_config |= (0x1 << 11) | (0x1 << 12);
++
++	GSW_MAC_PORT_0_CONFIG = mac_port_config;
++
++
++#if 0
++	for (II = 0; II < 0x2000; II++)
++	{
++		mac_port_config = GSW_MAC_PORT_0_CONFIG;
++		
++		if ((mac_port_config & 0x1) && !(mac_port_config & 0x2))
++		{
++
++			/* enable MAC port 0
++			*/
++			mac_port_config &= ~(0x1 << 18);
++
++		
++			/*
++			* enable the forwarding of unknown, multicast and broadcast packets to CPU
++			*/
++			mac_port_config &= ~((0x1 << 25) | (0x1 << 26) | (0x1 << 27));
++		
++			/*
++			* include unknown, multicast and broadcast packets into broadcast storm
++			*/
++			mac_port_config |= ((0x1 << 29) | (0x1 << 30) | ((u32)0x1 << 31));
++			// mac_port_config |= ( (0x1 << 30) | ((u32)0x1 << 31));
++			
++			GSW_MAC_PORT_0_CONFIG = mac_port_config;
++			
++			break;
++		}
++	}
++#endif
++
++	if (!(mac_port_config & 0x1) || (mac_port_config & 0x2))
++	{
++		/*
++		* Port 0 PHY link down or no TXC in Port 0
++		*/
++		printk("\rCheck MAC/PHY 0 Link Status : DOWN!\n");
++		
++	}
++	else
++	{
++		printk("\rCheck MAC/PHY 0 Link Status : UP!\n");
++	}
++#endif
++
++	//printk("Found ICPLUS175C_PHY\n");
++}
++#endif
+diff -rupN linux-2.6.35.11/drivers/net/str9100/star_gsw_phy.h linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_phy.h
+--- linux-2.6.35.11/drivers/net/str9100/star_gsw_phy.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/star_gsw_phy.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,160 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __STAR_GSW_PHY_H__
++#define __STAR_GSW_PHY_H__
++
++#include <linux/version.h>
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,32)
++#define LINUX24 1
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++#define LINUX26 1
++#endif
++
++#include <linux/types.h>
++
++
++//#define CONFIG_VIRGO
++//#define CONFIG_DORADO
++//#define CONFIG_DORADO2
++//#define CONFIG_LEO
++//#undef CONFIG_VIRGO
++//#undef CONFIG_DORADO
++//#undef CONFIG_DORADO2
++//#undef CONFIG_LEO
++
++#ifdef CONFIG_LIBRA
++#include "libra.h"
++#endif
++
++#ifdef CONFIG_VELA
++#include "vela.h"
++#endif
++
++#ifdef CONFIG_DORADO2
++#include "dorado2.h"
++#endif
++
++#ifdef CONFIG_DORADO
++#include "dorado.h"
++#endif
++
++#ifdef CONFIG_LEO
++#include "leo.h"
++#endif
++
++#ifdef CONFIG_VIRGO
++#include "virgo.h"
++#endif
++
++
++void star_gsw_config_ASIX(void);
++void star_gsw_config_AGERE(void);
++int AGERE_phy_power_down(int phy_addr, int y);
++int disable_AN_VSC7385(int y);
++void star_gsw_config_VSC7385(void);
++
++
++
++
++void star_gsw_config_AGERE(void);
++
++int str9100_gsw_config_mac_port0(void);
++int str9100_gsw_config_mac_port1(void);
++
++
++
++#define PORT0				(1 << 0)	/* bit map : bit 0 */
++#define PORT1				(1 << 1)	/* bit map : bit 1 */
++#define CPU_PORT			(1 << 2)	/* bit map : bit 2 */
++
++#define VLAN0_GROUP_ID			(0)
++#define VLAN1_GROUP_ID			(1)
++#define VLAN2_GROUP_ID			(2)
++#define VLAN3_GROUP_ID			(3)
++#define VLAN4_GROUP_ID			(4)
++#define VLAN5_GROUP_ID			(5)
++#define VLAN6_GROUP_ID			(6)
++#define VLAN7_GROUP_ID			(7)
++
++#define PORT0_PVID			(VLAN1_GROUP_ID)
++#define PORT1_PVID			(VLAN2_GROUP_ID)
++#define CPU_PORT_PVID			(VLAN0_GROUP_ID)
++
++#define INVALID_PORT_BASE_PMAP_PORT -1
++
++
++#ifdef LINUX26
++#define GSW_MAC_PORT_0_CONFIG GSW_MAC_PORT_0_CONFIG_REG
++#define GSW_MAC_PORT_1_CONFIG GSW_MAC_PORT_1_CONFIG_REG
++#define GSW_PORT_MIRROR GSW_PORT_MIRROR_REG
++#define GSW_QUEUE_STATUS_TEST_1 GSW_QUEUE_STATUS_TEST_1_REG
++#define GSW_PHY_CONTROL GSW_PHY_CONTROL_REG
++#define GSW_BIST_RESULT_TEST_0 GSW_BIST_RESULT_TEST_0_REG
++#define GSW_PORT0_CFG_REG (SYSVA_GSW_BASE_ADDR + 0x08)
++#define GSW_PORT1_CFG_REG (SYSVA_GSW_BASE_ADDR + 0x0C)
++#define GSW_SWITCH_CONFIG GSW_SWITCH_CONFIG_REG
++#define GSW_ARL_TABLE_ACCESS_CONTROL_0 GSW_ARL_TABLE_ACCESS_CONTROL_0_REG
++#define GSW_ARL_TABLE_ACCESS_CONTROL_1 GSW_ARL_TABLE_ACCESS_CONTROL_1_REG
++#define GSW_ARL_TABLE_ACCESS_CONTROL_2 GSW_ARL_TABLE_ACCESS_CONTROL_2_REG
++#define GSW_VLAN_PORT_PVID GSW_VLAN_PORT_PVID_REG
++#define GSW_VLAN_VID_0_1 GSW_VLAN_VID_0_1_REG
++#define GSW_VLAN_VID_2_3 GSW_VLAN_VID_2_3_REG
++#define GSW_VLAN_VID_4_5 GSW_VLAN_VID_4_5_REG
++#define GSW_VLAN_VID_6_7 GSW_VLAN_VID_6_7_REG
++#define GSW_VLAN_MEMBER_PORT_MAP GSW_VLAN_MEMBER_PORT_MAP_REG
++#define GSW_VLAN_TAG_PORT_MAP GSW_VLAN_TAG_PORT_MAP_REG
++#define GSW_INTERRUPT_MASK GSW_INTERRUPT_MASK_REG
++#define GSW_INTERRUPT_STATUS GSW_INTERRUPT_STATUS_REG
++#define INTC_INTERRUPT_CLEAR_EDGE_TRIGGER INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG
++#define GSW_TS_DMA_CONTROL GSW_TS_DMA_CONTROL_REG
++#define GSW_FS_DMA_CONTROL GSW_FS_DMA_CONTROL_REG
++#define GSW_TS_DESCRIPTOR_POINTER GSW_TS_DESCRIPTOR_POINTER_REG
++#define GSW_TS_DESCRIPTOR_BASE_ADDR GSW_TS_DESCRIPTOR_BASE_ADDR_REG
++#define GSW_FS_DESCRIPTOR_POINTER GSW_FS_DESCRIPTOR_POINTER_REG
++#define GSW_FS_DESCRIPTOR_BASE_ADDR GSW_FS_DESCRIPTOR_BASE_ADDR_REG
++#define GSW_CPU_PORT_CONFIG GSW_CPU_PORT_CONFIG_REG
++#define INTC_INTERRUPT_MASK INTC_INTERRUPT_MASK_REG
++#define GSW_DELAYED_INTERRUPT_CONFIG GSW_DELAYED_INTERRUPT_CONFIG_REG
++#define GSW_HNAT_SOURCE_MAC_0_HIGH GSW_HNAT_SOURCE_MAC_0_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_0_LOW GSW_HNAT_SOURCE_MAC_0_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_1_HIGH GSW_HNAT_SOURCE_MAC_1_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_1_LOW GSW_HNAT_SOURCE_MAC_1_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_2_HIGH GSW_HNAT_SOURCE_MAC_2_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_2_LOW GSW_HNAT_SOURCE_MAC_2_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_3_HIGH GSW_HNAT_SOURCE_MAC_3_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_3_LOW GSW_HNAT_SOURCE_MAC_3_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_4_HIGH GSW_HNAT_SOURCE_MAC_4_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_4_LOW GSW_HNAT_SOURCE_MAC_4_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_5_HIGH GSW_HNAT_SOURCE_MAC_5_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_5_LOW GSW_HNAT_SOURCE_MAC_5_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_6_HIGH GSW_HNAT_SOURCE_MAC_6_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_6_LOW GSW_HNAT_SOURCE_MAC_6_LOW_REG
++#define GSW_HNAT_SOURCE_MAC_7_HIGH GSW_HNAT_SOURCE_MAC_7_HIGH_REG
++#define GSW_HNAT_SOURCE_MAC_7_LOW GSW_HNAT_SOURCE_MAC_7_LOW_REG
++#define PWRMGT_SOFTWARE_RESET_CONTROL PWRMGT_SOFTWARE_RESET_CONTROL_REG
++
++#endif
++
++#endif /* __STAR_GSW_PHY_H__ */
+diff -rupN linux-2.6.35.11/drivers/net/str9100/vela.h linux-2.6.35.11-ts7500/drivers/net/str9100/vela.h
+--- linux-2.6.35.11/drivers/net/str9100/vela.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/vela.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,167 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef VELA_H
++#define VELA_H
++
++// add by descent 2006/07/07
++#define VELA
++#ifdef VELA
++// init phy or switch chip
++#define INIT_PORT0_PHY icp_101a_init(0);
++#define INIT_PORT1_PHY icp_101a_init(1);
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC init_packet_forward(1);
++
++#define PORT0_LINK_DOWN std_phy_power_down(0, 1);
++#define PORT0_LINK_UP std_phy_power_down(0, 0);
++
++#define PORT1_LINK_DOWN std_phy_power_down(1, 1);
++#define PORT1_LINK_UP std_phy_power_down(1, 0);
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 star_gsw_probe(WAN_PORT);
++#define CREATE_NET_DEV2
++
++
++#undef CONFIG_STR9100_VLAN_BASE
++#undef CONFIG_HAVE_VLAN_TAG
++
++#define CONFIG_STR9100_PORT_BASE
++// for port base, port base max is 2 port.
++// NET_DEV0 : rx->sp 0 (port 0)
++#define NET_DEV0 STAR_GSW_LAN_DEV
++// NET_DEV1 : rx->sp 1 (port 1)
++#define NET_DEV1 STAR_GSW_WAN_DEV
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT PORT0
++#define PORT_BASE_PMAP_WAN_PORT PORT1
++#define PORT_BASE_PMAP_EWC_PORT INVALID_PORT_BASE_PMAP_PORT
++
++
++// OPEN_PORT include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[LAN_GID].vlan_mac, 6);\
++       		PRINT_INFO("open mac port 0\n");\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* enable port 0 */ \
++	        mac_port_config &= (~(0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++		PORT0_LINK_UP\
++	} \
++	if(dev == STAR_GSW_WAN_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[WAN_GID].vlan_mac, 6);\
++       		PRINT_INFO("open mac port 1\n");\
++	        mac_port_config = GSW_MAC_PORT_1_CONFIG;\
++       		/* enable port 0 */ \
++	        mac_port_config &= (~(0x1 << 18));\
++       		GSW_MAC_PORT_1_CONFIG = mac_port_config;\
++		PORT1_LINK_UP\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++       		PRINT_INFO("close mac port 0\n");\
++		PORT0_LINK_DOWN\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* disable port 0 */ \
++	        mac_port_config |= ((0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	} \
++	if(dev == STAR_GSW_WAN_DEV) { \
++       		PRINT_INFO("close mac port 1\n");\
++		PORT1_LINK_DOWN\
++	        mac_port_config = GSW_MAC_PORT_1_CONFIG;\
++       		/* disable port 1 */ \
++	        mac_port_config |= ((0x1 << 18));\
++       		GSW_MAC_PORT_1_CONFIG = mac_port_config;\
++	} \
++}
++
++
++#define VLAN0_VID			(0x111)
++#define VLAN1_VID			(0x222)
++#define VLAN2_VID			(0x333)
++#define VLAN3_VID			(0x444)
++#define VLAN4_VID			(0x555)
++#define VLAN5_VID			(0x666)
++#define VLAN6_VID			(0x777)
++#define VLAN7_VID			(0x888)
++
++
++#define VLAN0_GROUP			(PORT0 | PORT1 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(PORT1 | CPU_PORT)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++
++#define VLAN0_VLAN_TAG			(0)
++#define VLAN1_VLAN_TAG			(0)
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++//#define PORT0_PVID			(VLAN0_GROUP_ID)
++//#define PORT1_PVID			(VLAN2_GROUP_ID)
++//#define CPU_PORT_PVID			(VLAN1_GROUP_ID)
++
++static u8 my_vlan0_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xcc, 0x11};
++static u8 my_vlan1_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xcc, 0x21};
++static u8 my_vlan2_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xcc, 0x31};
++static u8 my_vlan3_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xcc, 0x41};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 1
++#define WAN_GID 2
++
++
++#define MODEL "VELA"
++
++#endif // VELA
++
++#endif
++
+diff -rupN linux-2.6.35.11/drivers/net/str9100/virgo.h linux-2.6.35.11-ts7500/drivers/net/str9100/virgo.h
+--- linux-2.6.35.11/drivers/net/str9100/virgo.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/net/str9100/virgo.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,167 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef VIRGO_H
++#define VIRGO_H
++
++// add by descent 2006/07/07
++#define VIRGO
++#ifdef VIRGO
++// init phy or switch chip
++#define INIT_PORT0_PHY star_gsw_config_ASIX();
++#define INIT_PORT1_PHY star_gsw_config_AGERE();
++
++// configure mac0/mac1 register
++#define INIT_PORT0_MAC init_packet_forward(0);
++#define INIT_PORT1_MAC init_packet_forward(1);
++
++#define PORT0_LINK_DOWN disable_AN_VSC7385(0);
++#define PORT0_LINK_UP disable_AN_VSC7385(1);
++
++#define PORT1_LINK_DOWN AGERE_phy_power_down(1,1);
++#define PORT1_LINK_UP AGERE_phy_power_down(1,0);
++
++#define CREATE_NET_DEV0 star_gsw_probe(LAN_PORT);
++#define CREATE_NET_DEV1 star_gsw_probe(WAN_PORT);
++#define CREATE_NET_DEV2
++
++
++#undef CONFIG_STR9100_VLAN_BASE
++#undef CONFIG_HAVE_VLAN_TAG
++
++#define CONFIG_STR9100_PORT_BASE
++// for port base, port base max is 2 port.
++// NET_DEV0 : rx->sp 0 (port 0)
++#define NET_DEV0 STAR_GSW_LAN_DEV
++// NET_DEV1 : rx->sp 1 (port 1)
++#define NET_DEV1 STAR_GSW_WAN_DEV
++
++// for star_gsw_send_packet
++// port base and vlan base packet flow
++#define PORT_BASE_PMAP_LAN_PORT PORT0
++#define PORT_BASE_PMAP_WAN_PORT PORT1
++#define PORT_BASE_PMAP_EWC_PORT INVALID_PORT_BASE_PMAP_PORT
++
++#define MODEL "VIRGO"
++
++// OPEN_PORT include 2 actions
++// 1. enable mac port
++// 2. link up port
++#define OPEN_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[LAN_GID].vlan_mac, 6);\
++       		PRINT_INFO("open mac port 0\n");\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* enable port 0 */ \
++	        mac_port_config &= (~(0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++		PORT0_LINK_UP\
++	} \
++	if(dev == STAR_GSW_WAN_DEV) { \
++		memcpy(dev->dev_addr, star_gsw_info.vlan[WAN_GID].vlan_mac, 6);\
++       		PRINT_INFO("open mac port 1\n");\
++	        mac_port_config = GSW_MAC_PORT_1_CONFIG;\
++       		/* enable port 0 */ \
++	        mac_port_config &= (~(0x1 << 18));\
++       		GSW_MAC_PORT_1_CONFIG = mac_port_config;\
++		PORT1_LINK_UP\
++	} \
++}
++
++// CLOSE_PORT include 2 actions
++// 1. disable mac port
++// 2. link down port
++#define CLOSE_PORT(dev) \
++{ \
++        u32 mac_port_config; \
++ \
++	if (dev == STAR_GSW_LAN_DEV) { \
++       		PRINT_INFO("close mac port 0\n");\
++		PORT0_LINK_DOWN\
++	        mac_port_config = GSW_MAC_PORT_0_CONFIG;\
++       		/* disable port 0 */ \
++	        mac_port_config |= ((0x1 << 18));\
++       		GSW_MAC_PORT_0_CONFIG = mac_port_config;\
++	} \
++	if(dev == STAR_GSW_WAN_DEV) { \
++       		PRINT_INFO("close mac port 1\n");\
++		PORT1_LINK_DOWN\
++	        mac_port_config = GSW_MAC_PORT_1_CONFIG;\
++       		/* disable port 1 */ \
++	        mac_port_config |= ((0x1 << 18));\
++       		GSW_MAC_PORT_1_CONFIG = mac_port_config;\
++	} \
++}
++
++
++#define VLAN0_VID			(0x111)
++#define VLAN1_VID			(0x222)
++#define VLAN2_VID			(0x333)
++#define VLAN3_VID			(0x444)
++#define VLAN4_VID			(0x555)
++#define VLAN5_VID			(0x666)
++#define VLAN6_VID			(0x777)
++#define VLAN7_VID			(0x888)
++
++
++#define VLAN0_GROUP			(PORT0 | PORT1 | CPU_PORT)
++#define VLAN1_GROUP			(PORT0 | CPU_PORT)
++#define VLAN2_GROUP			(PORT1 | CPU_PORT)
++#define VLAN3_GROUP			(0)
++#define VLAN4_GROUP			(0)
++#define VLAN5_GROUP			(0)
++#define VLAN6_GROUP			(0)
++#define VLAN7_GROUP			(0)
++
++#define VLAN0_VLAN_TAG			(0)
++#define VLAN1_VLAN_TAG			(0)
++#define VLAN2_VLAN_TAG			(0)
++#define VLAN3_VLAN_TAG			(0)
++#define VLAN4_VLAN_TAG			(0)
++#define VLAN5_VLAN_TAG			(0)
++#define VLAN6_VLAN_TAG			(0)
++#define VLAN7_VLAN_TAG			(0)
++
++//#define PORT0_PVID			(VLAN0_GROUP_ID)
++//#define PORT1_PVID			(VLAN2_GROUP_ID)
++//#define CPU_PORT_PVID			(VLAN1_GROUP_ID)
++
++static u8 my_vlan0_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x11};
++static u8 my_vlan1_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x21};
++static u8 my_vlan2_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x31};
++static u8 my_vlan3_mac[6] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x41};
++
++// this value is for hnat
++// GID is vlan group id
++#define LAN_GID 1
++#define WAN_GID 2
++
++
++
++#endif // VIRGO
++
++#endif
++
+diff -rupN linux-2.6.35.11/drivers/pci/setup-bus.c linux-2.6.35.11-ts7500/drivers/pci/setup-bus.c
+--- linux-2.6.35.11/drivers/pci/setup-bus.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/pci/setup-bus.c	2011-03-14 11:18:24.000000000 -0400
+@@ -76,6 +76,21 @@ static void __dev_sort_resources(struct
+ {
+ 	u16 class = dev->class >> 8;
+ 
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++		{
++		u16 cmd;
++
++		pci_read_config_word(dev, PCI_COMMAND, &cmd);
++		cmd |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
++		pci_write_config_word(dev, PCI_COMMAND, cmd);
++		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x8); //configure cache line size
++		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40); //configure latency timer
++		}
++
++		if (dev->vendor == 0xeeee)
++			return;
++#endif   
++   
+ 	/* Don't touch classless devices or host bridges or ioapics.  */
+ 	if (class == PCI_CLASS_NOT_DEFINED || class == PCI_CLASS_BRIDGE_HOST)
+ 		return;
+diff -rupN linux-2.6.35.11/drivers/serial/8250.c linux-2.6.35.11-ts7500/drivers/serial/8250.c
+--- linux-2.6.35.11/drivers/serial/8250.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/serial/8250.c	2011-03-14 11:18:24.000000000 -0400
+@@ -45,6 +45,16 @@
+ 
+ #include "8250.h"
+ 
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++#include <asm/arch/star_gpio.h>
++extern int __init_or_module gpio_direction_input(unsigned int);
++extern int __init_or_module gpio_direction_output(unsigned int, unsigned int);
++extern void gpio_set_value(unsigned int, unsigned int);
++extern int gpio_get_value(unsigned int);
++unsigned int gpio_cts = 0;
++unsigned int gpio_rts;
++#endif
++
+ #ifdef CONFIG_SPARC
+ #include "suncore.h"
+ #endif
+@@ -622,6 +632,7 @@ static void serial_icr_write(struct uart
+ 	serial_out(up, UART_ICR, value);
+ }
+ 
++#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100)
+ static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
+ {
+ 	unsigned int value;
+@@ -633,6 +644,7 @@ static unsigned int serial_icr_read(stru
+ 
+ 	return value;
+ }
++#endif
+ 
+ /*
+  * FIFO support.
+@@ -738,6 +750,13 @@ static void disable_rsa(struct uart_8250
+ }
+ #endif /* CONFIG_SERIAL_8250_RSA */
+ 
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
++{
++	up->port.type = PORT_16550A;
++	return;
++}
++#else
+ /*
+  * This is a quickie test to see how big the FIFO is.
+  * It doesn't work at all the time, more's the pity.
+@@ -1253,6 +1272,7 @@ static void autoconfig(struct uart_8250_
+ 	spin_unlock_irqrestore(&up->port.lock, flags);
+ 	DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
+ }
++#endif
+ 
+ static void autoconfig_irq(struct uart_8250_port *up)
+ {
+@@ -1447,6 +1467,15 @@ receive_chars(struct uart_8250_port *up,
+ ignore_char:
+ 		lsr = serial_inp(up, UART_LSR);
+ 	} while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
++   
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++	if (gpio_rts)
++	{
++		gpio_set_value(CONFIG_GPIO_RTS,0);	/* assert RTS */
++		gpio_rts = 0;
++	}
++#endif   
++   
+ 	spin_unlock(&up->port.lock);
+ 	tty_flip_buffer_push(tty);
+ 	spin_lock(&up->port.lock);
+@@ -1465,6 +1494,10 @@ static void transmit_chars(struct uart_8
+ 		return;
+ 	}
+ 	if (uart_tx_stopped(&up->port)) {
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++		if (gpio_cts)
++			return;
++#endif      
+ 		serial8250_stop_tx(&up->port);
+ 		return;
+ 	}
+@@ -1495,6 +1528,22 @@ static unsigned int check_modem_status(s
+ {
+ 	unsigned int status = serial_in(up, UART_MSR);
+ 
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++	unsigned int gpio_new_cts = gpio_get_value(CONFIG_GPIO_CTS);
++
++	if (!gpio_new_cts)
++		status |= UART_MSR_CTS;		/* Assert CTS */
++	else
++		status &= ~UART_MSR_CTS;	/* Deassert CTS */
++
++	/* CTS pin has been changed */
++	if (gpio_new_cts != gpio_cts)
++	{
++		status |= UART_MSR_DCTS;
++		gpio_cts = gpio_new_cts;
++	}
++#endif
++
+ 	status |= up->msr_saved_flags;
+ 	up->msr_saved_flags = 0;
+ 	if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
+@@ -1521,10 +1570,24 @@ static void serial8250_handle_port(struc
+ {
+ 	unsigned int status;
+ 	unsigned long flags;
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++	unsigned int iir;
++#endif
+ 
+ 	spin_lock_irqsave(&up->port.lock, flags);
+ 
+ 	status = serial_inp(up, UART_LSR);
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++		iir = serial_in(up, UART_IIR);
++
++		if ((iir & 0x6) == 0x6)
++			printk("Overrun error!\n");
++		else if (iir & 0x4)
++		{
++			gpio_set_value(CONFIG_GPIO_RTS,1);		
++			gpio_rts = 1;
++		}
++#endif
+ 
+ 	DEBUG_INTR("status = %x...", status);
+ 
+@@ -1819,7 +1882,19 @@ static void serial8250_set_mctrl(struct
+ 	unsigned char mcr = 0;
+ 
+ 	if (mctrl & TIOCM_RTS)
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++	{
+ 		mcr |= UART_MCR_RTS;
++		gpio_set_value(CONFIG_GPIO_RTS,0);	/* assert RTS */
++	}
++	else
++	{
++		mcr &= ~UART_MCR_RTS;
++		gpio_set_value(CONFIG_GPIO_RTS,1);	/* deassert RTS */
++	}
++#else
++		mcr |= UART_MCR_RTS;
++#endif
+ 	if (mctrl & TIOCM_DTR)
+ 		mcr |= UART_MCR_DTR;
+ 	if (mctrl & TIOCM_OUT1)
+@@ -1938,6 +2013,9 @@ static int serial8250_startup(struct uar
+ {
+ 	struct uart_8250_port *up = (struct uart_8250_port *)port;
+ 	unsigned long flags;
++#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100)
++	unsigned char lsr;
++#endif   
+ 	unsigned char lsr, iir;
+ 	int retval;
+ 
+@@ -2107,6 +2185,7 @@ static int serial8250_startup(struct uar
+ 	if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST)
+ 		goto dont_test_tx_en;
+ 
++#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100)   
+ 	/*
+ 	 * Do a quick test to see if we receive an
+ 	 * interrupt when we enable the TX irq.
+@@ -2125,6 +2204,7 @@ static int serial8250_startup(struct uar
+ 	} else {
+ 		up->bugs &= ~UART_BUG_TXEN;
+ 	}
++#endif
+ 
+ dont_test_tx_en:
+ 	spin_unlock_irqrestore(&up->port.lock, flags);
+@@ -2812,7 +2892,11 @@ serial8250_console_write(struct console
+ static int __init serial8250_console_setup(struct console *co, char *options)
+ {
+ 	struct uart_port *port;
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++	int baud = CONFIG_CONSOLE_BAUD_RATE;
++#else
+ 	int baud = 9600;
++#endif
+ 	int bits = 8;
+ 	int parity = 'n';
+ 	int flow = 'n';
+@@ -3023,6 +3107,7 @@ static int __devexit serial8250_remove(s
+ 	return 0;
+ }
+ 
++#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100)
+ static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
+ {
+ 	int i;
+@@ -3050,12 +3135,15 @@ static int serial8250_resume(struct plat
+ 
+ 	return 0;
+ }
++#endif
+ 
+ static struct platform_driver serial8250_isa_driver = {
+ 	.probe		= serial8250_probe,
+ 	.remove		= __devexit_p(serial8250_remove),
++#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100)
+ 	.suspend	= serial8250_suspend,
+ 	.resume		= serial8250_resume,
++#endif
+ 	.driver		= {
+ 		.name	= "serial8250",
+ 		.owner	= THIS_MODULE,
+@@ -3197,6 +3285,31 @@ static int __init serial8250_init(void)
+ {
+ 	int ret;
+ 
++#ifdef CONFIG_SERIAL_8250_CTSRTS
++	/* enable GPIO pin function */
++	MISC_GPIOB_PIN_ENABLE_REG &= ~(1 << CONFIG_GPIO_CTS | 1 << CONFIG_GPIO_RTS | 1 << CONFIG_GPIO_DCD \
++						| 1<<CONFIG_GPIO_DTR | 1<<CONFIG_GPIO_DSR | 1<<CONFIG_GPIO_RI);
++
++	/* configure CTS pin (input) */
++	gpio_direction_input(CONFIG_GPIO_CTS);
++	gpio_cts = gpio_get_value(CONFIG_GPIO_CTS);
++
++	/* configure RTS pin (output) and set to high */
++	gpio_direction_output(CONFIG_GPIO_RTS,1);
++
++	/* configure DCD pin (input) */
++	gpio_direction_input(CONFIG_GPIO_DCD);
++
++	/* configure DTR pin (ouput) and set to low */
++	gpio_direction_output(CONFIG_GPIO_DTR,0);
++
++	/* configure DSR pin (input) */
++	gpio_direction_input(CONFIG_GPIO_DSR);
++
++	/* configure RI pin (input) */
++	gpio_direction_input(CONFIG_GPIO_RI);
++#endif
++
+ 	if (nr_uarts > UART_NR)
+ 		nr_uarts = UART_NR;
+ 
+diff -rupN linux-2.6.35.11/drivers/serial/8250.c.orig linux-2.6.35.11-ts7500/drivers/serial/8250.c.orig
+--- linux-2.6.35.11/drivers/serial/8250.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/serial/8250.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,3290 @@
++/*
++ *  linux/drivers/char/8250.c
++ *
++ *  Driver for 8250/16550-type serial ports
++ *
++ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
++ *
++ *  Copyright (C) 2001 Russell King.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * A note about mapbase / membase
++ *
++ *  mapbase is the physical address of the IO port.
++ *  membase is an 'ioremapped' cookie.
++ */
++
++#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++#define SUPPORT_SYSRQ
++#endif
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/ioport.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/sysrq.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial_reg.h>
++#include <linux/serial_core.h>
++#include <linux/serial.h>
++#include <linux/serial_8250.h>
++#include <linux/nmi.h>
++#include <linux/mutex.h>
++#include <linux/slab.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#include "8250.h"
++
++#ifdef CONFIG_SPARC
++#include "suncore.h"
++#endif
++
++/*
++ * Configuration:
++ *   share_irqs - whether we pass IRQF_SHARED to request_irq().  This option
++ *                is unsafe when used on edge-triggered interrupts.
++ */
++static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
++
++static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
++
++static struct uart_driver serial8250_reg;
++
++static int serial_index(struct uart_port *port)
++{
++	return (serial8250_reg.minor - 64) + port->line;
++}
++
++static unsigned int skip_txen_test; /* force skip of txen test at init time */
++
++/*
++ * Debugging.
++ */
++#if 0
++#define DEBUG_AUTOCONF(fmt...)	printk(fmt)
++#else
++#define DEBUG_AUTOCONF(fmt...)	do { } while (0)
++#endif
++
++#if 0
++#define DEBUG_INTR(fmt...)	printk(fmt)
++#else
++#define DEBUG_INTR(fmt...)	do { } while (0)
++#endif
++
++#define PASS_LIMIT	256
++
++#define BOTH_EMPTY 	(UART_LSR_TEMT | UART_LSR_THRE)
++
++
++/*
++ * We default to IRQ0 for the "no irq" hack.   Some
++ * machine types want others as well - they're free
++ * to redefine this in their header file.
++ */
++#define is_real_interrupt(irq)	((irq) != 0)
++
++#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
++#define CONFIG_SERIAL_DETECT_IRQ 1
++#endif
++#ifdef CONFIG_SERIAL_8250_MANY_PORTS
++#define CONFIG_SERIAL_MANY_PORTS 1
++#endif
++
++/*
++ * HUB6 is always on.  This will be removed once the header
++ * files have been cleaned.
++ */
++#define CONFIG_HUB6 1
++
++#include <asm/serial.h>
++/*
++ * SERIAL_PORT_DFNS tells us about built-in ports that have no
++ * standard enumeration mechanism.   Platforms that can find all
++ * serial ports via mechanisms like ACPI or PCI need not supply it.
++ */
++#ifndef SERIAL_PORT_DFNS
++#define SERIAL_PORT_DFNS
++#endif
++
++static const struct old_serial_port old_serial_port[] = {
++	SERIAL_PORT_DFNS /* defined in asm/serial.h */
++};
++
++#define UART_NR	CONFIG_SERIAL_8250_NR_UARTS
++
++#ifdef CONFIG_SERIAL_8250_RSA
++
++#define PORT_RSA_MAX 4
++static unsigned long probe_rsa[PORT_RSA_MAX];
++static unsigned int probe_rsa_count;
++#endif /* CONFIG_SERIAL_8250_RSA  */
++
++struct uart_8250_port {
++	struct uart_port	port;
++	struct timer_list	timer;		/* "no irq" timer */
++	struct list_head	list;		/* ports on this IRQ */
++	unsigned short		capabilities;	/* port capabilities */
++	unsigned short		bugs;		/* port bugs */
++	unsigned int		tx_loadsz;	/* transmit fifo load size */
++	unsigned char		acr;
++	unsigned char		ier;
++	unsigned char		lcr;
++	unsigned char		mcr;
++	unsigned char		mcr_mask;	/* mask of user bits */
++	unsigned char		mcr_force;	/* mask of forced bits */
++	unsigned char		cur_iotype;	/* Running I/O type */
++
++	/*
++	 * Some bits in registers are cleared on a read, so they must
++	 * be saved whenever the register is read but the bits will not
++	 * be immediately processed.
++	 */
++#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
++	unsigned char		lsr_saved_flags;
++#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
++	unsigned char		msr_saved_flags;
++
++	/*
++	 * We provide a per-port pm hook.
++	 */
++	void			(*pm)(struct uart_port *port,
++				      unsigned int state, unsigned int old);
++};
++
++struct irq_info {
++	struct			hlist_node node;
++	int			irq;
++	spinlock_t		lock;	/* Protects list not the hash */
++	struct list_head	*head;
++};
++
++#define NR_IRQ_HASH		32	/* Can be adjusted later */
++static struct hlist_head irq_lists[NR_IRQ_HASH];
++static DEFINE_MUTEX(hash_mutex);	/* Used to walk the hash */
++
++/*
++ * Here we define the default xmit fifo size used for each type of UART.
++ */
++static const struct serial8250_config uart_config[] = {
++	[PORT_UNKNOWN] = {
++		.name		= "unknown",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_8250] = {
++		.name		= "8250",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_16450] = {
++		.name		= "16450",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_16550] = {
++		.name		= "16550",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_16550A] = {
++		.name		= "16550A",
++		.fifo_size	= 16,
++		.tx_loadsz	= 16,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO,
++	},
++	[PORT_CIRRUS] = {
++		.name		= "Cirrus",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_16650] = {
++		.name		= "ST16650",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++	},
++	[PORT_16650V2] = {
++		.name		= "ST16650V2",
++		.fifo_size	= 32,
++		.tx_loadsz	= 16,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
++				  UART_FCR_T_TRIG_00,
++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++	},
++	[PORT_16750] = {
++		.name		= "TI16750",
++		.fifo_size	= 64,
++		.tx_loadsz	= 64,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
++				  UART_FCR7_64BYTE,
++		.flags		= UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE,
++	},
++	[PORT_STARTECH] = {
++		.name		= "Startech",
++		.fifo_size	= 1,
++		.tx_loadsz	= 1,
++	},
++	[PORT_16C950] = {
++		.name		= "16C950/954",
++		.fifo_size	= 128,
++		.tx_loadsz	= 128,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO,
++	},
++	[PORT_16654] = {
++		.name		= "ST16654",
++		.fifo_size	= 64,
++		.tx_loadsz	= 32,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
++				  UART_FCR_T_TRIG_10,
++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++	},
++	[PORT_16850] = {
++		.name		= "XR16850",
++		.fifo_size	= 128,
++		.tx_loadsz	= 128,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
++	},
++	[PORT_RSA] = {
++		.name		= "RSA",
++		.fifo_size	= 2048,
++		.tx_loadsz	= 2048,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11,
++		.flags		= UART_CAP_FIFO,
++	},
++	[PORT_NS16550A] = {
++		.name		= "NS16550A",
++		.fifo_size	= 16,
++		.tx_loadsz	= 16,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO | UART_NATSEMI,
++	},
++	[PORT_XSCALE] = {
++		.name		= "XScale",
++		.fifo_size	= 32,
++		.tx_loadsz	= 32,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO | UART_CAP_UUE,
++	},
++	[PORT_RM9000] = {
++		.name		= "RM9000",
++		.fifo_size	= 16,
++		.tx_loadsz	= 16,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO,
++	},
++	[PORT_OCTEON] = {
++		.name		= "OCTEON",
++		.fifo_size	= 64,
++		.tx_loadsz	= 64,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++		.flags		= UART_CAP_FIFO,
++	},
++	[PORT_AR7] = {
++		.name		= "AR7",
++		.fifo_size	= 16,
++		.tx_loadsz	= 16,
++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
++		.flags		= UART_CAP_FIFO | UART_CAP_AFE,
++	},
++};
++
++#if defined (CONFIG_SERIAL_8250_AU1X00)
++
++/* Au1x00 UART hardware has a weird register layout */
++static const u8 au_io_in_map[] = {
++	[UART_RX]  = 0,
++	[UART_IER] = 2,
++	[UART_IIR] = 3,
++	[UART_LCR] = 5,
++	[UART_MCR] = 6,
++	[UART_LSR] = 7,
++	[UART_MSR] = 8,
++};
++
++static const u8 au_io_out_map[] = {
++	[UART_TX]  = 1,
++	[UART_IER] = 2,
++	[UART_FCR] = 4,
++	[UART_LCR] = 5,
++	[UART_MCR] = 6,
++};
++
++/* sane hardware needs no mapping */
++static inline int map_8250_in_reg(struct uart_port *p, int offset)
++{
++	if (p->iotype != UPIO_AU)
++		return offset;
++	return au_io_in_map[offset];
++}
++
++static inline int map_8250_out_reg(struct uart_port *p, int offset)
++{
++	if (p->iotype != UPIO_AU)
++		return offset;
++	return au_io_out_map[offset];
++}
++
++#elif defined(CONFIG_SERIAL_8250_RM9K)
++
++static const u8
++	regmap_in[8] = {
++		[UART_RX]	= 0x00,
++		[UART_IER]	= 0x0c,
++		[UART_IIR]	= 0x14,
++		[UART_LCR]	= 0x1c,
++		[UART_MCR]	= 0x20,
++		[UART_LSR]	= 0x24,
++		[UART_MSR]	= 0x28,
++		[UART_SCR]	= 0x2c
++	},
++	regmap_out[8] = {
++		[UART_TX] 	= 0x04,
++		[UART_IER]	= 0x0c,
++		[UART_FCR]	= 0x18,
++		[UART_LCR]	= 0x1c,
++		[UART_MCR]	= 0x20,
++		[UART_LSR]	= 0x24,
++		[UART_MSR]	= 0x28,
++		[UART_SCR]	= 0x2c
++	};
++
++static inline int map_8250_in_reg(struct uart_port *p, int offset)
++{
++	if (p->iotype != UPIO_RM9000)
++		return offset;
++	return regmap_in[offset];
++}
++
++static inline int map_8250_out_reg(struct uart_port *p, int offset)
++{
++	if (p->iotype != UPIO_RM9000)
++		return offset;
++	return regmap_out[offset];
++}
++
++#else
++
++/* sane hardware needs no mapping */
++#define map_8250_in_reg(up, offset) (offset)
++#define map_8250_out_reg(up, offset) (offset)
++
++#endif
++
++static unsigned int hub6_serial_in(struct uart_port *p, int offset)
++{
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	outb(p->hub6 - 1 + offset, p->iobase);
++	return inb(p->iobase + 1);
++}
++
++static void hub6_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	outb(p->hub6 - 1 + offset, p->iobase);
++	outb(value, p->iobase + 1);
++}
++
++static unsigned int mem_serial_in(struct uart_port *p, int offset)
++{
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	return readb(p->membase + offset);
++}
++
++static void mem_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	writeb(value, p->membase + offset);
++}
++
++static void mem32_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	writel(value, p->membase + offset);
++}
++
++static unsigned int mem32_serial_in(struct uart_port *p, int offset)
++{
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	return readl(p->membase + offset);
++}
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++static unsigned int au_serial_in(struct uart_port *p, int offset)
++{
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	return __raw_readl(p->membase + offset);
++}
++
++static void au_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	__raw_writel(value, p->membase + offset);
++}
++#endif
++
++static unsigned int tsi_serial_in(struct uart_port *p, int offset)
++{
++	unsigned int tmp;
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	if (offset == UART_IIR) {
++		tmp = readl(p->membase + (UART_IIR & ~3));
++		return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
++	} else
++		return readb(p->membase + offset);
++}
++
++static void tsi_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	if (!((offset == UART_IER) && (value & UART_IER_UUE)))
++		writeb(value, p->membase + offset);
++}
++
++static void dwapb_serial_out(struct uart_port *p, int offset, int value)
++{
++	int save_offset = offset;
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	/* Save the LCR value so it can be re-written when a
++	 * Busy Detect interrupt occurs. */
++	if (save_offset == UART_LCR) {
++		struct uart_8250_port *up = (struct uart_8250_port *)p;
++		up->lcr = value;
++	}
++	writeb(value, p->membase + offset);
++	/* Read the IER to ensure any interrupt is cleared before
++	 * returning from ISR. */
++	if (save_offset == UART_TX || save_offset == UART_IER)
++		value = p->serial_in(p, UART_IER);
++}
++
++static unsigned int io_serial_in(struct uart_port *p, int offset)
++{
++	offset = map_8250_in_reg(p, offset) << p->regshift;
++	return inb(p->iobase + offset);
++}
++
++static void io_serial_out(struct uart_port *p, int offset, int value)
++{
++	offset = map_8250_out_reg(p, offset) << p->regshift;
++	outb(value, p->iobase + offset);
++}
++
++static void set_io_from_upio(struct uart_port *p)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)p;
++	switch (p->iotype) {
++	case UPIO_HUB6:
++		p->serial_in = hub6_serial_in;
++		p->serial_out = hub6_serial_out;
++		break;
++
++	case UPIO_MEM:
++		p->serial_in = mem_serial_in;
++		p->serial_out = mem_serial_out;
++		break;
++
++	case UPIO_RM9000:
++	case UPIO_MEM32:
++		p->serial_in = mem32_serial_in;
++		p->serial_out = mem32_serial_out;
++		break;
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++	case UPIO_AU:
++		p->serial_in = au_serial_in;
++		p->serial_out = au_serial_out;
++		break;
++#endif
++	case UPIO_TSI:
++		p->serial_in = tsi_serial_in;
++		p->serial_out = tsi_serial_out;
++		break;
++
++	case UPIO_DWAPB:
++		p->serial_in = mem_serial_in;
++		p->serial_out = dwapb_serial_out;
++		break;
++
++	default:
++		p->serial_in = io_serial_in;
++		p->serial_out = io_serial_out;
++		break;
++	}
++	/* Remember loaded iotype */
++	up->cur_iotype = p->iotype;
++}
++
++static void
++serial_out_sync(struct uart_8250_port *up, int offset, int value)
++{
++	struct uart_port *p = &up->port;
++	switch (p->iotype) {
++	case UPIO_MEM:
++	case UPIO_MEM32:
++#ifdef CONFIG_SERIAL_8250_AU1X00
++	case UPIO_AU:
++#endif
++	case UPIO_DWAPB:
++		p->serial_out(p, offset, value);
++		p->serial_in(p, UART_LCR);	/* safe, no side-effects */
++		break;
++	default:
++		p->serial_out(p, offset, value);
++	}
++}
++
++#define serial_in(up, offset)		\
++	(up->port.serial_in(&(up)->port, (offset)))
++#define serial_out(up, offset, value)	\
++	(up->port.serial_out(&(up)->port, (offset), (value)))
++/*
++ * We used to support using pause I/O for certain machines.  We
++ * haven't supported this for a while, but just in case it's badly
++ * needed for certain old 386 machines, I've left these #define's
++ * in....
++ */
++#define serial_inp(up, offset)		serial_in(up, offset)
++#define serial_outp(up, offset, value)	serial_out(up, offset, value)
++
++/* Uart divisor latch read */
++static inline int _serial_dl_read(struct uart_8250_port *up)
++{
++	return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8;
++}
++
++/* Uart divisor latch write */
++static inline void _serial_dl_write(struct uart_8250_port *up, int value)
++{
++	serial_outp(up, UART_DLL, value & 0xff);
++	serial_outp(up, UART_DLM, value >> 8 & 0xff);
++}
++
++#if defined(CONFIG_SERIAL_8250_AU1X00)
++/* Au1x00 haven't got a standard divisor latch */
++static int serial_dl_read(struct uart_8250_port *up)
++{
++	if (up->port.iotype == UPIO_AU)
++		return __raw_readl(up->port.membase + 0x28);
++	else
++		return _serial_dl_read(up);
++}
++
++static void serial_dl_write(struct uart_8250_port *up, int value)
++{
++	if (up->port.iotype == UPIO_AU)
++		__raw_writel(value, up->port.membase + 0x28);
++	else
++		_serial_dl_write(up, value);
++}
++#elif defined(CONFIG_SERIAL_8250_RM9K)
++static int serial_dl_read(struct uart_8250_port *up)
++{
++	return	(up->port.iotype == UPIO_RM9000) ?
++		(((__raw_readl(up->port.membase + 0x10) << 8) |
++		(__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
++		_serial_dl_read(up);
++}
++
++static void serial_dl_write(struct uart_8250_port *up, int value)
++{
++	if (up->port.iotype == UPIO_RM9000) {
++		__raw_writel(value, up->port.membase + 0x08);
++		__raw_writel(value >> 8, up->port.membase + 0x10);
++	} else {
++		_serial_dl_write(up, value);
++	}
++}
++#else
++#define serial_dl_read(up) _serial_dl_read(up)
++#define serial_dl_write(up, value) _serial_dl_write(up, value)
++#endif
++
++/*
++ * For the 16C950
++ */
++static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
++{
++	serial_out(up, UART_SCR, offset);
++	serial_out(up, UART_ICR, value);
++}
++
++static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
++{
++	unsigned int value;
++
++	serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
++	serial_out(up, UART_SCR, offset);
++	value = serial_in(up, UART_ICR);
++	serial_icr_write(up, UART_ACR, up->acr);
++
++	return value;
++}
++
++/*
++ * FIFO support.
++ */
++static void serial8250_clear_fifos(struct uart_8250_port *p)
++{
++	if (p->capabilities & UART_CAP_FIFO) {
++		serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO);
++		serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO |
++			       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
++		serial_outp(p, UART_FCR, 0);
++	}
++}
++
++/*
++ * IER sleep support.  UARTs which have EFRs need the "extended
++ * capability" bit enabled.  Note that on XR16C850s, we need to
++ * reset LCR to write to IER.
++ */
++static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
++{
++	if (p->capabilities & UART_CAP_SLEEP) {
++		if (p->capabilities & UART_CAP_EFR) {
++			serial_outp(p, UART_LCR, 0xBF);
++			serial_outp(p, UART_EFR, UART_EFR_ECB);
++			serial_outp(p, UART_LCR, 0);
++		}
++		serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
++		if (p->capabilities & UART_CAP_EFR) {
++			serial_outp(p, UART_LCR, 0xBF);
++			serial_outp(p, UART_EFR, 0);
++			serial_outp(p, UART_LCR, 0);
++		}
++	}
++}
++
++#ifdef CONFIG_SERIAL_8250_RSA
++/*
++ * Attempts to turn on the RSA FIFO.  Returns zero on failure.
++ * We set the port uart clock rate if we succeed.
++ */
++static int __enable_rsa(struct uart_8250_port *up)
++{
++	unsigned char mode;
++	int result;
++
++	mode = serial_inp(up, UART_RSA_MSR);
++	result = mode & UART_RSA_MSR_FIFO;
++
++	if (!result) {
++		serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
++		mode = serial_inp(up, UART_RSA_MSR);
++		result = mode & UART_RSA_MSR_FIFO;
++	}
++
++	if (result)
++		up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
++
++	return result;
++}
++
++static void enable_rsa(struct uart_8250_port *up)
++{
++	if (up->port.type == PORT_RSA) {
++		if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
++			spin_lock_irq(&up->port.lock);
++			__enable_rsa(up);
++			spin_unlock_irq(&up->port.lock);
++		}
++		if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
++			serial_outp(up, UART_RSA_FRR, 0);
++	}
++}
++
++/*
++ * Attempts to turn off the RSA FIFO.  Returns zero on failure.
++ * It is unknown why interrupts were disabled in here.  However,
++ * the caller is expected to preserve this behaviour by grabbing
++ * the spinlock before calling this function.
++ */
++static void disable_rsa(struct uart_8250_port *up)
++{
++	unsigned char mode;
++	int result;
++
++	if (up->port.type == PORT_RSA &&
++	    up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
++		spin_lock_irq(&up->port.lock);
++
++		mode = serial_inp(up, UART_RSA_MSR);
++		result = !(mode & UART_RSA_MSR_FIFO);
++
++		if (!result) {
++			serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
++			mode = serial_inp(up, UART_RSA_MSR);
++			result = !(mode & UART_RSA_MSR_FIFO);
++		}
++
++		if (result)
++			up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
++		spin_unlock_irq(&up->port.lock);
++	}
++}
++#endif /* CONFIG_SERIAL_8250_RSA */
++
++/*
++ * This is a quickie test to see how big the FIFO is.
++ * It doesn't work at all the time, more's the pity.
++ */
++static int size_fifo(struct uart_8250_port *up)
++{
++	unsigned char old_fcr, old_mcr, old_lcr;
++	unsigned short old_dl;
++	int count;
++
++	old_lcr = serial_inp(up, UART_LCR);
++	serial_outp(up, UART_LCR, 0);
++	old_fcr = serial_inp(up, UART_FCR);
++	old_mcr = serial_inp(up, UART_MCR);
++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
++		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
++	serial_outp(up, UART_MCR, UART_MCR_LOOP);
++	serial_outp(up, UART_LCR, UART_LCR_DLAB);
++	old_dl = serial_dl_read(up);
++	serial_dl_write(up, 0x0001);
++	serial_outp(up, UART_LCR, 0x03);
++	for (count = 0; count < 256; count++)
++		serial_outp(up, UART_TX, count);
++	mdelay(20);/* FIXME - schedule_timeout */
++	for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) &&
++	     (count < 256); count++)
++		serial_inp(up, UART_RX);
++	serial_outp(up, UART_FCR, old_fcr);
++	serial_outp(up, UART_MCR, old_mcr);
++	serial_outp(up, UART_LCR, UART_LCR_DLAB);
++	serial_dl_write(up, old_dl);
++	serial_outp(up, UART_LCR, old_lcr);
++
++	return count;
++}
++
++/*
++ * Read UART ID using the divisor method - set DLL and DLM to zero
++ * and the revision will be in DLL and device type in DLM.  We
++ * preserve the device state across this.
++ */
++static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
++{
++	unsigned char old_dll, old_dlm, old_lcr;
++	unsigned int id;
++
++	old_lcr = serial_inp(p, UART_LCR);
++	serial_outp(p, UART_LCR, UART_LCR_DLAB);
++
++	old_dll = serial_inp(p, UART_DLL);
++	old_dlm = serial_inp(p, UART_DLM);
++
++	serial_outp(p, UART_DLL, 0);
++	serial_outp(p, UART_DLM, 0);
++
++	id = serial_inp(p, UART_DLL) | serial_inp(p, UART_DLM) << 8;
++
++	serial_outp(p, UART_DLL, old_dll);
++	serial_outp(p, UART_DLM, old_dlm);
++	serial_outp(p, UART_LCR, old_lcr);
++
++	return id;
++}
++
++/*
++ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
++ * When this function is called we know it is at least a StarTech
++ * 16650 V2, but it might be one of several StarTech UARTs, or one of
++ * its clones.  (We treat the broken original StarTech 16650 V1 as a
++ * 16550, and why not?  Startech doesn't seem to even acknowledge its
++ * existence.)
++ *
++ * What evil have men's minds wrought...
++ */
++static void autoconfig_has_efr(struct uart_8250_port *up)
++{
++	unsigned int id1, id2, id3, rev;
++
++	/*
++	 * Everything with an EFR has SLEEP
++	 */
++	up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
++
++	/*
++	 * First we check to see if it's an Oxford Semiconductor UART.
++	 *
++	 * If we have to do this here because some non-National
++	 * Semiconductor clone chips lock up if you try writing to the
++	 * LSR register (which serial_icr_read does)
++	 */
++
++	/*
++	 * Check for Oxford Semiconductor 16C950.
++	 *
++	 * EFR [4] must be set else this test fails.
++	 *
++	 * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
++	 * claims that it's needed for 952 dual UART's (which are not
++	 * recommended for new designs).
++	 */
++	up->acr = 0;
++	serial_out(up, UART_LCR, 0xBF);
++	serial_out(up, UART_EFR, UART_EFR_ECB);
++	serial_out(up, UART_LCR, 0x00);
++	id1 = serial_icr_read(up, UART_ID1);
++	id2 = serial_icr_read(up, UART_ID2);
++	id3 = serial_icr_read(up, UART_ID3);
++	rev = serial_icr_read(up, UART_REV);
++
++	DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
++
++	if (id1 == 0x16 && id2 == 0xC9 &&
++	    (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
++		up->port.type = PORT_16C950;
++
++		/*
++		 * Enable work around for the Oxford Semiconductor 952 rev B
++		 * chip which causes it to seriously miscalculate baud rates
++		 * when DLL is 0.
++		 */
++		if (id3 == 0x52 && rev == 0x01)
++			up->bugs |= UART_BUG_QUOT;
++		return;
++	}
++
++	/*
++	 * We check for a XR16C850 by setting DLL and DLM to 0, and then
++	 * reading back DLL and DLM.  The chip type depends on the DLM
++	 * value read back:
++	 *  0x10 - XR16C850 and the DLL contains the chip revision.
++	 *  0x12 - XR16C2850.
++	 *  0x14 - XR16C854.
++	 */
++	id1 = autoconfig_read_divisor_id(up);
++	DEBUG_AUTOCONF("850id=%04x ", id1);
++
++	id2 = id1 >> 8;
++	if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
++		up->port.type = PORT_16850;
++		return;
++	}
++
++	/*
++	 * It wasn't an XR16C850.
++	 *
++	 * We distinguish between the '654 and the '650 by counting
++	 * how many bytes are in the FIFO.  I'm using this for now,
++	 * since that's the technique that was sent to me in the
++	 * serial driver update, but I'm not convinced this works.
++	 * I've had problems doing this in the past.  -TYT
++	 */
++	if (size_fifo(up) == 64)
++		up->port.type = PORT_16654;
++	else
++		up->port.type = PORT_16650V2;
++}
++
++/*
++ * We detected a chip without a FIFO.  Only two fall into
++ * this category - the original 8250 and the 16450.  The
++ * 16450 has a scratch register (accessible with LCR=0)
++ */
++static void autoconfig_8250(struct uart_8250_port *up)
++{
++	unsigned char scratch, status1, status2;
++
++	up->port.type = PORT_8250;
++
++	scratch = serial_in(up, UART_SCR);
++	serial_outp(up, UART_SCR, 0xa5);
++	status1 = serial_in(up, UART_SCR);
++	serial_outp(up, UART_SCR, 0x5a);
++	status2 = serial_in(up, UART_SCR);
++	serial_outp(up, UART_SCR, scratch);
++
++	if (status1 == 0xa5 && status2 == 0x5a)
++		up->port.type = PORT_16450;
++}
++
++static int broken_efr(struct uart_8250_port *up)
++{
++	/*
++	 * Exar ST16C2550 "A2" devices incorrectly detect as
++	 * having an EFR, and report an ID of 0x0201.  See
++	 * http://www.exar.com/info.php?pdf=dan180_oct2004.pdf
++	 */
++	if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
++		return 1;
++
++	return 0;
++}
++
++/*
++ * We know that the chip has FIFOs.  Does it have an EFR?  The
++ * EFR is located in the same register position as the IIR and
++ * we know the top two bits of the IIR are currently set.  The
++ * EFR should contain zero.  Try to read the EFR.
++ */
++static void autoconfig_16550a(struct uart_8250_port *up)
++{
++	unsigned char status1, status2;
++	unsigned int iersave;
++
++	up->port.type = PORT_16550A;
++	up->capabilities |= UART_CAP_FIFO;
++
++	/*
++	 * Check for presence of the EFR when DLAB is set.
++	 * Only ST16C650V1 UARTs pass this test.
++	 */
++	serial_outp(up, UART_LCR, UART_LCR_DLAB);
++	if (serial_in(up, UART_EFR) == 0) {
++		serial_outp(up, UART_EFR, 0xA8);
++		if (serial_in(up, UART_EFR) != 0) {
++			DEBUG_AUTOCONF("EFRv1 ");
++			up->port.type = PORT_16650;
++			up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
++		} else {
++			DEBUG_AUTOCONF("Motorola 8xxx DUART ");
++		}
++		serial_outp(up, UART_EFR, 0);
++		return;
++	}
++
++	/*
++	 * Maybe it requires 0xbf to be written to the LCR.
++	 * (other ST16C650V2 UARTs, TI16C752A, etc)
++	 */
++	serial_outp(up, UART_LCR, 0xBF);
++	if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
++		DEBUG_AUTOCONF("EFRv2 ");
++		autoconfig_has_efr(up);
++		return;
++	}
++
++	/*
++	 * Check for a National Semiconductor SuperIO chip.
++	 * Attempt to switch to bank 2, read the value of the LOOP bit
++	 * from EXCR1. Switch back to bank 0, change it in MCR. Then
++	 * switch back to bank 2, read it from EXCR1 again and check
++	 * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
++	 */
++	serial_outp(up, UART_LCR, 0);
++	status1 = serial_in(up, UART_MCR);
++	serial_outp(up, UART_LCR, 0xE0);
++	status2 = serial_in(up, 0x02); /* EXCR1 */
++
++	if (!((status2 ^ status1) & UART_MCR_LOOP)) {
++		serial_outp(up, UART_LCR, 0);
++		serial_outp(up, UART_MCR, status1 ^ UART_MCR_LOOP);
++		serial_outp(up, UART_LCR, 0xE0);
++		status2 = serial_in(up, 0x02); /* EXCR1 */
++		serial_outp(up, UART_LCR, 0);
++		serial_outp(up, UART_MCR, status1);
++
++		if ((status2 ^ status1) & UART_MCR_LOOP) {
++			unsigned short quot;
++
++			serial_outp(up, UART_LCR, 0xE0);
++
++			quot = serial_dl_read(up);
++			quot <<= 3;
++
++			status1 = serial_in(up, 0x04); /* EXCR2 */
++			status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
++			status1 |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
++			serial_outp(up, 0x04, status1);
++
++			serial_dl_write(up, quot);
++
++			serial_outp(up, UART_LCR, 0);
++
++			up->port.uartclk = 921600*16;
++			up->port.type = PORT_NS16550A;
++			up->capabilities |= UART_NATSEMI;
++			return;
++		}
++	}
++
++	/*
++	 * No EFR.  Try to detect a TI16750, which only sets bit 5 of
++	 * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
++	 * Try setting it with and without DLAB set.  Cheap clones
++	 * set bit 5 without DLAB set.
++	 */
++	serial_outp(up, UART_LCR, 0);
++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
++	status1 = serial_in(up, UART_IIR) >> 5;
++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++	serial_outp(up, UART_LCR, UART_LCR_DLAB);
++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
++	status2 = serial_in(up, UART_IIR) >> 5;
++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++	serial_outp(up, UART_LCR, 0);
++
++	DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
++
++	if (status1 == 6 && status2 == 7) {
++		up->port.type = PORT_16750;
++		up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP;
++		return;
++	}
++
++	/*
++	 * Try writing and reading the UART_IER_UUE bit (b6).
++	 * If it works, this is probably one of the Xscale platform's
++	 * internal UARTs.
++	 * We're going to explicitly set the UUE bit to 0 before
++	 * trying to write and read a 1 just to make sure it's not
++	 * already a 1 and maybe locked there before we even start start.
++	 */
++	iersave = serial_in(up, UART_IER);
++	serial_outp(up, UART_IER, iersave & ~UART_IER_UUE);
++	if (!(serial_in(up, UART_IER) & UART_IER_UUE)) {
++		/*
++		 * OK it's in a known zero state, try writing and reading
++		 * without disturbing the current state of the other bits.
++		 */
++		serial_outp(up, UART_IER, iersave | UART_IER_UUE);
++		if (serial_in(up, UART_IER) & UART_IER_UUE) {
++			/*
++			 * It's an Xscale.
++			 * We'll leave the UART_IER_UUE bit set to 1 (enabled).
++			 */
++			DEBUG_AUTOCONF("Xscale ");
++			up->port.type = PORT_XSCALE;
++			up->capabilities |= UART_CAP_UUE;
++			return;
++		}
++	} else {
++		/*
++		 * If we got here we couldn't force the IER_UUE bit to 0.
++		 * Log it and continue.
++		 */
++		DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 ");
++	}
++	serial_outp(up, UART_IER, iersave);
++}
++
++/*
++ * This routine is called by rs_init() to initialize a specific serial
++ * port.  It determines what type of UART chip this serial port is
++ * using: 8250, 16450, 16550, 16550A.  The important question is
++ * whether or not this UART is a 16550A or not, since this will
++ * determine whether or not we can use its FIFO features or not.
++ */
++static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
++{
++	unsigned char status1, scratch, scratch2, scratch3;
++	unsigned char save_lcr, save_mcr;
++	unsigned long flags;
++
++	if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
++		return;
++
++	DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ",
++		       serial_index(&up->port), up->port.iobase, up->port.membase);
++
++	/*
++	 * We really do need global IRQs disabled here - we're going to
++	 * be frobbing the chips IRQ enable register to see if it exists.
++	 */
++	spin_lock_irqsave(&up->port.lock, flags);
++
++	up->capabilities = 0;
++	up->bugs = 0;
++
++	if (!(up->port.flags & UPF_BUGGY_UART)) {
++		/*
++		 * Do a simple existence test first; if we fail this,
++		 * there's no point trying anything else.
++		 *
++		 * 0x80 is used as a nonsense port to prevent against
++		 * false positives due to ISA bus float.  The
++		 * assumption is that 0x80 is a non-existent port;
++		 * which should be safe since include/asm/io.h also
++		 * makes this assumption.
++		 *
++		 * Note: this is safe as long as MCR bit 4 is clear
++		 * and the device is in "PC" mode.
++		 */
++		scratch = serial_inp(up, UART_IER);
++		serial_outp(up, UART_IER, 0);
++#ifdef __i386__
++		outb(0xff, 0x080);
++#endif
++		/*
++		 * Mask out IER[7:4] bits for test as some UARTs (e.g. TL
++		 * 16C754B) allow only to modify them if an EFR bit is set.
++		 */
++		scratch2 = serial_inp(up, UART_IER) & 0x0f;
++		serial_outp(up, UART_IER, 0x0F);
++#ifdef __i386__
++		outb(0, 0x080);
++#endif
++		scratch3 = serial_inp(up, UART_IER) & 0x0f;
++		serial_outp(up, UART_IER, scratch);
++		if (scratch2 != 0 || scratch3 != 0x0F) {
++			/*
++			 * We failed; there's nothing here
++			 */
++			DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
++				       scratch2, scratch3);
++			goto out;
++		}
++	}
++
++	save_mcr = serial_in(up, UART_MCR);
++	save_lcr = serial_in(up, UART_LCR);
++
++	/*
++	 * Check to see if a UART is really there.  Certain broken
++	 * internal modems based on the Rockwell chipset fail this
++	 * test, because they apparently don't implement the loopback
++	 * test mode.  So this test is skipped on the COM 1 through
++	 * COM 4 ports.  This *should* be safe, since no board
++	 * manufacturer would be stupid enough to design a board
++	 * that conflicts with COM 1-4 --- we hope!
++	 */
++	if (!(up->port.flags & UPF_SKIP_TEST)) {
++		serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
++		status1 = serial_inp(up, UART_MSR) & 0xF0;
++		serial_outp(up, UART_MCR, save_mcr);
++		if (status1 != 0x90) {
++			DEBUG_AUTOCONF("LOOP test failed (%02x) ",
++				       status1);
++			goto out;
++		}
++	}
++
++	/*
++	 * We're pretty sure there's a port here.  Lets find out what
++	 * type of port it is.  The IIR top two bits allows us to find
++	 * out if it's 8250 or 16450, 16550, 16550A or later.  This
++	 * determines what we test for next.
++	 *
++	 * We also initialise the EFR (if any) to zero for later.  The
++	 * EFR occupies the same register location as the FCR and IIR.
++	 */
++	serial_outp(up, UART_LCR, 0xBF);
++	serial_outp(up, UART_EFR, 0);
++	serial_outp(up, UART_LCR, 0);
++
++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++	scratch = serial_in(up, UART_IIR) >> 6;
++
++	DEBUG_AUTOCONF("iir=%d ", scratch);
++
++	switch (scratch) {
++	case 0:
++		autoconfig_8250(up);
++		break;
++	case 1:
++		up->port.type = PORT_UNKNOWN;
++		break;
++	case 2:
++		up->port.type = PORT_16550;
++		break;
++	case 3:
++		autoconfig_16550a(up);
++		break;
++	}
++
++#ifdef CONFIG_SERIAL_8250_RSA
++	/*
++	 * Only probe for RSA ports if we got the region.
++	 */
++	if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) {
++		int i;
++
++		for (i = 0 ; i < probe_rsa_count; ++i) {
++			if (probe_rsa[i] == up->port.iobase &&
++			    __enable_rsa(up)) {
++				up->port.type = PORT_RSA;
++				break;
++			}
++		}
++	}
++#endif
++
++	serial_outp(up, UART_LCR, save_lcr);
++
++	if (up->capabilities != uart_config[up->port.type].flags) {
++		printk(KERN_WARNING
++		       "ttyS%d: detected caps %08x should be %08x\n",
++		       serial_index(&up->port), up->capabilities,
++		       uart_config[up->port.type].flags);
++	}
++
++	up->port.fifosize = uart_config[up->port.type].fifo_size;
++	up->capabilities = uart_config[up->port.type].flags;
++	up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
++
++	if (up->port.type == PORT_UNKNOWN)
++		goto out;
++
++	/*
++	 * Reset the UART.
++	 */
++#ifdef CONFIG_SERIAL_8250_RSA
++	if (up->port.type == PORT_RSA)
++		serial_outp(up, UART_RSA_FRR, 0);
++#endif
++	serial_outp(up, UART_MCR, save_mcr);
++	serial8250_clear_fifos(up);
++	serial_in(up, UART_RX);
++	if (up->capabilities & UART_CAP_UUE)
++		serial_outp(up, UART_IER, UART_IER_UUE);
++	else
++		serial_outp(up, UART_IER, 0);
++
++ out:
++	spin_unlock_irqrestore(&up->port.lock, flags);
++	DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
++}
++
++static void autoconfig_irq(struct uart_8250_port *up)
++{
++	unsigned char save_mcr, save_ier;
++	unsigned char save_ICP = 0;
++	unsigned int ICP = 0;
++	unsigned long irqs;
++	int irq;
++
++	if (up->port.flags & UPF_FOURPORT) {
++		ICP = (up->port.iobase & 0xfe0) | 0x1f;
++		save_ICP = inb_p(ICP);
++		outb_p(0x80, ICP);
++		(void) inb_p(ICP);
++	}
++
++	/* forget possible initially masked and pending IRQ */
++	probe_irq_off(probe_irq_on());
++	save_mcr = serial_inp(up, UART_MCR);
++	save_ier = serial_inp(up, UART_IER);
++	serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
++
++	irqs = probe_irq_on();
++	serial_outp(up, UART_MCR, 0);
++	udelay(10);
++	if (up->port.flags & UPF_FOURPORT) {
++		serial_outp(up, UART_MCR,
++			    UART_MCR_DTR | UART_MCR_RTS);
++	} else {
++		serial_outp(up, UART_MCR,
++			    UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
++	}
++	serial_outp(up, UART_IER, 0x0f);	/* enable all intrs */
++	(void)serial_inp(up, UART_LSR);
++	(void)serial_inp(up, UART_RX);
++	(void)serial_inp(up, UART_IIR);
++	(void)serial_inp(up, UART_MSR);
++	serial_outp(up, UART_TX, 0xFF);
++	udelay(20);
++	irq = probe_irq_off(irqs);
++
++	serial_outp(up, UART_MCR, save_mcr);
++	serial_outp(up, UART_IER, save_ier);
++
++	if (up->port.flags & UPF_FOURPORT)
++		outb_p(save_ICP, ICP);
++
++	up->port.irq = (irq > 0) ? irq : 0;
++}
++
++static inline void __stop_tx(struct uart_8250_port *p)
++{
++	if (p->ier & UART_IER_THRI) {
++		p->ier &= ~UART_IER_THRI;
++		serial_out(p, UART_IER, p->ier);
++	}
++}
++
++static void serial8250_stop_tx(struct uart_port *port)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++	__stop_tx(up);
++
++	/*
++	 * We really want to stop the transmitter from sending.
++	 */
++	if (up->port.type == PORT_16C950) {
++		up->acr |= UART_ACR_TXDIS;
++		serial_icr_write(up, UART_ACR, up->acr);
++	}
++}
++
++static void transmit_chars(struct uart_8250_port *up);
++
++static void serial8250_start_tx(struct uart_port *port)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++	if (!(up->ier & UART_IER_THRI)) {
++		up->ier |= UART_IER_THRI;
++		serial_out(up, UART_IER, up->ier);
++
++		if (up->bugs & UART_BUG_TXEN) {
++			unsigned char lsr;
++			lsr = serial_in(up, UART_LSR);
++			up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++			if ((up->port.type == PORT_RM9000) ?
++				(lsr & UART_LSR_THRE) :
++				(lsr & UART_LSR_TEMT))
++				transmit_chars(up);
++		}
++	}
++
++	/*
++	 * Re-enable the transmitter if we disabled it.
++	 */
++	if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
++		up->acr &= ~UART_ACR_TXDIS;
++		serial_icr_write(up, UART_ACR, up->acr);
++	}
++}
++
++static void serial8250_stop_rx(struct uart_port *port)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++	up->ier &= ~UART_IER_RLSI;
++	up->port.read_status_mask &= ~UART_LSR_DR;
++	serial_out(up, UART_IER, up->ier);
++}
++
++static void serial8250_enable_ms(struct uart_port *port)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++	/* no MSR capabilities */
++	if (up->bugs & UART_BUG_NOMSR)
++		return;
++
++	up->ier |= UART_IER_MSI;
++	serial_out(up, UART_IER, up->ier);
++}
++
++static void
++receive_chars(struct uart_8250_port *up, unsigned int *status)
++{
++	struct tty_struct *tty = up->port.state->port.tty;
++	unsigned char ch, lsr = *status;
++	int max_count = 256;
++	char flag;
++
++	do {
++		if (likely(lsr & UART_LSR_DR))
++			ch = serial_inp(up, UART_RX);
++		else
++			/*
++			 * Intel 82571 has a Serial Over Lan device that will
++			 * set UART_LSR_BI without setting UART_LSR_DR when
++			 * it receives a break. To avoid reading from the
++			 * receive buffer without UART_LSR_DR bit set, we
++			 * just force the read character to be 0
++			 */
++			ch = 0;
++
++		flag = TTY_NORMAL;
++		up->port.icount.rx++;
++
++		lsr |= up->lsr_saved_flags;
++		up->lsr_saved_flags = 0;
++
++		if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
++			/*
++			 * For statistics only
++			 */
++			if (lsr & UART_LSR_BI) {
++				lsr &= ~(UART_LSR_FE | UART_LSR_PE);
++				up->port.icount.brk++;
++				/*
++				 * We do the SysRQ and SAK checking
++				 * here because otherwise the break
++				 * may get masked by ignore_status_mask
++				 * or read_status_mask.
++				 */
++				if (uart_handle_break(&up->port))
++					goto ignore_char;
++			} else if (lsr & UART_LSR_PE)
++				up->port.icount.parity++;
++			else if (lsr & UART_LSR_FE)
++				up->port.icount.frame++;
++			if (lsr & UART_LSR_OE)
++				up->port.icount.overrun++;
++
++			/*
++			 * Mask off conditions which should be ignored.
++			 */
++			lsr &= up->port.read_status_mask;
++
++			if (lsr & UART_LSR_BI) {
++				DEBUG_INTR("handling break....");
++				flag = TTY_BREAK;
++			} else if (lsr & UART_LSR_PE)
++				flag = TTY_PARITY;
++			else if (lsr & UART_LSR_FE)
++				flag = TTY_FRAME;
++		}
++		if (uart_handle_sysrq_char(&up->port, ch))
++			goto ignore_char;
++
++		uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
++
++ignore_char:
++		lsr = serial_inp(up, UART_LSR);
++	} while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
++	spin_unlock(&up->port.lock);
++	tty_flip_buffer_push(tty);
++	spin_lock(&up->port.lock);
++	*status = lsr;
++}
++
++static void transmit_chars(struct uart_8250_port *up)
++{
++	struct circ_buf *xmit = &up->port.state->xmit;
++	int count;
++
++	if (up->port.x_char) {
++		serial_outp(up, UART_TX, up->port.x_char);
++		up->port.icount.tx++;
++		up->port.x_char = 0;
++		return;
++	}
++	if (uart_tx_stopped(&up->port)) {
++		serial8250_stop_tx(&up->port);
++		return;
++	}
++	if (uart_circ_empty(xmit)) {
++		__stop_tx(up);
++		return;
++	}
++
++	count = up->tx_loadsz;
++	do {
++		serial_out(up, UART_TX, xmit->buf[xmit->tail]);
++		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
++		up->port.icount.tx++;
++		if (uart_circ_empty(xmit))
++			break;
++	} while (--count > 0);
++
++	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++		uart_write_wakeup(&up->port);
++
++	DEBUG_INTR("THRE...");
++
++	if (uart_circ_empty(xmit))
++		__stop_tx(up);
++}
++
++static unsigned int check_modem_status(struct uart_8250_port *up)
++{
++	unsigned int status = serial_in(up, UART_MSR);
++
++	status |= up->msr_saved_flags;
++	up->msr_saved_flags = 0;
++	if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
++	    up->port.state != NULL) {
++		if (status & UART_MSR_TERI)
++			up->port.icount.rng++;
++		if (status & UART_MSR_DDSR)
++			up->port.icount.dsr++;
++		if (status & UART_MSR_DDCD)
++			uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
++		if (status & UART_MSR_DCTS)
++			uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
++
++		wake_up_interruptible(&up->port.state->port.delta_msr_wait);
++	}
++
++	return status;
++}
++
++/*
++ * This handles the interrupt from one port.
++ */
++static void serial8250_handle_port(struct uart_8250_port *up)
++{
++	unsigned int status;
++	unsigned long flags;
++
++	spin_lock_irqsave(&up->port.lock, flags);
++
++	status = serial_inp(up, UART_LSR);
++
++	DEBUG_INTR("status = %x...", status);
++
++	if (status & (UART_LSR_DR | UART_LSR_BI))
++		receive_chars(up, &status);
++	check_modem_status(up);
++	if (status & UART_LSR_THRE)
++		transmit_chars(up);
++
++	spin_unlock_irqrestore(&up->port.lock, flags);
++}
++
++/*
++ * This is the serial driver's interrupt routine.
++ *
++ * Arjan thinks the old way was overly complex, so it got simplified.
++ * Alan disagrees, saying that need the complexity to handle the weird
++ * nature of ISA shared interrupts.  (This is a special exception.)
++ *
++ * In order to handle ISA shared interrupts properly, we need to check
++ * that all ports have been serviced, and therefore the ISA interrupt
++ * line has been de-asserted.
++ *
++ * This means we need to loop through all ports. checking that they
++ * don't have an interrupt pending.
++ */
++static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
++{
++	struct irq_info *i = dev_id;
++	struct list_head *l, *end = NULL;
++	int pass_counter = 0, handled = 0;
++
++	DEBUG_INTR("serial8250_interrupt(%d)...", irq);
++
++	spin_lock(&i->lock);
++
++	l = i->head;
++	do {
++		struct uart_8250_port *up;
++		unsigned int iir;
++
++		up = list_entry(l, struct uart_8250_port, list);
++
++		iir = serial_in(up, UART_IIR);
++		if (!(iir & UART_IIR_NO_INT)) {
++			serial8250_handle_port(up);
++
++			handled = 1;
++
++			end = NULL;
++		} else if (up->port.iotype == UPIO_DWAPB &&
++			  (iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
++			/* The DesignWare APB UART has an Busy Detect (0x07)
++			 * interrupt meaning an LCR write attempt occured while the
++			 * UART was busy. The interrupt must be cleared by reading
++			 * the UART status register (USR) and the LCR re-written. */
++			unsigned int status;
++			status = *(volatile u32 *)up->port.private_data;
++			serial_out(up, UART_LCR, up->lcr);
++
++			handled = 1;
++
++			end = NULL;
++		} else if (end == NULL)
++			end = l;
++
++		l = l->next;
++
++		if (l == i->head && pass_counter++ > PASS_LIMIT) {
++			/* If we hit this, we're dead. */
++			printk(KERN_ERR "serial8250: too much work for "
++				"irq%d\n", irq);
++			break;
++		}
++	} while (l != end);
++
++	spin_unlock(&i->lock);
++
++	DEBUG_INTR("end.\n");
++
++	return IRQ_RETVAL(handled);
++}
++
++/*
++ * To support ISA shared interrupts, we need to have one interrupt
++ * handler that ensures that the IRQ line has been deasserted
++ * before returning.  Failing to do this will result in the IRQ
++ * line being stuck active, and, since ISA irqs are edge triggered,
++ * no more IRQs will be seen.
++ */
++static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
++{
++	spin_lock_irq(&i->lock);
++
++	if (!list_empty(i->head)) {
++		if (i->head == &up->list)
++			i->head = i->head->next;
++		list_del(&up->list);
++	} else {
++		BUG_ON(i->head != &up->list);
++		i->head = NULL;
++	}
++	spin_unlock_irq(&i->lock);
++	/* List empty so throw away the hash node */
++	if (i->head == NULL) {
++		hlist_del(&i->node);
++		kfree(i);
++	}
++}
++
++static int serial_link_irq_chain(struct uart_8250_port *up)
++{
++	struct hlist_head *h;
++	struct hlist_node *n;
++	struct irq_info *i;
++	int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
++
++	mutex_lock(&hash_mutex);
++
++	h = &irq_lists[up->port.irq % NR_IRQ_HASH];
++
++	hlist_for_each(n, h) {
++		i = hlist_entry(n, struct irq_info, node);
++		if (i->irq == up->port.irq)
++			break;
++	}
++
++	if (n == NULL) {
++		i = kzalloc(sizeof(struct irq_info), GFP_KERNEL);
++		if (i == NULL) {
++			mutex_unlock(&hash_mutex);
++			return -ENOMEM;
++		}
++		spin_lock_init(&i->lock);
++		i->irq = up->port.irq;
++		hlist_add_head(&i->node, h);
++	}
++	mutex_unlock(&hash_mutex);
++
++	spin_lock_irq(&i->lock);
++
++	if (i->head) {
++		list_add(&up->list, i->head);
++		spin_unlock_irq(&i->lock);
++
++		ret = 0;
++	} else {
++		INIT_LIST_HEAD(&up->list);
++		i->head = &up->list;
++		spin_unlock_irq(&i->lock);
++		irq_flags |= up->port.irqflags;
++		ret = request_irq(up->port.irq, serial8250_interrupt,
++				  irq_flags, "serial", i);
++		if (ret < 0)
++			serial_do_unlink(i, up);
++	}
++
++	return ret;
++}
++
++static void serial_unlink_irq_chain(struct uart_8250_port *up)
++{
++	struct irq_info *i;
++	struct hlist_node *n;
++	struct hlist_head *h;
++
++	mutex_lock(&hash_mutex);
++
++	h = &irq_lists[up->port.irq % NR_IRQ_HASH];
++
++	hlist_for_each(n, h) {
++		i = hlist_entry(n, struct irq_info, node);
++		if (i->irq == up->port.irq)
++			break;
++	}
++
++	BUG_ON(n == NULL);
++	BUG_ON(i->head == NULL);
++
++	if (list_empty(i->head))
++		free_irq(up->port.irq, i);
++
++	serial_do_unlink(i, up);
++	mutex_unlock(&hash_mutex);
++}
++
++/* Base timer interval for polling */
++static inline int poll_timeout(int timeout)
++{
++	return timeout > 6 ? (timeout / 2 - 2) : 1;
++}
++
++/*
++ * This function is used to handle ports that do not have an
++ * interrupt.  This doesn't work very well for 16450's, but gives
++ * barely passable results for a 16550A.  (Although at the expense
++ * of much CPU overhead).
++ */
++static void serial8250_timeout(unsigned long data)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)data;
++	unsigned int iir;
++
++	iir = serial_in(up, UART_IIR);
++	if (!(iir & UART_IIR_NO_INT))
++		serial8250_handle_port(up);
++	mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
++}
++
++static void serial8250_backup_timeout(unsigned long data)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)data;
++	unsigned int iir, ier = 0, lsr;
++	unsigned long flags;
++
++	/*
++	 * Must disable interrupts or else we risk racing with the interrupt
++	 * based handler.
++	 */
++	if (is_real_interrupt(up->port.irq)) {
++		ier = serial_in(up, UART_IER);
++		serial_out(up, UART_IER, 0);
++	}
++
++	iir = serial_in(up, UART_IIR);
++
++	/*
++	 * This should be a safe test for anyone who doesn't trust the
++	 * IIR bits on their UART, but it's specifically designed for
++	 * the "Diva" UART used on the management processor on many HP
++	 * ia64 and parisc boxes.
++	 */
++	spin_lock_irqsave(&up->port.lock, flags);
++	lsr = serial_in(up, UART_LSR);
++	up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++	spin_unlock_irqrestore(&up->port.lock, flags);
++	if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
++	    (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
++	    (lsr & UART_LSR_THRE)) {
++		iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
++		iir |= UART_IIR_THRI;
++	}
++
++	if (!(iir & UART_IIR_NO_INT))
++		serial8250_handle_port(up);
++
++	if (is_real_interrupt(up->port.irq))
++		serial_out(up, UART_IER, ier);
++
++	/* Standard timer interval plus 0.2s to keep the port running */
++	mod_timer(&up->timer,
++		jiffies + poll_timeout(up->port.timeout) + HZ / 5);
++}
++
++static unsigned int serial8250_tx_empty(struct uart_port *port)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++	unsigned long flags;
++	unsigned int lsr;
++
++	spin_lock_irqsave(&up->port.lock, flags);
++	lsr = serial_in(up, UART_LSR);
++	up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++	spin_unlock_irqrestore(&up->port.lock, flags);
++
++	return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
++}
++
++static unsigned int serial8250_get_mctrl(struct uart_port *port)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++	unsigned int status;
++	unsigned int ret;
++
++	status = check_modem_status(up);
++
++	ret = 0;
++	if (status & UART_MSR_DCD)
++		ret |= TIOCM_CAR;
++	if (status & UART_MSR_RI)
++		ret |= TIOCM_RNG;
++	if (status & UART_MSR_DSR)
++		ret |= TIOCM_DSR;
++	if (status & UART_MSR_CTS)
++		ret |= TIOCM_CTS;
++	return ret;
++}
++
++static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++	unsigned char mcr = 0;
++
++	if (mctrl & TIOCM_RTS)
++		mcr |= UART_MCR_RTS;
++	if (mctrl & TIOCM_DTR)
++		mcr |= UART_MCR_DTR;
++	if (mctrl & TIOCM_OUT1)
++		mcr |= UART_MCR_OUT1;
++	if (mctrl & TIOCM_OUT2)
++		mcr |= UART_MCR_OUT2;
++	if (mctrl & TIOCM_LOOP)
++		mcr |= UART_MCR_LOOP;
++
++	mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
++
++	serial_out(up, UART_MCR, mcr);
++}
++
++static void serial8250_break_ctl(struct uart_port *port, int break_state)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++	unsigned long flags;
++
++	spin_lock_irqsave(&up->port.lock, flags);
++	if (break_state == -1)
++		up->lcr |= UART_LCR_SBC;
++	else
++		up->lcr &= ~UART_LCR_SBC;
++	serial_out(up, UART_LCR, up->lcr);
++	spin_unlock_irqrestore(&up->port.lock, flags);
++}
++
++/*
++ *	Wait for transmitter & holding register to empty
++ */
++static void wait_for_xmitr(struct uart_8250_port *up, int bits)
++{
++	unsigned int status, tmout = 10000;
++
++	/* Wait up to 10ms for the character(s) to be sent. */
++	do {
++		status = serial_in(up, UART_LSR);
++
++		up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
++
++		if (--tmout == 0)
++			break;
++		udelay(1);
++	} while ((status & bits) != bits);
++
++	/* Wait up to 1s for flow control if necessary */
++	if (up->port.flags & UPF_CONS_FLOW) {
++		unsigned int tmout;
++		for (tmout = 1000000; tmout; tmout--) {
++			unsigned int msr = serial_in(up, UART_MSR);
++			up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
++			if (msr & UART_MSR_CTS)
++				break;
++			udelay(1);
++			touch_nmi_watchdog();
++		}
++	}
++}
++
++#ifdef CONFIG_CONSOLE_POLL
++/*
++ * Console polling routines for writing and reading from the uart while
++ * in an interrupt or debug context.
++ */
++
++static int serial8250_get_poll_char(struct uart_port *port)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++	unsigned char lsr = serial_inp(up, UART_LSR);
++
++	if (!(lsr & UART_LSR_DR))
++		return NO_POLL_CHAR;
++
++	return serial_inp(up, UART_RX);
++}
++
++
++static void serial8250_put_poll_char(struct uart_port *port,
++			 unsigned char c)
++{
++	unsigned int ier;
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++	/*
++	 *	First save the IER then disable the interrupts
++	 */
++	ier = serial_in(up, UART_IER);
++	if (up->capabilities & UART_CAP_UUE)
++		serial_out(up, UART_IER, UART_IER_UUE);
++	else
++		serial_out(up, UART_IER, 0);
++
++	wait_for_xmitr(up, BOTH_EMPTY);
++	/*
++	 *	Send the character out.
++	 *	If a LF, also do CR...
++	 */
++	serial_out(up, UART_TX, c);
++	if (c == 10) {
++		wait_for_xmitr(up, BOTH_EMPTY);
++		serial_out(up, UART_TX, 13);
++	}
++
++	/*
++	 *	Finally, wait for transmitter to become empty
++	 *	and restore the IER
++	 */
++	wait_for_xmitr(up, BOTH_EMPTY);
++	serial_out(up, UART_IER, ier);
++}
++
++#endif /* CONFIG_CONSOLE_POLL */
++
++static int serial8250_startup(struct uart_port *port)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++	unsigned long flags;
++	unsigned char lsr, iir;
++	int retval;
++
++	up->capabilities = uart_config[up->port.type].flags;
++	up->mcr = 0;
++
++	if (up->port.iotype != up->cur_iotype)
++		set_io_from_upio(port);
++
++	if (up->port.type == PORT_16C950) {
++		/* Wake up and initialize UART */
++		up->acr = 0;
++		serial_outp(up, UART_LCR, 0xBF);
++		serial_outp(up, UART_EFR, UART_EFR_ECB);
++		serial_outp(up, UART_IER, 0);
++		serial_outp(up, UART_LCR, 0);
++		serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
++		serial_outp(up, UART_LCR, 0xBF);
++		serial_outp(up, UART_EFR, UART_EFR_ECB);
++		serial_outp(up, UART_LCR, 0);
++	}
++
++#ifdef CONFIG_SERIAL_8250_RSA
++	/*
++	 * If this is an RSA port, see if we can kick it up to the
++	 * higher speed clock.
++	 */
++	enable_rsa(up);
++#endif
++
++	/*
++	 * Clear the FIFO buffers and disable them.
++	 * (they will be reenabled in set_termios())
++	 */
++	serial8250_clear_fifos(up);
++
++	/*
++	 * Clear the interrupt registers.
++	 */
++	(void) serial_inp(up, UART_LSR);
++	(void) serial_inp(up, UART_RX);
++	(void) serial_inp(up, UART_IIR);
++	(void) serial_inp(up, UART_MSR);
++
++	/*
++	 * At this point, there's no way the LSR could still be 0xff;
++	 * if it is, then bail out, because there's likely no UART
++	 * here.
++	 */
++	if (!(up->port.flags & UPF_BUGGY_UART) &&
++	    (serial_inp(up, UART_LSR) == 0xff)) {
++		printk(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
++		       serial_index(&up->port));
++		return -ENODEV;
++	}
++
++	/*
++	 * For a XR16C850, we need to set the trigger levels
++	 */
++	if (up->port.type == PORT_16850) {
++		unsigned char fctr;
++
++		serial_outp(up, UART_LCR, 0xbf);
++
++		fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
++		serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX);
++		serial_outp(up, UART_TRG, UART_TRG_96);
++		serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_TX);
++		serial_outp(up, UART_TRG, UART_TRG_96);
++
++		serial_outp(up, UART_LCR, 0);
++	}
++
++	if (is_real_interrupt(up->port.irq)) {
++		unsigned char iir1;
++		/*
++		 * Test for UARTs that do not reassert THRE when the
++		 * transmitter is idle and the interrupt has already
++		 * been cleared.  Real 16550s should always reassert
++		 * this interrupt whenever the transmitter is idle and
++		 * the interrupt is enabled.  Delays are necessary to
++		 * allow register changes to become visible.
++		 */
++		spin_lock_irqsave(&up->port.lock, flags);
++		if (up->port.irqflags & IRQF_SHARED)
++			disable_irq_nosync(up->port.irq);
++
++		wait_for_xmitr(up, UART_LSR_THRE);
++		serial_out_sync(up, UART_IER, UART_IER_THRI);
++		udelay(1); /* allow THRE to set */
++		iir1 = serial_in(up, UART_IIR);
++		serial_out(up, UART_IER, 0);
++		serial_out_sync(up, UART_IER, UART_IER_THRI);
++		udelay(1); /* allow a working UART time to re-assert THRE */
++		iir = serial_in(up, UART_IIR);
++		serial_out(up, UART_IER, 0);
++
++		if (up->port.irqflags & IRQF_SHARED)
++			enable_irq(up->port.irq);
++		spin_unlock_irqrestore(&up->port.lock, flags);
++
++		/*
++		 * If the interrupt is not reasserted, setup a timer to
++		 * kick the UART on a regular basis.
++		 */
++		if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) {
++			up->bugs |= UART_BUG_THRE;
++			pr_debug("ttyS%d - using backup timer\n",
++				 serial_index(port));
++		}
++	}
++
++	/*
++	 * The above check will only give an accurate result the first time
++	 * the port is opened so this value needs to be preserved.
++	 */
++	if (up->bugs & UART_BUG_THRE) {
++		up->timer.function = serial8250_backup_timeout;
++		up->timer.data = (unsigned long)up;
++		mod_timer(&up->timer, jiffies +
++			  poll_timeout(up->port.timeout) + HZ / 5);
++	}
++
++	/*
++	 * If the "interrupt" for this port doesn't correspond with any
++	 * hardware interrupt, we use a timer-based system.  The original
++	 * driver used to do this with IRQ0.
++	 */
++	if (!is_real_interrupt(up->port.irq)) {
++		up->timer.data = (unsigned long)up;
++		mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
++	} else {
++		retval = serial_link_irq_chain(up);
++		if (retval)
++			return retval;
++	}
++
++	/*
++	 * Now, initialize the UART
++	 */
++	serial_outp(up, UART_LCR, UART_LCR_WLEN8);
++
++	spin_lock_irqsave(&up->port.lock, flags);
++	if (up->port.flags & UPF_FOURPORT) {
++		if (!is_real_interrupt(up->port.irq))
++			up->port.mctrl |= TIOCM_OUT1;
++	} else
++		/*
++		 * Most PC uarts need OUT2 raised to enable interrupts.
++		 */
++		if (is_real_interrupt(up->port.irq))
++			up->port.mctrl |= TIOCM_OUT2;
++
++	serial8250_set_mctrl(&up->port, up->port.mctrl);
++
++	/* Serial over Lan (SoL) hack:
++	   Intel 8257x Gigabit ethernet chips have a
++	   16550 emulation, to be used for Serial Over Lan.
++	   Those chips take a longer time than a normal
++	   serial device to signalize that a transmission
++	   data was queued. Due to that, the above test generally
++	   fails. One solution would be to delay the reading of
++	   iir. However, this is not reliable, since the timeout
++	   is variable. So, let's just don't test if we receive
++	   TX irq. This way, we'll never enable UART_BUG_TXEN.
++	 */
++	if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST)
++		goto dont_test_tx_en;
++
++	/*
++	 * Do a quick test to see if we receive an
++	 * interrupt when we enable the TX irq.
++	 */
++	serial_outp(up, UART_IER, UART_IER_THRI);
++	lsr = serial_in(up, UART_LSR);
++	iir = serial_in(up, UART_IIR);
++	serial_outp(up, UART_IER, 0);
++
++	if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
++		if (!(up->bugs & UART_BUG_TXEN)) {
++			up->bugs |= UART_BUG_TXEN;
++			pr_debug("ttyS%d - enabling bad tx status workarounds\n",
++				 serial_index(port));
++		}
++	} else {
++		up->bugs &= ~UART_BUG_TXEN;
++	}
++
++dont_test_tx_en:
++	spin_unlock_irqrestore(&up->port.lock, flags);
++
++	/*
++	 * Clear the interrupt registers again for luck, and clear the
++	 * saved flags to avoid getting false values from polling
++	 * routines or the previous session.
++	 */
++	serial_inp(up, UART_LSR);
++	serial_inp(up, UART_RX);
++	serial_inp(up, UART_IIR);
++	serial_inp(up, UART_MSR);
++	up->lsr_saved_flags = 0;
++	up->msr_saved_flags = 0;
++
++	/*
++	 * Finally, enable interrupts.  Note: Modem status interrupts
++	 * are set via set_termios(), which will be occurring imminently
++	 * anyway, so we don't enable them here.
++	 */
++	up->ier = UART_IER_RLSI | UART_IER_RDI;
++	serial_outp(up, UART_IER, up->ier);
++
++	if (up->port.flags & UPF_FOURPORT) {
++		unsigned int icp;
++		/*
++		 * Enable interrupts on the AST Fourport board
++		 */
++		icp = (up->port.iobase & 0xfe0) | 0x01f;
++		outb_p(0x80, icp);
++		(void) inb_p(icp);
++	}
++
++	return 0;
++}
++
++static void serial8250_shutdown(struct uart_port *port)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++	unsigned long flags;
++
++	/*
++	 * Disable interrupts from this port
++	 */
++	up->ier = 0;
++	serial_outp(up, UART_IER, 0);
++
++	spin_lock_irqsave(&up->port.lock, flags);
++	if (up->port.flags & UPF_FOURPORT) {
++		/* reset interrupts on the AST Fourport board */
++		inb((up->port.iobase & 0xfe0) | 0x1f);
++		up->port.mctrl |= TIOCM_OUT1;
++	} else
++		up->port.mctrl &= ~TIOCM_OUT2;
++
++	serial8250_set_mctrl(&up->port, up->port.mctrl);
++	spin_unlock_irqrestore(&up->port.lock, flags);
++
++	/*
++	 * Disable break condition and FIFOs
++	 */
++	serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
++	serial8250_clear_fifos(up);
++
++#ifdef CONFIG_SERIAL_8250_RSA
++	/*
++	 * Reset the RSA board back to 115kbps compat mode.
++	 */
++	disable_rsa(up);
++#endif
++
++	/*
++	 * Read data port to reset things, and then unlink from
++	 * the IRQ chain.
++	 */
++	(void) serial_in(up, UART_RX);
++
++	del_timer_sync(&up->timer);
++	up->timer.function = serial8250_timeout;
++	if (is_real_interrupt(up->port.irq))
++		serial_unlink_irq_chain(up);
++}
++
++static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
++{
++	unsigned int quot;
++
++	/*
++	 * Handle magic divisors for baud rates above baud_base on
++	 * SMSC SuperIO chips.
++	 */
++	if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
++	    baud == (port->uartclk/4))
++		quot = 0x8001;
++	else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
++		 baud == (port->uartclk/8))
++		quot = 0x8002;
++	else
++		quot = uart_get_divisor(port, baud);
++
++	return quot;
++}
++
++static void
++serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
++		       struct ktermios *old)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++	unsigned char cval, fcr = 0;
++	unsigned long flags;
++	unsigned int baud, quot;
++
++	switch (termios->c_cflag & CSIZE) {
++	case CS5:
++		cval = UART_LCR_WLEN5;
++		break;
++	case CS6:
++		cval = UART_LCR_WLEN6;
++		break;
++	case CS7:
++		cval = UART_LCR_WLEN7;
++		break;
++	default:
++	case CS8:
++		cval = UART_LCR_WLEN8;
++		break;
++	}
++
++	if (termios->c_cflag & CSTOPB)
++		cval |= UART_LCR_STOP;
++	if (termios->c_cflag & PARENB)
++		cval |= UART_LCR_PARITY;
++	if (!(termios->c_cflag & PARODD))
++		cval |= UART_LCR_EPAR;
++#ifdef CMSPAR
++	if (termios->c_cflag & CMSPAR)
++		cval |= UART_LCR_SPAR;
++#endif
++
++	/*
++	 * Ask the core to calculate the divisor for us.
++	 */
++	baud = uart_get_baud_rate(port, termios, old,
++				  port->uartclk / 16 / 0xffff,
++				  port->uartclk / 16);
++	quot = serial8250_get_divisor(port, baud);
++
++	/*
++	 * Oxford Semi 952 rev B workaround
++	 */
++	if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
++		quot++;
++
++	if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
++		if (baud < 2400)
++			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
++		else
++			fcr = uart_config[up->port.type].fcr;
++	}
++
++	/*
++	 * MCR-based auto flow control.  When AFE is enabled, RTS will be
++	 * deasserted when the receive FIFO contains more characters than
++	 * the trigger, or the MCR RTS bit is cleared.  In the case where
++	 * the remote UART is not using CTS auto flow control, we must
++	 * have sufficient FIFO entries for the latency of the remote
++	 * UART to respond.  IOW, at least 32 bytes of FIFO.
++	 */
++	if (up->capabilities & UART_CAP_AFE && up->port.fifosize >= 32) {
++		up->mcr &= ~UART_MCR_AFE;
++		if (termios->c_cflag & CRTSCTS)
++			up->mcr |= UART_MCR_AFE;
++	}
++
++	/*
++	 * Ok, we're now changing the port state.  Do it with
++	 * interrupts disabled.
++	 */
++	spin_lock_irqsave(&up->port.lock, flags);
++
++	/*
++	 * Update the per-port timeout.
++	 */
++	uart_update_timeout(port, termios->c_cflag, baud);
++
++	up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
++	if (termios->c_iflag & INPCK)
++		up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
++	if (termios->c_iflag & (BRKINT | PARMRK))
++		up->port.read_status_mask |= UART_LSR_BI;
++
++	/*
++	 * Characteres to ignore
++	 */
++	up->port.ignore_status_mask = 0;
++	if (termios->c_iflag & IGNPAR)
++		up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
++	if (termios->c_iflag & IGNBRK) {
++		up->port.ignore_status_mask |= UART_LSR_BI;
++		/*
++		 * If we're ignoring parity and break indicators,
++		 * ignore overruns too (for real raw support).
++		 */
++		if (termios->c_iflag & IGNPAR)
++			up->port.ignore_status_mask |= UART_LSR_OE;
++	}
++
++	/*
++	 * ignore all characters if CREAD is not set
++	 */
++	if ((termios->c_cflag & CREAD) == 0)
++		up->port.ignore_status_mask |= UART_LSR_DR;
++
++	/*
++	 * CTS flow control flag and modem status interrupts
++	 */
++	up->ier &= ~UART_IER_MSI;
++	if (!(up->bugs & UART_BUG_NOMSR) &&
++			UART_ENABLE_MS(&up->port, termios->c_cflag))
++		up->ier |= UART_IER_MSI;
++	if (up->capabilities & UART_CAP_UUE)
++		up->ier |= UART_IER_UUE | UART_IER_RTOIE;
++
++	serial_out(up, UART_IER, up->ier);
++
++	if (up->capabilities & UART_CAP_EFR) {
++		unsigned char efr = 0;
++		/*
++		 * TI16C752/Startech hardware flow control.  FIXME:
++		 * - TI16C752 requires control thresholds to be set.
++		 * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled.
++		 */
++		if (termios->c_cflag & CRTSCTS)
++			efr |= UART_EFR_CTS;
++
++		serial_outp(up, UART_LCR, 0xBF);
++		serial_outp(up, UART_EFR, efr);
++	}
++
++#ifdef CONFIG_ARCH_OMAP
++	/* Workaround to enable 115200 baud on OMAP1510 internal ports */
++	if (cpu_is_omap1510() && is_omap_port(up)) {
++		if (baud == 115200) {
++			quot = 1;
++			serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
++		} else
++			serial_out(up, UART_OMAP_OSC_12M_SEL, 0);
++	}
++#endif
++
++	if (up->capabilities & UART_NATSEMI) {
++		/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
++		serial_outp(up, UART_LCR, 0xe0);
++	} else {
++		serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
++	}
++
++	serial_dl_write(up, quot);
++
++	/*
++	 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
++	 * is written without DLAB set, this mode will be disabled.
++	 */
++	if (up->port.type == PORT_16750)
++		serial_outp(up, UART_FCR, fcr);
++
++	serial_outp(up, UART_LCR, cval);		/* reset DLAB */
++	up->lcr = cval;					/* Save LCR */
++	if (up->port.type != PORT_16750) {
++		if (fcr & UART_FCR_ENABLE_FIFO) {
++			/* emulated UARTs (Lucent Venus 167x) need two steps */
++			serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++		}
++		serial_outp(up, UART_FCR, fcr);		/* set fcr */
++	}
++	serial8250_set_mctrl(&up->port, up->port.mctrl);
++	spin_unlock_irqrestore(&up->port.lock, flags);
++	/* Don't rewrite B0 */
++	if (tty_termios_baud_rate(termios))
++		tty_termios_encode_baud_rate(termios, baud, baud);
++}
++
++static void
++serial8250_set_ldisc(struct uart_port *port)
++{
++	int line = port->line;
++
++	if (line >= port->state->port.tty->driver->num)
++		return;
++
++	if (port->state->port.tty->ldisc->ops->num == N_PPS) {
++		port->flags |= UPF_HARDPPS_CD;
++		serial8250_enable_ms(port);
++	} else
++		port->flags &= ~UPF_HARDPPS_CD;
++}
++
++static void
++serial8250_pm(struct uart_port *port, unsigned int state,
++	      unsigned int oldstate)
++{
++	struct uart_8250_port *p = (struct uart_8250_port *)port;
++
++	serial8250_set_sleep(p, state != 0);
++
++	if (p->pm)
++		p->pm(port, state, oldstate);
++}
++
++static unsigned int serial8250_port_size(struct uart_8250_port *pt)
++{
++	if (pt->port.iotype == UPIO_AU)
++		return 0x1000;
++#ifdef CONFIG_ARCH_OMAP
++	if (is_omap_port(pt))
++		return 0x16 << pt->port.regshift;
++#endif
++	return 8 << pt->port.regshift;
++}
++
++/*
++ * Resource handling.
++ */
++static int serial8250_request_std_resource(struct uart_8250_port *up)
++{
++	unsigned int size = serial8250_port_size(up);
++	int ret = 0;
++
++	switch (up->port.iotype) {
++	case UPIO_AU:
++	case UPIO_TSI:
++	case UPIO_MEM32:
++	case UPIO_MEM:
++	case UPIO_DWAPB:
++		if (!up->port.mapbase)
++			break;
++
++		if (!request_mem_region(up->port.mapbase, size, "serial")) {
++			ret = -EBUSY;
++			break;
++		}
++
++		if (up->port.flags & UPF_IOREMAP) {
++			up->port.membase = ioremap_nocache(up->port.mapbase,
++									size);
++			if (!up->port.membase) {
++				release_mem_region(up->port.mapbase, size);
++				ret = -ENOMEM;
++			}
++		}
++		break;
++
++	case UPIO_HUB6:
++	case UPIO_PORT:
++		if (!request_region(up->port.iobase, size, "serial"))
++			ret = -EBUSY;
++		break;
++	}
++	return ret;
++}
++
++static void serial8250_release_std_resource(struct uart_8250_port *up)
++{
++	unsigned int size = serial8250_port_size(up);
++
++	switch (up->port.iotype) {
++	case UPIO_AU:
++	case UPIO_TSI:
++	case UPIO_MEM32:
++	case UPIO_MEM:
++	case UPIO_DWAPB:
++		if (!up->port.mapbase)
++			break;
++
++		if (up->port.flags & UPF_IOREMAP) {
++			iounmap(up->port.membase);
++			up->port.membase = NULL;
++		}
++
++		release_mem_region(up->port.mapbase, size);
++		break;
++
++	case UPIO_HUB6:
++	case UPIO_PORT:
++		release_region(up->port.iobase, size);
++		break;
++	}
++}
++
++static int serial8250_request_rsa_resource(struct uart_8250_port *up)
++{
++	unsigned long start = UART_RSA_BASE << up->port.regshift;
++	unsigned int size = 8 << up->port.regshift;
++	int ret = -EINVAL;
++
++	switch (up->port.iotype) {
++	case UPIO_HUB6:
++	case UPIO_PORT:
++		start += up->port.iobase;
++		if (request_region(start, size, "serial-rsa"))
++			ret = 0;
++		else
++			ret = -EBUSY;
++		break;
++	}
++
++	return ret;
++}
++
++static void serial8250_release_rsa_resource(struct uart_8250_port *up)
++{
++	unsigned long offset = UART_RSA_BASE << up->port.regshift;
++	unsigned int size = 8 << up->port.regshift;
++
++	switch (up->port.iotype) {
++	case UPIO_HUB6:
++	case UPIO_PORT:
++		release_region(up->port.iobase + offset, size);
++		break;
++	}
++}
++
++static void serial8250_release_port(struct uart_port *port)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++	serial8250_release_std_resource(up);
++	if (up->port.type == PORT_RSA)
++		serial8250_release_rsa_resource(up);
++}
++
++static int serial8250_request_port(struct uart_port *port)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++	int ret = 0;
++
++	ret = serial8250_request_std_resource(up);
++	if (ret == 0 && up->port.type == PORT_RSA) {
++		ret = serial8250_request_rsa_resource(up);
++		if (ret < 0)
++			serial8250_release_std_resource(up);
++	}
++
++	return ret;
++}
++
++static void serial8250_config_port(struct uart_port *port, int flags)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++	int probeflags = PROBE_ANY;
++	int ret;
++
++	/*
++	 * Find the region that we can probe for.  This in turn
++	 * tells us whether we can probe for the type of port.
++	 */
++	ret = serial8250_request_std_resource(up);
++	if (ret < 0)
++		return;
++
++	ret = serial8250_request_rsa_resource(up);
++	if (ret < 0)
++		probeflags &= ~PROBE_RSA;
++
++	if (up->port.iotype != up->cur_iotype)
++		set_io_from_upio(port);
++
++	if (flags & UART_CONFIG_TYPE)
++		autoconfig(up, probeflags);
++
++#ifdef CONFIG_SERIAL_8250_AU1X00
++	/* if access method is AU, it is a 16550 with a quirk */
++	if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
++		up->bugs |= UART_BUG_NOMSR;
++#endif
++
++	if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
++		autoconfig_irq(up);
++
++	if (up->port.type != PORT_RSA && probeflags & PROBE_RSA)
++		serial8250_release_rsa_resource(up);
++	if (up->port.type == PORT_UNKNOWN)
++		serial8250_release_std_resource(up);
++}
++
++static int
++serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
++{
++	if (ser->irq >= nr_irqs || ser->irq < 0 ||
++	    ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
++	    ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
++	    ser->type == PORT_STARTECH)
++		return -EINVAL;
++	return 0;
++}
++
++static const char *
++serial8250_type(struct uart_port *port)
++{
++	int type = port->type;
++
++	if (type >= ARRAY_SIZE(uart_config))
++		type = 0;
++	return uart_config[type].name;
++}
++
++static struct uart_ops serial8250_pops = {
++	.tx_empty	= serial8250_tx_empty,
++	.set_mctrl	= serial8250_set_mctrl,
++	.get_mctrl	= serial8250_get_mctrl,
++	.stop_tx	= serial8250_stop_tx,
++	.start_tx	= serial8250_start_tx,
++	.stop_rx	= serial8250_stop_rx,
++	.enable_ms	= serial8250_enable_ms,
++	.break_ctl	= serial8250_break_ctl,
++	.startup	= serial8250_startup,
++	.shutdown	= serial8250_shutdown,
++	.set_termios	= serial8250_set_termios,
++	.set_ldisc	= serial8250_set_ldisc,
++	.pm		= serial8250_pm,
++	.type		= serial8250_type,
++	.release_port	= serial8250_release_port,
++	.request_port	= serial8250_request_port,
++	.config_port	= serial8250_config_port,
++	.verify_port	= serial8250_verify_port,
++#ifdef CONFIG_CONSOLE_POLL
++	.poll_get_char = serial8250_get_poll_char,
++	.poll_put_char = serial8250_put_poll_char,
++#endif
++};
++
++static struct uart_8250_port serial8250_ports[UART_NR];
++
++static void __init serial8250_isa_init_ports(void)
++{
++	struct uart_8250_port *up;
++	static int first = 1;
++	int i, irqflag = 0;
++
++	if (!first)
++		return;
++	first = 0;
++
++	for (i = 0; i < nr_uarts; i++) {
++		struct uart_8250_port *up = &serial8250_ports[i];
++
++		up->port.line = i;
++		spin_lock_init(&up->port.lock);
++
++		init_timer(&up->timer);
++		up->timer.function = serial8250_timeout;
++
++		/*
++		 * ALPHA_KLUDGE_MCR needs to be killed.
++		 */
++		up->mcr_mask = ~ALPHA_KLUDGE_MCR;
++		up->mcr_force = ALPHA_KLUDGE_MCR;
++
++		up->port.ops = &serial8250_pops;
++	}
++
++	if (share_irqs)
++		irqflag = IRQF_SHARED;
++
++	for (i = 0, up = serial8250_ports;
++	     i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
++	     i++, up++) {
++		up->port.iobase   = old_serial_port[i].port;
++		up->port.irq      = irq_canonicalize(old_serial_port[i].irq);
++		up->port.irqflags = old_serial_port[i].irqflags;
++		up->port.uartclk  = old_serial_port[i].baud_base * 16;
++		up->port.flags    = old_serial_port[i].flags;
++		up->port.hub6     = old_serial_port[i].hub6;
++		up->port.membase  = old_serial_port[i].iomem_base;
++		up->port.iotype   = old_serial_port[i].io_type;
++		up->port.regshift = old_serial_port[i].iomem_reg_shift;
++		set_io_from_upio(&up->port);
++		up->port.irqflags |= irqflag;
++	}
++}
++
++static void
++serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type)
++{
++	up->port.type = type;
++	up->port.fifosize = uart_config[type].fifo_size;
++	up->capabilities = uart_config[type].flags;
++	up->tx_loadsz = uart_config[type].tx_loadsz;
++}
++
++static void __init
++serial8250_register_ports(struct uart_driver *drv, struct device *dev)
++{
++	int i;
++
++	for (i = 0; i < nr_uarts; i++) {
++		struct uart_8250_port *up = &serial8250_ports[i];
++		up->cur_iotype = 0xFF;
++	}
++
++	serial8250_isa_init_ports();
++
++	for (i = 0; i < nr_uarts; i++) {
++		struct uart_8250_port *up = &serial8250_ports[i];
++
++		up->port.dev = dev;
++
++		if (up->port.flags & UPF_FIXED_TYPE)
++			serial8250_init_fixed_type_port(up, up->port.type);
++
++		uart_add_one_port(drv, &up->port);
++	}
++}
++
++#ifdef CONFIG_SERIAL_8250_CONSOLE
++
++static void serial8250_console_putchar(struct uart_port *port, int ch)
++{
++	struct uart_8250_port *up = (struct uart_8250_port *)port;
++
++	wait_for_xmitr(up, UART_LSR_THRE);
++	serial_out(up, UART_TX, ch);
++}
++
++/*
++ *	Print a string to the serial port trying not to disturb
++ *	any possible real use of the port...
++ *
++ *	The console_lock must be held when we get here.
++ */
++static void
++serial8250_console_write(struct console *co, const char *s, unsigned int count)
++{
++	struct uart_8250_port *up = &serial8250_ports[co->index];
++	unsigned long flags;
++	unsigned int ier;
++	int locked = 1;
++
++	touch_nmi_watchdog();
++
++	local_irq_save(flags);
++	if (up->port.sysrq) {
++		/* serial8250_handle_port() already took the lock */
++		locked = 0;
++	} else if (oops_in_progress) {
++		locked = spin_trylock(&up->port.lock);
++	} else
++		spin_lock(&up->port.lock);
++
++	/*
++	 *	First save the IER then disable the interrupts
++	 */
++	ier = serial_in(up, UART_IER);
++
++	if (up->capabilities & UART_CAP_UUE)
++		serial_out(up, UART_IER, UART_IER_UUE);
++	else
++		serial_out(up, UART_IER, 0);
++
++	uart_console_write(&up->port, s, count, serial8250_console_putchar);
++
++	/*
++	 *	Finally, wait for transmitter to become empty
++	 *	and restore the IER
++	 */
++	wait_for_xmitr(up, BOTH_EMPTY);
++	serial_out(up, UART_IER, ier);
++
++	/*
++	 *	The receive handling will happen properly because the
++	 *	receive ready bit will still be set; it is not cleared
++	 *	on read.  However, modem control will not, we must
++	 *	call it if we have saved something in the saved flags
++	 *	while processing with interrupts off.
++	 */
++	if (up->msr_saved_flags)
++		check_modem_status(up);
++
++	if (locked)
++		spin_unlock(&up->port.lock);
++	local_irq_restore(flags);
++}
++
++static int __init serial8250_console_setup(struct console *co, char *options)
++{
++	struct uart_port *port;
++	int baud = 9600;
++	int bits = 8;
++	int parity = 'n';
++	int flow = 'n';
++
++	/*
++	 * Check whether an invalid uart number has been specified, and
++	 * if so, search for the first available port that does have
++	 * console support.
++	 */
++	if (co->index >= nr_uarts)
++		co->index = 0;
++	port = &serial8250_ports[co->index].port;
++	if (!port->iobase && !port->membase)
++		return -ENODEV;
++
++	if (options)
++		uart_parse_options(options, &baud, &parity, &bits, &flow);
++
++	return uart_set_options(port, co, baud, parity, bits, flow);
++}
++
++static int serial8250_console_early_setup(void)
++{
++	return serial8250_find_port_for_earlycon();
++}
++
++static struct console serial8250_console = {
++	.name		= "ttyS",
++	.write		= serial8250_console_write,
++	.device		= uart_console_device,
++	.setup		= serial8250_console_setup,
++	.early_setup	= serial8250_console_early_setup,
++	.flags		= CON_PRINTBUFFER,
++	.index		= -1,
++	.data		= &serial8250_reg,
++};
++
++static int __init serial8250_console_init(void)
++{
++	if (nr_uarts > UART_NR)
++		nr_uarts = UART_NR;
++
++	serial8250_isa_init_ports();
++	register_console(&serial8250_console);
++	return 0;
++}
++console_initcall(serial8250_console_init);
++
++int serial8250_find_port(struct uart_port *p)
++{
++	int line;
++	struct uart_port *port;
++
++	for (line = 0; line < nr_uarts; line++) {
++		port = &serial8250_ports[line].port;
++		if (uart_match_port(p, port))
++			return line;
++	}
++	return -ENODEV;
++}
++
++#define SERIAL8250_CONSOLE	&serial8250_console
++#else
++#define SERIAL8250_CONSOLE	NULL
++#endif
++
++static struct uart_driver serial8250_reg = {
++	.owner			= THIS_MODULE,
++	.driver_name		= "serial",
++	.dev_name		= "ttyS",
++	.major			= TTY_MAJOR,
++	.minor			= 64,
++	.cons			= SERIAL8250_CONSOLE,
++};
++
++/*
++ * early_serial_setup - early registration for 8250 ports
++ *
++ * Setup an 8250 port structure prior to console initialisation.  Use
++ * after console initialisation will cause undefined behaviour.
++ */
++int __init early_serial_setup(struct uart_port *port)
++{
++	struct uart_port *p;
++
++	if (port->line >= ARRAY_SIZE(serial8250_ports))
++		return -ENODEV;
++
++	serial8250_isa_init_ports();
++	p = &serial8250_ports[port->line].port;
++	p->iobase       = port->iobase;
++	p->membase      = port->membase;
++	p->irq          = port->irq;
++	p->irqflags     = port->irqflags;
++	p->uartclk      = port->uartclk;
++	p->fifosize     = port->fifosize;
++	p->regshift     = port->regshift;
++	p->iotype       = port->iotype;
++	p->flags        = port->flags;
++	p->mapbase      = port->mapbase;
++	p->private_data = port->private_data;
++	p->type		= port->type;
++	p->line		= port->line;
++
++	set_io_from_upio(p);
++	if (port->serial_in)
++		p->serial_in = port->serial_in;
++	if (port->serial_out)
++		p->serial_out = port->serial_out;
++
++	return 0;
++}
++
++/**
++ *	serial8250_suspend_port - suspend one serial port
++ *	@line:  serial line number
++ *
++ *	Suspend one serial port.
++ */
++void serial8250_suspend_port(int line)
++{
++	uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port);
++}
++
++/**
++ *	serial8250_resume_port - resume one serial port
++ *	@line:  serial line number
++ *
++ *	Resume one serial port.
++ */
++void serial8250_resume_port(int line)
++{
++	struct uart_8250_port *up = &serial8250_ports[line];
++
++	if (up->capabilities & UART_NATSEMI) {
++		unsigned char tmp;
++
++		/* Ensure it's still in high speed mode */
++		serial_outp(up, UART_LCR, 0xE0);
++
++		tmp = serial_in(up, 0x04); /* EXCR2 */
++		tmp &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
++		tmp |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
++		serial_outp(up, 0x04, tmp);
++
++		serial_outp(up, UART_LCR, 0);
++	}
++	uart_resume_port(&serial8250_reg, &up->port);
++}
++
++/*
++ * Register a set of serial devices attached to a platform device.  The
++ * list is terminated with a zero flags entry, which means we expect
++ * all entries to have at least UPF_BOOT_AUTOCONF set.
++ */
++static int __devinit serial8250_probe(struct platform_device *dev)
++{
++	struct plat_serial8250_port *p = dev->dev.platform_data;
++	struct uart_port port;
++	int ret, i, irqflag = 0;
++
++	memset(&port, 0, sizeof(struct uart_port));
++
++	if (share_irqs)
++		irqflag = IRQF_SHARED;
++
++	for (i = 0; p && p->flags != 0; p++, i++) {
++		port.iobase		= p->iobase;
++		port.membase		= p->membase;
++		port.irq		= p->irq;
++		port.irqflags		= p->irqflags;
++		port.uartclk		= p->uartclk;
++		port.regshift		= p->regshift;
++		port.iotype		= p->iotype;
++		port.flags		= p->flags;
++		port.mapbase		= p->mapbase;
++		port.hub6		= p->hub6;
++		port.private_data	= p->private_data;
++		port.type		= p->type;
++		port.serial_in		= p->serial_in;
++		port.serial_out		= p->serial_out;
++		port.dev		= &dev->dev;
++		port.irqflags		|= irqflag;
++		ret = serial8250_register_port(&port);
++		if (ret < 0) {
++			dev_err(&dev->dev, "unable to register port at index %d "
++				"(IO%lx MEM%llx IRQ%d): %d\n", i,
++				p->iobase, (unsigned long long)p->mapbase,
++				p->irq, ret);
++		}
++	}
++	return 0;
++}
++
++/*
++ * Remove serial ports registered against a platform device.
++ */
++static int __devexit serial8250_remove(struct platform_device *dev)
++{
++	int i;
++
++	for (i = 0; i < nr_uarts; i++) {
++		struct uart_8250_port *up = &serial8250_ports[i];
++
++		if (up->port.dev == &dev->dev)
++			serial8250_unregister_port(i);
++	}
++	return 0;
++}
++
++static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
++{
++	int i;
++
++	for (i = 0; i < UART_NR; i++) {
++		struct uart_8250_port *up = &serial8250_ports[i];
++
++		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
++			uart_suspend_port(&serial8250_reg, &up->port);
++	}
++
++	return 0;
++}
++
++static int serial8250_resume(struct platform_device *dev)
++{
++	int i;
++
++	for (i = 0; i < UART_NR; i++) {
++		struct uart_8250_port *up = &serial8250_ports[i];
++
++		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
++			serial8250_resume_port(i);
++	}
++
++	return 0;
++}
++
++static struct platform_driver serial8250_isa_driver = {
++	.probe		= serial8250_probe,
++	.remove		= __devexit_p(serial8250_remove),
++	.suspend	= serial8250_suspend,
++	.resume		= serial8250_resume,
++	.driver		= {
++		.name	= "serial8250",
++		.owner	= THIS_MODULE,
++	},
++};
++
++/*
++ * This "device" covers _all_ ISA 8250-compatible serial devices listed
++ * in the table in include/asm/serial.h
++ */
++static struct platform_device *serial8250_isa_devs;
++
++/*
++ * serial8250_register_port and serial8250_unregister_port allows for
++ * 16x50 serial ports to be configured at run-time, to support PCMCIA
++ * modems and PCI multiport cards.
++ */
++static DEFINE_MUTEX(serial_mutex);
++
++static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
++{
++	int i;
++
++	/*
++	 * First, find a port entry which matches.
++	 */
++	for (i = 0; i < nr_uarts; i++)
++		if (uart_match_port(&serial8250_ports[i].port, port))
++			return &serial8250_ports[i];
++
++	/*
++	 * We didn't find a matching entry, so look for the first
++	 * free entry.  We look for one which hasn't been previously
++	 * used (indicated by zero iobase).
++	 */
++	for (i = 0; i < nr_uarts; i++)
++		if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
++		    serial8250_ports[i].port.iobase == 0)
++			return &serial8250_ports[i];
++
++	/*
++	 * That also failed.  Last resort is to find any entry which
++	 * doesn't have a real port associated with it.
++	 */
++	for (i = 0; i < nr_uarts; i++)
++		if (serial8250_ports[i].port.type == PORT_UNKNOWN)
++			return &serial8250_ports[i];
++
++	return NULL;
++}
++
++/**
++ *	serial8250_register_port - register a serial port
++ *	@port: serial port template
++ *
++ *	Configure the serial port specified by the request. If the
++ *	port exists and is in use, it is hung up and unregistered
++ *	first.
++ *
++ *	The port is then probed and if necessary the IRQ is autodetected
++ *	If this fails an error is returned.
++ *
++ *	On success the port is ready to use and the line number is returned.
++ */
++int serial8250_register_port(struct uart_port *port)
++{
++	struct uart_8250_port *uart;
++	int ret = -ENOSPC;
++
++	if (port->uartclk == 0)
++		return -EINVAL;
++
++	mutex_lock(&serial_mutex);
++
++	uart = serial8250_find_match_or_unused(port);
++	if (uart) {
++		uart_remove_one_port(&serial8250_reg, &uart->port);
++
++		uart->port.iobase       = port->iobase;
++		uart->port.membase      = port->membase;
++		uart->port.irq          = port->irq;
++		uart->port.irqflags     = port->irqflags;
++		uart->port.uartclk      = port->uartclk;
++		uart->port.fifosize     = port->fifosize;
++		uart->port.regshift     = port->regshift;
++		uart->port.iotype       = port->iotype;
++		uart->port.flags        = port->flags | UPF_BOOT_AUTOCONF;
++		uart->port.mapbase      = port->mapbase;
++		uart->port.private_data = port->private_data;
++		if (port->dev)
++			uart->port.dev = port->dev;
++
++		if (port->flags & UPF_FIXED_TYPE)
++			serial8250_init_fixed_type_port(uart, port->type);
++
++		set_io_from_upio(&uart->port);
++		/* Possibly override default I/O functions.  */
++		if (port->serial_in)
++			uart->port.serial_in = port->serial_in;
++		if (port->serial_out)
++			uart->port.serial_out = port->serial_out;
++
++		ret = uart_add_one_port(&serial8250_reg, &uart->port);
++		if (ret == 0)
++			ret = uart->port.line;
++	}
++	mutex_unlock(&serial_mutex);
++
++	return ret;
++}
++EXPORT_SYMBOL(serial8250_register_port);
++
++/**
++ *	serial8250_unregister_port - remove a 16x50 serial port at runtime
++ *	@line: serial line number
++ *
++ *	Remove one serial port.  This may not be called from interrupt
++ *	context.  We hand the port back to the our control.
++ */
++void serial8250_unregister_port(int line)
++{
++	struct uart_8250_port *uart = &serial8250_ports[line];
++
++	mutex_lock(&serial_mutex);
++	uart_remove_one_port(&serial8250_reg, &uart->port);
++	if (serial8250_isa_devs) {
++		uart->port.flags &= ~UPF_BOOT_AUTOCONF;
++		uart->port.type = PORT_UNKNOWN;
++		uart->port.dev = &serial8250_isa_devs->dev;
++		uart_add_one_port(&serial8250_reg, &uart->port);
++	} else {
++		uart->port.dev = NULL;
++	}
++	mutex_unlock(&serial_mutex);
++}
++EXPORT_SYMBOL(serial8250_unregister_port);
++
++static int __init serial8250_init(void)
++{
++	int ret;
++
++	if (nr_uarts > UART_NR)
++		nr_uarts = UART_NR;
++
++	printk(KERN_INFO "Serial: 8250/16550 driver, "
++		"%d ports, IRQ sharing %sabled\n", nr_uarts,
++		share_irqs ? "en" : "dis");
++
++#ifdef CONFIG_SPARC
++	ret = sunserial_register_minors(&serial8250_reg, UART_NR);
++#else
++	serial8250_reg.nr = UART_NR;
++	ret = uart_register_driver(&serial8250_reg);
++#endif
++	if (ret)
++		goto out;
++
++	serial8250_isa_devs = platform_device_alloc("serial8250",
++						    PLAT8250_DEV_LEGACY);
++	if (!serial8250_isa_devs) {
++		ret = -ENOMEM;
++		goto unreg_uart_drv;
++	}
++
++	ret = platform_device_add(serial8250_isa_devs);
++	if (ret)
++		goto put_dev;
++
++	serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
++
++	ret = platform_driver_register(&serial8250_isa_driver);
++	if (ret == 0)
++		goto out;
++
++	platform_device_del(serial8250_isa_devs);
++put_dev:
++	platform_device_put(serial8250_isa_devs);
++unreg_uart_drv:
++#ifdef CONFIG_SPARC
++	sunserial_unregister_minors(&serial8250_reg, UART_NR);
++#else
++	uart_unregister_driver(&serial8250_reg);
++#endif
++out:
++	return ret;
++}
++
++static void __exit serial8250_exit(void)
++{
++	struct platform_device *isa_dev = serial8250_isa_devs;
++
++	/*
++	 * This tells serial8250_unregister_port() not to re-register
++	 * the ports (thereby making serial8250_isa_driver permanently
++	 * in use.)
++	 */
++	serial8250_isa_devs = NULL;
++
++	platform_driver_unregister(&serial8250_isa_driver);
++	platform_device_unregister(isa_dev);
++
++#ifdef CONFIG_SPARC
++	sunserial_unregister_minors(&serial8250_reg, UART_NR);
++#else
++	uart_unregister_driver(&serial8250_reg);
++#endif
++}
++
++module_init(serial8250_init);
++module_exit(serial8250_exit);
++
++EXPORT_SYMBOL(serial8250_suspend_port);
++EXPORT_SYMBOL(serial8250_resume_port);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
++
++module_param(share_irqs, uint, 0644);
++MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
++	" (unsafe)");
++
++module_param(nr_uarts, uint, 0644);
++MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
++
++module_param(skip_txen_test, uint, 0644);
++MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
++
++#ifdef CONFIG_SERIAL_8250_RSA
++module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
++MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
++#endif
++MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
+diff -rupN linux-2.6.35.11/drivers/serial/8250_early.c linux-2.6.35.11-ts7500/drivers/serial/8250_early.c
+--- linux-2.6.35.11/drivers/serial/8250_early.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/serial/8250_early.c	2011-03-14 11:18:24.000000000 -0400
+@@ -46,6 +46,24 @@ struct early_serial8250_device {
+ 
+ static struct early_serial8250_device early_device;
+ 
++
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++static unsigned int __init serial_in(struct uart_port *port, int offset)
++{
++	if (port->iotype == UPIO_MEM)
++		return readb(port->membase + (offset << 2));
++	else
++		return inb(port->iobase + (offset << 2));
++}
++
++static void __init serial_out(struct uart_port *port, int offset, int value)
++{
++	if (port->iotype == UPIO_MEM)
++		writeb(value, port->membase + (offset << 2));
++	else
++		outb(value, port->iobase + (offset << 2));
++}
++#else
+ static unsigned int __init serial_in(struct uart_port *port, int offset)
+ {
+ 	if (port->iotype == UPIO_MEM)
+@@ -62,6 +80,9 @@ static void __init serial_out(struct uar
+ 		outb(value, port->iobase + offset);
+ }
+ 
++
++#endif
++
+ #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+ 
+ static void __init wait_for_xmitr(struct uart_port *port)
+diff -rupN linux-2.6.35.11/drivers/serial/8250_early.c.orig linux-2.6.35.11-ts7500/drivers/serial/8250_early.c.orig
+--- linux-2.6.35.11/drivers/serial/8250_early.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/serial/8250_early.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,260 @@
++/*
++ * Early serial console for 8250/16550 devices
++ *
++ * (c) Copyright 2004 Hewlett-Packard Development Company, L.P.
++ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Based on the 8250.c serial driver, Copyright (C) 2001 Russell King,
++ * and on early_printk.c by Andi Kleen.
++ *
++ * This is for use before the serial driver has initialized, in
++ * particular, before the UARTs have been discovered and named.
++ * Instead of specifying the console device as, e.g., "ttyS0",
++ * we locate the device directly by its MMIO or I/O port address.
++ *
++ * The user can specify the device directly, e.g.,
++ *	earlycon=uart8250,io,0x3f8,9600n8
++ *	earlycon=uart8250,mmio,0xff5e0000,115200n8
++ * or
++ *	console=uart8250,io,0x3f8,9600n8
++ *	console=uart8250,mmio,0xff5e0000,115200n8
++ */
++
++#include <linux/tty.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/serial_core.h>
++#include <linux/serial_reg.h>
++#include <linux/serial.h>
++#include <linux/serial_8250.h>
++#include <asm/io.h>
++#include <asm/serial.h>
++#ifdef CONFIG_FIX_EARLYCON_MEM
++#include <asm/pgtable.h>
++#include <asm/fixmap.h>
++#endif
++
++struct early_serial8250_device {
++	struct uart_port port;
++	char options[16];		/* e.g., 115200n8 */
++	unsigned int baud;
++};
++
++static struct early_serial8250_device early_device;
++
++static unsigned int __init serial_in(struct uart_port *port, int offset)
++{
++	if (port->iotype == UPIO_MEM)
++		return readb(port->membase + offset);
++	else
++		return inb(port->iobase + offset);
++}
++
++static void __init serial_out(struct uart_port *port, int offset, int value)
++{
++	if (port->iotype == UPIO_MEM)
++		writeb(value, port->membase + offset);
++	else
++		outb(value, port->iobase + offset);
++}
++
++#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
++
++static void __init wait_for_xmitr(struct uart_port *port)
++{
++	unsigned int status;
++
++	for (;;) {
++		status = serial_in(port, UART_LSR);
++		if ((status & BOTH_EMPTY) == BOTH_EMPTY)
++			return;
++		cpu_relax();
++	}
++}
++
++static void __init serial_putc(struct uart_port *port, int c)
++{
++	wait_for_xmitr(port);
++	serial_out(port, UART_TX, c);
++}
++
++static void __init early_serial8250_write(struct console *console,
++					const char *s, unsigned int count)
++{
++	struct uart_port *port = &early_device.port;
++	unsigned int ier;
++
++	/* Save the IER and disable interrupts */
++	ier = serial_in(port, UART_IER);
++	serial_out(port, UART_IER, 0);
++
++	uart_console_write(port, s, count, serial_putc);
++
++	/* Wait for transmitter to become empty and restore the IER */
++	wait_for_xmitr(port);
++	serial_out(port, UART_IER, ier);
++}
++
++static unsigned int __init probe_baud(struct uart_port *port)
++{
++	unsigned char lcr, dll, dlm;
++	unsigned int quot;
++
++	lcr = serial_in(port, UART_LCR);
++	serial_out(port, UART_LCR, lcr | UART_LCR_DLAB);
++	dll = serial_in(port, UART_DLL);
++	dlm = serial_in(port, UART_DLM);
++	serial_out(port, UART_LCR, lcr);
++
++	quot = (dlm << 8) | dll;
++	return (port->uartclk / 16) / quot;
++}
++
++static void __init init_port(struct early_serial8250_device *device)
++{
++	struct uart_port *port = &device->port;
++	unsigned int divisor;
++	unsigned char c;
++
++	serial_out(port, UART_LCR, 0x3);	/* 8n1 */
++	serial_out(port, UART_IER, 0);		/* no interrupt */
++	serial_out(port, UART_FCR, 0);		/* no fifo */
++	serial_out(port, UART_MCR, 0x3);	/* DTR + RTS */
++
++	divisor = port->uartclk / (16 * device->baud);
++	c = serial_in(port, UART_LCR);
++	serial_out(port, UART_LCR, c | UART_LCR_DLAB);
++	serial_out(port, UART_DLL, divisor & 0xff);
++	serial_out(port, UART_DLM, (divisor >> 8) & 0xff);
++	serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
++}
++
++static int __init parse_options(struct early_serial8250_device *device,
++								char *options)
++{
++	struct uart_port *port = &device->port;
++	int mmio, length;
++
++	if (!options)
++		return -ENODEV;
++
++	port->uartclk = BASE_BAUD * 16;
++	if (!strncmp(options, "mmio,", 5)) {
++		port->iotype = UPIO_MEM;
++		port->mapbase = simple_strtoul(options + 5, &options, 0);
++#ifdef CONFIG_FIX_EARLYCON_MEM
++		set_fixmap_nocache(FIX_EARLYCON_MEM_BASE,
++					port->mapbase & PAGE_MASK);
++		port->membase =
++			(void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
++		port->membase += port->mapbase & ~PAGE_MASK;
++#else
++		port->membase = ioremap_nocache(port->mapbase, 64);
++		if (!port->membase) {
++			printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n",
++				__func__,
++			       (unsigned long long)port->mapbase);
++			return -ENOMEM;
++		}
++#endif
++		mmio = 1;
++	} else if (!strncmp(options, "io,", 3)) {
++		port->iotype = UPIO_PORT;
++		port->iobase = simple_strtoul(options + 3, &options, 0);
++		mmio = 0;
++	} else
++		return -EINVAL;
++
++	options = strchr(options, ',');
++	if (options) {
++		options++;
++		device->baud = simple_strtoul(options, NULL, 0);
++		length = min(strcspn(options, " "), sizeof(device->options));
++		strncpy(device->options, options, length);
++	} else {
++		device->baud = probe_baud(port);
++		snprintf(device->options, sizeof(device->options), "%u",
++			device->baud);
++	}
++
++	printk(KERN_INFO "Early serial console at %s 0x%llx (options '%s')\n",
++		mmio ? "MMIO" : "I/O port",
++		mmio ? (unsigned long long) port->mapbase
++		     : (unsigned long long) port->iobase,
++		device->options);
++	return 0;
++}
++
++static struct console early_serial8250_console __initdata = {
++	.name	= "uart",
++	.write	= early_serial8250_write,
++	.flags	= CON_PRINTBUFFER | CON_BOOT,
++	.index	= -1,
++};
++
++static int __init early_serial8250_setup(char *options)
++{
++	struct early_serial8250_device *device = &early_device;
++	int err;
++
++	if (device->port.membase || device->port.iobase)
++		return 0;
++
++	err = parse_options(device, options);
++	if (err < 0)
++		return err;
++
++	init_port(device);
++	return 0;
++}
++
++int __init setup_early_serial8250_console(char *cmdline)
++{
++	char *options;
++	int err;
++
++	options = strstr(cmdline, "uart8250,");
++	if (!options) {
++		options = strstr(cmdline, "uart,");
++		if (!options)
++			return 0;
++	}
++
++	options = strchr(cmdline, ',') + 1;
++	err = early_serial8250_setup(options);
++	if (err < 0)
++		return err;
++
++	register_console(&early_serial8250_console);
++
++	return 0;
++}
++
++int serial8250_find_port_for_earlycon(void)
++{
++	struct early_serial8250_device *device = &early_device;
++	struct uart_port *port = &device->port;
++	int line;
++	int ret;
++
++	if (!device->port.membase && !device->port.iobase)
++		return -ENODEV;
++
++	line = serial8250_find_port(port);
++	if (line < 0)
++		return -ENODEV;
++
++	ret = update_console_cmdline("uart", 8250,
++			     "ttyS", line, device->options);
++	if (ret < 0)
++		ret = update_console_cmdline("uart", 0,
++				     "ttyS", line, device->options);
++
++	return ret;
++}
++
++early_param("earlycon", setup_early_serial8250_console);
+diff -rupN linux-2.6.35.11/drivers/serial/Kconfig linux-2.6.35.11-ts7500/drivers/serial/Kconfig
+--- linux-2.6.35.11/drivers/serial/Kconfig	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/serial/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -163,6 +163,62 @@ config SERIAL_8250_MANY_PORTS
+ 	  say N here to save some memory. You can also say Y if you have an
+ 	  "intelligent" multiport card such as Cyclades, Digiboards, etc.
+ 
++config SERIAL_8250_CTSRTS
++	bool "Support hardware flow-control"
++	depends on SERIAL_8250 && ARCH_STR8100
++	default N
++	help
++	  say Y here if you want Hardware Flow Control supoort. 
++	  GPIOs are used to implement CTS and RTS function.
++
++config GPIO_CTS
++	int	"GPIO pin number of CTS"
++	depends on SERIAL_8250_CTSRTS
++	default 0
++	help
++	  GPIOA[0:31]  0~31
++	  GPIOB[0:31] 32~63
++
++config GPIO_RTS
++	int	"GPIO pin number of RTS"
++	depends on SERIAL_8250_CTSRTS
++	default 1
++	help
++	  GPIOA[0:31]  0~31
++	  GPIOB[0:31] 32~63
++
++config GPIO_DCD
++	int	"GPIO pin number of DCD"
++	depends on SERIAL_8250_CTSRTS
++	default 2
++	help
++	  GPIOA[0:31]  0~31
++	  GPIOB[0:31] 32~63
++
++config GPIO_DTR
++	int	"GPIO pin number of DTR"
++	depends on SERIAL_8250_CTSRTS
++	default 3
++	help
++	  GPIOA[0:31]  0~31
++	  GPIOB[0:31] 32~63
++	
++config GPIO_DSR
++	int	"GPIO pin number of DSR"
++	depends on SERIAL_8250_CTSRTS
++	default 4
++	help
++	  GPIOA[0:31]  0~31
++	  GPIOB[0:31] 32~63
++
++config GPIO_RI
++	int	"GPIO pin number of RI"
++	depends on SERIAL_8250_CTSRTS
++	default 5
++	help
++	  GPIOA[0:31]  0~31
++	  GPIOB[0:31] 32~63     
++     
+ #
+ # Multi-port serial cards
+ #
+diff -rupN linux-2.6.35.11/drivers/spi/Kconfig linux-2.6.35.11-ts7500/drivers/spi/Kconfig
+--- linux-2.6.35.11/drivers/spi/Kconfig	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/spi/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -100,6 +100,15 @@ config SPI_BUTTERFLY
+ 	  inexpensive battery powered microcontroller evaluation board.
+ 	  This same cable can be used to flash new firmware.
+ 
++# Eileen , for linux kernel 2.6.24 , 20080413 
++config SPI_STR8100
++	tristate "STR8100 SPI master"
++	depends on SPI_MASTER && EXPERIMENTAL
++	select SPI_BITBANG
++	help
++	  STR8100 SPI master support
++
++     
+ config SPI_COLDFIRE_QSPI
+ 	tristate "Freescale Coldfire QSPI controller"
+ 	depends on (M520x || M523x || M5249 || M527x || M528x || M532x)
+diff -rupN linux-2.6.35.11/drivers/spi/Makefile linux-2.6.35.11-ts7500/drivers/spi/Makefile
+--- linux-2.6.35.11/drivers/spi/Makefile	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/spi/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -47,6 +47,7 @@ obj-$(CONFIG_SPI_SH_SCI)		+= spi_sh_sci.
+ obj-$(CONFIG_SPI_SH_MSIOF)		+= spi_sh_msiof.o
+ obj-$(CONFIG_SPI_STMP3XXX)		+= spi_stmp.o
+ obj-$(CONFIG_SPI_NUC900)		+= spi_nuc900.o
++obj-$(CONFIG_SPI_STR8100)		+= spi_str8100.o
+ 
+ # special build for s3c24xx spi driver with fiq support
+ spi_s3c24xx_hw-y			:= spi_s3c24xx.o
+diff -rupN linux-2.6.35.11/drivers/spi/spi_bitbang.c linux-2.6.35.11-ts7500/drivers/spi/spi_bitbang.c
+--- linux-2.6.35.11/drivers/spi/spi_bitbang.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/spi/spi_bitbang.c	2011-03-14 11:18:24.000000000 -0400
+@@ -335,6 +335,16 @@ static void bitbang_work(struct work_str
+ 				 */
+ 				if (!m->is_dma_mapped)
+ 					t->rx_dma = t->tx_dma = 0;
++/* Eileen , for linux kernel 2.6.24 , 20080413 */
++#ifdef CONFIG_ARCH_STR8100
++
++				if (t->transfer_list.next == &m->transfers) {
++					t->last_in_message_list = 1;
++				} else {
++					t->last_in_message_list = 0;
++				}
++				
++#endif            
+ 				status = bitbang->txrx_bufs(spi, t);
+ 			}
+ 			if (status > 0)
+diff -rupN linux-2.6.35.11/drivers/spi/spi_bitbang.c.orig linux-2.6.35.11-ts7500/drivers/spi/spi_bitbang.c.orig
+--- linux-2.6.35.11/drivers/spi/spi_bitbang.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/spi/spi_bitbang.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,513 @@
++/*
++ * spi_bitbang.c - polling/bitbanging SPI master controller driver utilities
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#include <linux/init.h>
++#include <linux/spinlock.h>
++#include <linux/workqueue.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++
++#include <linux/spi/spi.h>
++#include <linux/spi/spi_bitbang.h>
++
++
++/*----------------------------------------------------------------------*/
++
++/*
++ * FIRST PART (OPTIONAL):  word-at-a-time spi_transfer support.
++ * Use this for GPIO or shift-register level hardware APIs.
++ *
++ * spi_bitbang_cs is in spi_device->controller_state, which is unavailable
++ * to glue code.  These bitbang setup() and cleanup() routines are always
++ * used, though maybe they're called from controller-aware code.
++ *
++ * chipselect() and friends may use use spi_device->controller_data and
++ * controller registers as appropriate.
++ *
++ *
++ * NOTE:  SPI controller pins can often be used as GPIO pins instead,
++ * which means you could use a bitbang driver either to get hardware
++ * working quickly, or testing for differences that aren't speed related.
++ */
++
++struct spi_bitbang_cs {
++	unsigned	nsecs;	/* (clock cycle time)/2 */
++	u32		(*txrx_word)(struct spi_device *spi, unsigned nsecs,
++					u32 word, u8 bits);
++	unsigned	(*txrx_bufs)(struct spi_device *,
++					u32 (*txrx_word)(
++						struct spi_device *spi,
++						unsigned nsecs,
++						u32 word, u8 bits),
++					unsigned, struct spi_transfer *);
++};
++
++static unsigned bitbang_txrx_8(
++	struct spi_device	*spi,
++	u32			(*txrx_word)(struct spi_device *spi,
++					unsigned nsecs,
++					u32 word, u8 bits),
++	unsigned		ns,
++	struct spi_transfer	*t
++) {
++	unsigned		bits = spi->bits_per_word;
++	unsigned		count = t->len;
++	const u8		*tx = t->tx_buf;
++	u8			*rx = t->rx_buf;
++
++	while (likely(count > 0)) {
++		u8		word = 0;
++
++		if (tx)
++			word = *tx++;
++		word = txrx_word(spi, ns, word, bits);
++		if (rx)
++			*rx++ = word;
++		count -= 1;
++	}
++	return t->len - count;
++}
++
++static unsigned bitbang_txrx_16(
++	struct spi_device	*spi,
++	u32			(*txrx_word)(struct spi_device *spi,
++					unsigned nsecs,
++					u32 word, u8 bits),
++	unsigned		ns,
++	struct spi_transfer	*t
++) {
++	unsigned		bits = spi->bits_per_word;
++	unsigned		count = t->len;
++	const u16		*tx = t->tx_buf;
++	u16			*rx = t->rx_buf;
++
++	while (likely(count > 1)) {
++		u16		word = 0;
++
++		if (tx)
++			word = *tx++;
++		word = txrx_word(spi, ns, word, bits);
++		if (rx)
++			*rx++ = word;
++		count -= 2;
++	}
++	return t->len - count;
++}
++
++static unsigned bitbang_txrx_32(
++	struct spi_device	*spi,
++	u32			(*txrx_word)(struct spi_device *spi,
++					unsigned nsecs,
++					u32 word, u8 bits),
++	unsigned		ns,
++	struct spi_transfer	*t
++) {
++	unsigned		bits = spi->bits_per_word;
++	unsigned		count = t->len;
++	const u32		*tx = t->tx_buf;
++	u32			*rx = t->rx_buf;
++
++	while (likely(count > 3)) {
++		u32		word = 0;
++
++		if (tx)
++			word = *tx++;
++		word = txrx_word(spi, ns, word, bits);
++		if (rx)
++			*rx++ = word;
++		count -= 4;
++	}
++	return t->len - count;
++}
++
++int spi_bitbang_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
++{
++	struct spi_bitbang_cs	*cs = spi->controller_state;
++	u8			bits_per_word;
++	u32			hz;
++
++	if (t) {
++		bits_per_word = t->bits_per_word;
++		hz = t->speed_hz;
++	} else {
++		bits_per_word = 0;
++		hz = 0;
++	}
++
++	/* spi_transfer level calls that work per-word */
++	if (!bits_per_word)
++		bits_per_word = spi->bits_per_word;
++	if (bits_per_word <= 8)
++		cs->txrx_bufs = bitbang_txrx_8;
++	else if (bits_per_word <= 16)
++		cs->txrx_bufs = bitbang_txrx_16;
++	else if (bits_per_word <= 32)
++		cs->txrx_bufs = bitbang_txrx_32;
++	else
++		return -EINVAL;
++
++	/* nsecs = (clock period)/2 */
++	if (!hz)
++		hz = spi->max_speed_hz;
++	if (hz) {
++		cs->nsecs = (1000000000/2) / hz;
++		if (cs->nsecs > (MAX_UDELAY_MS * 1000 * 1000))
++			return -EINVAL;
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(spi_bitbang_setup_transfer);
++
++/**
++ * spi_bitbang_setup - default setup for per-word I/O loops
++ */
++int spi_bitbang_setup(struct spi_device *spi)
++{
++	struct spi_bitbang_cs	*cs = spi->controller_state;
++	struct spi_bitbang	*bitbang;
++	int			retval;
++	unsigned long		flags;
++
++	bitbang = spi_master_get_devdata(spi->master);
++
++	if (!cs) {
++		cs = kzalloc(sizeof *cs, GFP_KERNEL);
++		if (!cs)
++			return -ENOMEM;
++		spi->controller_state = cs;
++	}
++
++	/* per-word shift register access, in hardware or bitbanging */
++	cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)];
++	if (!cs->txrx_word)
++		return -EINVAL;
++
++	retval = bitbang->setup_transfer(spi, NULL);
++	if (retval < 0)
++		return retval;
++
++	dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs);
++
++	/* NOTE we _need_ to call chipselect() early, ideally with adapter
++	 * setup, unless the hardware defaults cooperate to avoid confusion
++	 * between normal (active low) and inverted chipselects.
++	 */
++
++	/* deselect chip (low or high) */
++	spin_lock_irqsave(&bitbang->lock, flags);
++	if (!bitbang->busy) {
++		bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
++		ndelay(cs->nsecs);
++	}
++	spin_unlock_irqrestore(&bitbang->lock, flags);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(spi_bitbang_setup);
++
++/**
++ * spi_bitbang_cleanup - default cleanup for per-word I/O loops
++ */
++void spi_bitbang_cleanup(struct spi_device *spi)
++{
++	kfree(spi->controller_state);
++}
++EXPORT_SYMBOL_GPL(spi_bitbang_cleanup);
++
++static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
++{
++	struct spi_bitbang_cs	*cs = spi->controller_state;
++	unsigned		nsecs = cs->nsecs;
++
++	return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t);
++}
++
++/*----------------------------------------------------------------------*/
++
++/*
++ * SECOND PART ... simple transfer queue runner.
++ *
++ * This costs a task context per controller, running the queue by
++ * performing each transfer in sequence.  Smarter hardware can queue
++ * several DMA transfers at once, and process several controller queues
++ * in parallel; this driver doesn't match such hardware very well.
++ *
++ * Drivers can provide word-at-a-time i/o primitives, or provide
++ * transfer-at-a-time ones to leverage dma or fifo hardware.
++ */
++static void bitbang_work(struct work_struct *work)
++{
++	struct spi_bitbang	*bitbang =
++		container_of(work, struct spi_bitbang, work);
++	unsigned long		flags;
++	int			do_setup = -1;
++	int			(*setup_transfer)(struct spi_device *,
++					struct spi_transfer *);
++
++	setup_transfer = bitbang->setup_transfer;
++
++	spin_lock_irqsave(&bitbang->lock, flags);
++	bitbang->busy = 1;
++	while (!list_empty(&bitbang->queue)) {
++		struct spi_message	*m;
++		struct spi_device	*spi;
++		unsigned		nsecs;
++		struct spi_transfer	*t = NULL;
++		unsigned		tmp;
++		unsigned		cs_change;
++		int			status;
++
++		m = container_of(bitbang->queue.next, struct spi_message,
++				queue);
++		list_del_init(&m->queue);
++		spin_unlock_irqrestore(&bitbang->lock, flags);
++
++		/* FIXME this is made-up ... the correct value is known to
++		 * word-at-a-time bitbang code, and presumably chipselect()
++		 * should enforce these requirements too?
++		 */
++		nsecs = 100;
++
++		spi = m->spi;
++		tmp = 0;
++		cs_change = 1;
++		status = 0;
++
++		list_for_each_entry (t, &m->transfers, transfer_list) {
++
++			/* override speed or wordsize? */
++			if (t->speed_hz || t->bits_per_word)
++				do_setup = 1;
++
++			/* init (-1) or override (1) transfer params */
++			if (do_setup != 0) {
++				if (!setup_transfer) {
++					status = -ENOPROTOOPT;
++					break;
++				}
++				status = setup_transfer(spi, t);
++				if (status < 0)
++					break;
++			}
++
++			/* set up default clock polarity, and activate chip;
++			 * this implicitly updates clock and spi modes as
++			 * previously recorded for this device via setup().
++			 * (and also deselects any other chip that might be
++			 * selected ...)
++			 */
++			if (cs_change) {
++				bitbang->chipselect(spi, BITBANG_CS_ACTIVE);
++				ndelay(nsecs);
++			}
++			cs_change = t->cs_change;
++			if (!t->tx_buf && !t->rx_buf && t->len) {
++				status = -EINVAL;
++				break;
++			}
++
++			/* transfer data.  the lower level code handles any
++			 * new dma mappings it needs. our caller always gave
++			 * us dma-safe buffers.
++			 */
++			if (t->len) {
++				/* REVISIT dma API still needs a designated
++				 * DMA_ADDR_INVALID; ~0 might be better.
++				 */
++				if (!m->is_dma_mapped)
++					t->rx_dma = t->tx_dma = 0;
++				status = bitbang->txrx_bufs(spi, t);
++			}
++			if (status > 0)
++				m->actual_length += status;
++			if (status != t->len) {
++				/* always report some kind of error */
++				if (status >= 0)
++					status = -EREMOTEIO;
++				break;
++			}
++			status = 0;
++
++			/* protocol tweaks before next transfer */
++			if (t->delay_usecs)
++				udelay(t->delay_usecs);
++
++			if (!cs_change)
++				continue;
++			if (t->transfer_list.next == &m->transfers)
++				break;
++
++			/* sometimes a short mid-message deselect of the chip
++			 * may be needed to terminate a mode or command
++			 */
++			ndelay(nsecs);
++			bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
++			ndelay(nsecs);
++		}
++
++		m->status = status;
++		m->complete(m->context);
++
++		/* restore speed and wordsize if it was overridden */
++		if (do_setup == 1)
++			setup_transfer(spi, NULL);
++		do_setup = 0;
++
++		/* normally deactivate chipselect ... unless no error and
++		 * cs_change has hinted that the next message will probably
++		 * be for this chip too.
++		 */
++		if (!(status == 0 && cs_change)) {
++			ndelay(nsecs);
++			bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
++			ndelay(nsecs);
++		}
++
++		spin_lock_irqsave(&bitbang->lock, flags);
++	}
++	bitbang->busy = 0;
++	spin_unlock_irqrestore(&bitbang->lock, flags);
++}
++
++/**
++ * spi_bitbang_transfer - default submit to transfer queue
++ */
++int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m)
++{
++	struct spi_bitbang	*bitbang;
++	unsigned long		flags;
++	int			status = 0;
++
++	m->actual_length = 0;
++	m->status = -EINPROGRESS;
++
++	bitbang = spi_master_get_devdata(spi->master);
++
++	spin_lock_irqsave(&bitbang->lock, flags);
++	if (!spi->max_speed_hz)
++		status = -ENETDOWN;
++	else {
++		list_add_tail(&m->queue, &bitbang->queue);
++		queue_work(bitbang->workqueue, &bitbang->work);
++	}
++	spin_unlock_irqrestore(&bitbang->lock, flags);
++
++	return status;
++}
++EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
++
++/*----------------------------------------------------------------------*/
++
++/**
++ * spi_bitbang_start - start up a polled/bitbanging SPI master driver
++ * @bitbang: driver handle
++ *
++ * Caller should have zero-initialized all parts of the structure, and then
++ * provided callbacks for chip selection and I/O loops.  If the master has
++ * a transfer method, its final step should call spi_bitbang_transfer; or,
++ * that's the default if the transfer routine is not initialized.  It should
++ * also set up the bus number and number of chipselects.
++ *
++ * For i/o loops, provide callbacks either per-word (for bitbanging, or for
++ * hardware that basically exposes a shift register) or per-spi_transfer
++ * (which takes better advantage of hardware like fifos or DMA engines).
++ *
++ * Drivers using per-word I/O loops should use (or call) spi_bitbang_setup,
++ * spi_bitbang_cleanup and spi_bitbang_setup_transfer to handle those spi
++ * master methods.  Those methods are the defaults if the bitbang->txrx_bufs
++ * routine isn't initialized.
++ *
++ * This routine registers the spi_master, which will process requests in a
++ * dedicated task, keeping IRQs unblocked most of the time.  To stop
++ * processing those requests, call spi_bitbang_stop().
++ */
++int spi_bitbang_start(struct spi_bitbang *bitbang)
++{
++	int	status;
++
++	if (!bitbang->master || !bitbang->chipselect)
++		return -EINVAL;
++
++	INIT_WORK(&bitbang->work, bitbang_work);
++	spin_lock_init(&bitbang->lock);
++	INIT_LIST_HEAD(&bitbang->queue);
++
++	if (!bitbang->master->mode_bits)
++		bitbang->master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
++
++	if (!bitbang->master->transfer)
++		bitbang->master->transfer = spi_bitbang_transfer;
++	if (!bitbang->txrx_bufs) {
++		bitbang->use_dma = 0;
++		bitbang->txrx_bufs = spi_bitbang_bufs;
++		if (!bitbang->master->setup) {
++			if (!bitbang->setup_transfer)
++				bitbang->setup_transfer =
++					 spi_bitbang_setup_transfer;
++			bitbang->master->setup = spi_bitbang_setup;
++			bitbang->master->cleanup = spi_bitbang_cleanup;
++		}
++	} else if (!bitbang->master->setup)
++		return -EINVAL;
++
++	/* this task is the only thing to touch the SPI bits */
++	bitbang->busy = 0;
++	bitbang->workqueue = create_singlethread_workqueue(
++			dev_name(bitbang->master->dev.parent));
++	if (bitbang->workqueue == NULL) {
++		status = -EBUSY;
++		goto err1;
++	}
++
++	/* driver may get busy before register() returns, especially
++	 * if someone registered boardinfo for devices
++	 */
++	status = spi_register_master(bitbang->master);
++	if (status < 0)
++		goto err2;
++
++	return status;
++
++err2:
++	destroy_workqueue(bitbang->workqueue);
++err1:
++	return status;
++}
++EXPORT_SYMBOL_GPL(spi_bitbang_start);
++
++/**
++ * spi_bitbang_stop - stops the task providing spi communication
++ */
++int spi_bitbang_stop(struct spi_bitbang *bitbang)
++{
++	spi_unregister_master(bitbang->master);
++
++	WARN_ON(!list_empty(&bitbang->queue));
++
++	destroy_workqueue(bitbang->workqueue);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(spi_bitbang_stop);
++
++MODULE_LICENSE("GPL");
++
+diff -rupN linux-2.6.35.11/drivers/spi/spi.c linux-2.6.35.11-ts7500/drivers/spi/spi.c
+--- linux-2.6.35.11/drivers/spi/spi.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/spi/spi.c	2011-03-14 11:35:13.000000000 -0400
+@@ -22,12 +22,29 @@
+ #include <linux/device.h>
+ #include <linux/init.h>
+ #include <linux/cache.h>
+-#include <linux/mutex.h>
++// #include <linux/mutex.h>
++#include <linux/semaphore.h>
+ #include <linux/slab.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/spi/spi.h>
+ 
++#include <mach/star_spi.h>
+ 
++static inline u8 str8131_spi_bus_idle(void)
++{
++       return ((SPI_SERVICE_STATUS_REG & 0x1) ? 0 : 1);
++}
++
++static inline u8 str8131_spi_tx_buffer_empty(void)
++{
++       return ((SPI_INTERRUPT_STATUS_REG & (0x1 << 3)) ? 1 : 0);
++}
++
++static inline u8 str8131_spi_rx_buffer_full(void)
++{
++       return ((SPI_INTERRUPT_STATUS_REG & (0x1 << 2)) ? 1 : 0);
++}
++ 
+ /* SPI bustype and spi_master class are registered after board init code
+  * provides the SPI device tables, ensuring that both are present by the
+  * time controller driver registration causes spi_devices to "enumerate".
+@@ -855,6 +872,82 @@ int spi_write_then_read(struct spi_devic
+ }
+ EXPORT_SYMBOL_GPL(spi_write_then_read);
+ 
++
++#ifdef CONFIG_ARCH_STR8100
++/**
++ * spi_write_read_sync - SPI synchronous write & read
++ * @spi: device with which data will be exchanged
++ * @txbuf: data to be written (need not be dma-safe)
++ * @n_tx: size of txbuf, in bytes
++ * @rxbuf: buffer into which data will be read
++ * @n_rx: size of rxbuf, in bytes (need not be dma-safe)
++ *
++ * This performs a half duplex MicroWire style transaction with the
++ * device, sending txbuf and then reading rxbuf.  The return value
++ * is zero for success, else a negative errno status code.
++ * This call may only be used from a context that may sleep.
++ *
++ * Parameters to this routine are always copied using a small buffer;
++ * performance-sensitive or bulk transfer code should instead use
++ * spi_{async,sync}() calls with dma-safe buffers.
++ */
++int spi_write_read_sync(struct spi_device *spi,
++		const u8 *txbuf, unsigned n_tx,
++		u8 *rxbuf, unsigned n_rx)
++{
++	static DECLARE_MUTEX(lock);
++
++	int			status;
++	struct spi_message	message;
++	struct spi_transfer	x;
++	u8			*local_buf;
++
++	/* Use preallocated DMA-safe buffer.  We can't avoid copying here,
++	 * (as a pure convenience thing), but we can keep heap costs
++	 * out of the hot path ...
++	 */
++	 while (!str8131_spi_bus_idle()){
++		printk("spi bus is not idle \n"); // do nothing
++	 	}
++	while (!str8131_spi_tx_buffer_empty()){
++		printk("spi tx buffer is not empty \n"); // do nothing
++		}
++	if ((n_tx + n_rx) > SPI_BUFSIZ)
++		return -EINVAL;
++	spi_message_init(&message);
++	memset(&x, 0, sizeof x);
++	x.len = n_tx;
++	spi_message_add_tail(&x, &message);
++
++	/* ... unless someone else is using the pre-allocated buffer */
++	if (down_trylock(&lock)) {
++		local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
++		if (!local_buf)
++			return -ENOMEM;
++	} else
++		local_buf = buf;
++
++	memcpy(local_buf, txbuf, n_tx);
++	x.tx_buf = local_buf;
++	x.rx_buf = local_buf + n_tx;
++
++	/* do the i/o */
++	status = spi_sync(spi, &message);
++	if (status == 0) {
++		memcpy(rxbuf, x.rx_buf, n_rx);
++		status = message.status;
++	}
++
++	if (x.tx_buf == buf)
++		up(&lock);
++	else
++		kfree(local_buf);
++
++	return status;
++}
++EXPORT_SYMBOL_GPL(spi_write_read_sync);
++#endif
++
+ /*-------------------------------------------------------------------------*/
+ 
+ static int __init spi_init(void)
+diff -rupN linux-2.6.35.11/drivers/spi/spi.c.orig linux-2.6.35.11-ts7500/drivers/spi/spi.c.orig
+--- linux-2.6.35.11/drivers/spi/spi.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/spi/spi.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,896 @@
++/*
++ * spi.c - SPI init/core code
++ *
++ * Copyright (C) 2005 David Brownell
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/cache.h>
++#include <linux/mutex.h>
++#include <linux/slab.h>
++#include <linux/mod_devicetable.h>
++#include <linux/spi/spi.h>
++
++
++/* SPI bustype and spi_master class are registered after board init code
++ * provides the SPI device tables, ensuring that both are present by the
++ * time controller driver registration causes spi_devices to "enumerate".
++ */
++static void spidev_release(struct device *dev)
++{
++	struct spi_device	*spi = to_spi_device(dev);
++
++	/* spi masters may cleanup for released devices */
++	if (spi->master->cleanup)
++		spi->master->cleanup(spi);
++
++	spi_master_put(spi->master);
++	kfree(spi);
++}
++
++static ssize_t
++modalias_show(struct device *dev, struct device_attribute *a, char *buf)
++{
++	const struct spi_device	*spi = to_spi_device(dev);
++
++	return sprintf(buf, "%s\n", spi->modalias);
++}
++
++static struct device_attribute spi_dev_attrs[] = {
++	__ATTR_RO(modalias),
++	__ATTR_NULL,
++};
++
++/* modalias support makes "modprobe $MODALIAS" new-style hotplug work,
++ * and the sysfs version makes coldplug work too.
++ */
++
++static const struct spi_device_id *spi_match_id(const struct spi_device_id *id,
++						const struct spi_device *sdev)
++{
++	while (id->name[0]) {
++		if (!strcmp(sdev->modalias, id->name))
++			return id;
++		id++;
++	}
++	return NULL;
++}
++
++const struct spi_device_id *spi_get_device_id(const struct spi_device *sdev)
++{
++	const struct spi_driver *sdrv = to_spi_driver(sdev->dev.driver);
++
++	return spi_match_id(sdrv->id_table, sdev);
++}
++EXPORT_SYMBOL_GPL(spi_get_device_id);
++
++static int spi_match_device(struct device *dev, struct device_driver *drv)
++{
++	const struct spi_device	*spi = to_spi_device(dev);
++	const struct spi_driver	*sdrv = to_spi_driver(drv);
++
++	if (sdrv->id_table)
++		return !!spi_match_id(sdrv->id_table, spi);
++
++	return strcmp(spi->modalias, drv->name) == 0;
++}
++
++static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
++{
++	const struct spi_device		*spi = to_spi_device(dev);
++
++	add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias);
++	return 0;
++}
++
++#ifdef	CONFIG_PM
++
++static int spi_suspend(struct device *dev, pm_message_t message)
++{
++	int			value = 0;
++	struct spi_driver	*drv = to_spi_driver(dev->driver);
++
++	/* suspend will stop irqs and dma; no more i/o */
++	if (drv) {
++		if (drv->suspend)
++			value = drv->suspend(to_spi_device(dev), message);
++		else
++			dev_dbg(dev, "... can't suspend\n");
++	}
++	return value;
++}
++
++static int spi_resume(struct device *dev)
++{
++	int			value = 0;
++	struct spi_driver	*drv = to_spi_driver(dev->driver);
++
++	/* resume may restart the i/o queue */
++	if (drv) {
++		if (drv->resume)
++			value = drv->resume(to_spi_device(dev));
++		else
++			dev_dbg(dev, "... can't resume\n");
++	}
++	return value;
++}
++
++#else
++#define spi_suspend	NULL
++#define spi_resume	NULL
++#endif
++
++struct bus_type spi_bus_type = {
++	.name		= "spi",
++	.dev_attrs	= spi_dev_attrs,
++	.match		= spi_match_device,
++	.uevent		= spi_uevent,
++	.suspend	= spi_suspend,
++	.resume		= spi_resume,
++};
++EXPORT_SYMBOL_GPL(spi_bus_type);
++
++
++static int spi_drv_probe(struct device *dev)
++{
++	const struct spi_driver		*sdrv = to_spi_driver(dev->driver);
++
++	return sdrv->probe(to_spi_device(dev));
++}
++
++static int spi_drv_remove(struct device *dev)
++{
++	const struct spi_driver		*sdrv = to_spi_driver(dev->driver);
++
++	return sdrv->remove(to_spi_device(dev));
++}
++
++static void spi_drv_shutdown(struct device *dev)
++{
++	const struct spi_driver		*sdrv = to_spi_driver(dev->driver);
++
++	sdrv->shutdown(to_spi_device(dev));
++}
++
++/**
++ * spi_register_driver - register a SPI driver
++ * @sdrv: the driver to register
++ * Context: can sleep
++ */
++int spi_register_driver(struct spi_driver *sdrv)
++{
++	sdrv->driver.bus = &spi_bus_type;
++	if (sdrv->probe)
++		sdrv->driver.probe = spi_drv_probe;
++	if (sdrv->remove)
++		sdrv->driver.remove = spi_drv_remove;
++	if (sdrv->shutdown)
++		sdrv->driver.shutdown = spi_drv_shutdown;
++	return driver_register(&sdrv->driver);
++}
++EXPORT_SYMBOL_GPL(spi_register_driver);
++
++/*-------------------------------------------------------------------------*/
++
++/* SPI devices should normally not be created by SPI device drivers; that
++ * would make them board-specific.  Similarly with SPI master drivers.
++ * Device registration normally goes into like arch/.../mach.../board-YYY.c
++ * with other readonly (flashable) information about mainboard devices.
++ */
++
++struct boardinfo {
++	struct list_head	list;
++	unsigned		n_board_info;
++	struct spi_board_info	board_info[0];
++};
++
++static LIST_HEAD(board_list);
++static DEFINE_MUTEX(board_lock);
++
++/**
++ * spi_alloc_device - Allocate a new SPI device
++ * @master: Controller to which device is connected
++ * Context: can sleep
++ *
++ * Allows a driver to allocate and initialize a spi_device without
++ * registering it immediately.  This allows a driver to directly
++ * fill the spi_device with device parameters before calling
++ * spi_add_device() on it.
++ *
++ * Caller is responsible to call spi_add_device() on the returned
++ * spi_device structure to add it to the SPI master.  If the caller
++ * needs to discard the spi_device without adding it, then it should
++ * call spi_dev_put() on it.
++ *
++ * Returns a pointer to the new device, or NULL.
++ */
++struct spi_device *spi_alloc_device(struct spi_master *master)
++{
++	struct spi_device	*spi;
++	struct device		*dev = master->dev.parent;
++
++	if (!spi_master_get(master))
++		return NULL;
++
++	spi = kzalloc(sizeof *spi, GFP_KERNEL);
++	if (!spi) {
++		dev_err(dev, "cannot alloc spi_device\n");
++		spi_master_put(master);
++		return NULL;
++	}
++
++	spi->master = master;
++	spi->dev.parent = dev;
++	spi->dev.bus = &spi_bus_type;
++	spi->dev.release = spidev_release;
++	device_initialize(&spi->dev);
++	return spi;
++}
++EXPORT_SYMBOL_GPL(spi_alloc_device);
++
++/**
++ * spi_add_device - Add spi_device allocated with spi_alloc_device
++ * @spi: spi_device to register
++ *
++ * Companion function to spi_alloc_device.  Devices allocated with
++ * spi_alloc_device can be added onto the spi bus with this function.
++ *
++ * Returns 0 on success; negative errno on failure
++ */
++int spi_add_device(struct spi_device *spi)
++{
++	static DEFINE_MUTEX(spi_add_lock);
++	struct device *dev = spi->master->dev.parent;
++	struct device *d;
++	int status;
++
++	/* Chipselects are numbered 0..max; validate. */
++	if (spi->chip_select >= spi->master->num_chipselect) {
++		dev_err(dev, "cs%d >= max %d\n",
++			spi->chip_select,
++			spi->master->num_chipselect);
++		return -EINVAL;
++	}
++
++	/* Set the bus ID string */
++	dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->master->dev),
++			spi->chip_select);
++
++
++	/* We need to make sure there's no other device with this
++	 * chipselect **BEFORE** we call setup(), else we'll trash
++	 * its configuration.  Lock against concurrent add() calls.
++	 */
++	mutex_lock(&spi_add_lock);
++
++	d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));
++	if (d != NULL) {
++		dev_err(dev, "chipselect %d already in use\n",
++				spi->chip_select);
++		put_device(d);
++		status = -EBUSY;
++		goto done;
++	}
++
++	/* Drivers may modify this initial i/o setup, but will
++	 * normally rely on the device being setup.  Devices
++	 * using SPI_CS_HIGH can't coexist well otherwise...
++	 */
++	status = spi_setup(spi);
++	if (status < 0) {
++		dev_err(dev, "can't %s %s, status %d\n",
++				"setup", dev_name(&spi->dev), status);
++		goto done;
++	}
++
++	/* Device may be bound to an active driver when this returns */
++	status = device_add(&spi->dev);
++	if (status < 0)
++		dev_err(dev, "can't %s %s, status %d\n",
++				"add", dev_name(&spi->dev), status);
++	else
++		dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev));
++
++done:
++	mutex_unlock(&spi_add_lock);
++	return status;
++}
++EXPORT_SYMBOL_GPL(spi_add_device);
++
++/**
++ * spi_new_device - instantiate one new SPI device
++ * @master: Controller to which device is connected
++ * @chip: Describes the SPI device
++ * Context: can sleep
++ *
++ * On typical mainboards, this is purely internal; and it's not needed
++ * after board init creates the hard-wired devices.  Some development
++ * platforms may not be able to use spi_register_board_info though, and
++ * this is exported so that for example a USB or parport based adapter
++ * driver could add devices (which it would learn about out-of-band).
++ *
++ * Returns the new device, or NULL.
++ */
++struct spi_device *spi_new_device(struct spi_master *master,
++				  struct spi_board_info *chip)
++{
++	struct spi_device	*proxy;
++	int			status;
++
++	/* NOTE:  caller did any chip->bus_num checks necessary.
++	 *
++	 * Also, unless we change the return value convention to use
++	 * error-or-pointer (not NULL-or-pointer), troubleshootability
++	 * suggests syslogged diagnostics are best here (ugh).
++	 */
++
++	proxy = spi_alloc_device(master);
++	if (!proxy)
++		return NULL;
++
++	WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias));
++
++	proxy->chip_select = chip->chip_select;
++	proxy->max_speed_hz = chip->max_speed_hz;
++	proxy->mode = chip->mode;
++	proxy->irq = chip->irq;
++	strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias));
++	proxy->dev.platform_data = (void *) chip->platform_data;
++	proxy->controller_data = chip->controller_data;
++	proxy->controller_state = NULL;
++
++	status = spi_add_device(proxy);
++	if (status < 0) {
++		spi_dev_put(proxy);
++		return NULL;
++	}
++
++	return proxy;
++}
++EXPORT_SYMBOL_GPL(spi_new_device);
++
++/**
++ * spi_register_board_info - register SPI devices for a given board
++ * @info: array of chip descriptors
++ * @n: how many descriptors are provided
++ * Context: can sleep
++ *
++ * Board-specific early init code calls this (probably during arch_initcall)
++ * with segments of the SPI device table.  Any device nodes are created later,
++ * after the relevant parent SPI controller (bus_num) is defined.  We keep
++ * this table of devices forever, so that reloading a controller driver will
++ * not make Linux forget about these hard-wired devices.
++ *
++ * Other code can also call this, e.g. a particular add-on board might provide
++ * SPI devices through its expansion connector, so code initializing that board
++ * would naturally declare its SPI devices.
++ *
++ * The board info passed can safely be __initdata ... but be careful of
++ * any embedded pointers (platform_data, etc), they're copied as-is.
++ */
++int __init
++spi_register_board_info(struct spi_board_info const *info, unsigned n)
++{
++	struct boardinfo	*bi;
++
++	bi = kmalloc(sizeof(*bi) + n * sizeof *info, GFP_KERNEL);
++	if (!bi)
++		return -ENOMEM;
++	bi->n_board_info = n;
++	memcpy(bi->board_info, info, n * sizeof *info);
++
++	mutex_lock(&board_lock);
++	list_add_tail(&bi->list, &board_list);
++	mutex_unlock(&board_lock);
++	return 0;
++}
++
++/* FIXME someone should add support for a __setup("spi", ...) that
++ * creates board info from kernel command lines
++ */
++
++static void scan_boardinfo(struct spi_master *master)
++{
++	struct boardinfo	*bi;
++
++	mutex_lock(&board_lock);
++	list_for_each_entry(bi, &board_list, list) {
++		struct spi_board_info	*chip = bi->board_info;
++		unsigned		n;
++
++		for (n = bi->n_board_info; n > 0; n--, chip++) {
++			if (chip->bus_num != master->bus_num)
++				continue;
++			/* NOTE: this relies on spi_new_device to
++			 * issue diagnostics when given bogus inputs
++			 */
++			(void) spi_new_device(master, chip);
++		}
++	}
++	mutex_unlock(&board_lock);
++}
++
++/*-------------------------------------------------------------------------*/
++
++static void spi_master_release(struct device *dev)
++{
++	struct spi_master *master;
++
++	master = container_of(dev, struct spi_master, dev);
++	kfree(master);
++}
++
++static struct class spi_master_class = {
++	.name		= "spi_master",
++	.owner		= THIS_MODULE,
++	.dev_release	= spi_master_release,
++};
++
++
++/**
++ * spi_alloc_master - allocate SPI master controller
++ * @dev: the controller, possibly using the platform_bus
++ * @size: how much zeroed driver-private data to allocate; the pointer to this
++ *	memory is in the driver_data field of the returned device,
++ *	accessible with spi_master_get_devdata().
++ * Context: can sleep
++ *
++ * This call is used only by SPI master controller drivers, which are the
++ * only ones directly touching chip registers.  It's how they allocate
++ * an spi_master structure, prior to calling spi_register_master().
++ *
++ * This must be called from context that can sleep.  It returns the SPI
++ * master structure on success, else NULL.
++ *
++ * The caller is responsible for assigning the bus number and initializing
++ * the master's methods before calling spi_register_master(); and (after errors
++ * adding the device) calling spi_master_put() to prevent a memory leak.
++ */
++struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
++{
++	struct spi_master	*master;
++
++	if (!dev)
++		return NULL;
++
++	master = kzalloc(size + sizeof *master, GFP_KERNEL);
++	if (!master)
++		return NULL;
++
++	device_initialize(&master->dev);
++	master->dev.class = &spi_master_class;
++	master->dev.parent = get_device(dev);
++	spi_master_set_devdata(master, &master[1]);
++
++	return master;
++}
++EXPORT_SYMBOL_GPL(spi_alloc_master);
++
++/**
++ * spi_register_master - register SPI master controller
++ * @master: initialized master, originally from spi_alloc_master()
++ * Context: can sleep
++ *
++ * SPI master controllers connect to their drivers using some non-SPI bus,
++ * such as the platform bus.  The final stage of probe() in that code
++ * includes calling spi_register_master() to hook up to this SPI bus glue.
++ *
++ * SPI controllers use board specific (often SOC specific) bus numbers,
++ * and board-specific addressing for SPI devices combines those numbers
++ * with chip select numbers.  Since SPI does not directly support dynamic
++ * device identification, boards need configuration tables telling which
++ * chip is at which address.
++ *
++ * This must be called from context that can sleep.  It returns zero on
++ * success, else a negative error code (dropping the master's refcount).
++ * After a successful return, the caller is responsible for calling
++ * spi_unregister_master().
++ */
++int spi_register_master(struct spi_master *master)
++{
++	static atomic_t		dyn_bus_id = ATOMIC_INIT((1<<15) - 1);
++	struct device		*dev = master->dev.parent;
++	int			status = -ENODEV;
++	int			dynamic = 0;
++
++	if (!dev)
++		return -ENODEV;
++
++	/* even if it's just one always-selected device, there must
++	 * be at least one chipselect
++	 */
++	if (master->num_chipselect == 0)
++		return -EINVAL;
++
++	/* convention:  dynamically assigned bus IDs count down from the max */
++	if (master->bus_num < 0) {
++		/* FIXME switch to an IDR based scheme, something like
++		 * I2C now uses, so we can't run out of "dynamic" IDs
++		 */
++		master->bus_num = atomic_dec_return(&dyn_bus_id);
++		dynamic = 1;
++	}
++
++	/* register the device, then userspace will see it.
++	 * registration fails if the bus ID is in use.
++	 */
++	dev_set_name(&master->dev, "spi%u", master->bus_num);
++	status = device_add(&master->dev);
++	if (status < 0)
++		goto done;
++	dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev),
++			dynamic ? " (dynamic)" : "");
++
++	/* populate children from any spi device tables */
++	scan_boardinfo(master);
++	status = 0;
++done:
++	return status;
++}
++EXPORT_SYMBOL_GPL(spi_register_master);
++
++
++static int __unregister(struct device *dev, void *master_dev)
++{
++	/* note: before about 2.6.14-rc1 this would corrupt memory: */
++	if (dev != master_dev)
++		spi_unregister_device(to_spi_device(dev));
++	return 0;
++}
++
++/**
++ * spi_unregister_master - unregister SPI master controller
++ * @master: the master being unregistered
++ * Context: can sleep
++ *
++ * This call is used only by SPI master controller drivers, which are the
++ * only ones directly touching chip registers.
++ *
++ * This must be called from context that can sleep.
++ */
++void spi_unregister_master(struct spi_master *master)
++{
++	int dummy;
++
++	dummy = device_for_each_child(master->dev.parent, &master->dev,
++					__unregister);
++	device_unregister(&master->dev);
++}
++EXPORT_SYMBOL_GPL(spi_unregister_master);
++
++static int __spi_master_match(struct device *dev, void *data)
++{
++	struct spi_master *m;
++	u16 *bus_num = data;
++
++	m = container_of(dev, struct spi_master, dev);
++	return m->bus_num == *bus_num;
++}
++
++/**
++ * spi_busnum_to_master - look up master associated with bus_num
++ * @bus_num: the master's bus number
++ * Context: can sleep
++ *
++ * This call may be used with devices that are registered after
++ * arch init time.  It returns a refcounted pointer to the relevant
++ * spi_master (which the caller must release), or NULL if there is
++ * no such master registered.
++ */
++struct spi_master *spi_busnum_to_master(u16 bus_num)
++{
++	struct device		*dev;
++	struct spi_master	*master = NULL;
++
++	dev = class_find_device(&spi_master_class, NULL, &bus_num,
++				__spi_master_match);
++	if (dev)
++		master = container_of(dev, struct spi_master, dev);
++	/* reference got in class_find_device */
++	return master;
++}
++EXPORT_SYMBOL_GPL(spi_busnum_to_master);
++
++
++/*-------------------------------------------------------------------------*/
++
++/* Core methods for SPI master protocol drivers.  Some of the
++ * other core methods are currently defined as inline functions.
++ */
++
++/**
++ * spi_setup - setup SPI mode and clock rate
++ * @spi: the device whose settings are being modified
++ * Context: can sleep, and no requests are queued to the device
++ *
++ * SPI protocol drivers may need to update the transfer mode if the
++ * device doesn't work with its default.  They may likewise need
++ * to update clock rates or word sizes from initial values.  This function
++ * changes those settings, and must be called from a context that can sleep.
++ * Except for SPI_CS_HIGH, which takes effect immediately, the changes take
++ * effect the next time the device is selected and data is transferred to
++ * or from it.  When this function returns, the spi device is deselected.
++ *
++ * Note that this call will fail if the protocol driver specifies an option
++ * that the underlying controller or its driver does not support.  For
++ * example, not all hardware supports wire transfers using nine bit words,
++ * LSB-first wire encoding, or active-high chipselects.
++ */
++int spi_setup(struct spi_device *spi)
++{
++	unsigned	bad_bits;
++	int		status;
++
++	/* help drivers fail *cleanly* when they need options
++	 * that aren't supported with their current master
++	 */
++	bad_bits = spi->mode & ~spi->master->mode_bits;
++	if (bad_bits) {
++		dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
++			bad_bits);
++		return -EINVAL;
++	}
++
++	if (!spi->bits_per_word)
++		spi->bits_per_word = 8;
++
++	status = spi->master->setup(spi);
++
++	dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s"
++				"%u bits/w, %u Hz max --> %d\n",
++			(int) (spi->mode & (SPI_CPOL | SPI_CPHA)),
++			(spi->mode & SPI_CS_HIGH) ? "cs_high, " : "",
++			(spi->mode & SPI_LSB_FIRST) ? "lsb, " : "",
++			(spi->mode & SPI_3WIRE) ? "3wire, " : "",
++			(spi->mode & SPI_LOOP) ? "loopback, " : "",
++			spi->bits_per_word, spi->max_speed_hz,
++			status);
++
++	return status;
++}
++EXPORT_SYMBOL_GPL(spi_setup);
++
++/**
++ * spi_async - asynchronous SPI transfer
++ * @spi: device with which data will be exchanged
++ * @message: describes the data transfers, including completion callback
++ * Context: any (irqs may be blocked, etc)
++ *
++ * This call may be used in_irq and other contexts which can't sleep,
++ * as well as from task contexts which can sleep.
++ *
++ * The completion callback is invoked in a context which can't sleep.
++ * Before that invocation, the value of message->status is undefined.
++ * When the callback is issued, message->status holds either zero (to
++ * indicate complete success) or a negative error code.  After that
++ * callback returns, the driver which issued the transfer request may
++ * deallocate the associated memory; it's no longer in use by any SPI
++ * core or controller driver code.
++ *
++ * Note that although all messages to a spi_device are handled in
++ * FIFO order, messages may go to different devices in other orders.
++ * Some device might be higher priority, or have various "hard" access
++ * time requirements, for example.
++ *
++ * On detection of any fault during the transfer, processing of
++ * the entire message is aborted, and the device is deselected.
++ * Until returning from the associated message completion callback,
++ * no other spi_message queued to that device will be processed.
++ * (This rule applies equally to all the synchronous transfer calls,
++ * which are wrappers around this core asynchronous primitive.)
++ */
++int spi_async(struct spi_device *spi, struct spi_message *message)
++{
++	struct spi_master *master = spi->master;
++
++	/* Half-duplex links include original MicroWire, and ones with
++	 * only one data pin like SPI_3WIRE (switches direction) or where
++	 * either MOSI or MISO is missing.  They can also be caused by
++	 * software limitations.
++	 */
++	if ((master->flags & SPI_MASTER_HALF_DUPLEX)
++			|| (spi->mode & SPI_3WIRE)) {
++		struct spi_transfer *xfer;
++		unsigned flags = master->flags;
++
++		list_for_each_entry(xfer, &message->transfers, transfer_list) {
++			if (xfer->rx_buf && xfer->tx_buf)
++				return -EINVAL;
++			if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf)
++				return -EINVAL;
++			if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf)
++				return -EINVAL;
++		}
++	}
++
++	message->spi = spi;
++	message->status = -EINPROGRESS;
++	return master->transfer(spi, message);
++}
++EXPORT_SYMBOL_GPL(spi_async);
++
++
++/*-------------------------------------------------------------------------*/
++
++/* Utility methods for SPI master protocol drivers, layered on
++ * top of the core.  Some other utility methods are defined as
++ * inline functions.
++ */
++
++static void spi_complete(void *arg)
++{
++	complete(arg);
++}
++
++/**
++ * spi_sync - blocking/synchronous SPI data transfers
++ * @spi: device with which data will be exchanged
++ * @message: describes the data transfers
++ * Context: can sleep
++ *
++ * This call may only be used from a context that may sleep.  The sleep
++ * is non-interruptible, and has no timeout.  Low-overhead controller
++ * drivers may DMA directly into and out of the message buffers.
++ *
++ * Note that the SPI device's chip select is active during the message,
++ * and then is normally disabled between messages.  Drivers for some
++ * frequently-used devices may want to minimize costs of selecting a chip,
++ * by leaving it selected in anticipation that the next message will go
++ * to the same chip.  (That may increase power usage.)
++ *
++ * Also, the caller is guaranteeing that the memory associated with the
++ * message will not be freed before this call returns.
++ *
++ * It returns zero on success, else a negative error code.
++ */
++int spi_sync(struct spi_device *spi, struct spi_message *message)
++{
++	DECLARE_COMPLETION_ONSTACK(done);
++	int status;
++
++	message->complete = spi_complete;
++	message->context = &done;
++	status = spi_async(spi, message);
++	if (status == 0) {
++		wait_for_completion(&done);
++		status = message->status;
++	}
++	message->context = NULL;
++	return status;
++}
++EXPORT_SYMBOL_GPL(spi_sync);
++
++/* portable code must never pass more than 32 bytes */
++#define	SPI_BUFSIZ	max(32,SMP_CACHE_BYTES)
++
++static u8	*buf;
++
++/**
++ * spi_write_then_read - SPI synchronous write followed by read
++ * @spi: device with which data will be exchanged
++ * @txbuf: data to be written (need not be dma-safe)
++ * @n_tx: size of txbuf, in bytes
++ * @rxbuf: buffer into which data will be read (need not be dma-safe)
++ * @n_rx: size of rxbuf, in bytes
++ * Context: can sleep
++ *
++ * This performs a half duplex MicroWire style transaction with the
++ * device, sending txbuf and then reading rxbuf.  The return value
++ * is zero for success, else a negative errno status code.
++ * This call may only be used from a context that may sleep.
++ *
++ * Parameters to this routine are always copied using a small buffer;
++ * portable code should never use this for more than 32 bytes.
++ * Performance-sensitive or bulk transfer code should instead use
++ * spi_{async,sync}() calls with dma-safe buffers.
++ */
++int spi_write_then_read(struct spi_device *spi,
++		const u8 *txbuf, unsigned n_tx,
++		u8 *rxbuf, unsigned n_rx)
++{
++	static DEFINE_MUTEX(lock);
++
++	int			status;
++	struct spi_message	message;
++	struct spi_transfer	x[2];
++	u8			*local_buf;
++
++	/* Use preallocated DMA-safe buffer.  We can't avoid copying here,
++	 * (as a pure convenience thing), but we can keep heap costs
++	 * out of the hot path ...
++	 */
++	if ((n_tx + n_rx) > SPI_BUFSIZ)
++		return -EINVAL;
++
++	spi_message_init(&message);
++	memset(x, 0, sizeof x);
++	if (n_tx) {
++		x[0].len = n_tx;
++		spi_message_add_tail(&x[0], &message);
++	}
++	if (n_rx) {
++		x[1].len = n_rx;
++		spi_message_add_tail(&x[1], &message);
++	}
++
++	/* ... unless someone else is using the pre-allocated buffer */
++	if (!mutex_trylock(&lock)) {
++		local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
++		if (!local_buf)
++			return -ENOMEM;
++	} else
++		local_buf = buf;
++
++	memcpy(local_buf, txbuf, n_tx);
++	x[0].tx_buf = local_buf;
++	x[1].rx_buf = local_buf + n_tx;
++
++	/* do the i/o */
++	status = spi_sync(spi, &message);
++	if (status == 0)
++		memcpy(rxbuf, x[1].rx_buf, n_rx);
++
++	if (x[0].tx_buf == buf)
++		mutex_unlock(&lock);
++	else
++		kfree(local_buf);
++
++	return status;
++}
++EXPORT_SYMBOL_GPL(spi_write_then_read);
++
++/*-------------------------------------------------------------------------*/
++
++static int __init spi_init(void)
++{
++	int	status;
++
++	buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
++	if (!buf) {
++		status = -ENOMEM;
++		goto err0;
++	}
++
++	status = bus_register(&spi_bus_type);
++	if (status < 0)
++		goto err1;
++
++	status = class_register(&spi_master_class);
++	if (status < 0)
++		goto err2;
++	return 0;
++
++err2:
++	bus_unregister(&spi_bus_type);
++err1:
++	kfree(buf);
++	buf = NULL;
++err0:
++	return status;
++}
++
++/* board_info is normally registered in arch_initcall(),
++ * but even essential drivers wait till later
++ *
++ * REVISIT only boardinfo really needs static linking. the rest (device and
++ * driver registration) _could_ be dynamically linked (modular) ... costs
++ * include needing to have boardinfo data structures be much more public.
++ */
++postcore_initcall(spi_init);
++
+diff -rupN linux-2.6.35.11/drivers/spi/spi_str8100.c linux-2.6.35.11-ts7500/drivers/spi/spi_str8100.c
+--- linux-2.6.35.11/drivers/spi/spi_str8100.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/spi/spi_str8100.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,452 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/init.h>
++#include <linux/spinlock.h>
++#include <linux/workqueue.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/err.h>
++#include <linux/clk.h>
++#include <linux/platform_device.h>
++
++#include <linux/spi/spi.h>
++#include <linux/spi/spi_bitbang.h>
++#include <linux/mtd/partitions.h>
++
++#include <asm/io.h>
++#include <asm/dma.h>
++#include <asm/hardware.h>
++#include <asm/arch/star_intc.h>
++#include <asm/arch/star_spi.h>
++#include <asm/arch/star_misc.h>
++#include <asm/arch/star_powermgt.h>
++
++//#define STR8100_SPI_DEBUG
++
++struct str8100_spi {
++	/* bitbang has to be first */
++	struct spi_bitbang	 bitbang;
++	struct completion	 done;
++
++	int			 len;
++	int			 count;
++
++	/* data buffers */
++	const unsigned char	*tx;
++	unsigned char		*rx;
++
++	struct spi_master	*master;
++	struct device		*dev;
++	struct spi_device	*spi_dev[4];
++
++	int			board_count;
++	struct spi_board_info	board_info[4];
++};
++
++extern u32 APB_clock;
++
++static inline u8 str8100_spi_bus_idle(void)
++{
++	return ((SPI_SERVICE_STATUS_REG & 0x1) ? 0 : 1);
++}
++
++static inline u8 str8100_spi_tx_buffer_empty(void)
++{
++	return ((SPI_INTERRUPT_STATUS_REG & (0x1 << 3)) ? 1 : 0);
++}
++
++static inline u8 str8100_spi_rx_buffer_full(void)
++{
++	return ((SPI_INTERRUPT_STATUS_REG & (0x1 << 2)) ? 1 : 0);
++}
++
++static u8 str8100_spi_tx_rx(u8 tx_channel, u8 tx_eof_flag, u32 tx_data, u32 *rx_data)
++{
++	u8 rx_channel;
++	u8 rx_eof_flag;
++
++	while (!str8100_spi_bus_idle())
++		; // do nothing
++
++	while (!str8100_spi_tx_buffer_empty())
++		; // do nothing
++
++	SPI_TRANSMIT_CONTROL_REG &= ~(0x7);
++	SPI_TRANSMIT_CONTROL_REG |= (tx_channel & 0x3) | ((tx_eof_flag & 0x1) << 2);
++
++	SPI_TRANSMIT_BUFFER_REG = tx_data;
++
++	while (!str8100_spi_rx_buffer_full())
++		; // do nothing
++
++	rx_channel = (SPI_RECEIVE_CONTROL_REG & 0x3);
++
++	rx_eof_flag = (SPI_RECEIVE_CONTROL_REG & (0x1 << 2)) ? 1 : 0;
++
++	*rx_data = SPI_RECEIVE_BUFFER_REG;
++
++	if ((tx_channel != rx_channel) || (tx_eof_flag != rx_eof_flag)) {
++		return 0;
++	} else {
++		return 1;
++	}
++}
++
++static inline struct str8100_spi *to_hw(struct spi_device *sdev)
++{
++	return spi_master_get_devdata(sdev->master);
++}
++
++static void str8100_spi_chipselect(struct spi_device *spi, int value)
++{
++	unsigned int spi_config;
++	int i;
++
++	switch (value) {
++	case BITBANG_CS_INACTIVE:
++		break;
++
++	case BITBANG_CS_ACTIVE:
++		spi_config = SPI_CONFIGURATION_REG;
++		if (spi->mode & SPI_CPHA)
++			spi_config |= (0x1 << 13);
++		else
++			spi_config &= ~(0x1 << 13);
++
++		if (spi->mode & SPI_CPOL)
++			spi_config |= (0x1 << 14);
++		else
++			spi_config &= ~(0x1 << 14);
++
++		/* write new configration */
++		SPI_CONFIGURATION_REG = spi_config;
++
++		SPI_TRANSMIT_CONTROL_REG &= ~(0x7);
++		SPI_TRANSMIT_CONTROL_REG |= (spi->chip_select & 0x3);
++
++		for (i = 0; i < 8; i++) {
++			if (spi->max_speed_hz > (APB_clock >> i))
++				break;
++		}
++#ifdef STR8100_SPI_DEBUG
++		printk("[STR8100_SPI_DEBUG] APB_clock:%u\n", APB_clock);
++		printk("[STR8100_SPI_DEBUG] spi->max_speed_hz:%u\n", spi->max_speed_hz);
++		printk("[STR8100_SPI_DEBUG] SPI bit rate control val:%d\n", i);
++#endif
++		SPI_BIT_RATE_CONTROL_REG = i;
++
++		break;
++	}
++}
++
++static int str8100_spi_setup(struct spi_device *spi)
++{
++	if (!spi->bits_per_word)
++		spi->bits_per_word = 8;
++
++	return 0;
++}
++
++static int str8100_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
++{
++	struct str8100_spi *hw = to_hw(spi);
++	int error = 0;
++
++	hw->tx = t->tx_buf;
++	hw->rx = t->rx_buf;
++	hw->len = t->len;
++	hw->count = 0;
++
++#ifdef STR8100_SPI_DEBUG
++	printk("[STR8100_SPI_DEBUG] txrx: tx %p, rx %p, len %d\n", t->tx_buf, t->rx_buf, t->len);
++	if (hw->tx) {
++		int i;
++		for (i = 0; i < t->len; i++) {
++			printk("[STR8100_SPI_DEBUG] t->tx_buf[%02d]: 0x%02x\n", i, hw->tx[i]);
++		}
++	}
++#endif
++	if (hw->tx) {
++		int i;
++		u32 rx_data;
++		for (i = 0; i < (hw->len - 1); i++) {
++			str8100_spi_tx_rx(spi->chip_select, 0, hw->tx[i], &rx_data);
++			if (hw->rx) {
++				hw->rx[i] = rx_data;
++#ifdef STR8100_SPI_DEBUG
++				printk("[STR8100_SPI_DEBUG] hw->rx[%02d]:0x%02x\n", i, hw->rx[i]);
++#endif
++			}
++		}
++		if (t->last_in_message_list) {
++			str8100_spi_tx_rx(spi->chip_select, 1, hw->tx[i], &rx_data);
++			if (hw->rx) {
++				hw->rx[i] = rx_data;
++#ifdef STR8100_SPI_DEBUG
++				printk("[STR8100_SPI_DEBUG] hw->rx[%02d]:0x%02x\n", i, hw->rx[i]);
++#endif
++			}
++		} else {
++			str8100_spi_tx_rx(spi->chip_select, 0, hw->tx[i], &rx_data);
++		}
++		goto done;
++	}
++
++	if (hw->rx) {
++		int i;
++		u32 rx_data;
++		for (i = 0; i < (hw->len - 1); i++) {
++			str8100_spi_tx_rx(spi->chip_select, 0, 0xff, &rx_data);
++			hw->rx[i] = rx_data;
++#ifdef STR8100_SPI_DEBUG
++			printk("[STR8100_SPI_DEBUG] hw->rx[%02d]:0x%02x\n", i, hw->rx[i]);
++#endif
++		}
++		if (t->last_in_message_list) {
++			str8100_spi_tx_rx(spi->chip_select, 1, 0xff, &rx_data);
++			hw->rx[i] = rx_data;
++#ifdef STR8100_SPI_DEBUG
++			printk("[STR8100_SPI_DEBUG] hw->rx[%02d]:0x%02x\n", i, hw->rx[i]);
++#endif
++		} else {
++			str8100_spi_tx_rx(spi->chip_select, 0, 0xff, &rx_data);
++			hw->rx[i] = rx_data;
++#ifdef STR8100_SPI_DEBUG
++			printk("[STR8100_SPI_DEBUG] hw->rx[%02d]:0x%02x\n", i, hw->rx[i]);
++#endif
++		}
++	}
++
++done:
++	return t->len;
++}
++
++static int __init str8100_spi_probe(struct platform_device *pdev)
++{
++	struct str8100_spi *hw;
++	struct spi_master *master;
++	unsigned int receive_data;
++	int err = 0;
++
++	master = spi_alloc_master(&pdev->dev, sizeof(struct str8100_spi));
++	if (master == NULL) {
++		dev_err(&pdev->dev, "No memory for spi_master\n");
++		err = -ENOMEM;
++		goto err_nomem;
++	}
++
++	master->bus_num = 1;
++	master->num_chipselect = 4;
++
++	hw = spi_master_get_devdata(master);
++	memset(hw, 0, sizeof(struct str8100_spi));
++
++	hw->master = spi_master_get(master);
++
++	hw->dev = &pdev->dev;
++
++	platform_set_drvdata(pdev, hw);
++	init_completion(&hw->done);
++
++	/* scott.patch.spi */
++	// Clear spurious interrupt sources
++	SPI_INTERRUPT_STATUS_REG = (0xF << 4);
++
++	// Disable SPI interrupt
++	SPI_INTERRUPT_ENABLE_REG = 0;
++
++	// Enable SPI
++	SPI_CONFIGURATION_REG |= (0x1 << 31);
++
++	/* setup the state for the bitbang driver */
++
++	hw->bitbang.master         = hw->master;
++	hw->bitbang.chipselect     = str8100_spi_chipselect;
++	hw->bitbang.txrx_bufs      = str8100_spi_txrx;
++	hw->bitbang.master->setup  = str8100_spi_setup;
++
++	dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
++
++	/* register our spi controller */
++
++	err = spi_bitbang_start(&hw->bitbang);
++	if (err) {
++		dev_err(&pdev->dev, "Failed to register SPI master\n");
++		goto err_register;
++	}
++
++#ifdef STR8100_SPI_DEBUG
++{
++	int i;
++	u32 rx_data1, rx_data2, rx_data3;
++
++	str8100_spi_tx_rx(0, 0, 0x9f, &rx_data1);
++	str8100_spi_tx_rx(0, 0, 0xff, &rx_data1);
++	str8100_spi_tx_rx(0, 0, 0xff, &rx_data2);
++	str8100_spi_tx_rx(0, 1, 0xff, &rx_data3);
++	printk("[STR8100_SPI_DEBUG] manufacturer: %x\n", rx_data1);
++	printk("[STR8100_SPI_DEBUG] device:       %x\n", ((rx_data2 & 0xff) << 8) | (u16) (rx_data3 & 0xff));
++
++	str8100_spi_tx_rx(0, 0, 0x03, &rx_data1);
++	str8100_spi_tx_rx(0, 0, 0x00, &rx_data1);
++	str8100_spi_tx_rx(0, 0, 0x00, &rx_data1);
++	str8100_spi_tx_rx(0, 0, 0x00, &rx_data1);
++	for (i = 0; i < 15; i++) {
++		str8100_spi_tx_rx(0, 0, 0xff, &rx_data1);
++		printk("[STR8100_SPI_DEBUG] flash[%02d]:0x%02x\n", i, rx_data1 & 0xff);
++	}
++	str8100_spi_tx_rx(0, 1, 0xff, &rx_data1);
++	printk("[STR8100_SPI_DEBUG] flash[%02d]:0x%02x\n", i, rx_data1 & 0xff);
++}
++#endif
++
++	return 0;
++
++err_register:
++	spi_master_put(hw->master);;
++
++err_nomem:
++	return err;
++}
++
++static int str8100_spi_remove(struct platform_device *dev)
++{
++	struct str8100_spi *hw = platform_get_drvdata(dev);
++
++	platform_set_drvdata(dev, NULL);
++
++	spi_unregister_master(hw->master);
++
++	//str8100_spi_clk_disable();
++
++	spi_master_put(hw->master);
++
++	return 0;
++}
++
++
++#ifdef CONFIG_PM
++
++static int str8100_spi_suspend(struct platform_device *pdev, pm_message_t msg)
++{
++	struct str8100_spi *hw = platform_get_drvdata(pdev);
++
++	//str8100_spi_clk_disable();
++	return 0;
++}
++
++static int str8100_spi_resume(struct platform_device *pdev)
++{
++	struct str8100_spi *hw = platform_get_drvdata(pdev);
++
++	//str8100_spi_clk_enable()
++	return 0;
++}
++
++#else
++#define str8100_spi_suspend	NULL
++#define str8100_spi_resume	NULL
++#endif
++
++static void __init str8100_spi_hw_init(void)
++{
++	u32 receive_data;
++
++	// Enable SPI pins
++	HAL_MISC_ENABLE_SPI_PINS();
++
++	// Enable SPI clock
++	HAL_PWRMGT_ENABLE_SPI_CLOCK();
++
++	// Disable SPI serial flash access through 0x30000000 region
++	HAL_MISC_DISABLE_SPI_SERIAL_FLASH_BANK_ACCESS();
++
++	/*
++	 * Note SPI is NOT enabled after this function is invoked!!
++	 */
++	SPI_CONFIGURATION_REG =
++		(((0x0 & 0x3) << 0) | /* 8bits shift length */
++		 (0x0 << 9) | /* general SPI mode */
++		 (0x0 << 10) | /* disable FIFO */
++		 (0x1 << 11) | /* SPI master mode */
++		 (0x0 << 12) | /* disable SPI loopback mode */
++		 (0x0 << 13) | /* clock phase */
++		 (0x0 << 14) | /* clock polarity */
++		 (0x0 << 24) | /* disable SPI Data Swap */
++		 (0x0 << 30) | /* disable SPI High Speed Read for BootUp */
++		 (0x0 << 31)); /* disable SPI */
++
++	SPI_BIT_RATE_CONTROL_REG = 0x1; // PCLK/2
++
++	// Configure SPI's Tx channel
++	SPI_TRANSMIT_CONTROL_REG = 0;
++
++	// Configure Tx FIFO Threshold
++	SPI_FIFO_TRANSMIT_CONFIG_REG &= ~(0x03 << 4);
++	SPI_FIFO_TRANSMIT_CONFIG_REG |= ((0x0 & 0x03) << 4);
++
++	// Configure Rx FIFO Threshold
++	SPI_FIFO_RECEIVE_CONFIG_REG &= ~(0x03 << 4);
++	SPI_FIFO_RECEIVE_CONFIG_REG |= ((0x0 & 0x03) << 4);
++
++	SPI_INTERRUPT_ENABLE_REG = 0;
++
++	// Clear spurious interrupt sources
++	SPI_INTERRUPT_STATUS_REG = (0xF << 4);
++
++	receive_data = SPI_RECEIVE_BUFFER_REG;
++
++	return;
++}
++
++static struct platform_driver str8100_spidrv = {
++	.remove		= __devexit_p(str8100_spi_remove),
++	.suspend	= str8100_spi_suspend,
++	.resume		= str8100_spi_resume,
++	.driver		= {
++		.name	= "str8100_spi",
++		.owner	= THIS_MODULE,
++	},
++};
++
++static int __init str8100_spi_init(void)
++{
++	printk("STR8100 SPI: init\n");
++	str8100_spi_hw_init();
++
++	return platform_driver_probe(&str8100_spidrv, str8100_spi_probe);
++}
++
++static void __exit str8100_spi_exit(void)
++{
++	platform_driver_unregister(&str8100_spidrv);
++}
++
++module_init(str8100_spi_init);
++module_exit(str8100_spi_exit);
++
++MODULE_DESCRIPTION("STR8100 SPI Driver");
++MODULE_AUTHOR("STAR Semi Corp.");
++MODULE_LICENSE("GPL");
+diff -rupN linux-2.6.35.11/drivers/star/Makefile linux-2.6.35.11-ts7500/drivers/star/Makefile
+--- linux-2.6.35.11/drivers/star/Makefile	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,30 @@
++################################################################################
++#
++# 
++# Copyright(c) 2005 -  Star semiconduction. All rights reserved.
++# 
++# This program is free software; you can redistribute it and/or modify it 
++# under the terms of the GNU General Public License as published by the Free 
++# Software Foundation; either version 2 of the License, or (at your option) 
++# any later version.
++# 
++# This program is distributed in the hope that it will be useful, but WITHOUT 
++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
++# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
++# more details.
++# 
++# You should have received a copy of the GNU General Public License along with
++# this program; if not, write to the Free Software Foundation, Inc., 59 
++# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++# 
++# The full GNU General Public License is included in this distribution in the
++# file called LICENSE.
++# 
++# Contact Information:
++# Star semiconduction Linux Support <support@starsemi.com>
++#
++################################################################################
++
++obj-$(CONFIG_ARCH_STR9100) += str9100/
++obj-$(CONFIG_ARCH_STR8100) += str8100/
++
+diff -rupN linux-2.6.35.11/drivers/star/str8100/crash.c linux-2.6.35.11-ts7500/drivers/star/str8100/crash.c
+--- linux-2.6.35.11/drivers/star/str8100/crash.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str8100/crash.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,85 @@
++/*======================================================================
++
++   Copyright (C) 2006 STAR Semiconductor Limited
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 2 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++
++======================================================================*/
++ 
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/smp_lock.h>
++
++#include <asm/arch/star_gpio.h>
++#include <asm/arch/star_intc.h>
++#include <asm/arch/star_misc.h>
++#include <asm/arch/star_powermgt.h>
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++static int mode=0;
++module_param(mode, int, 0);
++MODULE_PARM_DESC(mode, "");
++static irqreturn_t str8100_ext_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	void (*fnptr)(void)=NULL;
++	printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++
++	if(mode==1) while(1);
++	else fnptr();
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++static int __init str8100_inthandler_init(void)
++{
++	int ret;
++printk("%s: \n",__FUNCTION__);
++	if(mode==0) panic("%s: panic for testing...\n",__FUNCTION__);
++
++#define register_ext_int(_i){\
++			printk("%s: registering int handler for external int%d\n",__FUNCTION__,_i);\
++			HAL_MISC_ENABLE_EXT_INT##_i##_PINS();\
++			str8100_set_interrupt_trigger (INTC_EXT_INT##_i##_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_LOW);\
++			if ((ret=request_irq(INTC_EXT_INT##_i##_BIT_INDEX, str8100_ext_irq_handler, 0, "testing", NULL))){\
++				printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_EXT_INT##_i##_BIT_INDEX,ret,-EBUSY);\
++				return -EBUSY;\
++			}\
++		}
++	register_ext_int(29);
++	register_ext_int(30);
++	return 0;
++}
++
++static void __exit str8100_inthandler_exit(void) 
++{ 
++//#ifdef DEBUG
++		printk("%s: \n",__FUNCTION__);
++//#endif
++    lock_kernel();
++    free_irq(INTC_EXT_INT29_BIT_INDEX, NULL);
++    free_irq(INTC_EXT_INT30_BIT_INDEX, NULL);
++    unlock_kernel();
++}
++
++module_init(str8100_inthandler_init);
++module_exit(str8100_inthandler_exit);
++
+diff -rupN linux-2.6.35.11/drivers/star/str8100/int28handler.c linux-2.6.35.11-ts7500/drivers/star/str8100/int28handler.c
+--- linux-2.6.35.11/drivers/star/str8100/int28handler.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str8100/int28handler.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,80 @@
++/*======================================================================
++
++   Copyright (C) 2006 STAR Semiconductor Limited
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 2 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++
++======================================================================*/
++ 
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++
++#include <asm/arch/star_gpio.h>
++#include <asm/arch/star_intc.h>
++#include <asm/arch/star_misc.h>
++#include <asm/arch/star_powermgt.h>
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++static struct work_struct reboot_work;
++void do_reboot(){
++	char* argv[2];
++	char* env[1];
++	argv[0]="/sbin/reboot";
++	argv[1]=NULL;
++	env[0]=NULL;
++	call_usermodehelper(argv[0],argv,env,0);
++
++}
++static irqreturn_t str8100_int28vbus_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++printk("%s: registering work\n",__FUNCTION__);
++	INIT_WORK(&reboot_work,do_reboot,NULL);
++	if(PWRMGT_USB_DEVICE_POWERMGT_REG&0x1)
++		schedule_work(&reboot_work);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	return IRQ_HANDLED;
++}
++
++static int __init str8100_int28vbus_inthandler_init(void)
++{
++	int ret;
++printk("%s: \n",__FUNCTION__);
++	if(PWRMGT_USB_DEVICE_POWERMGT_REG&0x1)
++		HAL_PWRMGT_GLOBAL_SOFTWARE_RESET();
++	//	schedule_work(&reboot_work);
++
++	//str8100_set_interrupt_trigger (INTC_GPIO_EXTERNAL_INT_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_USB_DEVICE_VBUS_BIT_INDEX, str8100_int28vbus_irq_handler, 0, "vbus", NULL))){
++		printk("%s: request_irq failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,ret,-EBUSY);
++		return -EBUSY;
++	}
++	return 0;
++}
++
++static void __exit str8100_int28vbus_inthandler_exit(void) 
++{ 
++	printk("%s: \n",__FUNCTION__);
++	lock_kernel();
++	free_irq(INTC_USB_DEVICE_VBUS_BIT_INDEX, NULL);
++	unlock_kernel();
++}
++
++module_init(str8100_int28vbus_inthandler_init);
++module_exit(str8100_int28vbus_inthandler_exit);
++
+diff -rupN linux-2.6.35.11/drivers/star/str8100/inthandler.c linux-2.6.35.11-ts7500/drivers/star/str8100/inthandler.c
+--- linux-2.6.35.11/drivers/star/str8100/inthandler.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str8100/inthandler.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,178 @@
++/*======================================================================
++
++   Copyright (C) 2006 STAR Semiconductor Limited
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 2 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++
++======================================================================*/
++ 
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/smp_lock.h>
++
++#include <asm/arch/star_gpio.h>
++#include <asm/arch/star_intc.h>
++#include <asm/arch/star_misc.h>
++#include <asm/arch/star_powermgt.h>
++
++static int gpio=0;
++module_param(gpio, int, 0);
++MODULE_PARM_DESC(gpio, "GPIO int switch(0: disable, 1:enable default=0)");
++
++static int ext29=0;
++module_param(ext29, int, 0);
++MODULE_PARM_DESC(ext29, "Ext int 29 switch(0: disable, 1:enable default=0)");
++
++static int ext30=0;
++module_param(ext30, int, 0);
++MODULE_PARM_DESC(ext30, "Ext int 30 switch(0: disable, 1:enable default=0)");
++
++static int debug=1;
++module_param(debug, int, 0);
++MODULE_PARM_DESC(debug, "debug mode (1=on, 0=off, default=1");
++
++static irqreturn_t (*gpioA_irq_handler)(int, void*, struct pt_regs*)=NULL;
++static irqreturn_t (*gpioB_irq_handler)(int, void*, struct pt_regs*)=NULL;
++static irqreturn_t (*ext_irq_handler)(int, void*, struct pt_regs*)=NULL;
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int);
++
++static irqreturn_t str8100_ext_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	if(debug) printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
++	if(ext_irq_handler){
++		ext_irq_handler(this_irq,dev_id,regs);
++	}
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);
++
++    return IRQ_HANDLED;
++}
++
++static irqreturn_t str8100_gpio_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	unsigned int volatile    statusA,statusB;
++	int i;
++
++	if(debug) printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++
++	HAL_GPIOA_READ_INTERRUPT_MASKED_STATUS(statusA);
++	HAL_GPIOB_READ_INTERRUPT_MASKED_STATUS(statusB);
++//printk("%s: %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x \n",__FUNCTION__,GPIOA_DATA_OUTPUT_REG,GPIOA_DATA_INPUT_REG,GPIOA_DIRECTION_REG,GPIOA_INTERRUPT_ENABLE_REG,GPIOA_INTERRUPT_RAW_STATUS_REG,GPIOA_INTERRUPT_MASKED_STATUS_REG,GPIOA_INTERRUPT_MASKED_STATUS_REG,GPIOA_INTERRUPT_MASK_REG,GPIOA_INTERRUPT_TRIGGER_METHOD_REG,GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG,GPIOA_INTERRUPT_TRIGGER_TYPE_REG,GPIOA_BOUNCE_ENABLE_REG,GPIOA_BOUNCE_CLOCK_PRESCALE_REG);
++	for (i = 0; i < 32; i++)
++	{
++		if (statusA & (1 << i)){
++       			if(debug) printk("%s: GPIOA Int %d\n",__FUNCTION__,i);
++       			if(gpioA_irq_handler){
++       				gpioA_irq_handler(i,dev_id,regs);
++       			}
++		}	 
++		if (statusB & (1 << i)){
++       			if(debug) printk("%s: GPIOB Int %d\n",__FUNCTION__,i);
++       			if(gpioB_irq_handler){
++       				gpioB_irq_handler(i,dev_id,regs);
++       			}
++		}	 
++	}
++	HAL_GPIOA_CLEAR_INTERRUPT(statusA);
++	HAL_GPIOB_CLEAR_INTERRUPT(statusB);
++
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++
++    return IRQ_HANDLED;
++}
++
++static int __init str8100_inthandler_init(void)
++{
++	int ret;
++if(debug) printk("%s: \n",__FUNCTION__);
++
++#if 0
++    /*
++     * Configure system Xtal clock to be output to CLKOUT pin
++     */
++    HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(0, 0);
++#endif
++
++//	HAL_MISC_ENABLE_ALL_SHARED_GPIO_PINS();	
++	if(gpio){
++		if(debug) printk("%s: registering int handler for gpio int\n",__FUNCTION__);\
++//gpio initialization depend on application
++#if 0
++		HAL_MISC_DISABLE_EXT_INT29_PINS();
++		HAL_MISC_DISABLE_EXT_INT30_PINS();
++
++		HAL_PWRMGT_ENABLE_GPIO_CLOCK();
++
++		PWRMGT_SOFTWARE_RESET_CONTROL_REG |=  (0x1 << PWRMGT_GPIO_SOFTWARE_RESET_BIT_INDEX);
++		PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << PWRMGT_GPIO_SOFTWARE_RESET_BIT_INDEX);
++		PWRMGT_SOFTWARE_RESET_CONTROL_REG |=  (0x1 << PWRMGT_GPIO_SOFTWARE_RESET_BIT_INDEX);	
++
++		HAL_GPIOA_SET_DIRECTION_INPUT(3);
++		HAL_GPIOA_ENABLE_INTERRUPT(3);
++		HAL_GPIOA_DISABLE_INTERRUPT_MASK(3);
++		HAL_GPIOA_SET_INTERRUPT_EDGE_TRIGGER_MODE(3);
++#endif
++
++		str8100_set_interrupt_trigger (INTC_GPIO_EXTERNAL_INT_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++		if ((ret=request_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, str8100_gpio_irq_handler, 0, "testing", NULL))){
++			if(debug) printk("%s: request_irq failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,ret,-EBUSY);
++			return -EBUSY;
++		}
++	}
++#define register_ext_int(_i){\
++			if(debug) printk("%s: registering int handler for external int%d\n",__FUNCTION__,_i);\
++			HAL_MISC_ENABLE_EXT_INT##_i##_PINS();\
++			str8100_set_interrupt_trigger (INTC_EXT_INT##_i##_BIT_INDEX,INTC_LEVEL_TRIGGER,INTC_ACTIVE_LOW);\
++			if ((ret=request_irq(INTC_EXT_INT##_i##_BIT_INDEX, str8100_ext_irq_handler, 0, "testing", NULL))){\
++				if(debug) printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,INTC_EXT_INT##_i##_BIT_INDEX,ret,-EBUSY);\
++				return -EBUSY;\
++			}\
++		}
++	if(ext29) register_ext_int(29);
++	if(ext30) register_ext_int(30);
++
++/*	HAL_MISC_ENABLE_EXT_INT30_PINS();
++	str8100_set_interrupt_trigger (INTC_EXT_INT30_BIT_INDEX,INTC_IRQ_INTERRUPT,INTC_LEVEL_TRIGGER,INTC_ACTIVE_LOW);
++	if ((ret=request_irq(INTC_EXT_INT30_BIT_INDEX, str8100_pm_irq_handler, 0, "testing", NULL))){
++		printk("%s: request_irq failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,ret,-EBUSY);
++		return -EBUSY;
++	}
++*/
++	return 0;
++}
++
++static void __exit str8100_inthandler_exit(void) 
++{ 
++//#ifdef DEBUG
++		if(debug) printk("%s: \n",__FUNCTION__);
++//#endif
++    lock_kernel();
++    if(gpio) free_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, NULL);
++    if(ext29) free_irq(INTC_EXT_INT29_BIT_INDEX, NULL);
++    if(ext30) free_irq(INTC_EXT_INT30_BIT_INDEX, NULL);
++    unlock_kernel();
++}
++
++module_init(str8100_inthandler_init);
++module_exit(str8100_inthandler_exit);
++
+diff -rupN linux-2.6.35.11/drivers/star/str8100/Makefile linux-2.6.35.11-ts7500/drivers/star/str8100/Makefile
+--- linux-2.6.35.11/drivers/star/str8100/Makefile	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str8100/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,33 @@
++################################################################################
++#
++# 
++# Copyright(c) 2005 -  Star semiconduction. All rights reserved.
++# 
++# This program is free software; you can redistribute it and/or modify it 
++# under the terms of the GNU General Public License as published by the Free 
++# Software Foundation; either version 2 of the License, or (at your option) 
++# any later version.
++# 
++# This program is distributed in the hope that it will be useful, but WITHOUT 
++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
++# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
++# more details.
++# 
++# You should have received a copy of the GNU General Public License along with
++# this program; if not, write to the Free Software Foundation, Inc., 59 
++# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++# 
++# The full GNU General Public License is included in this distribution in the
++# file called LICENSE.
++# 
++# Contact Information:
++# Star semiconduction Linux Support <support@starsemi.com>
++#
++################################################################################
++
++#obj-y += str8100_tool.o
++#obj-$(CONFIG_STR8100_INFO) += str8100_info.o
++
++obj-$(CONFIG_STR8100_USBD_REBOOT_INTHANDLER) += int28handler.o
++obj-m += inthandler.o
++obj-m += crash.o
+diff -rupN linux-2.6.35.11/drivers/star/str8100/str8100_gpio_test.c linux-2.6.35.11-ts7500/drivers/star/str8100/str8100_gpio_test.c
+--- linux-2.6.35.11/drivers/star/str8100/str8100_gpio_test.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str8100/str8100_gpio_test.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,140 @@
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/mm.h>
++#include <linux/miscdevice.h>
++#include <linux/watchdog.h>
++#include <linux/reboot.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/smp_lock.h>
++#include <linux/delay.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/arch/star_powermgt.h>
++#include <asm/arch/star_intc.h>
++#include <asm/arch/star_misc.h>
++#include <asm/arch/star_gpio.h>
++
++MODULE_LICENSE("Dual BSD/GPL");
++
++extern void str8100_led_all_on(void);
++extern void str8100_led_all_off(void);
++extern void str8100_led_on(unsigned int led_index);
++extern void str8100_led_off(unsigned int led_index);
++extern void str8100_led_toggle(unsigned int led_index);
++extern void str8100_led_init(void);
++
++extern void str8100_set_interrupt_trigger(unsigned int, unsigned int, unsigned int, unsigned int);
++
++static irqreturn_t str8100_gpio_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++{
++	unsigned int volatile    status;
++	int i;
++
++	printk("%s: \n",__FUNCTION__);
++
++	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	HAL_GPIOA_READ_INTERRUPT_MASKED_STATUS(status);
++
++//printk("%s: %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x \n", \
++//	__FUNCTION__, \
++//	GPIOA_DATA_OUTPUT_REG, \
++//	GPIOA_DATA_INPUT_REG, \
++//	GPIOA_DIRECTION_REG, \
++//	GPIOA_INTERRUPT_ENABLE_REG, \
++//	GPIOA_INTERRUPT_RAW_STATUS_REG, \
++//	GPIOA_INTERRUPT_MASKED_STATUS_REG, \
++//	GPIOA_INTERRUPT_MASKED_STATUS_REG, \
++//	GPIOA_INTERRUPT_MASK_REG, \
++//	GPIOA_INTERRUPT_TRIGGER_METHOD_REG, \
++//	GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG, \
++//	GPIOA_INTERRUPT_TRIGGER_TYPE_REG, \
++//	GPIOA_BOUNCE_ENABLE_REG, \
++//	GPIOA_BOUNCE_CLOCK_PRESCALE_REG);
++
++	for (i = 0; i < 32; i++) {
++		if (status & (1 << i)) {
++			printk(" str8100 gpio: Interrupt Happen (status: 0x%x, GPIO %.2d)\n",status,i);
++			//GPIOA[0] will toggle GPIOB[2]
++			//GPIOA[1] will toggle GPIOB[3]
++			str8100_led_toggle(1<<(i+2));
++		}	 
++	}
++
++	HAL_GPIOA_CLEAR_INTERRUPT(status);
++	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
++
++	return IRQ_HANDLED;
++}
++
++static int __init test_init(void){
++	int ret;
++//	__u32 data,cnt=0;
++
++	printk("%s: Output led test...\n",__FUNCTION__);
++
++	
++	HAL_MISC_ENABLE_ALL_SHARED_GPIO_PINS();	
++	HAL_PWRMGT_ENABLE_GPIO_CLOCK();
++
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |=  (0x1 << PWRMGT_GPIO_SOFTWARE_RESET_BIT_INDEX);
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1 << PWRMGT_GPIO_SOFTWARE_RESET_BIT_INDEX);
++	PWRMGT_SOFTWARE_RESET_CONTROL_REG |=  (0x1 << PWRMGT_GPIO_SOFTWARE_RESET_BIT_INDEX);	
++
++	str8100_led_init();
++
++/*
++	printk("%s: Input button test...\n",__FUNCTION__);
++	HAL_GPIOA_SET_DIRECTION_INPUT(3);
++	while(cnt<20){
++		HAL_GPIOA_READ_DATA_IN_STATUS(data);
++		printk("%d-%s: read data=0x%x\n",cnt,__FUNCTION__,data);
++		msleep(500);
++		cnt++;
++	}
++*/
++
++	printk("%s: IRQ test...\n",__FUNCTION__);
++	//Configure GPIOA[0:1] as interrupts
++	HAL_GPIOA_SET_DIRECTION_INPUT(3);
++	HAL_GPIOA_ENABLE_INTERRUPT(3);
++	HAL_GPIOA_DISABLE_INTERRUPT_MASK(3);
++
++	//GPIOA[0] will toggle GPIOB[2] (in interrupt handler)
++	//set GPIOA[0] to level trigger
++	//==> GPIOB[2] will keep blinking while button pressed
++	HAL_GPIOA_SET_INTERRUPT_LEVEL_TRIGGER_MODE(1);
++	HAL_GPIOA_SET_INTERRUPT_LOW_LEVEL_TRIGGER_MODE(1);
++//	HAL_GPIOA_SET_INTERRUPT_SINGLE_EDGE_TRIGGER_MODE(1);
++//	HAL_GPIOA_SET_INTERRUPT_SINGLE_FALLING_EDGE_TRIGGER_MODE(1);
++//	HAL_GPIOA_SET_INTERRUPT_SINGLE_RISING_EDGE_TRIGGER_MODE(1);
++
++	//GPIOA[1] will toggle GPIOB[3] (in interrupt handler)
++	//set GPIOA[1] to edge trigger
++	//==> GPIOB[3] will turn on while pressed
++	HAL_GPIOA_SET_INTERRUPT_EDGE_TRIGGER_MODE(2);
++	HAL_GPIOA_SET_INTERRUPT_BOTH_EDGE_TRIGGER_MODE(2);
++
++	str8100_set_interrupt_trigger (INTC_GPIO_EXTERNAL_INT_BIT_INDEX,INTC_IRQ_INTERRUPT,INTC_LEVEL_TRIGGER,INTC_ACTIVE_HIGH);
++	if ((ret=request_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX, str8100_gpio_irq_handler, 0, "testing", NULL))){
++		printk("%s: request_irq failed(ret=0x%x)(-EBUSY=0x%x)\n",__FUNCTION__,ret,-EBUSY);
++		return -EBUSY;
++	}
++
++	return 0;
++}
++
++static void __exit test_exit(void){
++	printk("%s: \n",__FUNCTION__);
++	free_irq(INTC_GPIO_EXTERNAL_INT_BIT_INDEX,NULL);
++}
++
++module_init(test_init);
++module_exit(test_exit);
++
+diff -rupN linux-2.6.35.11/drivers/star/str8100/str8100_led.c linux-2.6.35.11-ts7500/drivers/star/str8100/str8100_led.c
+--- linux-2.6.35.11/drivers/star/str8100/str8100_led.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str8100/str8100_led.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,158 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <asm/arch/star_gpio.h>
++
++#define LED_MASK_A 			0xfe3fe07f
++#define LED_MASK_B 			0xffe0dfff
++
++#if 0
++#define LED_MASK 					LED_MASK_A
++#define GPIO_DIRECTION_REG			GPIOA_DIRECTION_REG
++#define GPIO_DATA_OUTPUT_REG 		GPIOA_DATA_OUTPUT_REG
++#define GPIO_DATA_BIT_SET_REG 		GPIOA_DATA_BIT_SET_REG
++#define GPIO_DATA_BIT_CLEAR_REG 	GPIOA_DATA_BIT_CLEAR_REG
++#else
++#define LED_MASK 					LED_MASK_B
++#define GPIO_DIRECTION_REG			GPIOB_DIRECTION_REG
++#define GPIO_DATA_OUTPUT_REG 		GPIOB_DATA_OUTPUT_REG
++#define GPIO_DATA_BIT_SET_REG 		GPIOB_DATA_BIT_SET_REG
++#define GPIO_DATA_BIT_CLEAR_REG 	GPIOB_DATA_BIT_CLEAR_REG
++#endif
++
++
++#define LED_DELAY_MS		50
++
++/*
++ * Configure all LEDs on
++ */
++void str8100_led_all_on(void)
++{
++    /*
++     * perform Write Low to GPIO Pin
++     */    
++    GPIO_DATA_BIT_CLEAR_REG |= LED_MASK;
++}
++
++
++
++/*
++ * Configure all LEDs off
++ */
++void str8100_led_all_off(void)
++{
++    /*
++     * perform Write High to GPIO Pin
++     */
++    GPIO_DATA_BIT_SET_REG |= LED_MASK;
++}
++
++
++/*
++ * Configure one LED on
++ */
++void str8100_led_on(unsigned int led_index)
++{
++    /*
++     * perform Write Low to GPIO Pin
++     */
++    GPIO_DATA_BIT_CLEAR_REG |= (led_index & LED_MASK);
++}
++
++
++/*
++ * Configure one LED off
++ */
++void str8100_led_off(unsigned int led_index)
++{
++    /*
++     * perform Write High to GPIO Pin
++     */
++    GPIO_DATA_BIT_SET_REG |= (led_index & LED_MASK);
++}
++
++
++
++/*
++ * Toggle one LED on/off
++ */
++void str8100_led_toggle(unsigned int led_index)
++{     
++    volatile unsigned int    data_out_state;
++
++
++    /*
++     * 1. read GPIO Data Out State
++     * 2. if GPIO High, turn LED on, otherwise, turn LED off
++     */
++    data_out_state = GPIO_DATA_OUTPUT_REG;
++    
++    if (data_out_state & led_index& LED_MASK)
++    {
++        // GPIO High, i.e., LED is off. Now, turn it on
++        str8100_led_on(led_index & LED_MASK);
++    }
++    else
++    {
++        // GPIO Low, i.e., LED is on. Now turn it off
++        str8100_led_off(led_index & LED_MASK);
++    }
++}
++
++
++/*
++ * Initilaize LED settings
++ */
++void str8100_led_init(void)
++{
++    volatile unsigned int    ii;
++
++
++    /*
++     * Configure all GPIO pins as follows:
++     * 1. output pins
++     * 2. turn all leds off
++     * 3. sequentially turn all leds on and all leds off     
++     *    then, we can set GPIO Low to turn LED On, and GPIO High to turn LED Off 
++     */
++	printk("%s: \n",__FUNCTION__);
++
++	GPIO_DIRECTION_REG |= LED_MASK;
++    
++    str8100_led_all_off();
++    
++    for (ii = 0; ii < 32; ii++)
++    {
++    	if(1<<ii&LED_MASK){
++//printk("%s: ii=%d\n",__FUNCTION__,ii);
++        	str8100_led_on(1 << ii);
++        	msleep(LED_DELAY_MS);
++        	str8100_led_off(1 << ii);
++//        	msleep(LED_DELAY_MS);
++
++        }
++    }
++}
++
+diff -rupN linux-2.6.35.11/drivers/star/str9100/Makefile linux-2.6.35.11-ts7500/drivers/star/str9100/Makefile
+--- linux-2.6.35.11/drivers/star/str9100/Makefile	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str9100/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,32 @@
++################################################################################
++#
++# 
++# Copyright(c) 2005 -  Star semiconduction. All rights reserved.
++# 
++# This program is free software; you can redistribute it and/or modify it 
++# under the terms of the GNU General Public License as published by the Free 
++# Software Foundation; either version 2 of the License, or (at your option) 
++# any later version.
++# 
++# This program is distributed in the hope that it will be useful, but WITHOUT 
++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
++# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
++# more details.
++# 
++# You should have received a copy of the GNU General Public License along with
++# this program; if not, write to the Free Software Foundation, Inc., 59 
++# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++# 
++# The full GNU General Public License is included in this distribution in the
++# file called LICENSE.
++# 
++# Contact Information:
++# Star semiconduction Linux Support <support@starsemi.com>
++#
++################################################################################
++
++obj-y += str9100_tool.o
++
++obj-$(CONFIG_STR9100_INFO) += str9100_info.o
++obj-$(CONFIG_STR9100_SHNAT) += str9100_shnat_hook.o
++
+diff -rupN linux-2.6.35.11/drivers/star/str9100/str9100_info.c linux-2.6.35.11-ts7500/drivers/star/str9100/str9100_info.c
+--- linux-2.6.35.11/drivers/star/str9100/str9100_info.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str9100/str9100_info.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,755 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/version.h>
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,32)
++#define LINUX24 1
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++#define LINUX26 1
++#endif
++
++#include <linux/stddef.h>
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <asm/byteorder.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/string.h>
++#include <linux/proc_fs.h>
++#include <asm/arch/hardware.h>
++#include <linux/kdev_t.h>
++#include <linux/miscdevice.h>
++#include <asm/uaccess.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/system.h>
++#include "../../net/str9100/star_gsw.h"
++
++#ifdef LINUX24
++#include <asm/arch/str9100_info.h>
++#include <asm/arch/str9100/star_tool.h>
++#include <asm/arch/str9100/star_gsw.h>
++#endif
++
++#ifdef LINUX26
++#include <linux/str9100/str9100_tool.h>
++#include <linux/str9100/str9100_info.h>
++#endif
++
++
++
++
++
++
++
++
++static const char *cpu_str[]={
++"175",
++"200",
++"225",
++"250"};
++
++static const char *v18_str[] = {
++"1.537",
++"1.594",
++"1.655",
++"1.721",
++"1.793",
++"1.871",
++"1.956",
++"2.049"};
++
++static const char *pciclk_str[] = {
++"33",
++"66",
++"-"};
++
++static const char *dram_str[] = {
++"16",
++"32",
++"64",
++"-"};
++
++#ifdef LINUX24
++struct proc_dir_entry *str9100_info_proc;
++#endif
++
++
++typedef struct STR9100_INFO_{
++	u32 cpu;
++	u32 v18regular;
++	u32 pciclk;
++	u32 dram;
++}STR9100_INFO;
++
++static STR9100_INFO str9100_info;
++
++#ifdef LINUX26
++static struct proc_dir_entry *str9100_info_proc_entry;
++#endif
++
++
++#ifdef LINUX24
++int get_system_info(void){
++	u32 volatile temp;
++	temp = (((*(u32 volatile *)(IO_ADDRESS(0x77000014))) >> 6) & 0x3);
++	str9100_info.cpu = temp;
++
++	temp = (*(u32 volatile *)(IO_ADDRESS(0x77000018)));
++	temp = ((temp >> 11)&0x7);
++	str9100_info.v18regular = temp;
++
++#if defined(CONFIG_STAR9100_PCI66M)
++	str9100_info.pciclk = 1;
++#elif defined(CONFIG_STAR9100_PCI33M)
++	str9100_info.pciclk = 0;
++#elif 
++	str9100_info.pciclk = 2;
++#endif
++
++#if defined(CONFIG_STR9100_DRAM_64M)
++	str9100_info.dram = 2;
++#elif defined(CONFIG_STR9100_DRAM_32M)
++	str9100_info.dram = 1;
++#elif defined(CONFIG_STR9100_DRAM_16M)
++	str9100_info.dram = 0;
++#else
++	str9100_info.dram = 3;
++#endif
++
++
++	return 0;
++}
++#endif
++
++#ifdef LINUX26
++static int get_system_info(void)
++{
++	u32 temp;
++	temp = (PWRMGT_RESET_LATCH_CONFIGURATION_REG >> 6) & 0x3;
++	str9100_info.cpu = temp;
++
++	temp = (PWRMGT_REGULATOR_CONTROL_REG >> 11) & 0x7;
++	temp = ((temp >> 11)&0x7);
++	str9100_info.v18regular = temp;
++
++#if defined(CONFIG_STR9100_PCI66M)
++	str9100_info.pciclk = 1;
++#elif defined(CONFIG_STR9100_PCI33M)
++	str9100_info.pciclk = 0;
++#else
++	str9100_info.pciclk = 2;
++#endif
++
++#if defined(CONFIG_STR9100_DRAM_64M)
++	str9100_info.dram = 2;
++#elif defined(CONFIG_STR9100_DRAM_32M)
++	str9100_info.dram = 1;
++#elif defined(CONFIG_STR9100_DRAM_16M)
++	str9100_info.dram = 0;
++#else
++	str9100_info.dram = 3;
++#endif
++
++	return 0;
++}
++#endif
++
++
++#ifdef LINUX24
++static int str9100_info_read_proc(char *page, char **start,  off_t off, int count, int *eof, void *data){
++	int num = 0;
++
++        volatile unsigned long remap = (unsigned long)ioremap(FLASH_BASE_ADDR, FLASH_SIZE);
++        volatile u16 *addr = (u16 *)(remap + 0);
++
++	// for human readable
++	num += sprintf(page+num, "--- CPU \n");
++	num += sprintf(page+num, "CPU Clock: Str9100 %sMhz\n",cpu_str[str9100_info.cpu]);
++	num += sprintf(page+num, "1.8V Regulator Regulated vdd Output : %sv \n",v18_str[str9100_info.v18regular]);
++	num += sprintf(page+num, "--- Device \n");
++	num += sprintf(page+num, "PCI Clock: %sMhz\n",pciclk_str[str9100_info.pciclk]);
++	num += sprintf(page+num, "--- Memory \n");
++	num += sprintf(page+num, "DRAM Size: %sMBytes\n",dram_str[str9100_info.dram]);
++#ifdef CONFIG_CPU_ISCRATCHPAD_ENABLE
++	num += sprintf(page+num, "enable I-Scratchpad\n");
++#else
++	num += sprintf(page+num, "disable I-Scratchpad\n");
++#endif
++	num += sprintf(page+num, "flash type: %s\n", get_flash_type(addr) );
++
++
++        iounmap(remap);
++		
++	return num;
++}
++#endif
++
++#ifdef LINUX26
++static int str9100_info_read_proc(char *page, char **start,  off_t off, int count, int *eof, void *data)
++{
++	int num = 0;
++
++	// for human readable
++	num += sprintf(page+num, "--- CPU \n");
++	num += sprintf(page+num, "CPU Clock: STR9100 %sMhz\n", cpu_str[str9100_info.cpu]);
++	num += sprintf(page+num, "1.8V Regulator Regulated vdd Output : %sv \n", v18_str[str9100_info.v18regular]);
++	num += sprintf(page+num, "--- Device \n");
++	num += sprintf(page+num, "PCI Clock: %sMhz\n", pciclk_str[str9100_info.pciclk]);
++	num += sprintf(page+num, "--- Memory \n");
++	num += sprintf(page+num, "DRAM Size: %sMBytes\n", dram_str[str9100_info.dram]);
++#ifdef CONFIG_CPU_ISPAD_ENABLE
++	num += sprintf(page+num, "I-Scratchpad enable\n");
++#else
++	num += sprintf(page+num, "I-Scratchpad disable\n");
++#endif
++	num += sprintf(page+num, "flash type: %s\n", get_flash_type());
++
++	return num;
++}
++#endif
++
++int str9100_info_write_proc(struct file *file, const char *buffer, unsigned long count, void *data){
++
++	return 0;
++}
++
++// copy form drivers/net/str9100/star_gsw_phy.h
++#ifdef LINUX26
++#define GSW_VLAN_VID_0_1 GSW_VLAN_VID_0_1_REG
++#define GSW_VLAN_VID_2_3 GSW_VLAN_VID_2_3_REG
++#define GSW_VLAN_VID_4_5 GSW_VLAN_VID_4_5_REG
++#define GSW_VLAN_VID_6_7 GSW_VLAN_VID_6_7_REG
++#define GSW_HNAT_CONFIG GSW_HNAT_CONFIG_REG
++#endif
++
++
++//#define CONFIG_SWITCH_IOCTL
++#ifdef CONFIG_SWITCH_IOCTL
++
++#define GSW_SET_VLAN_0_VID(vid) \
++{ \
++	((GSW_VLAN_VID_0_1) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_0_1) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_1_VID(vid) \
++{ \
++	((GSW_VLAN_VID_0_1) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_0_1) |= (((vid) & 0xFFF) << 12)); \
++}
++
++#define GSW_SET_VLAN_2_VID(vid) \
++{ \
++	((GSW_VLAN_VID_2_3) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_2_3) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_3_VID(vid) \
++{ \
++	((GSW_VLAN_VID_2_3) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_2_3) |= (((vid) & 0xFFF) << 12)); \
++}
++
++#define GSW_SET_VLAN_4_VID(vid) \
++{ \
++	((GSW_VLAN_VID_4_5) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_4_5) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_5_VID(vid) \
++{ \
++	((GSW_VLAN_VID_4_5) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_4_5) |= (((vid) & 0xFFF) << 12)); \
++}
++
++#define GSW_SET_VLAN_6_VID(vid) \
++{ \
++	((GSW_VLAN_VID_6_7) &= (~(0xFFF << 0))); \
++	((GSW_VLAN_VID_6_7) |= (((vid) & 0xFFF) << 0)); \
++}
++
++#define GSW_SET_VLAN_7_VID(vid) \
++{ \
++	((GSW_VLAN_VID_6_7) &= (~(0xFFF << 12))); \
++	((GSW_VLAN_VID_6_7) |= (((vid) & 0xFFF) << 12)); \
++}
++
++void change_vid(u8 gid, u16 vid)
++{
++		switch (gid) 
++		{
++		    case 0:
++		    {
++			GSW_SET_VLAN_0_VID(vid);
++			break;
++		    }
++		    case 1:
++		    {
++			GSW_SET_VLAN_1_VID(vid); 
++			break;
++		    }
++		    case 2:
++		    {
++			GSW_SET_VLAN_2_VID(vid);
++			break;
++		    }
++		    case 3:
++		    {
++			GSW_SET_VLAN_3_VID(vid); 
++			break;
++		    }
++		    case 4:
++		    {
++			GSW_SET_VLAN_4_VID(vid);
++			break;
++		    }
++		    case 5:
++		    {
++			GSW_SET_VLAN_5_VID(vid); 
++			break;
++		    }
++		    case 6:
++		    {
++			GSW_SET_VLAN_6_VID(vid);
++			break;
++		    }
++		    case 7:
++		    {
++			GSW_SET_VLAN_7_VID(vid); 
++			break;
++		    }
++		}
++
++}
++
++int get_vid(u8 gid)
++{
++	switch (gid) 
++	{
++	    case 0:
++	    {
++		return (GSW_VLAN_VID_0_1 & 0x0fff);
++	    }
++	    case 1:
++	    {
++		return ((GSW_VLAN_VID_0_1 >> 12) & 0x0fff);
++	    }
++	    case 2:
++	    {
++		return (GSW_VLAN_VID_2_3 & 0x0fff);
++	    }
++	    case 3:
++	    {
++		return ((GSW_VLAN_VID_2_3 >> 12) & 0x0fff);
++	    }
++	    case 4:
++	    {
++		return (GSW_VLAN_VID_4_5 & 0x0fff);
++	    }
++	    case 5:
++	    {
++		return ((GSW_VLAN_VID_4_5 >> 12) & 0x0fff);
++	    }
++	    case 6:
++	    {
++		return (GSW_VLAN_VID_6_7 & 0x0fff);
++	    }
++	    case 7:
++	    {
++		return ((GSW_VLAN_VID_6_7 >> 12) & 0x0fff);
++	    }
++	}
++
++	return -1;
++}
++#endif
++
++static int str9100_info_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){
++
++#if 1
++     int count,len;
++     char temp[STR9100_INFO_SIZE];
++#ifdef CONFIG_SWITCH_IOCTL
++	int merge_int;
++	u16 vvid_num;
++	VVIDContent vvid_content;
++	VGIDPair vgid_pair;
++	VGIDMAC vgid_mac;
++	u8 gid;
++	u32 shnat_wangid;
++	u32 hnat_cfg;
++
++	extern gsw_info_t star_gsw_info;
++
++#endif
++
++
++     switch (cmd) {
++
++#ifdef CONFIG_SWITCH_IOCTL
++        case STR9100_GSW_GET_SHNAT_WANGID:
++		copy_from_user(&shnat_wangid, (u32*)arg, sizeof(u32));
++                GSW_READ_HNAT_CONFIGURATION(hnat_cfg);
++		shnat_wangid = hnat_cfg >> 16;
++
++  		copy_to_user((u32*)arg, &shnat_wangid, sizeof(u32));
++
++		return 0;
++
++        case STR9100_GSW_SET_SHNAT_WANGID:
++		copy_from_user(&shnat_wangid, (u32 *)arg, sizeof(u32));
++
++
++                GSW_READ_HNAT_CONFIGURATION(hnat_cfg);
++                hnat_cfg &= (~(0xff << 16));
++                //gid_bitmap=simple_strtol(buf_param1, NULL, 16);
++                printk("[kernel mode] shnat_wangid : %x\n", shnat_wangid);
++                hnat_cfg |= (shnat_wangid << 16);
++                GSW_WRITE_HNAT_CONFIGURATION(hnat_cfg);
++		return 0;
++#if 1
++        case STR9100_GSW_LOOKUP_ARL:
++		copy_from_user(&vgid_mac, (VGIDMAC *)arg, sizeof(VGIDMAC));
++		#if 0
++		printk("[kernel mode] STR9100_GSW_LOOKUP_ARL\n");
++		printk("[kernel mode] gid : %d\n", vgid_mac.gid_);
++		printk("[kernel mode] mac # %x:%x:%x:%x:%x:%x\n", vgid_mac.mac_[0], vgid_mac.mac_[1],vgid_mac.mac_[2],vgid_mac.mac_[3],vgid_mac.mac_[4],vgid_mac.mac_[5]);
++		#endif
++
++		//memcpy(vgid_mac.mac_, star_gsw_info.vlan[vgid_mac.gid_].vlan_mac, 6);
++
++	        vgid_mac.vid_ = star_gsw_info.vlan[vgid_mac.gid_].vlan_vid;
++
++		printk("[kernel mode] gid : %d\n", vgid_mac.gid_);
++		printk("[kernel mode] vid : %d\n", vgid_mac.vid_);
++		//printk("[kernel mode] mac # %x:%x:%x:%x:%x:%x\n", vgid_mac.mac_[0], vgid_mac.mac_[1],vgid_mac.mac_[2],vgid_mac.mac_[3],vgid_mac.mac_[4],vgid_mac.mac_[5]);
++
++		if (star_gsw_search_arl_table(vgid_mac.mac_, vgid_mac.gid_)) {
++			return 1; // found
++		}
++		else {
++			return 0; // found
++		}
++		return 0;
++
++        //  unrelated variable star_gsw_info
++        case STR9100_GSW_ADD_VID_MAC:
++                // add a mac into arl table
++                #if 0
++                printk("[kernel mode] STR9100_GSW_ADD_VID_MAC\n");
++                #endif
++                copy_from_user(&vgid_mac, (VGIDMAC *)arg, sizeof(VGIDMAC));
++                add_mac_into_arl(vgid_mac.gid_, vgid_mac.mac_);
++                return 0;
++
++        //  unrelated variable star_gsw_info
++        //  unrelated hnat
++        case STR9100_GSW_PURE_DEL_VID_MAC:
++                copy_from_user(&vgid_mac, (VGIDMAC *)arg, sizeof(VGIDMAC));
++		//star_gsw_del_arl_table(vgid_mac.mac_, vgid_mac.gid_);
++		del_mac_from_arl(vgid_mac.gid_, vgid_mac.mac_);
++                return 0;
++
++
++	// related hnat
++        case STR9100_GSW_DEL_VID_MAC:
++		#if 0
++		printk("[kernel mode] STR9100_GSW_DEL_VID_MAC\n");
++		#endif
++		copy_from_user(&vgid_mac, (VGIDMAC *)arg, sizeof(VGIDMAC));
++
++		del_my_vlan_mac(vgid_mac.gid_);
++		return 0;
++#endif
++        case STR9100_GSW_SET_VID_MAC:
++		copy_from_user(&vgid_mac, (VGIDMAC *)arg, sizeof(VGIDMAC));
++		#if 0
++		printk("[kernel mode] STR9100_GSW_SET_VID_MAC\n");
++		//printk("[kernel mode] net_device_index_ : %d\n", vgid_mac.net_device_index_);
++		printk("[kernel mode] gid : %d\n", vgid_mac.gid_);
++		printk("[kernel mode] vid : %d\n", vgid_mac.vid_);
++		printk("[kernel mode] mac # %x:%x:%x:%x:%x:%x\n", vgid_mac.mac_[0], vgid_mac.mac_[1],vgid_mac.mac_[2],vgid_mac.mac_[3],vgid_mac.mac_[4],vgid_mac.mac_[5]);
++		#endif
++
++		change_vid(vgid_mac.gid_, vgid_mac.vid_);
++		del_my_vlan_mac(vgid_mac.gid_);
++		config_my_vlan_mac(vgid_mac.gid_, vgid_mac.vid_, vgid_mac.mac_);
++		star_gsw_hnat_write_vlan_src_mac(vgid_mac.gid_, vgid_mac.mac_);
++		//gid_map_ary[vgid_mac.net_device_index_]=vgid_mac.gid_;
++		return 0;
++
++
++        case STR9100_GSW_GET_VID_MAC:
++		copy_from_user(&vgid_mac, (VGIDMAC *)arg, sizeof(VGIDMAC));
++        	star_gsw_info.vlan[vgid_mac.gid_].vlan_gid;
++	        vgid_mac.vid_ = star_gsw_info.vlan[vgid_mac.gid_].vlan_vid;
++	        //vgid_mac.net_device_index_ = 
++		memcpy(vgid_mac.mac_, star_gsw_info.vlan[vgid_mac.gid_].vlan_mac, 6);
++
++		#if 0
++		printk("[kernel mode] STR9100_GSW_GET_VID_MAC\n");
++		printk("[kernel mode] gid : %d\n", vgid_mac.gid_);
++		printk("[kernel mode] vid : %d\n", vgid_mac.vid_);
++		printk("[kernel mode] mac # %x:%x:%x:%x:%x:%x\n", vgid_mac.mac_[0], vgid_mac.mac_[1],vgid_mac.mac_[2],vgid_mac.mac_[3],vgid_mac.mac_[4],vgid_mac.mac_[5]);
++		#endif
++	  	copy_to_user((VGIDMAC*)arg, &vgid_mac, sizeof(VGIDMAC));
++
++
++		return 0;
++
++
++        case STR9100_GSW_SET_VID:
++		copy_from_user(&vgid_pair, (VGIDPair*)arg, sizeof(VGIDPair));
++
++		//printk("SET_VID\n");
++		//printk("vgid_pair.vid_", vgid_pair.vid_);
++		//printk("vgid_pair.gid_", vgid_pair.gid_);
++		if (0 <= vgid_pair.gid_ && vgid_pair.gid_ <=7)
++		{
++			change_vid(vgid_pair.gid_, vgid_pair.vid_);
++			return 0;
++		}
++		else
++		{
++			printk("not valid gid: %d\n", vgid_pair.gid_);
++           		return -ENOTTY;
++		}
++
++        case STR9100_GSW_GET_VID:
++		copy_from_user(&vgid_pair, (VGIDPair*)arg, sizeof(VGIDPair));
++		
++		//printk("GET_VID\n");
++		//printk("vgid_pair.vid_", vgid_pair.vid_);
++		//printk("vgid_pair.gid_", vgid_pair.gid_);
++		if (0 <= vgid_pair.gid_ && vgid_pair.gid_ <=7)
++		{
++			u16 vid=get_vid(vgid_pair.gid_);
++			vgid_pair.vid_=vid;
++			//printk("vid : %d\n", vid);
++	  		copy_to_user((VGIDPair*)arg, &vgid_pair, sizeof (VGIDPair));
++			return 0;
++		}
++		else
++		{
++			printk("not valid gid: %d\n", vgid_pair.gid_);
++           		return -ENOTTY;
++		}
++
++#ifdef CONFIG_VVID
++        case STR9100_GSW_SET_VVID:
++		//copy_from_user(&vvid_data, (VVID *)arg, sizeof(VVID));
++		copy_from_user(&vvid_content, (VVIDContent *)arg, sizeof(VVIDContent));
++		//printk("vvid.pri_: %d\n", vvid_data.pri_);
++		//printk("vvid.vid_: %d\n", vvid_data.vid_);
++         	merge_int = (vvid_content.pri_ << 12 | vvid_content.vid_);
++		if (vvid[merge_int]==0)
++		{ // insert a vvid number (vvid_szie)
++			++vvid_size;
++			vvid[merge_int]=vvid_content.vvid_num_;
++			vvid_ary[vvid_content.vvid_num_].pri_=vvid_content.pri_;
++			vvid_ary[vvid_content.vvid_num_].vid_=vvid_content.vid_;
++			//printk("in kernel vvid_ary[%d] => (%d, %d)\n", vvid_content.vvid_num_, vvid_ary[vvid_content.vvid_num_].pri_, vvid_ary[vvid_content.vvid_num_].vid_);
++		}
++		else
++		{
++			printk("vvid[%d] already exist\n", merge_int);
++		}
++		return vvid_size;
++
++
++        case STR9100_GSW_GET_VVID:
++		copy_from_user(&vvid_content, (VVIDContent *)arg, sizeof(VVIDContent));
++		//printk("in kernel vvid_content.vvid_num_: %d\n", vvid_content.vvid_num_);
++		vvid_content.pri_ = vvid_ary[vvid_content.vvid_num_].pri_;
++		vvid_content.vid_ = vvid_ary[vvid_content.vvid_num_].vid_;
++		printk("in get kernel vvid_ary[%d] => (%d, %d)\n", vvid_content.vvid_num_, vvid_content.pri_, vvid_content.vid_);
++	  	copy_to_user((VVIDContent*)arg, &vvid_content, sizeof (VVIDContent));
++		return 0;
++	   	break;
++
++#endif // CONFIG_VVID
++#endif // end CONFIG_SWITCH_IOCTL
++
++
++        case STR9100_INFO_IOCGETD:    
++	   printk("STR9100_INFO_IOCGETD \n");
++           copy_to_user((unsigned char *)arg, (unsigned char *)&str9100_info, sizeof(str9100_info));
++	   goto ioctlexit;
++
++        case STR9100_INFO_IOCSETD:
++	   printk("STR9100_INFO_IOCSETD \n");
++           //if (copy_from_user(temp, (unsigned char *)arg, count))     
++           //    return -EFAULT;    
++	   goto ioctlexit;
++
++	case STR9100_INFO_IOCPUCLK:
++	   len = strlen(cpu_str[str9100_info.cpu]);
++	   strcpy(temp,cpu_str[str9100_info.cpu]);
++	   break;
++
++	case STR9100_INFO_IOV18:
++	   len = strlen(v18_str[str9100_info.v18regular]);
++	   strcpy(temp,v18_str[str9100_info.v18regular]);
++	   break;
++
++	case STR9100_INFO_IOPCICLK:
++	   len = strlen(pciclk_str[str9100_info.pciclk]);
++	   strcpy(temp,pciclk_str[str9100_info.pciclk]);
++	   break;
++
++	case STR9100_INFO_IODRAMSZ:
++	   len = strlen(dram_str[str9100_info.dram]);
++	   strcpy(temp,dram_str[str9100_info.dram]);
++	   break;
++
++
++
++        default:
++           return -ENOTTY;
++  /*         return -EINVAL; another return option */                      
++     }
++
++
++	  copy_to_user((unsigned char *)arg,temp,len+1);
++
++
++
++ioctlexit:
++#endif
++	return 0;
++}
++
++static int str9100_info_open(struct inode *inode, struct file *file)
++{
++        unsigned int minor = MINOR(inode->i_rdev);
++        if (minor != STR9100_INFO_MINOR)
++                return -ENODEV;
++
++#ifdef MODULE
++        MOD_INC_USE_COUNT;
++#endif
++
++        return 0;
++}
++
++
++static int str9100_info_release(struct inode *inode, struct file *file)
++{
++
++#ifdef MODULE
++        MOD_DEC_USE_COUNT;
++#endif
++
++        return 0;
++}
++
++
++/*
++ * ioctl interface
++ */
++static struct file_operations str9100_info_fops =
++{
++        owner:          THIS_MODULE,
++        ioctl:          str9100_info_ioctl,
++        open:           str9100_info_open,
++        release:        str9100_info_release,
++};
++
++/* STR9100_MINOR in include/linux/miscdevice.h */
++static struct miscdevice str9100_info_miscdev =
++{
++        STR9100_INFO_MINOR,
++        "str9100_info",
++        &str9100_info_fops
++};
++
++
++#ifdef LINUX24
++static int __init str9100_info_init(void){
++	struct proc_dir_entry *procdir=0;
++
++
++	get_system_info();
++
++	misc_register(&str9100_info_miscdev);
++
++	//proc_mkdir("str9100",0);
++	procdir= create_proc_str9100(PROC_STR);
++	if (procdir)
++	{
++		str9100_info_proc = create_proc_entry("info", S_IFREG | S_IRUGO, procdir);
++                if (str9100_info_proc) {
++                        str9100_info_proc->read_proc = str9100_info_read_proc;
++                        str9100_info_proc->write_proc = str9100_info_write_proc;
++                }
++		printk("Str9100 Information inited \n");
++                return 0;
++        }
++        else
++                return -1;
++	
++	//str9100_info_proc=create_proc_read_entry( "str9100/info", 0, NULL, str9100_info_read_proc,NULL) ;
++        //str9100_info_proc->write_proc=star9100_info_write_proc;
++
++
++}
++#endif
++
++#ifdef LINUX26
++static int __init str9100_info_init(void)
++{
++	get_system_info();
++
++	str9100_info_proc_entry = create_proc_entry("str9100/info", S_IFREG | S_IRUGO, NULL);
++	if (str9100_info_proc_entry) {
++		str9100_info_proc_entry->read_proc = str9100_info_read_proc;
++		str9100_info_proc_entry->write_proc = str9100_info_write_proc;
++	}
++
++	misc_register(&str9100_info_miscdev);
++
++	return 1;
++}
++#endif
++
++
++static void __exit str9100_info_exit(void){
++
++	misc_deregister(&str9100_info_miscdev);
++
++	remove_proc_entry("str9100/info",NULL);
++
++	printk("Str9100 Information exit \n");
++}
++
++module_init(str9100_info_init);
++module_exit(str9100_info_exit);
++
+diff -rupN linux-2.6.35.11/drivers/star/str9100/str9100_info.c.26 linux-2.6.35.11-ts7500/drivers/star/str9100/str9100_info.c.26
+--- linux-2.6.35.11/drivers/star/str9100/str9100_info.c.26	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str9100/str9100_info.c.26	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,262 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/stddef.h>
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <asm/byteorder.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/string.h>
++#include <linux/proc_fs.h>
++#include <asm/arch/hardware.h>
++#include <linux/kdev_t.h>
++#include <linux/miscdevice.h>
++#include <asm/uaccess.h>
++
++#include <linux/str9100/str9100_tool.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/system.h>
++
++static const char *cpu_str[] = {
++"175",
++"200",
++"225",
++"250"
++};
++
++static const char *v18_str[] = {
++"1.537",
++"1.594",
++"1.655",
++"1.721",
++"1.793",
++"1.871",
++"1.956",
++"2.049"
++};
++
++static const char *pciclk_str[] = {
++"33",
++"66",
++"-"
++};
++
++static const char *dram_str[] = {
++"16",
++"32",
++"64",
++"-"
++};
++
++typedef struct STR9100_INFO {
++	u32 cpu;
++	u32 v18regular;
++	u32 pciclk;
++	u32 dram;
++} STR9100_INFO;
++
++static STR9100_INFO str9100_info;
++static struct proc_dir_entry *str9100_info_proc_entry;
++
++static int get_system_info(void)
++{
++	u32 temp;
++	temp = (PWRMGT_RESET_LATCH_CONFIGURATION_REG >> 6) & 0x3;
++	str9100_info.cpu = temp;
++
++	temp = (PWRMGT_REGULATOR_CONTROL_REG >> 11) & 0x7;
++	temp = ((temp >> 11)&0x7);
++	str9100_info.v18regular = temp;
++
++#if defined(CONFIG_STR9100_PCI66M)
++	str9100_info.pciclk = 1;
++#elif defined(CONFIG_STR9100_PCI33M)
++	str9100_info.pciclk = 0;
++#else
++	str9100_info.pciclk = 2;
++#endif
++
++#if defined(CONFIG_STR9100_DRAM_64M)
++	str9100_info.dram = 2;
++#elif defined(CONFIG_STR9100_DRAM_32M)
++	str9100_info.dram = 1;
++#elif defined(CONFIG_STR9100_DRAM_16M)
++	str9100_info.dram = 0;
++#else
++	str9100_info.dram = 3;
++#endif
++
++	return 0;
++}
++
++static int str9100_info_read_proc(char *page, char **start,  off_t off, int count, int *eof, void *data)
++{
++	int num = 0;
++
++	// for human readable
++	num += sprintf(page+num, "--- CPU \n");
++	num += sprintf(page+num, "CPU Clock: STR9100 %sMhz\n", cpu_str[str9100_info.cpu]);
++	num += sprintf(page+num, "1.8V Regulator Regulated vdd Output : %sv \n", v18_str[str9100_info.v18regular]);
++	num += sprintf(page+num, "--- Device \n");
++	num += sprintf(page+num, "PCI Clock: %sMhz\n", pciclk_str[str9100_info.pciclk]);
++	num += sprintf(page+num, "--- Memory \n");
++	num += sprintf(page+num, "DRAM Size: %sMBytes\n", dram_str[str9100_info.dram]);
++#ifdef CONFIG_CPU_ISPAD_ENABLE
++	num += sprintf(page+num, "I-Scratchpad enable\n");
++#else
++	num += sprintf(page+num, "I-Scratchpad disable\n");
++#endif
++	num += sprintf(page+num, "flash type: %s\n", get_flash_type());
++
++	return num;
++}
++
++static int str9100_info_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
++{
++	return 0;
++}
++
++static int str9100_info_ioctl(struct inode *inode, struct file *file,
++	unsigned int cmd, unsigned long arg)
++{
++	int count,len;
++	char temp[STR9100_INFO_SIZE];
++
++	switch (cmd) {
++	case STR9100_INFO_IOCGETD:    
++		printk("STR9100_INFO_IOCGETD \n");
++		copy_to_user((unsigned char *)arg, (unsigned char *)&str9100_info, sizeof(str9100_info));
++		break;
++
++	case STR9100_INFO_IOCSETD:
++		printk("STR9100_INFO_IOCSETD \n");
++		//if (copy_from_user(temp, (unsigned char *)arg, count))     
++			//return -EFAULT;
++		break;
++
++	case STR9100_INFO_IOCPUCLK:
++		len = strlen(cpu_str[str9100_info.cpu]);
++		strcpy(temp,cpu_str[str9100_info.cpu]);
++		copy_to_user((unsigned char *)arg, temp, len + 1);
++		break;
++
++	case STR9100_INFO_IOV18:
++		len = strlen(v18_str[str9100_info.v18regular]);
++		strcpy(temp,v18_str[str9100_info.v18regular]);
++		copy_to_user((unsigned char *)arg, temp, len + 1);
++		break;
++
++	case STR9100_INFO_IOPCICLK:
++		len = strlen(pciclk_str[str9100_info.pciclk]);
++		strcpy(temp,pciclk_str[str9100_info.pciclk]);
++		copy_to_user((unsigned char *)arg, temp, len + 1);
++		break;
++
++	case STR9100_INFO_IODRAMSZ:
++		len = strlen(dram_str[str9100_info.dram]);
++		strcpy(temp,dram_str[str9100_info.dram]);
++		copy_to_user((unsigned char *)arg, temp, len + 1);
++		break;
++
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++static int str9100_info_open(struct inode *inode, struct file *file)
++{
++	unsigned int minor = MINOR(inode->i_rdev);
++	if (minor != STR9100_INFO_MINOR)
++		return -ENODEV;
++
++#ifdef MODULE
++	MOD_INC_USE_COUNT;
++#endif
++
++	return 0;
++}
++
++
++static int str9100_info_release(struct inode *inode, struct file *file)
++{
++#ifdef MODULE
++	MOD_DEC_USE_COUNT;
++#endif
++
++	return 0;
++}
++
++
++/*
++ * ioctl interface
++ */
++static struct file_operations str9100_info_fops =
++{
++	owner:		THIS_MODULE,
++	ioctl:		str9100_info_ioctl,
++	open:		str9100_info_open,
++	release:	str9100_info_release,
++};
++
++/* STR9100_MINOR in include/linux/miscdevice.h */
++static struct miscdevice str9100_info_miscdev =
++{
++	STR9100_INFO_MINOR,
++	"str9100_info",
++	&str9100_info_fops
++};
++
++static int __init str9100_info_init(void)
++{
++	get_system_info();
++
++	str9100_info_proc_entry = create_proc_entry("str9100/info", S_IFREG | S_IRUGO, NULL);
++	if (str9100_info_proc_entry) {
++		str9100_info_proc_entry->read_proc = str9100_info_read_proc;
++		str9100_info_proc_entry->write_proc = str9100_info_write_proc;
++	}
++
++	misc_register(&str9100_info_miscdev);
++
++	return 1;
++}
++
++static void __exit str9100_info_exit(void)
++{
++	misc_deregister(&str9100_info_miscdev);
++	remove_proc_entry("str9100/info", NULL);
++}
++
++module_init(str9100_info_init);
++module_exit(str9100_info_exit);
++
+diff -rupN linux-2.6.35.11/drivers/star/str9100/str9100_shnat_hook.c linux-2.6.35.11-ts7500/drivers/star/str9100/str9100_shnat_hook.c
+--- linux-2.6.35.11/drivers/star/str9100/str9100_shnat_hook.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str9100/str9100_shnat_hook.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,78 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/config.h>
++
++#ifdef CONFIG_NETFILTER
++#include <linux/types.h>
++#include <linux/inetdevice.h>
++#include <linux/ip.h>
++#include <linux/timer.h>
++#include <linux/module.h>
++#include <linux/netfilter.h>
++#include <net/protocol.h>
++#include <net/ip.h>
++#include <net/checksum.h>
++#include <net/route.h>
++#include <linux/netfilter_ipv4.h>
++#include <linux/netfilter_ipv4/ip_nat_rule.h>
++#include <linux/netfilter_ipv4/ip_tables.h>
++
++#include <linux/str9100/star9100_shnat.h>
++#include <linux/str9100/str9100_shnat_hook.h>
++
++//#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
++struct net_device *pci_netdev[MAX_FP_PCIDEV];
++EXPORT_SYMBOL(pci_netdev);
++int (*star9100_shnat_pci_fp_forward_skb_ptr)(struct sk_buff *skb);
++//#endif
++
++int star9100_shnat_hook_ready;
++int (*star9100_shnat_preadd_hnatable_hook)(u32 sip,u16 sport,u16 dport, u32 proto);
++int (*star9100_shnat_check_shnat_enable_hook)(void);
++int (*star9100_shnat_nf_nat_preadd_hnatable_hook)(const struct ip_conntrack *ct, int dir, const u16 port);
++int (*star9100_shnat_nf_remove_hnatable_hook)(struct ip_conntrack *);
++int (*star9100_shnat_nf_add_hnatable_hook)(const struct ip_conntrack *ct,const struct iphdr *iph, u16 proto);
++int (*star9100_shnat_add_arptable_hook)(u32 myip, u32 targetip);
++int (*star9100_shnat_fix_arptable_hook)(u32 myip, u32 targetip);
++int (*star9100_shnat_nf_preadd_hnatable_hook)(const struct sk_buff **pskb);
++int (*star9100_shnat_check_ftponly_enable_hook)(void);
++int (*star9100_shnat_pci_fp_getdev_hook)(struct sk_buff *skb_ptr);
++star9100_arp_table *(*star9100_shnat_getarptable_hook)( u32 ip_addr);
++
++
++EXPORT_SYMBOL(star9100_shnat_hook_ready);
++EXPORT_SYMBOL(star9100_shnat_preadd_hnatable_hook);
++EXPORT_SYMBOL(star9100_shnat_check_shnat_enable_hook);
++EXPORT_SYMBOL(star9100_shnat_nf_nat_preadd_hnatable_hook);
++EXPORT_SYMBOL(star9100_shnat_nf_remove_hnatable_hook);
++EXPORT_SYMBOL(star9100_shnat_nf_add_hnatable_hook);
++EXPORT_SYMBOL(star9100_shnat_add_arptable_hook);
++EXPORT_SYMBOL(star9100_shnat_fix_arptable_hook);
++EXPORT_SYMBOL(star9100_shnat_nf_preadd_hnatable_hook);
++EXPORT_SYMBOL(star9100_shnat_check_ftponly_enable_hook);
++EXPORT_SYMBOL(star9100_shnat_getarptable_hook);
++EXPORT_SYMBOL(star9100_shnat_pci_fp_getdev_hook);
++EXPORT_SYMBOL(star9100_shnat_pci_fp_forward_skb_ptr);
++
++#endif
+diff -rupN linux-2.6.35.11/drivers/star/str9100/str9100_tool.c linux-2.6.35.11-ts7500/drivers/star/str9100/str9100_tool.c
+--- linux-2.6.35.11/drivers/star/str9100/str9100_tool.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str9100/str9100_tool.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,287 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/version.h>
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,32)
++#define LINUX24 1
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++#define LINUX26 1
++#endif
++
++#ifdef LINUX24
++#include <asm/arch/str9100/star_tool.h>
++#endif
++
++#ifdef LINUX26
++#include <linux/str9100/str9100_tool.h>
++#endif
++
++#include <linux/proc_fs.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/system.h>
++#include <linux/delay.h>
++
++
++
++#ifdef LINUX24
++// for star_tool.h create_proc_str9100()
++//int create_proc_dir=0;
++
++
++struct proc_dir_entry *create_proc_str9100(const char* proc_str)
++{
++	struct proc_dir_entry *de;
++	struct proc_dir_entry *str9100_gsw_procdir=0;
++
++
++        de = &proc_root;
++        for (de = de->subdir; de ; de = de->next) {
++		if (strcmp(de->name, "str9100")==0) // find it
++		{
++			return de;
++		}
++        }
++
++	// not found /proc/str9100, so create it.
++
++	
++       	str9100_gsw_procdir=proc_mkdir(proc_str, NULL);
++       	if (str9100_gsw_procdir==0)
++		return 0;
++
++
++	return str9100_gsw_procdir;
++}
++#endif
++
++
++
++#define CONFIG_GET_FLASH_VAR
++#ifdef CONFIG_GET_FLASH_VAR
++// add by descent 2006/07/20
++
++/* Add for read MAC from FLASH. */
++#ifndef __ARM_BE__
++#define B0(h)   ((h) & 0xFF)
++#define B1(h)   (((h) >> 8) & 0xFF)
++#else
++#define B0(h)   (((h) >> 8) & 0xFF)
++#define B1(h)   ((h) & 0xFF) 
++#endif
++
++void copy_from_flash(unsigned long from, void *to,ssize_t len)
++{   
++        int i;  
++        u8 *dest = (u8*)to;
++        u16 data;
++        unsigned long remap = (unsigned long)ioremap(FLASH_BASE_ADDR,FLASH_SIZE);
++        u16 *src = (u16 *)(remap + from);
++
++        for(i = 0; i < (len / 2);i++){
++                data = src[i];
++                dest[i * 2] = B0(data);
++                dest[i * 2 + 1] = B1(data);
++
++        }
++        if(len & 1)
++                dest[len - 1] = B0(src[i]);
++	iounmap(remap);
++}
++
++#if 0
++char *get_flash_env(const char *env_name)
++{
++	const int ENV_SIZE=0x8000;
++	//const char *ENV_BEGIN=FLASH_ADDRESS(0x10000000)+0x20000;
++	//const char *ENV_BEGIN=FLASH_ADDRESS(0x10020000);
++	unsigned long from=0x20000;
++
++        volatile unsigned long remap = (unsigned long)ioremap(FLASH_BASE_ADDR, FLASH_SIZE);
++        volatile u8 *src = (u16 *)(remap + from);
++
++	int i=0;
++	char *str_p=env_name;
++	char *beg_p=src;
++	char *p;
++	 
++
++	while(1) {
++		p=strstr(beg_p, env_name);
++		if (p) { // found
++			char *asign_p=strchr(p, '=');
++			if (asign_p)
++			{
++        			iounmap(remap);
++				return asign_p+1;
++			}
++			else
++				break; // should not this case
++		}
++		else
++		{
++			++beg_p;
++		}
++
++		if (p > src+ENV_SIZE) {
++			break;
++		}
++	}
++        iounmap(remap);
++	return 0; // not found
++}
++#else
++// copy from 2.6.16
++char *get_flash_env(const char *env_name)
++{
++	const int ENV_SIZE = 0x8000;
++	unsigned long from = 0x20000;
++
++	u8 *remap = ioremap(FLASH_BASE_ADDR, FLASH_SIZE);
++	volatile u8 *src = (volatile u8 *)(remap + from);
++
++	char *str_p = env_name;
++	char *beg_p = src;
++	char *p;
++
++	while (1) {
++		p = strstr(beg_p, str_p);
++		if (p) { // found
++			char *asign_p = strchr(p, '=');
++			if (asign_p) {
++				iounmap(remap);
++				return asign_p + 1;
++			} else
++				break; // should not this case
++		} else {
++			++beg_p;
++		}
++		if (p > (src + ENV_SIZE)) {
++			break;
++		}
++	}
++        iounmap(remap);
++	return 0; // not found
++}
++
++#endif
++#endif // ifdef CONFIG_GET_FLASH_VAR
++
++
++/*
++ *  * MXIC's flash manufacture ID
++ *   */
++#define MX_MANUFACT     0x00C200C2      /* MXIC    manuf. ID in D23..D16, D7..D0 */
++
++
++#define MXIC_MANUFACTURE_ID             0x00C20000
++
++/*
++ *  * MXIC's flash device ID
++ *   */
++#define MXIC_DEVICE_ID_MX29LV320B       0x000000A8
++#define MX_ID_LV640BB       0x22CB22CB      /* 29LV640BB by Macronix, AMD compatible */
++#define MX_ID_LV640BT       0x22C922C9      /* 29LV640BT by Macronix, AMD compatible */
++
++#ifdef LINUX24
++const char *get_flash_type(volatile u16 *saddr)
++{
++	short i;
++	u16 mid;
++	u16 did;
++	int name_index=0;
++	const char *flash_name[]={
++	                           0,
++	                           "EON_EN29LV640HL(8MB)",
++	                           "MXIC_MX29LV640BT(8MB)"
++	                         };
++	//u32  base = (u32)addr;
++
++        //volatile unsigned long remap = (unsigned long)ioremap(FLASH_BASE_ADDR, FLASH_SIZE);
++        //volatile u16 *saddr = (u16 *)(remap + 0);
++
++        //volatile u8 *src = (u16 *)(remap + 0);
++	//volatile u8 *saddr = src;
++
++	/* Write auto select command: read Manufacturer ID */
++	saddr[0x555] = 0xAA;
++	saddr[0x2AA] = 0x55;
++	saddr[0x555] = 0x90;
++
++	mid = saddr[0];
++	did = saddr[1];
++
++	if ( ((mid & 0xffff) == 0x007f) && ((did & 0xFFFF) == 0x227e) ) // "EON_EN29LV640HL(8MB)"
++		name_index=1;
++	if ( ((mid & 0xffff) == 0x00c2) && ((did & 0xFFFF) == 0x22c9) ) // "MXIC_MX29LV640BT(8MB)"
++		name_index=2;
++
++
++
++	/* reset to read mode */
++	saddr[0] = 0xF0; /* reset the bank */
++	udelay(10000);
++
++	return flash_name[name_index];
++}
++#endif
++
++#ifdef LINUX26
++const char *get_flash_type(void)
++{
++	u8 *remap = ioremap(FLASH_BASE_ADDR, FLASH_SIZE);
++	volatile u16 *saddr = (volatile u16 *)remap;
++	u16 mid;
++	u16 did;
++	int name_index = 0;
++	const char *flash_name[] = {
++		0,
++		"EON_EN29LV640HL(8MB)",
++		"MXIC_MX29LV640BT(8MB)"
++	};
++
++	/* Write auto select command: read Manufacturer ID */
++	saddr[0x555] = 0xAA;
++	saddr[0x2AA] = 0x55;
++	saddr[0x555] = 0x90;
++
++	mid = saddr[0];
++	did = saddr[1];
++
++	if (((mid & 0xffff) == 0x007f) && ((did & 0xFFFF) == 0x227e) ) // "EON_EN29LV640HL(8MB)"
++		name_index=1;
++	if (((mid & 0xffff) == 0x00c2) && ((did & 0xFFFF) == 0x22c9) ) // "MXIC_MX29LV640BT(8MB)"
++		name_index=2;
++
++	/* reset to read mode */
++	saddr[0] = 0xF0; /* reset the bank */
++	udelay(1000);
++
++	iounmap(remap);
++
++	return flash_name[name_index];
++}
++#endif
++
+diff -rupN linux-2.6.35.11/drivers/star/str9100/str9100_tool.c.26 linux-2.6.35.11-ts7500/drivers/star/str9100/str9100_tool.c.26
+--- linux-2.6.35.11/drivers/star/str9100/str9100_tool.c.26	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/star/str9100/str9100_tool.c.26	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,145 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/proc_fs.h>
++#include <linux/delay.h>
++
++//#include <asm/arch/star_tool.h>
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/system.h>
++
++#define CONFIG_GET_FLASH_VAR
++
++#ifdef CONFIG_GET_FLASH_VAR
++// add by descent 2006/07/20
++/* Add for read MAC from FLASH. */
++#ifndef __ARM_BE__
++#define B0(h)	((h) & 0xFF)
++#define B1(h)	(((h) >> 8) & 0xFF)
++#else
++#define B0(h)	(((h) >> 8) & 0xFF)
++#define B1(h)	((h) & 0xFF) 
++#endif
++
++void copy_from_flash(unsigned long from, void *to, ssize_t len)
++{
++	int i;
++	u8 *dest = (u8*)to;
++	u16 data;
++	u8 *remap = ioremap(FLASH_BASE_ADDR, FLASH_SIZE);
++	volatile u16 *src = (volatile u16 *)(remap + from);
++
++	for (i = 0; i < (len / 2); i++) {
++		data = src[i];
++		dest[i * 2] = B0(data);
++		dest[i * 2 + 1] = B1(data);
++	}
++
++	if (len & 1)
++		dest[len - 1] = B0(src[i]);
++
++	iounmap(remap);
++}
++
++char *get_flash_env(const char *env_name)
++{
++	const int ENV_SIZE = 0x8000;
++	unsigned long from = 0x20000;
++
++	u8 *remap = ioremap(FLASH_BASE_ADDR, FLASH_SIZE);
++	volatile u8 *src = (volatile u8 *)(remap + from);
++
++	char *str_p = env_name;
++	char *beg_p = src;
++	char *p;
++
++	while (1) {
++		p = strstr(beg_p, str_p);
++		if (p) { // found
++			char *asign_p = strchr(p, '=');
++			if (asign_p) {
++				iounmap(remap);
++				return asign_p + 1;
++			} else
++				break; // should not this case
++		} else {
++			++beg_p;
++		}
++		if (p > (src + ENV_SIZE)) {
++			break;
++		}
++	}
++        iounmap(remap);
++	return 0; // not found
++}
++#endif
++
++/*
++ * MXIC's flash manufacture ID
++ */
++#define MX_MANUFACT			0x00C200C2 /* MXIC manuf. ID in D23..D16, D7..D0 */
++#define MXIC_MANUFACTURE_ID		0x00C20000
++
++/*
++ * MXIC's flash device ID
++ */
++#define MXIC_DEVICE_ID_MX29LV320B	0x000000A8
++#define MX_ID_LV640BB			0x22CB22CB /* 29LV640BB by Macronix, AMD compatible */
++#define MX_ID_LV640BT			0x22C922C9 /* 29LV640BT by Macronix, AMD compatible */
++
++const char *get_flash_type(void)
++{
++	u8 *remap = ioremap(FLASH_BASE_ADDR, FLASH_SIZE);
++	volatile u16 *saddr = (volatile u16 *)remap;
++	u16 mid;
++	u16 did;
++	int name_index = 0;
++	const char *flash_name[] = {
++		0,
++		"EON_EN29LV640HL(8MB)",
++		"MXIC_MX29LV640BT(8MB)"
++	};
++
++	/* Write auto select command: read Manufacturer ID */
++	saddr[0x555] = 0xAA;
++	saddr[0x2AA] = 0x55;
++	saddr[0x555] = 0x90;
++
++	mid = saddr[0];
++	did = saddr[1];
++
++	if (((mid & 0xffff) == 0x007f) && ((did & 0xFFFF) == 0x227e) ) // "EON_EN29LV640HL(8MB)"
++		name_index=1;
++	if (((mid & 0xffff) == 0x00c2) && ((did & 0xFFFF) == 0x22c9) ) // "MXIC_MX29LV640BT(8MB)"
++		name_index=2;
++
++	/* reset to read mode */
++	saddr[0] = 0xF0; /* reset the bank */
++	udelay(1000);
++
++	iounmap(remap);
++
++	return flash_name[name_index];
++}
++
+diff -rupN linux-2.6.35.11/drivers/usb/core/buffer.c linux-2.6.35.11-ts7500/drivers/usb/core/buffer.c
+--- linux-2.6.35.11/drivers/usb/core/buffer.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/usb/core/buffer.c	2011-03-14 11:18:24.000000000 -0400
+@@ -53,9 +53,11 @@ int hcd_buffer_create(struct usb_hcd *hc
+ 	char		name[16];
+ 	int 		i, size;
+ 
++#if !defined(CONFIG_ARCH_STR9100) && !defined(CONFIG_ARCH_STR8100)
+ 	if (!hcd->self.controller->dma_mask &&
+ 	    !(hcd->driver->flags & HCD_LOCAL_MEM))
+ 		return 0;
++#endif
+ 
+ 	for (i = 0; i < HCD_BUFFER_POOLS; i++) {
+ 		size = pool_max[i];
+diff -rupN linux-2.6.35.11/drivers/usb/host/ehci-hcd.c linux-2.6.35.11-ts7500/drivers/usb/host/ehci-hcd.c
+--- linux-2.6.35.11/drivers/usb/host/ehci-hcd.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/usb/host/ehci-hcd.c	2011-03-14 11:18:24.000000000 -0400
+@@ -722,7 +722,12 @@ static irqreturn_t ehci_irq (struct usb_
+ 	masked_status = status & INTR_MASK;
+ 	if (!masked_status) {		/* irq sharing? */
+ 		spin_unlock(&ehci->lock);
+-		return IRQ_NONE;
++#ifdef CONFIG_VIC_INTERRUPT
++                return IRQ_HANDLED;
++#else
++                return IRQ_NONE;
++#endif
++		
+ 	}
+ 
+ 	/* clear (just) interrupts */
+@@ -1143,6 +1148,11 @@ MODULE_LICENSE ("GPL");
+ #define	PLATFORM_DRIVER		ehci_orion_driver
+ #endif
+ 
++#ifdef CONFIG_ARCH_STR8100
++#include "ehci-str8100.c"
++#define PLATFORM_DRIVER         str8100_ehci_hcd_driver
++#endif
++
+ #ifdef CONFIG_ARCH_IXP4XX
+ #include "ehci-ixp4xx.c"
+ #define	PLATFORM_DRIVER		ixp4xx_ehci_driver
+diff -rupN linux-2.6.35.11/drivers/usb/host/ehci-hcd.c.orig linux-2.6.35.11-ts7500/drivers/usb/host/ehci-hcd.c.orig
+--- linux-2.6.35.11/drivers/usb/host/ehci-hcd.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/usb/host/ehci-hcd.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,1278 @@
++/*
++ * Copyright (c) 2000-2004 by David Brownell
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++ * for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software Foundation,
++ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/dmapool.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/vmalloc.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/ktime.h>
++#include <linux/list.h>
++#include <linux/interrupt.h>
++#include <linux/usb.h>
++#include <linux/usb/hcd.h>
++#include <linux/moduleparam.h>
++#include <linux/dma-mapping.h>
++#include <linux/debugfs.h>
++#include <linux/slab.h>
++
++#include <asm/byteorder.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/unaligned.h>
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * EHCI hc_driver implementation ... experimental, incomplete.
++ * Based on the final 1.0 register interface specification.
++ *
++ * USB 2.0 shows up in upcoming www.pcmcia.org technology.
++ * First was PCMCIA, like ISA; then CardBus, which is PCI.
++ * Next comes "CardBay", using USB 2.0 signals.
++ *
++ * Contains additional contributions by Brad Hards, Rory Bolt, and others.
++ * Special thanks to Intel and VIA for providing host controllers to
++ * test this driver on, and Cypress (including In-System Design) for
++ * providing early devices for those host controllers to talk to!
++ */
++
++#define DRIVER_AUTHOR "David Brownell"
++#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
++
++static const char	hcd_name [] = "ehci_hcd";
++
++
++#undef VERBOSE_DEBUG
++#undef EHCI_URB_TRACE
++
++#ifdef DEBUG
++#define EHCI_STATS
++#endif
++
++/* magic numbers that can affect system performance */
++#define	EHCI_TUNE_CERR		3	/* 0-3 qtd retries; 0 == don't stop */
++#define	EHCI_TUNE_RL_HS		4	/* nak throttle; see 4.9 */
++#define	EHCI_TUNE_RL_TT		0
++#define	EHCI_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
++#define	EHCI_TUNE_MULT_TT	1
++#define	EHCI_TUNE_FLS		2	/* (small) 256 frame schedule */
++
++#define EHCI_IAA_MSECS		10		/* arbitrary */
++#define EHCI_IO_JIFFIES		(HZ/10)		/* io watchdog > irq_thresh */
++#define EHCI_ASYNC_JIFFIES	(HZ/20)		/* async idle timeout */
++#define EHCI_SHRINK_FRAMES	5		/* async qh unlink delay */
++
++/* Initial IRQ latency:  faster than hw default */
++static int log2_irq_thresh = 0;		// 0 to 6
++module_param (log2_irq_thresh, int, S_IRUGO);
++MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
++
++/* initial park setting:  slower than hw default */
++static unsigned park = 0;
++module_param (park, uint, S_IRUGO);
++MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
++
++/* for flakey hardware, ignore overcurrent indicators */
++static int ignore_oc = 0;
++module_param (ignore_oc, bool, S_IRUGO);
++MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");
++
++#define	INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
++
++/*-------------------------------------------------------------------------*/
++
++#include "ehci.h"
++#include "ehci-dbg.c"
++
++/*-------------------------------------------------------------------------*/
++
++static void
++timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
++{
++	/* Don't override timeouts which shrink or (later) disable
++	 * the async ring; just the I/O watchdog.  Note that if a
++	 * SHRINK were pending, OFF would never be requested.
++	 */
++	if (timer_pending(&ehci->watchdog)
++			&& ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
++				& ehci->actions))
++		return;
++
++	if (!test_and_set_bit(action, &ehci->actions)) {
++		unsigned long t;
++
++		switch (action) {
++		case TIMER_IO_WATCHDOG:
++			if (!ehci->need_io_watchdog)
++				return;
++			t = EHCI_IO_JIFFIES;
++			break;
++		case TIMER_ASYNC_OFF:
++			t = EHCI_ASYNC_JIFFIES;
++			break;
++		/* case TIMER_ASYNC_SHRINK: */
++		default:
++			/* add a jiffie since we synch against the
++			 * 8 KHz uframe counter.
++			 */
++			t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
++			break;
++		}
++		mod_timer(&ehci->watchdog, t + jiffies);
++	}
++}
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * handshake - spin reading hc until handshake completes or fails
++ * @ptr: address of hc register to be read
++ * @mask: bits to look at in result of read
++ * @done: value of those bits when handshake succeeds
++ * @usec: timeout in microseconds
++ *
++ * Returns negative errno, or zero on success
++ *
++ * Success happens when the "mask" bits have the specified value (hardware
++ * handshake done).  There are two failure modes:  "usec" have passed (major
++ * hardware flakeout), or the register reads as all-ones (hardware removed).
++ *
++ * That last failure should_only happen in cases like physical cardbus eject
++ * before driver shutdown. But it also seems to be caused by bugs in cardbus
++ * bridge shutdown:  shutting down the bridge before the devices using it.
++ */
++static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
++		      u32 mask, u32 done, int usec)
++{
++	u32	result;
++
++	do {
++		result = ehci_readl(ehci, ptr);
++		if (result == ~(u32)0)		/* card removed */
++			return -ENODEV;
++		result &= mask;
++		if (result == done)
++			return 0;
++		udelay (1);
++		usec--;
++	} while (usec > 0);
++	return -ETIMEDOUT;
++}
++
++/* force HC to halt state from unknown (EHCI spec section 2.3) */
++static int ehci_halt (struct ehci_hcd *ehci)
++{
++	u32	temp = ehci_readl(ehci, &ehci->regs->status);
++
++	/* disable any irqs left enabled by previous code */
++	ehci_writel(ehci, 0, &ehci->regs->intr_enable);
++
++	if ((temp & STS_HALT) != 0)
++		return 0;
++
++	temp = ehci_readl(ehci, &ehci->regs->command);
++	temp &= ~CMD_RUN;
++	ehci_writel(ehci, temp, &ehci->regs->command);
++	return handshake (ehci, &ehci->regs->status,
++			  STS_HALT, STS_HALT, 16 * 125);
++}
++
++static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
++				       u32 mask, u32 done, int usec)
++{
++	int error;
++
++	error = handshake(ehci, ptr, mask, done, usec);
++	if (error) {
++		ehci_halt(ehci);
++		ehci_to_hcd(ehci)->state = HC_STATE_HALT;
++		ehci_err(ehci, "force halt; handshake %p %08x %08x -> %d\n",
++			ptr, mask, done, error);
++	}
++
++	return error;
++}
++
++/* put TDI/ARC silicon into EHCI mode */
++static void tdi_reset (struct ehci_hcd *ehci)
++{
++	u32 __iomem	*reg_ptr;
++	u32		tmp;
++
++	reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
++	tmp = ehci_readl(ehci, reg_ptr);
++	tmp |= USBMODE_CM_HC;
++	/* The default byte access to MMR space is LE after
++	 * controller reset. Set the required endian mode
++	 * for transfer buffers to match the host microprocessor
++	 */
++	if (ehci_big_endian_mmio(ehci))
++		tmp |= USBMODE_BE;
++	ehci_writel(ehci, tmp, reg_ptr);
++}
++
++/* reset a non-running (STS_HALT == 1) controller */
++static int ehci_reset (struct ehci_hcd *ehci)
++{
++	int	retval;
++	u32	command = ehci_readl(ehci, &ehci->regs->command);
++
++	/* If the EHCI debug controller is active, special care must be
++	 * taken before and after a host controller reset */
++	if (ehci->debug && !dbgp_reset_prep())
++		ehci->debug = NULL;
++
++	command |= CMD_RESET;
++	dbg_cmd (ehci, "reset", command);
++	ehci_writel(ehci, command, &ehci->regs->command);
++	ehci_to_hcd(ehci)->state = HC_STATE_HALT;
++	ehci->next_statechange = jiffies;
++	retval = handshake (ehci, &ehci->regs->command,
++			    CMD_RESET, 0, 250 * 1000);
++
++	if (ehci->has_hostpc) {
++		ehci_writel(ehci, USBMODE_EX_HC | USBMODE_EX_VBPS,
++			(u32 __iomem *)(((u8 *)ehci->regs) + USBMODE_EX));
++		ehci_writel(ehci, TXFIFO_DEFAULT,
++			(u32 __iomem *)(((u8 *)ehci->regs) + TXFILLTUNING));
++	}
++	if (retval)
++		return retval;
++
++	if (ehci_is_TDI(ehci))
++		tdi_reset (ehci);
++
++	if (ehci->debug)
++		dbgp_external_startup();
++
++	return retval;
++}
++
++/* idle the controller (from running) */
++static void ehci_quiesce (struct ehci_hcd *ehci)
++{
++	u32	temp;
++
++#ifdef DEBUG
++	if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
++		BUG ();
++#endif
++
++	/* wait for any schedule enables/disables to take effect */
++	temp = ehci_readl(ehci, &ehci->regs->command) << 10;
++	temp &= STS_ASS | STS_PSS;
++	if (handshake_on_error_set_halt(ehci, &ehci->regs->status,
++					STS_ASS | STS_PSS, temp, 16 * 125))
++		return;
++
++	/* then disable anything that's still active */
++	temp = ehci_readl(ehci, &ehci->regs->command);
++	temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE);
++	ehci_writel(ehci, temp, &ehci->regs->command);
++
++	/* hardware can take 16 microframes to turn off ... */
++	handshake_on_error_set_halt(ehci, &ehci->regs->status,
++				    STS_ASS | STS_PSS, 0, 16 * 125);
++}
++
++/*-------------------------------------------------------------------------*/
++
++static void end_unlink_async(struct ehci_hcd *ehci);
++static void ehci_work(struct ehci_hcd *ehci);
++
++#include "ehci-hub.c"
++#include "ehci-mem.c"
++#include "ehci-q.c"
++#include "ehci-sched.c"
++
++/*-------------------------------------------------------------------------*/
++
++static void ehci_iaa_watchdog(unsigned long param)
++{
++	struct ehci_hcd		*ehci = (struct ehci_hcd *) param;
++	unsigned long		flags;
++
++	spin_lock_irqsave (&ehci->lock, flags);
++
++	/* Lost IAA irqs wedge things badly; seen first with a vt8235.
++	 * So we need this watchdog, but must protect it against both
++	 * (a) SMP races against real IAA firing and retriggering, and
++	 * (b) clean HC shutdown, when IAA watchdog was pending.
++	 */
++	if (ehci->reclaim
++			&& !timer_pending(&ehci->iaa_watchdog)
++			&& HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
++		u32 cmd, status;
++
++		/* If we get here, IAA is *REALLY* late.  It's barely
++		 * conceivable that the system is so busy that CMD_IAAD
++		 * is still legitimately set, so let's be sure it's
++		 * clear before we read STS_IAA.  (The HC should clear
++		 * CMD_IAAD when it sets STS_IAA.)
++		 */
++		cmd = ehci_readl(ehci, &ehci->regs->command);
++		if (cmd & CMD_IAAD)
++			ehci_writel(ehci, cmd & ~CMD_IAAD,
++					&ehci->regs->command);
++
++		/* If IAA is set here it either legitimately triggered
++		 * before we cleared IAAD above (but _way_ late, so we'll
++		 * still count it as lost) ... or a silicon erratum:
++		 * - VIA seems to set IAA without triggering the IRQ;
++		 * - IAAD potentially cleared without setting IAA.
++		 */
++		status = ehci_readl(ehci, &ehci->regs->status);
++		if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
++			COUNT (ehci->stats.lost_iaa);
++			ehci_writel(ehci, STS_IAA, &ehci->regs->status);
++		}
++
++		ehci_vdbg(ehci, "IAA watchdog: status %x cmd %x\n",
++				status, cmd);
++		end_unlink_async(ehci);
++	}
++
++	spin_unlock_irqrestore(&ehci->lock, flags);
++}
++
++static void ehci_watchdog(unsigned long param)
++{
++	struct ehci_hcd		*ehci = (struct ehci_hcd *) param;
++	unsigned long		flags;
++
++	spin_lock_irqsave(&ehci->lock, flags);
++
++	/* stop async processing after it's idled a bit */
++	if (test_bit (TIMER_ASYNC_OFF, &ehci->actions))
++		start_unlink_async (ehci, ehci->async);
++
++	/* ehci could run by timer, without IRQs ... */
++	ehci_work (ehci);
++
++	spin_unlock_irqrestore (&ehci->lock, flags);
++}
++
++/* On some systems, leaving remote wakeup enabled prevents system shutdown.
++ * The firmware seems to think that powering off is a wakeup event!
++ * This routine turns off remote wakeup and everything else, on all ports.
++ */
++static void ehci_turn_off_all_ports(struct ehci_hcd *ehci)
++{
++	int	port = HCS_N_PORTS(ehci->hcs_params);
++
++	while (port--)
++		ehci_writel(ehci, PORT_RWC_BITS,
++				&ehci->regs->port_status[port]);
++}
++
++/*
++ * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
++ * Should be called with ehci->lock held.
++ */
++static void ehci_silence_controller(struct ehci_hcd *ehci)
++{
++	ehci_halt(ehci);
++	ehci_turn_off_all_ports(ehci);
++
++	/* make BIOS/etc use companion controller during reboot */
++	ehci_writel(ehci, 0, &ehci->regs->configured_flag);
++
++	/* unblock posted writes */
++	ehci_readl(ehci, &ehci->regs->configured_flag);
++}
++
++/* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
++ * This forcibly disables dma and IRQs, helping kexec and other cases
++ * where the next system software may expect clean state.
++ */
++static void ehci_shutdown(struct usb_hcd *hcd)
++{
++	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
++
++	del_timer_sync(&ehci->watchdog);
++	del_timer_sync(&ehci->iaa_watchdog);
++
++	spin_lock_irq(&ehci->lock);
++	ehci_silence_controller(ehci);
++	spin_unlock_irq(&ehci->lock);
++}
++
++static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
++{
++	unsigned port;
++
++	if (!HCS_PPC (ehci->hcs_params))
++		return;
++
++	ehci_dbg (ehci, "...power%s ports...\n", is_on ? "up" : "down");
++	for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; )
++		(void) ehci_hub_control(ehci_to_hcd(ehci),
++				is_on ? SetPortFeature : ClearPortFeature,
++				USB_PORT_FEAT_POWER,
++				port--, NULL, 0);
++	/* Flush those writes */
++	ehci_readl(ehci, &ehci->regs->command);
++	msleep(20);
++}
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * ehci_work is called from some interrupts, timers, and so on.
++ * it calls driver completion functions, after dropping ehci->lock.
++ */
++static void ehci_work (struct ehci_hcd *ehci)
++{
++	timer_action_done (ehci, TIMER_IO_WATCHDOG);
++
++	/* another CPU may drop ehci->lock during a schedule scan while
++	 * it reports urb completions.  this flag guards against bogus
++	 * attempts at re-entrant schedule scanning.
++	 */
++	if (ehci->scanning)
++		return;
++	ehci->scanning = 1;
++	scan_async (ehci);
++	if (ehci->next_uframe != -1)
++		scan_periodic (ehci);
++	ehci->scanning = 0;
++
++	/* the IO watchdog guards against hardware or driver bugs that
++	 * misplace IRQs, and should let us run completely without IRQs.
++	 * such lossage has been observed on both VT6202 and VT8235.
++	 */
++	if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) &&
++			(ehci->async->qh_next.ptr != NULL ||
++			 ehci->periodic_sched != 0))
++		timer_action (ehci, TIMER_IO_WATCHDOG);
++}
++
++/*
++ * Called when the ehci_hcd module is removed.
++ */
++static void ehci_stop (struct usb_hcd *hcd)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++
++	ehci_dbg (ehci, "stop\n");
++
++	/* no more interrupts ... */
++	del_timer_sync (&ehci->watchdog);
++	del_timer_sync(&ehci->iaa_watchdog);
++
++	spin_lock_irq(&ehci->lock);
++	if (HC_IS_RUNNING (hcd->state))
++		ehci_quiesce (ehci);
++
++	ehci_silence_controller(ehci);
++	ehci_reset (ehci);
++	spin_unlock_irq(&ehci->lock);
++
++	remove_companion_file(ehci);
++	remove_debug_files (ehci);
++
++	/* root hub is shut down separately (first, when possible) */
++	spin_lock_irq (&ehci->lock);
++	if (ehci->async)
++		ehci_work (ehci);
++	spin_unlock_irq (&ehci->lock);
++	ehci_mem_cleanup (ehci);
++
++#ifdef	EHCI_STATS
++	ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n",
++		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim,
++		ehci->stats.lost_iaa);
++	ehci_dbg (ehci, "complete %ld unlink %ld\n",
++		ehci->stats.complete, ehci->stats.unlink);
++#endif
++
++	dbg_status (ehci, "ehci_stop completed",
++		    ehci_readl(ehci, &ehci->regs->status));
++}
++
++/* one-time init, only for memory state */
++static int ehci_init(struct usb_hcd *hcd)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
++	u32			temp;
++	int			retval;
++	u32			hcc_params;
++	struct ehci_qh_hw	*hw;
++
++	spin_lock_init(&ehci->lock);
++
++	/*
++	 * keep io watchdog by default, those good HCDs could turn off it later
++	 */
++	ehci->need_io_watchdog = 1;
++	init_timer(&ehci->watchdog);
++	ehci->watchdog.function = ehci_watchdog;
++	ehci->watchdog.data = (unsigned long) ehci;
++
++	init_timer(&ehci->iaa_watchdog);
++	ehci->iaa_watchdog.function = ehci_iaa_watchdog;
++	ehci->iaa_watchdog.data = (unsigned long) ehci;
++
++	/*
++	 * hw default: 1K periodic list heads, one per frame.
++	 * periodic_size can shrink by USBCMD update if hcc_params allows.
++	 */
++	ehci->periodic_size = DEFAULT_I_TDPS;
++	INIT_LIST_HEAD(&ehci->cached_itd_list);
++	INIT_LIST_HEAD(&ehci->cached_sitd_list);
++	if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
++		return retval;
++
++	/* controllers may cache some of the periodic schedule ... */
++	hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
++	if (HCC_ISOC_CACHE(hcc_params))		// full frame cache
++		ehci->i_thresh = 2 + 8;
++	else					// N microframes cached
++		ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params);
++
++	ehci->reclaim = NULL;
++	ehci->next_uframe = -1;
++	ehci->clock_frame = -1;
++
++	/*
++	 * dedicate a qh for the async ring head, since we couldn't unlink
++	 * a 'real' qh without stopping the async schedule [4.8].  use it
++	 * as the 'reclamation list head' too.
++	 * its dummy is used in hw_alt_next of many tds, to prevent the qh
++	 * from automatically advancing to the next td after short reads.
++	 */
++	ehci->async->qh_next.qh = NULL;
++	hw = ehci->async->hw;
++	hw->hw_next = QH_NEXT(ehci, ehci->async->qh_dma);
++	hw->hw_info1 = cpu_to_hc32(ehci, QH_HEAD);
++	hw->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT);
++	hw->hw_qtd_next = EHCI_LIST_END(ehci);
++	ehci->async->qh_state = QH_STATE_LINKED;
++	hw->hw_alt_next = QTD_NEXT(ehci, ehci->async->dummy->qtd_dma);
++
++	/* clear interrupt enables, set irq latency */
++	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
++		log2_irq_thresh = 0;
++	temp = 1 << (16 + log2_irq_thresh);
++	if (HCC_CANPARK(hcc_params)) {
++		/* HW default park == 3, on hardware that supports it (like
++		 * NVidia and ALI silicon), maximizes throughput on the async
++		 * schedule by avoiding QH fetches between transfers.
++		 *
++		 * With fast usb storage devices and NForce2, "park" seems to
++		 * make problems:  throughput reduction (!), data errors...
++		 */
++		if (park) {
++			park = min(park, (unsigned) 3);
++			temp |= CMD_PARK;
++			temp |= park << 8;
++		}
++		ehci_dbg(ehci, "park %d\n", park);
++	}
++	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
++		/* periodic schedule size can be smaller than default */
++		temp &= ~(3 << 2);
++		temp |= (EHCI_TUNE_FLS << 2);
++		switch (EHCI_TUNE_FLS) {
++		case 0: ehci->periodic_size = 1024; break;
++		case 1: ehci->periodic_size = 512; break;
++		case 2: ehci->periodic_size = 256; break;
++		default:	BUG();
++		}
++	}
++	ehci->command = temp;
++
++	/* Accept arbitrarily long scatter-gather lists */
++	hcd->self.sg_tablesize = ~0;
++	return 0;
++}
++
++/* start HC running; it's halted, ehci_init() has been run (once) */
++static int ehci_run (struct usb_hcd *hcd)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++	int			retval;
++	u32			temp;
++	u32			hcc_params;
++
++	hcd->uses_new_polling = 1;
++	hcd->poll_rh = 0;
++
++	/* EHCI spec section 4.1 */
++	if ((retval = ehci_reset(ehci)) != 0) {
++		ehci_mem_cleanup(ehci);
++		return retval;
++	}
++	ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
++	ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next);
++
++	/*
++	 * hcc_params controls whether ehci->regs->segment must (!!!)
++	 * be used; it constrains QH/ITD/SITD and QTD locations.
++	 * pci_pool consistent memory always uses segment zero.
++	 * streaming mappings for I/O buffers, like pci_map_single(),
++	 * can return segments above 4GB, if the device allows.
++	 *
++	 * NOTE:  the dma mask is visible through dma_supported(), so
++	 * drivers can pass this info along ... like NETIF_F_HIGHDMA,
++	 * Scsi_Host.highmem_io, and so forth.  It's readonly to all
++	 * host side drivers though.
++	 */
++	hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
++	if (HCC_64BIT_ADDR(hcc_params)) {
++		ehci_writel(ehci, 0, &ehci->regs->segment);
++#if 0
++// this is deeply broken on almost all architectures
++		if (!dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)))
++			ehci_info(ehci, "enabled 64bit DMA\n");
++#endif
++	}
++
++
++	// Philips, Intel, and maybe others need CMD_RUN before the
++	// root hub will detect new devices (why?); NEC doesn't
++	ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
++	ehci->command |= CMD_RUN;
++	ehci_writel(ehci, ehci->command, &ehci->regs->command);
++	dbg_cmd (ehci, "init", ehci->command);
++
++	/*
++	 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
++	 * are explicitly handed to companion controller(s), so no TT is
++	 * involved with the root hub.  (Except where one is integrated,
++	 * and there's no companion controller unless maybe for USB OTG.)
++	 *
++	 * Turning on the CF flag will transfer ownership of all ports
++	 * from the companions to the EHCI controller.  If any of the
++	 * companions are in the middle of a port reset at the time, it
++	 * could cause trouble.  Write-locking ehci_cf_port_reset_rwsem
++	 * guarantees that no resets are in progress.  After we set CF,
++	 * a short delay lets the hardware catch up; new resets shouldn't
++	 * be started before the port switching actions could complete.
++	 */
++	down_write(&ehci_cf_port_reset_rwsem);
++	hcd->state = HC_STATE_RUNNING;
++	ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
++	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
++	msleep(5);
++	up_write(&ehci_cf_port_reset_rwsem);
++	ehci->last_periodic_enable = ktime_get_real();
++
++	temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
++	ehci_info (ehci,
++		"USB %x.%x started, EHCI %x.%02x%s\n",
++		((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
++		temp >> 8, temp & 0xff,
++		ignore_oc ? ", overcurrent ignored" : "");
++
++	ehci_writel(ehci, INTR_MASK,
++		    &ehci->regs->intr_enable); /* Turn On Interrupts */
++
++	/* GRR this is run-once init(), being done every time the HC starts.
++	 * So long as they're part of class devices, we can't do it init()
++	 * since the class device isn't created that early.
++	 */
++	create_debug_files(ehci);
++	create_companion_file(ehci);
++
++	return 0;
++}
++
++/*-------------------------------------------------------------------------*/
++
++static irqreturn_t ehci_irq (struct usb_hcd *hcd)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++	u32			status, masked_status, pcd_status = 0, cmd;
++	int			bh;
++
++	spin_lock (&ehci->lock);
++
++	status = ehci_readl(ehci, &ehci->regs->status);
++
++	/* e.g. cardbus physical eject */
++	if (status == ~(u32) 0) {
++		ehci_dbg (ehci, "device removed\n");
++		goto dead;
++	}
++
++	masked_status = status & INTR_MASK;
++	if (!masked_status) {		/* irq sharing? */
++		spin_unlock(&ehci->lock);
++		return IRQ_NONE;
++	}
++
++	/* clear (just) interrupts */
++	ehci_writel(ehci, masked_status, &ehci->regs->status);
++	cmd = ehci_readl(ehci, &ehci->regs->command);
++	bh = 0;
++
++#ifdef	VERBOSE_DEBUG
++	/* unrequested/ignored: Frame List Rollover */
++	dbg_status (ehci, "irq", status);
++#endif
++
++	/* INT, ERR, and IAA interrupt rates can be throttled */
++
++	/* normal [4.15.1.2] or error [4.15.1.1] completion */
++	if (likely ((status & (STS_INT|STS_ERR)) != 0)) {
++		if (likely ((status & STS_ERR) == 0))
++			COUNT (ehci->stats.normal);
++		else
++			COUNT (ehci->stats.error);
++		bh = 1;
++	}
++
++	/* complete the unlinking of some qh [4.15.2.3] */
++	if (status & STS_IAA) {
++		/* guard against (alleged) silicon errata */
++		if (cmd & CMD_IAAD) {
++			ehci_writel(ehci, cmd & ~CMD_IAAD,
++					&ehci->regs->command);
++			ehci_dbg(ehci, "IAA with IAAD still set?\n");
++		}
++		if (ehci->reclaim) {
++			COUNT(ehci->stats.reclaim);
++			end_unlink_async(ehci);
++		} else
++			ehci_dbg(ehci, "IAA with nothing to reclaim?\n");
++	}
++
++	/* remote wakeup [4.3.1] */
++	if (status & STS_PCD) {
++		unsigned	i = HCS_N_PORTS (ehci->hcs_params);
++
++		/* kick root hub later */
++		pcd_status = status;
++
++		/* resume root hub? */
++		if (!(cmd & CMD_RUN))
++			usb_hcd_resume_root_hub(hcd);
++
++		while (i--) {
++			int pstatus = ehci_readl(ehci,
++						 &ehci->regs->port_status [i]);
++
++			if (pstatus & PORT_OWNER)
++				continue;
++			if (!(test_bit(i, &ehci->suspended_ports) &&
++					((pstatus & PORT_RESUME) ||
++						!(pstatus & PORT_SUSPEND)) &&
++					(pstatus & PORT_PE) &&
++					ehci->reset_done[i] == 0))
++				continue;
++
++			/* start 20 msec resume signaling from this port,
++			 * and make khubd collect PORT_STAT_C_SUSPEND to
++			 * stop that signaling.  Use 5 ms extra for safety,
++			 * like usb_port_resume() does.
++			 */
++			ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
++			ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
++			mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
++		}
++	}
++
++	/* PCI errors [4.15.2.4] */
++	if (unlikely ((status & STS_FATAL) != 0)) {
++		ehci_err(ehci, "fatal error\n");
++		dbg_cmd(ehci, "fatal", cmd);
++		dbg_status(ehci, "fatal", status);
++		ehci_halt(ehci);
++dead:
++		ehci_reset(ehci);
++		ehci_writel(ehci, 0, &ehci->regs->configured_flag);
++		/* generic layer kills/unlinks all urbs, then
++		 * uses ehci_stop to clean up the rest
++		 */
++		bh = 1;
++	}
++
++	if (bh)
++		ehci_work (ehci);
++	spin_unlock (&ehci->lock);
++	if (pcd_status)
++		usb_hcd_poll_rh_status(hcd);
++	return IRQ_HANDLED;
++}
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * non-error returns are a promise to giveback() the urb later
++ * we drop ownership so next owner (or urb unlink) can get it
++ *
++ * urb + dev is in hcd.self.controller.urb_list
++ * we're queueing TDs onto software and hardware lists
++ *
++ * hcd-specific init for hcpriv hasn't been done yet
++ *
++ * NOTE:  control, bulk, and interrupt share the same code to append TDs
++ * to a (possibly active) QH, and the same QH scanning code.
++ */
++static int ehci_urb_enqueue (
++	struct usb_hcd	*hcd,
++	struct urb	*urb,
++	gfp_t		mem_flags
++) {
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++	struct list_head	qtd_list;
++
++	INIT_LIST_HEAD (&qtd_list);
++
++	switch (usb_pipetype (urb->pipe)) {
++	case PIPE_CONTROL:
++		/* qh_completions() code doesn't handle all the fault cases
++		 * in multi-TD control transfers.  Even 1KB is rare anyway.
++		 */
++		if (urb->transfer_buffer_length > (16 * 1024))
++			return -EMSGSIZE;
++		/* FALLTHROUGH */
++	/* case PIPE_BULK: */
++	default:
++		if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
++			return -ENOMEM;
++		return submit_async(ehci, urb, &qtd_list, mem_flags);
++
++	case PIPE_INTERRUPT:
++		if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
++			return -ENOMEM;
++		return intr_submit(ehci, urb, &qtd_list, mem_flags);
++
++	case PIPE_ISOCHRONOUS:
++		if (urb->dev->speed == USB_SPEED_HIGH)
++			return itd_submit (ehci, urb, mem_flags);
++		else
++			return sitd_submit (ehci, urb, mem_flags);
++	}
++}
++
++static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
++{
++	/* failfast */
++	if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state) && ehci->reclaim)
++		end_unlink_async(ehci);
++
++	/* If the QH isn't linked then there's nothing we can do
++	 * unless we were called during a giveback, in which case
++	 * qh_completions() has to deal with it.
++	 */
++	if (qh->qh_state != QH_STATE_LINKED) {
++		if (qh->qh_state == QH_STATE_COMPLETING)
++			qh->needs_rescan = 1;
++		return;
++	}
++
++	/* defer till later if busy */
++	if (ehci->reclaim) {
++		struct ehci_qh		*last;
++
++		for (last = ehci->reclaim;
++				last->reclaim;
++				last = last->reclaim)
++			continue;
++		qh->qh_state = QH_STATE_UNLINK_WAIT;
++		last->reclaim = qh;
++
++	/* start IAA cycle */
++	} else
++		start_unlink_async (ehci, qh);
++}
++
++/* remove from hardware lists
++ * completions normally happen asynchronously
++ */
++
++static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++	struct ehci_qh		*qh;
++	unsigned long		flags;
++	int			rc;
++
++	spin_lock_irqsave (&ehci->lock, flags);
++	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
++	if (rc)
++		goto done;
++
++	switch (usb_pipetype (urb->pipe)) {
++	// case PIPE_CONTROL:
++	// case PIPE_BULK:
++	default:
++		qh = (struct ehci_qh *) urb->hcpriv;
++		if (!qh)
++			break;
++		switch (qh->qh_state) {
++		case QH_STATE_LINKED:
++		case QH_STATE_COMPLETING:
++			unlink_async(ehci, qh);
++			break;
++		case QH_STATE_UNLINK:
++		case QH_STATE_UNLINK_WAIT:
++			/* already started */
++			break;
++		case QH_STATE_IDLE:
++			/* QH might be waiting for a Clear-TT-Buffer */
++			qh_completions(ehci, qh);
++			break;
++		}
++		break;
++
++	case PIPE_INTERRUPT:
++		qh = (struct ehci_qh *) urb->hcpriv;
++		if (!qh)
++			break;
++		switch (qh->qh_state) {
++		case QH_STATE_LINKED:
++		case QH_STATE_COMPLETING:
++			intr_deschedule (ehci, qh);
++			break;
++		case QH_STATE_IDLE:
++			qh_completions (ehci, qh);
++			break;
++		default:
++			ehci_dbg (ehci, "bogus qh %p state %d\n",
++					qh, qh->qh_state);
++			goto done;
++		}
++		break;
++
++	case PIPE_ISOCHRONOUS:
++		// itd or sitd ...
++
++		// wait till next completion, do it then.
++		// completion irqs can wait up to 1024 msec,
++		break;
++	}
++done:
++	spin_unlock_irqrestore (&ehci->lock, flags);
++	return rc;
++}
++
++/*-------------------------------------------------------------------------*/
++
++// bulk qh holds the data toggle
++
++static void
++ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++	unsigned long		flags;
++	struct ehci_qh		*qh, *tmp;
++
++	/* ASSERT:  any requests/urbs are being unlinked */
++	/* ASSERT:  nobody can be submitting urbs for this any more */
++
++rescan:
++	spin_lock_irqsave (&ehci->lock, flags);
++	qh = ep->hcpriv;
++	if (!qh)
++		goto done;
++
++	/* endpoints can be iso streams.  for now, we don't
++	 * accelerate iso completions ... so spin a while.
++	 */
++	if (qh->hw == NULL) {
++		ehci_vdbg (ehci, "iso delay\n");
++		goto idle_timeout;
++	}
++
++	if (!HC_IS_RUNNING (hcd->state))
++		qh->qh_state = QH_STATE_IDLE;
++	switch (qh->qh_state) {
++	case QH_STATE_LINKED:
++	case QH_STATE_COMPLETING:
++		for (tmp = ehci->async->qh_next.qh;
++				tmp && tmp != qh;
++				tmp = tmp->qh_next.qh)
++			continue;
++		/* periodic qh self-unlinks on empty, and a COMPLETING qh
++		 * may already be unlinked.
++		 */
++		if (tmp)
++			unlink_async(ehci, qh);
++		/* FALL THROUGH */
++	case QH_STATE_UNLINK:		/* wait for hw to finish? */
++	case QH_STATE_UNLINK_WAIT:
++idle_timeout:
++		spin_unlock_irqrestore (&ehci->lock, flags);
++		schedule_timeout_uninterruptible(1);
++		goto rescan;
++	case QH_STATE_IDLE:		/* fully unlinked */
++		if (qh->clearing_tt)
++			goto idle_timeout;
++		if (list_empty (&qh->qtd_list)) {
++			qh_put (qh);
++			break;
++		}
++		/* else FALL THROUGH */
++	default:
++		/* caller was supposed to have unlinked any requests;
++		 * that's not our job.  just leak this memory.
++		 */
++		ehci_err (ehci, "qh %p (#%02x) state %d%s\n",
++			qh, ep->desc.bEndpointAddress, qh->qh_state,
++			list_empty (&qh->qtd_list) ? "" : "(has tds)");
++		break;
++	}
++	ep->hcpriv = NULL;
++done:
++	spin_unlock_irqrestore (&ehci->lock, flags);
++	return;
++}
++
++static void
++ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
++	struct ehci_qh		*qh;
++	int			eptype = usb_endpoint_type(&ep->desc);
++	int			epnum = usb_endpoint_num(&ep->desc);
++	int			is_out = usb_endpoint_dir_out(&ep->desc);
++	unsigned long		flags;
++
++	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
++		return;
++
++	spin_lock_irqsave(&ehci->lock, flags);
++	qh = ep->hcpriv;
++
++	/* For Bulk and Interrupt endpoints we maintain the toggle state
++	 * in the hardware; the toggle bits in udev aren't used at all.
++	 * When an endpoint is reset by usb_clear_halt() we must reset
++	 * the toggle bit in the QH.
++	 */
++	if (qh) {
++		usb_settoggle(qh->dev, epnum, is_out, 0);
++		if (!list_empty(&qh->qtd_list)) {
++			WARN_ONCE(1, "clear_halt for a busy endpoint\n");
++		} else if (qh->qh_state == QH_STATE_LINKED ||
++				qh->qh_state == QH_STATE_COMPLETING) {
++
++			/* The toggle value in the QH can't be updated
++			 * while the QH is active.  Unlink it now;
++			 * re-linking will call qh_refresh().
++			 */
++			if (eptype == USB_ENDPOINT_XFER_BULK)
++				unlink_async(ehci, qh);
++			else
++				intr_deschedule(ehci, qh);
++		}
++	}
++	spin_unlock_irqrestore(&ehci->lock, flags);
++}
++
++static int ehci_get_frame (struct usb_hcd *hcd)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
++	return (ehci_readl(ehci, &ehci->regs->frame_index) >> 3) %
++		ehci->periodic_size;
++}
++
++/*-------------------------------------------------------------------------*/
++
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_AUTHOR (DRIVER_AUTHOR);
++MODULE_LICENSE ("GPL");
++
++#ifdef CONFIG_PCI
++#include "ehci-pci.c"
++#define	PCI_DRIVER		ehci_pci_driver
++#endif
++
++#ifdef CONFIG_USB_EHCI_FSL
++#include "ehci-fsl.c"
++#define	PLATFORM_DRIVER		ehci_fsl_driver
++#endif
++
++#ifdef CONFIG_USB_EHCI_MXC
++#include "ehci-mxc.c"
++#define PLATFORM_DRIVER		ehci_mxc_driver
++#endif
++
++#ifdef CONFIG_SOC_AU1200
++#include "ehci-au1xxx.c"
++#define	PLATFORM_DRIVER		ehci_hcd_au1xxx_driver
++#endif
++
++#ifdef CONFIG_ARCH_OMAP3
++#include "ehci-omap.c"
++#define        PLATFORM_DRIVER         ehci_hcd_omap_driver
++#endif
++
++#ifdef CONFIG_PPC_PS3
++#include "ehci-ps3.c"
++#define	PS3_SYSTEM_BUS_DRIVER	ps3_ehci_driver
++#endif
++
++#ifdef CONFIG_USB_EHCI_HCD_PPC_OF
++#include "ehci-ppc-of.c"
++#define OF_PLATFORM_DRIVER	ehci_hcd_ppc_of_driver
++#endif
++
++#ifdef CONFIG_XPS_USB_HCD_XILINX
++#include "ehci-xilinx-of.c"
++#define XILINX_OF_PLATFORM_DRIVER	ehci_hcd_xilinx_of_driver
++#endif
++
++#ifdef CONFIG_PLAT_ORION
++#include "ehci-orion.c"
++#define	PLATFORM_DRIVER		ehci_orion_driver
++#endif
++
++#ifdef CONFIG_ARCH_IXP4XX
++#include "ehci-ixp4xx.c"
++#define	PLATFORM_DRIVER		ixp4xx_ehci_driver
++#endif
++
++#ifdef CONFIG_USB_W90X900_EHCI
++#include "ehci-w90x900.c"
++#define	PLATFORM_DRIVER		ehci_hcd_w90x900_driver
++#endif
++
++#ifdef CONFIG_ARCH_AT91
++#include "ehci-atmel.c"
++#define	PLATFORM_DRIVER		ehci_atmel_driver
++#endif
++
++#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
++    !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
++    !defined(XILINX_OF_PLATFORM_DRIVER)
++#error "missing bus glue for ehci-hcd"
++#endif
++
++static int __init ehci_hcd_init(void)
++{
++	int retval = 0;
++
++	if (usb_disabled())
++		return -ENODEV;
++
++	printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name);
++	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
++	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
++			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
++		printk(KERN_WARNING "Warning! ehci_hcd should always be loaded"
++				" before uhci_hcd and ohci_hcd, not after\n");
++
++	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
++		 hcd_name,
++		 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
++		 sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
++
++#ifdef DEBUG
++	ehci_debug_root = debugfs_create_dir("ehci", usb_debug_root);
++	if (!ehci_debug_root) {
++		retval = -ENOENT;
++		goto err_debug;
++	}
++#endif
++
++#ifdef PLATFORM_DRIVER
++	retval = platform_driver_register(&PLATFORM_DRIVER);
++	if (retval < 0)
++		goto clean0;
++#endif
++
++#ifdef PCI_DRIVER
++	retval = pci_register_driver(&PCI_DRIVER);
++	if (retval < 0)
++		goto clean1;
++#endif
++
++#ifdef PS3_SYSTEM_BUS_DRIVER
++	retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER);
++	if (retval < 0)
++		goto clean2;
++#endif
++
++#ifdef OF_PLATFORM_DRIVER
++	retval = of_register_platform_driver(&OF_PLATFORM_DRIVER);
++	if (retval < 0)
++		goto clean3;
++#endif
++
++#ifdef XILINX_OF_PLATFORM_DRIVER
++	retval = of_register_platform_driver(&XILINX_OF_PLATFORM_DRIVER);
++	if (retval < 0)
++		goto clean4;
++#endif
++	return retval;
++
++#ifdef XILINX_OF_PLATFORM_DRIVER
++	/* of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); */
++clean4:
++#endif
++#ifdef OF_PLATFORM_DRIVER
++	of_unregister_platform_driver(&OF_PLATFORM_DRIVER);
++clean3:
++#endif
++#ifdef PS3_SYSTEM_BUS_DRIVER
++	ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
++clean2:
++#endif
++#ifdef PCI_DRIVER
++	pci_unregister_driver(&PCI_DRIVER);
++clean1:
++#endif
++#ifdef PLATFORM_DRIVER
++	platform_driver_unregister(&PLATFORM_DRIVER);
++clean0:
++#endif
++#ifdef DEBUG
++	debugfs_remove(ehci_debug_root);
++	ehci_debug_root = NULL;
++err_debug:
++#endif
++	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
++	return retval;
++}
++module_init(ehci_hcd_init);
++
++static void __exit ehci_hcd_cleanup(void)
++{
++#ifdef XILINX_OF_PLATFORM_DRIVER
++	of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER);
++#endif
++#ifdef OF_PLATFORM_DRIVER
++	of_unregister_platform_driver(&OF_PLATFORM_DRIVER);
++#endif
++#ifdef PLATFORM_DRIVER
++	platform_driver_unregister(&PLATFORM_DRIVER);
++#endif
++#ifdef PCI_DRIVER
++	pci_unregister_driver(&PCI_DRIVER);
++#endif
++#ifdef PS3_SYSTEM_BUS_DRIVER
++	ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
++#endif
++#ifdef DEBUG
++	debugfs_remove(ehci_debug_root);
++#endif
++	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
++}
++module_exit(ehci_hcd_cleanup);
++
+diff -rupN linux-2.6.35.11/drivers/usb/host/ehci-str8100.c linux-2.6.35.11-ts7500/drivers/usb/host/ehci-str8100.c
+--- linux-2.6.35.11/drivers/usb/host/ehci-str8100.c	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/drivers/usb/host/ehci-str8100.c	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,190 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#include <linux/platform_device.h>
++#include <asm/arch/hardware.h>
++
++static int str8100_ehci_setup(struct usb_hcd *hcd)
++{
++	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
++	int			retval;
++
++	ehci->caps = hcd->regs;
++	ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase));
++	dbg_hcs_params(ehci, "reset");
++	dbg_hcc_params(ehci, "reset");
++
++	/* cache this readonly data; minimize chip reads */
++	ehci->hcs_params = readl(&ehci->caps->hcs_params);
++
++	retval = ehci_halt(ehci);
++	if (retval)
++		return retval;
++
++	return ehci_init(hcd);
++}
++#ifdef	CONFIG_PM
++//mkl070226: the functionality of suspend/resume is not complete
++static int ehci_suspend (struct usb_hcd *hcd)
++{
++	printk("%s: not implemented, just pass it\n",__FUNCTION__);
++	return 0;
++}
++static int ehci_resume (struct usb_hcd *hcd)
++{
++	printk("%s: not implemented, just pass it\n",__FUNCTION__);
++	return 0;
++}
++#endif
++
++static const struct hc_driver str8100_ehci_driver = {
++	.description =		hcd_name,
++        .product_desc =		"str8100-ehci",
++        .hcd_priv_size =	sizeof(struct ehci_hcd),
++	/*
++	 * generic hardware linkage
++	 */
++	.irq =			ehci_irq,
++	.flags =		HCD_MEMORY | HCD_USB2,
++
++	/*
++	 * basic lifecycle operations
++	 */
++	.reset =		str8100_ehci_setup, 
++	.start =		ehci_run,
++#ifdef	CONFIG_PM
++//mkl070226: the functionality of suspend/resume is not complete
++	.suspend =		ehci_suspend,
++	.resume =		ehci_resume,
++
++	.bus_suspend =		ehci_suspend,
++	.bus_resume =		ehci_resume,
++#endif
++	.stop =			ehci_stop,
++
++	/*
++	 * managing i/o requests and associated device resources
++	 */
++	.urb_enqueue =		ehci_urb_enqueue,
++	.urb_dequeue =		ehci_urb_dequeue,
++	.endpoint_disable =	ehci_endpoint_disable,
++
++	/*
++	 * scheduling support
++	 */
++	.get_frame_number =	ehci_get_frame,
++
++	/*
++	 * root hub support
++	 */
++	.hub_status_data =	ehci_hub_status_data,
++	.hub_control =		ehci_hub_control,
++};
++
++static void  str8100_usb20_config_reg_init(void)
++{
++#if 0
++	__asm__ __volatile__(
++		"mov	r1, #0			\n"
++		"mcr	p15, 0, r1, c7, c5, 0	\n"
++		"mov	r1, #0			\n"
++		"mcr	p15, 0, r1, c7, c14, 0	\n"
++	);
++#endif
++	__raw_writel(0x106, SYSVA_USB20_CONFIG_BASE_ADDR + 0x04);
++	__raw_writel((3 << 5) | 0x20000, SYSVA_USB20_OPERATION_BASE_ADDR + 0x40);
++	mdelay(100);
++}
++
++int str8100_ehci_usb_hcd_probe(const struct hc_driver *driver, 
++	struct platform_device *pdev)
++{
++	struct usb_hcd *hcd;
++	char *name = "str8100-ehci";
++	int retval = 0;
++
++	str8100_usb20_config_reg_init();
++	hcd = usb_create_hcd(driver, &pdev->dev, name);
++	if (!hcd) { 
++		retval = -ENOMEM;
++		return retval;
++	}
++	hcd->regs = (unsigned int *)SYSVA_USB20_OPERATION_BASE_ADDR;
++	hcd->rsrc_start = SYSPA_USB20_OPERATION_BASE_ADDR;
++	hcd->rsrc_len = 4096;
++	hcd->driver = driver;
++	/* scott.usb
++	retval = usb_add_hcd(hcd, INTC_USB20_BIT_INDEX, SA_INTERRUPT);
++	*/
++	retval = usb_add_hcd(hcd, INTC_USB20_BIT_INDEX, IRQF_SHARED);
++	if (retval == 0) {
++		return retval;
++	}
++	printk("str8100 ehci init fail, %d\n", retval);
++	usb_put_hcd(hcd);
++	return retval;
++}
++
++int str8100_ehci_usb_hcd_remove(struct platform_device *pdev)
++{
++	struct usb_hcd *hcd = platform_get_drvdata(pdev);
++	usb_remove_hcd(hcd);
++	usb_put_hcd(hcd);
++	return 0;
++}
++
++static int str8100_ehci_hcd_drv_probe(struct platform_device *pdev)
++{
++	return str8100_ehci_usb_hcd_probe(&str8100_ehci_driver, pdev);
++}
++
++static struct platform_driver str8100_ehci_hcd_driver = {
++	.probe		= str8100_ehci_hcd_drv_probe,
++	.remove		= str8100_ehci_usb_hcd_remove,
++	.driver		= {
++		.owner	= THIS_MODULE,
++		.name	= "str8100-ehci",
++	},
++};
++
++/*
++static int __init str8100_ehci_hcd_init(void)
++{
++	if (usb_disabled())
++		return -ENODEV;
++
++	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
++		hcd_name,
++		sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
++		sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
++
++	return platform_driver_register(&str8100_ehci_hcd_driver);
++}
++module_init(str8100_ehci_hcd_init);
++
++static void __exit str8100_ehci_hcd_cleanup(void)
++{
++	platform_driver_unregister(&str8100_ehci_hcd_driver);
++}
++module_exit(str8100_ehci_hcd_cleanup);
++*/
+diff -rupN linux-2.6.35.11/files.txt linux-2.6.35.11-ts7500/files.txt
+--- linux-2.6.35.11/files.txt	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/files.txt	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,97 @@
++../linux-2.6.24-cavium/arch/arm/mm/Kconfig
++../linux-2.6.24-cavium/arch/arm/boot/compressed/Makefile
++../linux-2.6.24-cavium/arch/arm/boot/compressed/head.S
++../linux-2.6.24-cavium/arch/arm/boot/compressed/misc.c
++../linux-2.6.24-cavium/arch/arm/boot/compressed/head-str8100.S
++../linux-2.6.24-cavium/arch/arm/boot/initrd
++../linux-2.6.24-cavium/arch/arm/mach-str8100/Makefile
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_pm.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_hsdma.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_gpio.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_intc.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_misc.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/Kconfig
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_demo_i2s_wm8772_config.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_setup.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_demo_i2s_config.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_demo_pcm_legerity_config_2phone.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_timer.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_i2s.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_dma.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_demo_dma.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_pci.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_counter.c
++../linux-2.6.24-cavium/arch/arm/mach-str8100/str8100_rtc.c
++../linux-2.6.24-cavium/arch/arm/configs/str8133_defconfig
++../linux-2.6.24-cavium/arch/arm/configs/str9100_defconfig
++../linux-2.6.24-cavium/arch/arm/configs/ts7500_defconfig
++../linux-2.6.24-cavium/arch/arm/Makefile
++../linux-2.6.24-cavium/arch/arm/tools/mach-types
++../linux-2.6.24-cavium/arch/arm/Kconfig
++../linux-2.6.24-cavium/arch/arm/kernel/setup.c
++../linux-2.6.24-cavium/arch/arm/kernel/head.S
++../linux-2.6.24-cavium/drivers/i2c/busses/Makefile
++../linux-2.6.24-cavium/drivers/i2c/busses/Kconfig
++../linux-2.6.24-cavium/drivers/i2c/busses/i2c-str8100.c
++../linux-2.6.24-cavium/drivers/i2c/busses/i2c-str8100.h
++../linux-2.6.24-cavium/drivers/ide/arm/Makefile
++../linux-2.6.24-cavium/drivers/ide/arm/str8100-ide.c
++../linux-2.6.24-cavium/drivers/ide/ide-lib.c
++../linux-2.6.24-cavium/drivers/ide/ide.c
++../linux-2.6.24-cavium/drivers/ide/ide-io.c
++../linux-2.6.24-cavium/drivers/ide/Kconfig
++../linux-2.6.24-cavium/drivers/ide/setup-pci.c
++../linux-2.6.24-cavium/drivers/ide/ide-probe.c
++../linux-2.6.24-cavium/drivers/ide/ide-dma.c
++../linux-2.6.24-cavium/drivers/net/Makefile
++../linux-2.6.24-cavium/drivers/net/e1000/e1000_main.c
++../linux-2.6.24-cavium/drivers/net/Kconfig
++../linux-2.6.24-cavium/drivers/net/str8100/star_nic.c
++../linux-2.6.24-cavium/drivers/net/str8100/Kconfig
++../linux-2.6.24-cavium/drivers/mtd/maps/Makefile
++../linux-2.6.24-cavium/drivers/mtd/maps/Kconfig
++../linux-2.6.24-cavium/drivers/mtd/maps/str8100.c
++../linux-2.6.24-cavium/drivers/pci/setup-bus.c
++../linux-2.6.24-cavium/drivers/spi/Makefile
++../linux-2.6.24-cavium/drivers/spi/spi.c
++../linux-2.6.24-cavium/drivers/spi/spi_bitbang.c
++../linux-2.6.24-cavium/drivers/spi/Kconfig
++../linux-2.6.24-cavium/drivers/spi/spi_str8100.c
++../linux-2.6.24-cavium/drivers/usb/core/buffer.c
++../linux-2.6.24-cavium/drivers/usb/host/ehci-hcd.c
++../linux-2.6.24-cavium/drivers/usb/host/ehci-str8100.c
++../linux-2.6.24-cavium/drivers/usb/host/ohci-hcd.c
++../linux-2.6.24-cavium/drivers/usb/host/ohci-str8100.c
++../linux-2.6.24-cavium/drivers/usb/gadget/Makefile
++../linux-2.6.24-cavium/drivers/usb/gadget/gadget_chips.h
++../linux-2.6.24-cavium/drivers/usb/gadget/file_storage.c
++../linux-2.6.24-cavium/drivers/usb/gadget/Kconfig
++../linux-2.6.24-cavium/drivers/usb/gadget/str8100_udc.c
++../linux-2.6.24-cavium/drivers/usb/gadget/str8100_udc.h
++../linux-2.6.24-cavium/drivers/star/Makefile
++../linux-2.6.24-cavium/drivers/star/str8100/int28handler.c
++../linux-2.6.24-cavium/drivers/star/str8100/Makefile
++../linux-2.6.24-cavium/drivers/star/str8100/crash.c
++../linux-2.6.24-cavium/drivers/star/str8100/str8100_gpio_test.c
++../linux-2.6.24-cavium/drivers/star/str8100/str8100_led.c
++../linux-2.6.24-cavium/drivers/star/str8100/inthandler.c
++../linux-2.6.24-cavium/drivers/watchdog/Makefile
++../linux-2.6.24-cavium/drivers/watchdog/Kconfig
++../linux-2.6.24-cavium/drivers/watchdog/str8100_ebwdt.c
++../linux-2.6.24-cavium/drivers/watchdog/str8100_wdt.c
++../linux-2.6.24-cavium/drivers/serial/Kconfig
++../linux-2.6.24-cavium/drivers/serial/8250_early.c
++../linux-2.6.24-cavium/drivers/serial/8250.c
++../linux-2.6.24-cavium/include/linux/spi/spi.h
++../linux-2.6.24-cavium/include/linux/i2c.h
++../linux-2.6.24-cavium/include/linux/ide.h
++../linux-2.6.24-cavium/include/linux/skbuff.h
++../linux-2.6.24-cavium/include/linux/sysctl.h
++../linux-2.6.24-cavium/include/asm-arm/arch-str8100/star_spi.h
++../linux-2.6.24-cavium/include/asm-arm/arch-str8100/system.h
++../linux-2.6.24-cavium/include/asm-arm/arch-str8100/star_demo_dma.h
++../linux-2.6.24-cavium/include/asm-arm/arch-str8100/memory.h
++../linux-2.6.24-cavium/include/asm-arm/pci.h
++../linux-2.6.24-cavium/kernel/sysctl_check.c
++../linux-2.6.24-cavium/net/core/skbuff.c
++../linux-2.6.24-cavium/sound/drivers/star-i2s-wm8759.c
+diff -rupN linux-2.6.35.11/fs/char_dev.c linux-2.6.35.11-ts7500/fs/char_dev.c
+--- linux-2.6.35.11/fs/char_dev.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/fs/char_dev.c	2011-03-14 11:18:24.000000000 -0400
+@@ -568,6 +568,8 @@ static struct kobject *base_probe(dev_t
+ 
+ void __init chrdev_init(void)
+ {
++   //printk("chrdev_init(), calling kobj_map_init()\n");
++   
+ 	cdev_map = kobj_map_init(base_probe, &chrdevs_lock);
+ 	bdi_init(&directly_mappable_cdev_bdi);
+ }
+diff -rupN linux-2.6.35.11/include/asm/arch/hardware.h linux-2.6.35.11-ts7500/include/asm/arch/hardware.h
+--- linux-2.6.35.11/include/asm/arch/hardware.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/hardware.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,18 @@
++/*
++ *  linux/include/asm-arm/hardware.h
++ *
++ *  Copyright (C) 1996 Russell King
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  Common hardware definitions
++ */
++
++#ifndef __ASM_HARDWARE_H
++#define __ASM_HARDWARE_H
++
++#include <asm/arch/hardware.h>
++
++#endif
+diff -rupN linux-2.6.35.11/include/asm/arch/star_demo_dma.h linux-2.6.35.11-ts7500/include/asm/arch/star_demo_dma.h
+--- linux-2.6.35.11/include/asm/arch/star_demo_dma.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_demo_dma.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,189 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef __DEMO_DMA_H__
++#define __DEMO_DMA_H__
++#include <linux/types.h>	/* size_t */
++#include <linux/interrupt.h>
++#include <linux/module.h>
++
++#include <mach/star_dmac.h>
++
++/*
++ * defines for each channel
++ */
++#define DMAC_CH_DISABLE                0
++#define DMAC_CH_ENABLE                 1
++
++#define DMAC_CH_DST_SEL_M0             0
++#define DMAC_CH_DST_SEL_M1             1
++
++#define DMAC_CH_SRC_SEL_M0             0
++#define DMAC_CH_SRC_SEL_M1             1
++
++#define DMAC_CH_DSTAD_CTL_INC          0
++#define DMAC_CH_DSTAD_CTL_DEC          1
++#define DMAC_CH_DSTAD_CTL_FIX          2
++
++#define DMAC_CH_SRCAD_CTL_INC          0
++#define DMAC_CH_SRCAD_CTL_DEC          1
++#define DMAC_CH_SRCAD_CTL_FIX          2
++
++#define DMAC_CH_MODE_HW_HANDSHAKE      1
++
++#define DMAC_CH_SRC_WIDTH_8_BITS       0
++#define DMAC_CH_SRC_WIDTH_16_BITS      1
++#define DMAC_CH_SRC_WIDTH_32_BITS      2
++
++#define DMAC_CH_DST_WIDTH_8_BITS       0
++#define DMAC_CH_DST_WIDTH_16_BITS      1
++#define DMAC_CH_DST_WIDTH_32_BITS      2
++
++#define DMAC_CH_ABT_TRANSFER           1
++
++#define DMAC_CH_PROT1_PRIVILEGED_MODE  1
++#define DMAC_CH_PROT1_USER_MODE        0
++
++#define DMAC_CH_PROT2_BUFFERABLE       1
++#define DMAC_CH_PROT2_NON_BUFFERABLE   0
++
++#define DMAC_CH_PROT3_CACHEABLE        1
++#define DMAC_CH_PROT3_NON_CACHEABLE    0
++
++#define DMAC_CH_PRI_LEVEL_0            0
++#define DMAC_CH_PRI_LEVEL_1            1
++#define DMAC_CH_PRI_LEVEL_2            2
++#define DMAC_CH_PRI_LEVEL_3            3
++
++#define DMAC_CH_TC_MASK_DISABLE        0
++#define DMAC_CH_TC_MASK_ENABLE         1
++
++#define DMAC_MAX_CHANNEL_NUM           (8)
++
++
++#define DMAC_CH0_ID                    (1 << 0)
++#define DMAC_CH1_ID                    (1 << 1)
++#define DMAC_CH2_ID                    (1 << 2)
++#define DMAC_CH3_ID                    (1 << 3)
++#define DMAC_CH4_ID                    (1 << 4)
++#define DMAC_CH5_ID                    (1 << 5)
++#define DMAC_CH6_ID                    (1 << 6)
++#define DMAC_CH7_ID                    (1 << 7)
++#define DMAC_CH_ID(idx)                (1 << idx) 
++
++#define DMAC_LITTLE_ENDIAN             (0)
++#define DMAC_BIG_ENDIAN                (1)
++
++/* 
++ * DMAC LLP Descriptor
++ */
++typedef struct _DMAC_LLP_CONTROL_    DMAC_LLP_CONTROL_T;
++
++struct _DMAC_LLP_CONTROL_
++{
++//#if (ENDIAN_MODE == LITTLE_ENDIAN)
++#if 1
++    unsigned int    tot_size              : 12;//b11-0
++    unsigned int    reserved_1            : 4; //b15-12    
++    unsigned int    dst_sel               : 1; //b16
++    unsigned int    src_sel               : 1; //b17    
++    unsigned int    dstad_ctl             : 2; //b19-18        
++    unsigned int    srcad_ctl             : 2; //b21-20        
++    unsigned int    dst_width             : 3; //b24-22
++    unsigned int    src_width             : 3; //b27-25
++    unsigned int    tc_status_mask        : 1; //b28
++    unsigned int    reserved_0            : 3; //b31-29
++
++#else
++
++
++    unsigned int    reserved_0            : 3; //b31-29
++    unsigned int    tc_status_mask        : 1; //b28
++    unsigned int    src_width             : 3; //b27-25
++    unsigned int    dst_width             : 3; //b24-22
++    unsigned int    srcad_ctl             : 2; //b21-20
++    unsigned int    dstad_ctl             : 2; //b19-18    
++    unsigned int    src_sel               : 1; //b17
++    unsigned int    dst_sel               : 1; //b16
++    unsigned int    reserved_1            : 4; //b15-12
++    unsigned int    tot_size              : 12;//b11-0
++
++
++#endif
++}; 
++
++
++/* 
++ * DMAC LLP Descriptor object
++ */
++typedef struct _DMAC_LLP_    DMAC_LLP_T;
++struct _DMAC_LLP_
++{
++    unsigned int    SrcAddr;
++    
++    unsigned int    DstAddr;
++    
++    DMAC_LLP_T     *LLP;
++
++    DMAC_LLP_CONTROL_T    Ctrl_TotSize;    
++};
++
++typedef struct _DMAC_HARDWARE_HANDSHAKE_OBJ_    DMAC_HARDWARE_HANDSHAKE_OBJ_T;
++struct _DMAC_HARDWARE_HANDSHAKE_OBJ_
++{
++    unsigned int    src_addr;                     //Src address
++    unsigned int    dst_addr;                     //Dst address
++    unsigned int    src_master;                   //0:AHB0, 1:AHB1
++    unsigned int    dst_master;                   //0:AHB0, 1:AHB1
++    unsigned int    dstad_ctl;                    //0:Incr, 1:Decr, 2:Fix
++    unsigned int    srcad_ctl;                    //0:Incr, 1:Decr, 2:Fix
++    unsigned int    src_width;                    //0:8bits, 1:16bits, 2:32bits
++    unsigned int    dst_width;                    //0:8bits, 1:16bits, 2:32bits
++    unsigned int    transfer_bytes;               //Byte Count to be transferred
++    unsigned int    channel_id;                   //0~7 for Channel0-7 selection
++    unsigned int    channel_num;                   //0~7
++    unsigned int    target_select;                //target ID
++    unsigned int    src_burst_size;               //number of transfer 
++    unsigned int    llp_addr;                     //LLP address
++
++    void * private_data;
++    DMAC_LLP_T* llp_head;
++}; 
++
++
++extern void Hal_Dmac_Configure_DMA_Handshake(DMAC_HARDWARE_HANDSHAKE_OBJ_T *dmac_obj);
++extern irqreturn_t str8100_dma_err_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs);
++//extern int str8100_i2s_init(int sampling_rate);
++extern int str8100_i2s_init(int sampling_rate,u32 i2s_sdata_width, u32 i2s_mode,
++			u32 i2s_tranfer_timing_ctrl, u32 i2s_sclk_mode);
++extern u32 Hal_Dmac_Get_Channel_Transfer_Unit_Number(u32 byte_size, u32 src_width);
++
++extern u32 I2s_Gpio_SSP_Initialise(void);
++extern void I2s_Gpio_SSP_Write(u16);
++extern void I2s_Gpio_SSP_Switch_To_Record_Data(void);
++extern void I2s_Gpio_SSP_Switcg_To_Playback_Data(void);
++
++
++#endif //#ifndef __DEMO_DMA_H__
++
++
+diff -rupN linux-2.6.35.11/include/asm/arch/star_dmac.h linux-2.6.35.11-ts7500/include/asm/arch/star_dmac.h
+--- linux-2.6.35.11/include/asm/arch/star_dmac.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_dmac.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,409 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_DMAC_H_
++#define	_STAR_DMAC_H_
++
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	DMAC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_GDMAC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	DMAC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_GDMAC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	DMAC_INT_STATUS_REG			DMAC_MEM_MAP_VALUE(0x000)
++
++#define	DMAC_INT_TC_STATUS_REG			DMAC_MEM_MAP_VALUE(0x004)
++#define	DMAC_INT_TC_STATUS_CLR_REG		DMAC_MEM_MAP_VALUE(0x008)
++
++#define	DMAC_INT_ERR_STATUS_REG			DMAC_MEM_MAP_VALUE(0x00C)
++#define	DMAC_INT_ERR_STATUS_CLR_REG		DMAC_MEM_MAP_VALUE(0x010)
++
++#define	DMAC_TC_STATUS_REG			DMAC_MEM_MAP_VALUE(0x014)
++#define	DMAC_ERR_STATUS_REG			DMAC_MEM_MAP_VALUE(0x018)
++
++#define	DMAC_CH_ENABLE_STATUS_REG		DMAC_MEM_MAP_VALUE(0x01C)
++#define	DMAC_CH_BUSY_STATUS_REG			DMAC_MEM_MAP_VALUE(0x020)
++
++#define	DMAC_CSR_REG				DMAC_MEM_MAP_VALUE(0x024)
++#define	DMAC_SYNC_REG				DMAC_MEM_MAP_VALUE(0x028)
++
++#define	DMAC_CH0_CSR_REG			DMAC_MEM_MAP_VALUE(0x100)
++#define	DMAC_CH0_CFG_REG			DMAC_MEM_MAP_VALUE(0x104)
++#define	DMAC_CH0_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x108)
++#define	DMAC_CH0_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x10C)
++#define	DMAC_CH0_LLP_REG			DMAC_MEM_MAP_VALUE(0x110)
++#define	DMAC_CH0_SIZE_REG			DMAC_MEM_MAP_VALUE(0x114)
++
++#define	DMAC_CH1_CSR_REG			DMAC_MEM_MAP_VALUE(0x120)
++#define	DMAC_CH1_CFG_REG			DMAC_MEM_MAP_VALUE(0x124)
++#define	DMAC_CH1_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x128)
++#define	DMAC_CH1_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x12C)
++#define	DMAC_CH1_LLP_REG			DMAC_MEM_MAP_VALUE(0x130)
++#define	DMAC_CH1_SIZE_REG			DMAC_MEM_MAP_VALUE(0x134)
++
++#define	DMAC_CH2_CSR_REG			DMAC_MEM_MAP_VALUE(0x140)
++#define	DMAC_CH2_CFG_REG			DMAC_MEM_MAP_VALUE(0x144)
++#define	DMAC_CH2_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x148)
++#define	DMAC_CH2_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x14C)
++#define	DMAC_CH2_LLP_REG			DMAC_MEM_MAP_VALUE(0x150)
++#define	DMAC_CH2_SIZE_REG			DMAC_MEM_MAP_VALUE(0x154)
++
++#define	DMAC_CH3_CSR_REG			DMAC_MEM_MAP_VALUE(0x160)
++#define	DMAC_CH3_CFG_REG			DMAC_MEM_MAP_VALUE(0x164)
++#define	DMAC_CH3_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x168)
++#define	DMAC_CH3_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x16C)
++#define	DMAC_CH3_LLP_REG			DMAC_MEM_MAP_VALUE(0x170)
++#define	DMAC_CH3_SIZE_REG			DMAC_MEM_MAP_VALUE(0x174)
++
++#define	DMAC_CH4_CSR_REG			DMAC_MEM_MAP_VALUE(0x180)
++#define	DMAC_CH4_CFG_REG			DMAC_MEM_MAP_VALUE(0x184)
++#define	DMAC_CH4_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x188)
++#define	DMAC_CH4_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x18C)
++#define	DMAC_CH4_LLP_REG			DMAC_MEM_MAP_VALUE(0x190)
++#define	DMAC_CH4_SIZE_REG			DMAC_MEM_MAP_VALUE(0x194)
++
++#define	DMAC_CH5_CSR_REG			DMAC_MEM_MAP_VALUE(0x1A0)
++#define	DMAC_CH5_CFG_REG			DMAC_MEM_MAP_VALUE(0x1A4)
++#define	DMAC_CH5_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1A8)
++#define	DMAC_CH5_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1AC)
++#define	DMAC_CH5_LLP_REG			DMAC_MEM_MAP_VALUE(0x1B0)
++#define	DMAC_CH5_SIZE_REG			DMAC_MEM_MAP_VALUE(0x1B4)
++
++#define	DMAC_CH6_CSR_REG			DMAC_MEM_MAP_VALUE(0x1C0)
++#define	DMAC_CH6_CFG_REG			DMAC_MEM_MAP_VALUE(0x1C4)
++#define	DMAC_CH6_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1C8)
++#define	DMAC_CH6_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1CC)
++#define	DMAC_CH6_LLP_REG			DMAC_MEM_MAP_VALUE(0x1D0)
++#define	DMAC_CH6_SIZE_REG			DMAC_MEM_MAP_VALUE(0x1D4)
++
++#define	DMAC_CH7_CSR_REG			DMAC_MEM_MAP_VALUE(0x1E0)
++#define	DMAC_CH7_CFG_REG			DMAC_MEM_MAP_VALUE(0x1E4)
++#define	DMAC_CH7_SRC_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1E8)
++#define	DMAC_CH7_DST_ADDR_REG			DMAC_MEM_MAP_VALUE(0x1EC)
++#define	DMAC_CH7_LLP_REG			DMAC_MEM_MAP_VALUE(0x1F0)
++#define	DMAC_CH7_SIZE_REG			DMAC_MEM_MAP_VALUE(0x1F4)
++
++
++#define DMAC_CH0_INT_BIT_INDEX			0
++#define DMAC_CH1_INT_BIT_INDEX			1
++#define DMAC_CH2_INT_BIT_INDEX			2
++#define DMAC_CH3_INT_BIT_INDEX			3
++#define DMAC_CH4_INT_BIT_INDEX			4
++#define DMAC_CH5_INT_BIT_INDEX			5
++#define DMAC_CH6_INT_BIT_INDEX			6
++#define DMAC_CH7_INT_BIT_INDEX			7
++
++#define DMAC_CH0_INT_TC_BIT_INDEX		0
++#define DMAC_CH1_INT_TC_BIT_INDEX		1
++#define DMAC_CH2_INT_TC_BIT_INDEX		2
++#define DMAC_CH3_INT_TC_BIT_INDEX		3
++#define DMAC_CH4_INT_TC_BIT_INDEX		4
++#define DMAC_CH5_INT_TC_BIT_INDEX		5
++#define DMAC_CH6_INT_TC_BIT_INDEX		6
++#define DMAC_CH7_INT_TC_BIT_INDEX		7
++
++#define DMAC_CH0_INT_TC_CLR_BIT_INDEX		0
++#define DMAC_CH1_INT_TC_CLR_BIT_INDEX		1
++#define DMAC_CH2_INT_TC_CLR_BIT_INDEX		2
++#define DMAC_CH3_INT_TC_CLR_BIT_INDEX		3
++#define DMAC_CH4_INT_TC_CLR_BIT_INDEX		4
++#define DMAC_CH5_INT_TC_CLR_BIT_INDEX		5
++#define DMAC_CH6_INT_TC_CLR_BIT_INDEX		6
++#define DMAC_CH7_INT_TC_CLR_BIT_INDEX		7
++
++#define DMAC_CH0_INT_ERR_BIT_INDEX		0
++#define DMAC_CH1_INT_ERR_BIT_INDEX		1
++#define DMAC_CH2_INT_ERR_BIT_INDEX		2
++#define DMAC_CH3_INT_ERR_BIT_INDEX		3
++#define DMAC_CH4_INT_ERR_BIT_INDEX		4
++#define DMAC_CH5_INT_ERR_BIT_INDEX		5
++#define DMAC_CH6_INT_ERR_BIT_INDEX		6
++#define DMAC_CH7_INT_ERR_BIT_INDEX		7
++
++#define DMAC_CH0_INT_ERR_CLR_BIT_INDEX		0
++#define DMAC_CH1_INT_ERR_CLR_BIT_INDEX		1
++#define DMAC_CH2_INT_ERR_CLR_BIT_INDEX		2
++#define DMAC_CH3_INT_ERR_CLR_BIT_INDEX		3
++#define DMAC_CH4_INT_ERR_CLR_BIT_INDEX		4
++#define DMAC_CH5_INT_ERR_CLR_BIT_INDEX		5
++#define DMAC_CH6_INT_ERR_CLR_BIT_INDEX		6
++#define DMAC_CH7_INT_ERR_CLR_BIT_INDEX		7
++
++#define DMAC_CH0_TC_STATUS_BIT_INDEX		0
++#define DMAC_CH1_TC_STATUS_BIT_INDEX		1
++#define DMAC_CH2_TC_STATUS_BIT_INDEX		2
++#define DMAC_CH3_TC_STATUS_BIT_INDEX		3
++#define DMAC_CH4_TC_STATUS_BIT_INDEX		4
++#define DMAC_CH5_TC_STATUS_BIT_INDEX		5
++#define DMAC_CH6_TC_STATUS_BIT_INDEX		6
++#define DMAC_CH7_TC_STATUS_BIT_INDEX		7
++
++#define DMAC_CH0_ERR_STATUS_BIT_INDEX		0
++#define DMAC_CH1_ERR_STATUS_BIT_INDEX		1
++#define DMAC_CH2_ERR_STATUS_BIT_INDEX		2
++#define DMAC_CH3_ERR_STATUS_BIT_INDEX		3
++#define DMAC_CH4_ERR_STATUS_BIT_INDEX		4
++#define DMAC_CH5_ERR_STATUS_BIT_INDEX		5
++#define DMAC_CH6_ERR_STATUS_BIT_INDEX		6
++#define DMAC_CH7_ERR_STATUS_BIT_INDEX		7
++
++#define DMAC_CH0_ENABLE_STATUS_BIT_INDEX	0
++#define DMAC_CH1_ENABLE_STATUS_BIT_INDEX	1
++#define DMAC_CH2_ENABLE_STATUS_BIT_INDEX	2
++#define DMAC_CH3_ENABLE_STATUS_BIT_INDEX	3
++#define DMAC_CH4_ENABLE_STATUS_BIT_INDEX	4
++#define DMAC_CH5_ENABLE_STATUS_BIT_INDEX	5
++#define DMAC_CH6_ENABLE_STATUS_BIT_INDEX	6
++#define DMAC_CH7_ENABLE_STATUS_BIT_INDEX	7
++
++#define DMAC_CH0_BUSY_STATUS_BIT_INDEX		0
++#define DMAC_CH1_BUSY_STATUS_BIT_INDEX		1
++#define DMAC_CH2_BUSY_STATUS_BIT_INDEX		2
++#define DMAC_CH3_BUSY_STATUS_BIT_INDEX		3
++#define DMAC_CH4_BUSY_STATUS_BIT_INDEX		4
++#define DMAC_CH5_BUSY_STATUS_BIT_INDEX		5
++#define DMAC_CH6_BUSY_STATUS_BIT_INDEX		6
++#define DMAC_CH7_BUSY_STATUS_BIT_INDEX		7
++
++#define DMAC_ENABLE_BIT_INDEX			0
++#define DMAC_MASTER0_ENDIAN_BIT_INDEX		1
++#define DMAC_MASTER1_ENDIAN_BIT_INDEX		2
++
++#define DMAC_CH0_SYNC_ENABLE_BIT_INDEX		0
++#define DMAC_CH1_SYNC_ENABLE_BIT_INDEX		1
++#define DMAC_CH2_SYNC_ENABLE_BIT_INDEX		2
++#define DMAC_CH3_SYNC_ENABLE_BIT_INDEX		3
++#define DMAC_CH4_SYNC_ENABLE_BIT_INDEX		4
++#define DMAC_CH5_SYNC_ENABLE_BIT_INDEX		5
++#define DMAC_CH6_SYNC_ENABLE_BIT_INDEX		6
++#define DMAC_CH7_SYNC_ENABLE_BIT_INDEX		7
++
++#define DMAC_CH_INT_TC_MASK_BIT_INDEX		0
++#define DMAC_CH_INT_ERR_MASK_BIT_INDEX		1
++#define DMAC_CH_INT_ABT_MASK_BIT_INDEX		2
++#define DMAC_CH_BUSY_BIT_INDEX			8
++
++#define DMAC_CH_ENABLE_BIT_INDEX		0
++#define DMAC_CH_DST_SEL_BIT_INDEX		1
++#define DMAC_CH_SRC_SEL_BIT_INDEX		2
++#define DMAC_CH_DST_ADDR_CTL_BIT_INDEX		3
++#define DMAC_CH_SRC_ADDR_CTL_BIT_INDEX		5
++#define DMAC_CH_MODE_BIT_INDEX			7
++#define DMAC_CH_DST_WIDTH_BIT_INDEX		8
++#define DMAC_CH_SRC_WIDTH_BIT_INDEX		11
++#define DMAC_CH_ABT_BIT_INDEX			15
++#define DMAC_CH_SRC_BURST_SIZE_BIT_INDEX	16
++#define DMAC_CH_PROTECT_MODE_BIT_INDEX		19
++#define DMAC_CH_PROTECT_BUFFERABLE_BIT_INDEX	20
++#define DMAC_CH_PROTECT_CACHEABLE_BIT_INDEX	21
++#define DMAC_CH_PRIORITY_BIT_INDEX		22
++#define DMAC_CH_HHST_SEL_BIT_INDEX		25
++
++#define DMAC_CH_DST_ADDR_CTL_MASK		0x3
++#define DMAC_CH_DST_ADDR_CTL_INC		0x0
++#define DMAC_CH_DST_ADDR_CTL_DEC		0x1
++#define DMAC_CH_DST_ADDR_CTL_FIXED		0x2
++
++#define DMAC_CH_SRC_ADDR_CTL_MASK		0x3
++#define DMAC_CH_SRC_ADDR_CTL_INC		0x0
++#define DMAC_CH_SRC_ADDR_CTL_DEC		0x1
++#define DMAC_CH_SRC_ADDR_CTL_FIXED		0x2
++
++#define DMAC_CH_MODE_NORMAL			0x0
++#define DMAC_CH_MODE_HANDSHAKE			0x1
++
++#define DMAC_CH_DST_WIDTH_MASK			0x3
++#define DMAC_CH_DST_WIDTH_8BIT			0x0
++#define DMAC_CH_DST_WIDTH_16BIT			0x1
++#define DMAC_CH_DST_WIDTH_32BIT			0x2
++
++#define DMAC_CH_SRC_WIDTH_MASK			0x3
++#define DMAC_CH_SRC_WIDTH_8BIT			0x0
++#define DMAC_CH_SRC_WIDTH_16BIT			0x1
++#define DMAC_CH_SRC_WIDTH_32BIT			0x2
++
++#define DMAC_CH_SRC_BURST_SIZE_MASK		0x8
++#define DMAC_CH_SRC_BURST_SIZE_1		0x0
++#define DMAC_CH_SRC_BURST_SIZE_4		0x1
++#define DMAC_CH_SRC_BURST_SIZE_8		0x2
++#define DMAC_CH_SRC_BURST_SIZE_16		0x3
++#define DMAC_CH_SRC_BURST_SIZE_32		0x4
++#define DMAC_CH_SRC_BURST_SIZE_64		0x5
++#define DMAC_CH_SRC_BURST_SIZE_128		0x6
++#define DMAC_CH_SRC_BURST_SIZE_256		0x7
++
++#define DMAC_CH_PRIORITY_MASK			0x4
++#define DMAC_CH_PRIORITY_0			0x0	/* lowest priority */
++#define DMAC_CH_PRIORITY_1			0x1
++#define DMAC_CH_PRIORITY_2			0x2
++#define DMAC_CH_PRIORITY_3			0x3	/* highest priority */
++
++
++#define	DMAC_CH_CSR_REG(idx)			DMAC_MEM_MAP_VALUE(0x100+0x20*(idx))
++#define	DMAC_CH_CFG_REG(idx)			DMAC_MEM_MAP_VALUE(0x104+0x20*(idx))
++#define	DMAC_CH_SRC_ADDR_REG(idx)		DMAC_MEM_MAP_VALUE(0x108+0x20*(idx))
++#define	DMAC_CH_DST_ADDR_REG(idx)		DMAC_MEM_MAP_VALUE(0x10C+0x20*(idx))
++#define	DMAC_CH_LLP_REG(idx)			DMAC_MEM_MAP_VALUE(0x110+0x20*(idx))
++#define	DMAC_CH_SIZE_REG(idx)			DMAC_MEM_MAP_VALUE(0x114+0x20*(idx))
++
++
++#define	HAL_DMAC_ENABLE_CHANNEL(idx)		((DMAC_CH_CSR_REG(idx)) |= (0x1))
++
++#define	HAL_DMAC_DISABLE_CHANNEL(idx)		((DMAC_CH_CSR_REG(idx)) &= ~(0x1))
++
++#define	HAL_GET_DMAC_CHANNEL_LLP_COUNTER(ch)	((DMAC_CH_CFG_REG(ch) >> 16) & 0xF)
++
++
++/*DMAC HW Hand-shake target ID*/
++#define	DMAC_HW_HAND_SHAKE_PCM_TX0_ID		0x0
++#define	DMAC_HW_HAND_SHAKE_PCM_RX0_ID		0x1
++
++#define	DMAC_HW_HAND_SHAKE_SPI_TX_ID		0x2
++#define	DMAC_HW_HAND_SHAKE_SPI_RX_ID		0x3
++
++#define	DMAC_HW_HAND_SHAKE_I2S_TX_LEFT_ID	0x4
++#define	DMAC_HW_HAND_SHAKE_I2S_TX_RIGHT_ID	0x5
++
++#define	DMAC_HW_HAND_SHAKE_UART0_TX_ID		0x6
++#define	DMAC_HW_HAND_SHAKE_UART0_RX_ID		0x7
++
++#define	DMAC_HW_HAND_SHAKE_UART1_TX_ID		0x8
++#define	DMAC_HW_HAND_SHAKE_UART1_RX_ID		0x9
++
++#define	DMAC_HW_HAND_SHAKE_USBDEV_ID		0xA
++
++#define	DMAC_HW_HAND_SHAKE_I2S_RX_LEFT_ID	0xB
++#define	DMAC_HW_HAND_SHAKE_I2S_RX_RIGHT_ID	0xC
++
++#define	DMAC_HW_HAND_SHAKE_PCM_TX1_ID		0xD
++#define	DMAC_HW_HAND_SHAKE_PCM_RX1_ID		0xE
++
++
++#define MAX_DMA_VEC				32
++
++#define DMAC_DST_SEL_MASTER0			0
++#define DMAC_DST_SEL_MASTER1			1
++#define DMAC_SRC_SEL_MASTER0			0
++#define DMAC_SRC_SEL_MASTER1			1
++
++#define DMAC_RESPONSE_OK			0
++#define DMAC_RESPONSE_ERR			-1
++
++struct dma_xfer;
++typedef struct dma_xfer dma_xfer_t;
++typedef void (*dma_end_io_t)(dma_xfer_t *dma_xfer, int err);
++typedef struct
++{
++	u32	src_addr;	// virtual addr
++	u32	dst_addr;	// virtual addr
++	u32	size;		// bytes
++	u8	dst_sel;
++	u8	src_sel;
++	u8	dst_addr_ctl;
++	u8	src_addr_ctl;
++	u8	dst_width;
++	u8	src_width;
++} dma_vec_t;
++
++struct dma_xfer
++{
++	u8		nr_vec;
++	dma_vec_t	vec[MAX_DMA_VEC];
++	dma_end_io_t	dma_end_io;
++	void		*private;
++};
++
++/*
++ * DMAC	LLP Descriptor
++ */
++typedef struct
++{
++	u32	src_addr;			// physical addr
++	u32	dst_addr;			// physical addr
++	u32	llp;
++	u32	tot_size	: 12;
++	u32	reserved0	: 4;
++	u32	dst_sel		: 1;
++	u32	src_sel		: 1;
++	u32	dst_addr_ctl	: 2;
++	u32	src_addr_ctl	: 2;
++	u32	dst_width	: 3;
++	u32	src_width	: 3;
++	u32	tc_mask		: 1;
++	u32	reserved1	: 3;
++} __attribute__((packed)) dma_llp_descr_t;
++
++#define HAL_DMAC_ENABLE() \
++	    ((DMAC_CSR_REG) |= (1<<DMAC_ENABLE_BIT_INDEX))
++
++
++#define HAL_DMAC_DISABLE() \
++	    ((DMAC_CSR_REG) &= ~(1<<DMAC_ENABLE_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER0_BIG_ENDIAN() \
++	    ((DMAC_CSR_REG) |= (1<<DMAC_MASTER0_ENDIAN_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER0_LITTLE_ENDIAN() \
++	    ((DMAC_CSR_REG) &= ~(1<<DMAC_MASTER0_ENDIAN_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER1_BIG_ENDIAN() \
++	    ((DMAC_CSR_REG) |= (1<<DMAC_MASTER1_ENDIAN_BIT_INDEX))
++
++
++#define HAL_DMAC_SET_MASTER1_LITTLE_ENDIAN() \
++	    ((DMAC_CSR_REG) &= ~(1<<DMAC_MASTER1_ENDIAN_BIT_INDEX))
++
++#define HAL_DMAC_READ_ERROR_ABORT_INTERRUPT_STATUS(err_abt_status) \
++	    ((err_abt_status) = (DMAC_INT_ERR_STATUS_REG))
++
++
++#define HAL_DMAC_CLEAR_ERROR_ABORT_INTERRUPT_STATUS(err_abt_status) \
++	    ((DMAC_INT_ERR_STATUS_CLR_REG) = (err_abt_status))
++
++
++#define HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(tc_status) \
++	    ((tc_status) = (DMAC_INT_TC_STATUS_REG) & 0xFF)
++
++
++#define HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(tc_status) \
++	    ((DMAC_INT_TC_STATUS_CLR_REG) = (tc_status) & 0xFF)
++
++
++
++
++
++
++#endif	// end of #ifndef _STAR_DMAC_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_gpio.h linux-2.6.35.11-ts7500/include/asm/arch/star_gpio.h
+--- linux-2.6.35.11/include/asm/arch/star_gpio.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_gpio.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,327 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_GPIO_H_
++#define	_STAR_GPIO_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	GPIOA_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSPA_GPIOA_BASE_ADDR + reg_offset)))
++#define	GPIOB_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSPA_GPIOB_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	GPIOA_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSVA_GPIOA_BASE_ADDR + reg_offset)))
++#define	GPIOB_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSVA_GPIOB_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * For GPIO Set	A
++ */
++#define	GPIOA_DATA_OUTPUT_REG			GPIOA_MEM_MAP_VALUE(0x00)
++#define	GPIOA_DATA_INPUT_REG			GPIOA_MEM_MAP_VALUE(0x04)
++#define	GPIOA_DIRECTION_REG			GPIOA_MEM_MAP_VALUE(0x08)
++
++#define	GPIOA_DATA_BIT_SET_REG			GPIOA_MEM_MAP_VALUE(0x10)
++#define	GPIOA_DATA_BIT_CLEAR_REG		GPIOA_MEM_MAP_VALUE(0x14)
++
++#define	GPIOA_INTERRUPT_ENABLE_REG		GPIOA_MEM_MAP_VALUE(0x20)
++#define	GPIOA_INTERRUPT_RAW_STATUS_REG		GPIOA_MEM_MAP_VALUE(0x24)
++#define	GPIOA_INTERRUPT_MASKED_STATUS_REG	GPIOA_MEM_MAP_VALUE(0x28)
++#define	GPIOA_INTERRUPT_MASK_REG		GPIOA_MEM_MAP_VALUE(0x2C)
++#define	GPIOA_INTERRUPT_CLEAR_REG		GPIOA_MEM_MAP_VALUE(0x30)
++#define	GPIOA_INTERRUPT_TRIGGER_METHOD_REG	GPIOA_MEM_MAP_VALUE(0x34)
++#define	GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG	GPIOA_MEM_MAP_VALUE(0x38)
++#define	GPIOA_INTERRUPT_TRIGGER_TYPE_REG	GPIOA_MEM_MAP_VALUE(0x3C)
++
++#define	GPIOA_BOUNCE_ENABLE_REG			GPIOA_MEM_MAP_VALUE(0x40)
++#define	GPIOA_BOUNCE_CLOCK_PRESCALE_REG		GPIOA_MEM_MAP_VALUE(0x44)
++
++
++/*
++ * For GPIO Set	B
++ */
++#define	GPIOB_DATA_OUTPUT_REG			GPIOB_MEM_MAP_VALUE(0x00)
++#define	GPIOB_DATA_INPUT_REG			GPIOB_MEM_MAP_VALUE(0x04)
++#define	GPIOB_DIRECTION_REG			GPIOB_MEM_MAP_VALUE(0x08)
++
++#define	GPIOB_DATA_BIT_SET_REG			GPIOB_MEM_MAP_VALUE(0x10)
++#define	GPIOB_DATA_BIT_CLEAR_REG		GPIOB_MEM_MAP_VALUE(0x14)
++
++#define	GPIOB_INTERRUPT_ENABLE_REG		GPIOB_MEM_MAP_VALUE(0x20)
++#define	GPIOB_INTERRUPT_RAW_STATUS_REG		GPIOB_MEM_MAP_VALUE(0x24)
++#define	GPIOB_INTERRUPT_MASKED_STATUS_REG	GPIOB_MEM_MAP_VALUE(0x28)
++#define	GPIOB_INTERRUPT_MASK_REG		GPIOB_MEM_MAP_VALUE(0x2C)
++#define	GPIOB_INTERRUPT_CLEAR_REG		GPIOB_MEM_MAP_VALUE(0x30)
++#define	GPIOB_INTERRUPT_TRIGGER_METHOD_REG	GPIOB_MEM_MAP_VALUE(0x34)
++#define	GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG	GPIOB_MEM_MAP_VALUE(0x38)
++#define	GPIOB_INTERRUPT_TRIGGER_TYPE_REG	GPIOB_MEM_MAP_VALUE(0x3C)
++
++#define	GPIOB_BOUNCE_ENABLE_REG			GPIOB_MEM_MAP_VALUE(0x40)
++#define	GPIOB_BOUNCE_CLOCK_PRESCALE_REG		GPIOB_MEM_MAP_VALUE(0x44)
++
++
++/*
++ * define constant macros
++ */
++
++#define	MAX_GPIO_PINS		(32)
++
++#define	GPIO_0_MASK		(1 << 0)
++#define	GPIO_1_MASK		(1 << 1)
++#define	GPIO_2_MASK		(1 << 2)
++#define	GPIO_3_MASK		(1 << 3)
++#define	GPIO_4_MASK		(1 << 4)
++#define	GPIO_5_MASK		(1 << 5)
++#define	GPIO_6_MASK		(1 << 6)
++#define	GPIO_7_MASK		(1 << 7)
++#define	GPIO_8_MASK		(1 << 8)
++#define	GPIO_9_MASK		(1 << 9)
++#define	GPIO_10_MASK		(1 << 10)
++#define	GPIO_11_MASK		(1 << 11)
++#define	GPIO_12_MASK		(1 << 12)
++#define	GPIO_13_MASK		(1 << 13)
++#define	GPIO_14_MASK		(1 << 14)
++#define	GPIO_15_MASK		(1 << 15)
++#define	GPIO_16_MASK		(1 << 16)
++#define	GPIO_17_MASK		(1 << 17)
++#define	GPIO_18_MASK		(1 << 18)
++#define	GPIO_19_MASK		(1 << 19)
++#define	GPIO_20_MASK		(1 << 20)
++#define	GPIO_21_MASK		(1 << 21)
++#define	GPIO_22_MASK		(1 << 22)
++#define	GPIO_23_MASK		(1 << 23)
++#define	GPIO_24_MASK		(1 << 24)
++#define	GPIO_25_MASK		(1 << 25)
++#define	GPIO_26_MASK		(1 << 26)
++#define	GPIO_27_MASK		(1 << 27)
++#define	GPIO_28_MASK		(1 << 28)
++#define	GPIO_29_MASK		(1 << 29)
++#define	GPIO_30_MASK		(1 << 30)
++#define	GPIO_31_MASK		(1 << 31)
++
++
++/*
++ * macro declarations for GPIO Set A
++ */
++#define	HAL_GPIOA_READ_DATA_OUT_STATUS(data_out_state) \
++    ((data_out_state) =	(GPIOA_DATA_OUTPUT_REG))
++
++#define	HAL_GPIOA_READ_DATA_IN_STATUS(data_in_state) \
++    ((data_in_state) = (GPIOA_DATA_INPUT_REG))
++
++#define	HAL_GPIOA_SET_DIRECTION_OUTPUT(gpio_index) \
++    ((GPIOA_DIRECTION_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_SET_DIRECTION_INPUT(gpio_index) \
++    ((GPIOA_DIRECTION_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_SET_DATA_OUT_HIGH(gpio_index)	\
++    ((GPIOA_DATA_BIT_SET_REG) =	(gpio_index))
++
++#define	HAL_GPIOA_SET_DATA_OUT_LOW(gpio_index) \
++    ((GPIOA_DATA_BIT_CLEAR_REG)	= (gpio_index))
++
++#define	HAL_GPIOA_ENABLE_INTERRUPT(gpio_index) \
++    ((GPIOA_INTERRUPT_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_DISABLE_INTERRUPT(gpio_index)	\
++    ((GPIOA_INTERRUPT_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_READ_INTERRUPT_RAW_STATUS(raw_state) \
++    ((raw_state) = (GPIOA_INTERRUPT_RAW_STATUS_REG))
++
++#define	HAL_GPIOA_READ_INTERRUPT_MASKED_STATUS(masked_raw_state) \
++    ((masked_raw_state)	= (GPIOA_INTERRUPT_MASKED_STATUS_REG))
++
++#define	HAL_GPIOA_DISABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOA_INTERRUPT_MASK_REG)	&= ~(gpio_index))
++
++#define	HAL_GPIOA_ENABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOA_INTERRUPT_MASK_REG)	|= (gpio_index))
++
++#define	HAL_GPIOA_CLEAR_INTERRUPT(gpio_index) \
++    ((GPIOA_INTERRUPT_CLEAR_REG) = (gpio_index))
++
++#define	HAL_GPIOA_SET_INTERRUPT_EDGE_TRIGGER_MODE(gpio_index) \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_SET_INTERRUPT_LEVEL_TRIGGER_MODE(gpio_index) \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_SET_INTERRUPT_SINGLE_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_BOTH_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) |= (gpio_index));	\
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_SINGLE_RISING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_SINGLE_FALLING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_HIGH_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOA_SET_INTERRUPT_LOW_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOA_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOA_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOA_ENABLE_BOUNCE(gpio_index) \
++    ((GPIOA_BOUNCE_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOA_DISABLE_BOUNCE(gpio_index) \
++    ((GPIOA_BOUNCE_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOA_READ_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((prescale_ratio) =	((GPIOA_BOUNCE_CLOCK_PRESCALE_REG) & 0x0000FFFF))
++
++#define	HAL_GPIOA_WRITE_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((GPIOA_BOUNCE_CLOCK_PRESCALE_REG) = (prescale_ratio & 0x0000FFFF))
++
++
++
++/*
++ * macro declarations for GPIO Set B
++ */
++#define	HAL_GPIOB_READ_DATA_OUT_STATUS(data_out_state) \
++    ((data_out_state) =	(GPIOB_DATA_OUTPUT_REG))
++
++#define	HAL_GPIOB_READ_DATA_IN_STATUS(data_in_state) \
++    ((data_in_state) = (GPIOB_DATA_INPUT_REG))
++
++#define	HAL_GPIOB_SET_DIRECTION_OUTPUT(gpio_index) \
++    ((GPIOB_DIRECTION_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_SET_DIRECTION_INPUT(gpio_index) \
++    ((GPIOB_DIRECTION_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_SET_DATA_OUT_HIGH(gpio_index)	\
++    ((GPIOB_DATA_BIT_SET_REG) =	(gpio_index))
++
++#define	HAL_GPIOB_SET_DATA_OUT_LOW(gpio_index) \
++    ((GPIOB_DATA_BIT_CLEAR_REG)	= (gpio_index))
++
++#define	HAL_GPIOB_ENABLE_INTERRUPT(gpio_index) \
++    ((GPIOB_INTERRUPT_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_DISABLE_INTERRUPT(gpio_index)	\
++    ((GPIOB_INTERRUPT_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_READ_INTERRUPT_RAW_STATUS(raw_state) \
++    ((raw_state) = (GPIOB_INTERRUPT_RAW_STATUS_REG))
++
++#define	HAL_GPIOB_READ_INTERRUPT_MASKED_STATUS(masked_raw_state) \
++    ((masked_raw_state)	= (GPIOB_INTERRUPT_MASKED_STATUS_REG))
++
++#define	HAL_GPIOB_DISABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOB_INTERRUPT_MASK_REG)	&= ~(gpio_index))
++
++#define	HAL_GPIOB_ENABLE_INTERRUPT_MASK(gpio_index) \
++    ((GPIOB_INTERRUPT_MASK_REG)	|= (gpio_index))
++
++#define	HAL_GPIOB_CLEAR_INTERRUPT(gpio_index) \
++    ((GPIOB_INTERRUPT_CLEAR_REG) = (gpio_index))
++
++#define	HAL_GPIOB_SET_INTERRUPT_EDGE_TRIGGER_MODE(gpio_index) \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_SET_INTERRUPT_LEVEL_TRIGGER_MODE(gpio_index) \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_SET_INTERRUPT_SINGLE_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_BOTH_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) |= (gpio_index));	\
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_SINGLE_RISING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_SINGLE_FALLING_EDGE_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_BOTH_EDGES_REG) &= ~(gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_HIGH_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	&= ~(gpio_index)); \
++}
++
++#define	HAL_GPIOB_SET_INTERRUPT_LOW_LEVEL_TRIGGER_MODE(gpio_index) \
++{ \
++    ((GPIOB_INTERRUPT_TRIGGER_METHOD_REG) |= (gpio_index)); \
++    ((GPIOB_INTERRUPT_TRIGGER_TYPE_REG)	|= (gpio_index)); \
++}
++
++#define	HAL_GPIOB_ENABLE_BOUNCE(gpio_index) \
++    ((GPIOB_BOUNCE_ENABLE_REG) |= (gpio_index))
++
++#define	HAL_GPIOB_DISABLE_BOUNCE(gpio_index) \
++    ((GPIOB_BOUNCE_ENABLE_REG) &= ~(gpio_index))
++
++#define	HAL_GPIOB_READ_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((prescale_ratio) =	((GPIOB_BOUNCE_CLOCK_PRESCALE_REG) & 0x0000FFFF))
++
++#define	HAL_GPIOB_WRITE_BOUNCE_PRESCALE_RATIO(prescale_ratio) \
++    ((GPIOB_BOUNCE_CLOCK_PRESCALE_REG) = (prescale_ratio & 0x0000FFFF))
++
++
++#endif	// end of _STAR_GPIO_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_hsdmac.h linux-2.6.35.11-ts7500/include/asm/arch/star_hsdmac.h
+--- linux-2.6.35.11/include/asm/arch/star_hsdmac.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_hsdmac.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,106 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_HSDMAC_H_
++#define	_STAR_HSDMAC_H_
++
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	HSDMAC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSPA_MISC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	HSDMAC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSVA_MISC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	HSDMAC_CONTROL_STATUS_REG		HSDMAC_MEM_MAP_VALUE(0x040)
++
++#define	HSDMAC_MASTER0_ADDR_REG			HSDMAC_MEM_MAP_VALUE(0x050)
++
++#define	HSDMAC_MASTER1_ADDR_REG			HSDMAC_MEM_MAP_VALUE(0x054)
++
++#define	HSDMAC_LLP_REG				HSDMAC_MEM_MAP_VALUE(0x058)
++
++#define	HSDMAC_TOT_SIZE_REG			HSDMAC_MEM_MAP_VALUE(0x05C)
++
++
++#define	HAL_GET_HSDMAC_LLP_COUNTER		((HSDMAC_CONTROL_STATUS_REG >> 8) & 0xF)
++
++#define	HAL_HSDMAC_ENABLE()			((HSDMAC_CONTROL_STATUS_REG) |= (0x1))
++
++#define	HAL_HSDMAC_DISABLE()			((HSDMAC_CONTROL_STATUS_REG) &= ~(0x1))
++
++
++#define HSDMAC_MASTER0_TO_MASTER1		0
++#define HSDMAC_MASTER1_TO_MASTER0		1
++
++#define HSDMAC_RESPONSE_OK			0
++#define HSDMAC_RESPONSE_ERR			-1
++
++#define MAX_HSDMA_VEC 				32
++
++#define MAX_HSDMA_XFER_SIZE			(0xFFF << 2)
++
++struct hsdma_xfer;
++typedef struct hsdma_xfer hsdma_xfer_t;
++typedef void (*hsdma_end_io_t)(hsdma_xfer_t *hsdma_xfer, int err);
++typedef struct
++{
++	u8	data_direction;
++	u32	src_addr; // virtual
++	u32	dst_addr; // virtual
++	u32	size; // bytes
++} __attribute__((packed)) hsdma_vec_t;
++
++struct hsdma_xfer
++{
++	u8			nr_vec;
++	hsdma_vec_t		vec[MAX_HSDMA_VEC];
++	hsdma_end_io_t		hsdma_end_io;
++	void			*private;
++};
++
++/*
++ * HSDMAC LLP Descriptor object
++ */
++typedef struct
++{
++	u32	src_addr; // physical
++	u32	dst_addr; // physical
++	u32	llp;
++	u32	tot_size	: 16;//b15-b0
++	u32	reserved0	: 12;//b27-b16
++	u32	tc_mask		: 1; //b28
++	u32	data_direction	: 1; //b29
++	u32	reserved1	: 2; //b31-30
++} __attribute__((packed)) hsdma_llp_descr_t;
++
++
++#endif	// end of #ifndef _STAR_HSDMAC_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_i2c.h linux-2.6.35.11-ts7500/include/asm/arch/star_i2c.h
+--- linux-2.6.35.11/include/asm/arch/star_i2c.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_i2c.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,69 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_I2C_H_
++#define _STAR_I2C_H_
++
++#include <mach/star_sys_memory_map.h>
++
++#define I2C_MEM_MAP_ADDR(reg_offset)          (SYSVA_I2C_BASE_ADDR + reg_offset) 
++#define I2C_MEM_MAP_VALUE(reg_offset)         (*((unsigned int volatile *)I2C_MEM_MAP_ADDR(reg_offset)))
++
++#define I2C_CONTROLLER_REG_ADDR               I2C_MEM_MAP_ADDR(0x20)
++#define I2C_TIME_OUT_REG_ADDR                 I2C_MEM_MAP_ADDR(0x24)
++#define I2C_SLAVE_ADDRESS_REG_ADDR            I2C_MEM_MAP_ADDR(0x28)
++#define I2C_WRITE_DATA_REG_ADDR               I2C_MEM_MAP_ADDR(0x2C)
++#define I2C_READ_DATA_REG_ADDR                I2C_MEM_MAP_ADDR(0x30)
++#define I2C_INTERRUPT_STATUS_REG_ADDR         I2C_MEM_MAP_ADDR(0x34)
++#define I2C_INTERRUPT_ENABLE_REG_ADDR         I2C_MEM_MAP_ADDR(0x38)
++
++#define I2C_CONTROLLER_REG                    I2C_MEM_MAP_VALUE(0x20)
++#define I2C_TIME_OUT_REG                      I2C_MEM_MAP_VALUE(0x24)
++#define I2C_SLAVE_ADDRESS_REG                 I2C_MEM_MAP_VALUE(0x28)
++#define I2C_WRITE_DATA_REG                    I2C_MEM_MAP_VALUE(0x2C)
++#define I2C_READ_DATA_REG                     I2C_MEM_MAP_VALUE(0x30)
++#define I2C_INTERRUPT_STATUS_REG              I2C_MEM_MAP_VALUE(0x34)
++#define I2C_INTERRUPT_ENABLE_REG              I2C_MEM_MAP_VALUE(0x38)
++
++#define I2C_READ_ONLY_CMD      (0)
++#define I2C_WRITE_ONLY_CMD     (1)
++#define I2C_WRITE_READ_CMD     (2)
++#define I2C_READ_WRITE_CMD     (3)
++
++#define I2C_DATA_LEN_1_BYTE    (0)
++#define I2C_DATA_LEN_2_BYTE    (1)
++#define I2C_DATA_LEN_3_BYTE    (2)
++#define I2C_DATA_LEN_4_BYTE    (3)
++
++#define I2C_BUS_ERROR_FLAG     (0x1)
++#define I2C_ACTION_DONE_FLAG   (0x2)
++
++#define HAL_I2C_ENABLE_I2C()          (I2C_CONTROLLER_REG) |= ((unsigned int)0x1 << 31); 
++#define HAL_I2C_DISABLE_I2C()         (I2C_CONTROLLER_REG) &= ~((unsigned int)0x1 << 31);
++#define HAL_I2C_ENABLE_DATA_SWAP()    (I2C_CONTROLLER_REG) |= (0x1 << 24); 
++#define HAL_I2C_DISABLE_DATA_SWAP()   (I2C_CONTROLLER_REG) &= ~(0x1 << 24); 
++#define HAL_I2C_START_TRANSFER()      (I2C_CONTROLLER_REG) |= (0x1 << 6); 
++#define HAL_I2C_STOP_TRANSFER()       (I2C_CONTROLLER_REG) &= ~(0x1 << 6); 
++
++#endif
++
+diff -rupN linux-2.6.35.11/include/asm/arch/star_i2s.h linux-2.6.35.11-ts7500/include/asm/arch/star_i2s.h
+--- linux-2.6.35.11/include/asm/arch/star_i2s.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_i2s.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,176 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_I2S_H_
++#define _STAR_I2S_H_
++
++/******************************************************************************
++ * MODULE NAME:    star_i2s.h
++ * PROJECT CODE:   Orion
++ * DESCRIPTION:    
++ * MAINTAINER:     MJLIU
++ * DATE:           15 September 2005
++ *
++ * SOURCE CONTROL: 
++ *
++ * REVISION HISTORY:
++ *     15 September 2005  -  MJLIU	- Initial Version v1.0
++ *
++ *
++ * SOURCE:
++ * ISSUES:
++ * NOTES TO USERS:
++ ******************************************************************************/
++
++#include <mach/star_sys_memory_map.h>
++
++#define I2S_MEM_MAP_ADDR(reg_offset)          (SYSVA_I2S_BASE_ADDR + reg_offset) 
++#define I2S_MEM_MAP_VALUE(reg_offset)         (*((unsigned int volatile *)I2S_MEM_MAP_ADDR(reg_offset)))
++
++//#define I2S_BASE_ADDR                         (SYS_I2S_BASE_ADDR)
++
++
++/*
++ * define access macros
++ */
++#define I2S_CONFIGURATION_REG_ADDR            I2S_MEM_MAP_ADDR(0xC0)
++#define I2S_RIGHT_TRANSMIT_DATA_REG_ADDR      I2S_MEM_MAP_ADDR(0xC4)
++#define I2S_LEFT_TRANSMIT_DATA_REG_ADDR       I2S_MEM_MAP_ADDR(0xC8)
++#define I2S_RIGHT_RECEIVE_DATA_REG_ADDR       I2S_MEM_MAP_ADDR(0xCC)
++#define I2S_LEFT_RECEIVE_DATA_REG_ADDR        I2S_MEM_MAP_ADDR(0xD0)
++#define I2S_INTERRUPT_STATUS_REG_ADDR         I2S_MEM_MAP_ADDR(0xD4)
++#define I2S_INTERRUPT_ENABLE_REG_ADDR         I2S_MEM_MAP_ADDR(0xD8)
++
++#define I2S_CONFIGURATION_REG                 I2S_MEM_MAP_VALUE(0xC0)
++#define I2S_RIGHT_TRANSMIT_DATA_REG           I2S_MEM_MAP_VALUE(0xC4)
++#define I2S_LEFT_TRANSMIT_DATA_REG            I2S_MEM_MAP_VALUE(0xC8)
++#define I2S_RIGHT_RECEIVE_DATA_REG            I2S_MEM_MAP_VALUE(0xCC)
++#define I2S_LEFT_RECEIVE_DATA_REG             I2S_MEM_MAP_VALUE(0xD0)
++#define I2S_INTERRUPT_STATUS_REG              I2S_MEM_MAP_VALUE(0xD4)
++#define I2S_INTERRUPT_ENABLE_REG              I2S_MEM_MAP_VALUE(0xD8)
++
++
++/*
++ * define constants macros
++ */
++#define I2S_DATA_16_BIT             (0)
++#define I2S_DATA_32_BIT             (1)
++
++#define I2S_RXBF_R_FULL_FLAG        (0x01)
++#define I2S_TXBF_R_EMPTY_FLAG       (0x02)
++#define I2S_RXBF_L_FULL_FLAG        (0x04)
++#define I2S_TXBF_L_EMPTY_FLAG       (0x08)
++
++#define I2S_RXBF_R_OR_FLAG          (0x10)
++#define I2S_TXBF_R_UR_FLAG          (0x20)
++#define I2S_RXBF_L_OR_FLAG          (0x40)
++#define I2S_TXBF_L_UR_FLAG          (0x80)
++
++
++#define I2S_MASTER_MODE             (1)
++#define I2S_SLAVE_MODE              (0)
++
++#define I2S_I2S_MODE                (1)
++#define I2S_RJF_MODE                (2)
++#define I2S_LJF_MODE                (3)
++
++#define I2S_CLOCK_CONTINUOUS_MODE   (0)
++#define I2S_CLOCK_256S_MODE         (1)
++
++
++#define I2S_WS_RATE_32KHZ           (1)    /* 8.192 MHz */
++#define I2S_WS_RATE_44_1KHZ         (2)    /* 11.2896 MHz */
++#define I2S_WS_RATE_48KHZ           (3)    /* 12.288 MHz */
++
++
++/*
++ * define data structure
++ */
++#if 0
++typedef struct _I2S_OBJECT_    I2S_OBJECT_T;
++
++struct _I2S_OBJECT_
++{
++    u_int32          config;
++    u_int32          interrupt_config;
++
++
++    /* 
++     * For interrupt setting
++     */
++    INTC_OBJECT_T    intc_obj;
++};
++
++
++/*
++ * function declarations
++ */
++void    Hal_I2s_Initialize(I2S_OBJECT_T *);
++#endif
++
++
++/*
++ * macro declarations
++ */
++#define HAL_I2S_ENABLE_I2S() \
++{ \
++    (I2S_CONFIGURATION_REG) |= ((u32)0x1 << 31); \
++}
++
++#define HAL_I2S_DISABLE_I2S() \
++{ \
++    (I2S_CONFIGURATION_REG) &= ~((u32)0x1 << 31); \
++}
++
++#define HAL_I2S_ENABLE_DATA_SWAP() \
++{ \
++    (I2S_CONFIGURATION_REG) |= (0x1 << 24); \
++}
++
++#define HAL_I2S_DISABLE_DATA_SWAP() \
++{ \
++    (I2S_CONFIGURATION_REG) &= ~(0x1 << 24); \
++}
++
++#define HAL_I2S_DISABLE_LEFT_CHANNEL_TRANSMIT_BUFFER_UNDERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_TXBF_L_UR_FLAG); \
++}
++
++#define HAL_I2S_DISABLE_RIGHT_CHANNEL_TRANSMIT_BUFFER_UNDERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_TXBF_R_UR_FLAG); \
++}
++
++#define HAL_I2S_DISABLE_LEFT_CHANNEL_RECEIVE_BUFFER_OVERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_RXBF_L_OR_FLAG); \
++}
++
++#define HAL_I2S_DISABLE_RIGHT_CHANNEL_RECEIVE_BUFFER_OVERRUN_INTERRUPT() \
++{ \
++    (I2S_INTERRUPT_ENABLE_REG) &= ~(I2S_RXBF_R_OR_FLAG); \
++}
++
++
++#endif  // end of #ifndef _STAR_I2S_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_ide.h linux-2.6.35.11-ts7500/include/asm/arch/star_ide.h
+--- linux-2.6.35.11/include/asm/arch/star_ide.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_ide.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,245 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_IDE_H_
++#define	_STAR_IDE_H_
++
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	IDE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_IDE_CONTROLLER_BASE_ADDR + reg_offset)))
++#define	IDE_BUS_MEM_MAP_VALUE(reg_offset)	(*((u8 volatile *)(SYSPA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#define IDE_DATA_MEM_MAP_VALUE(reg_offset)	(*((u16 volatile *)(SYSPA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	IDE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_IDE_CONTROLLER_BASE_ADDR + reg_offset)))
++#define	IDE_BUS_MEM_MAP_VALUE(reg_offset)	(*((u8 volatile *)(SYSVA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#define IDE_DATA_MEM_MAP_VALUE(reg_offset)	(*((u16 volatile *)(SYSVA_IDE_DEVICE_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * IDE Controller Registers
++ */
++#define IDE_PIO_CONTROL_REG			IDE_MEM_MAP_VALUE(0x00)
++#define IDE_DRIVE0_PIO_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x04)
++#define IDE_DRIVE1_PIO_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x08)
++#define IDE_DRIVE0_DMA_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x0C)
++#define IDE_DRIVE1_DMA_TIMING_CONFIG_REG	IDE_MEM_MAP_VALUE(0x10)
++#define IDE_UDMA_TIMING_CONFIG_REG		IDE_MEM_MAP_VALUE(0x14)
++#define IDE_DMA_UDMA_CONTROL_REG		IDE_MEM_MAP_VALUE(0x18)
++#define IDE_STATUS_CONTROL_REG			IDE_MEM_MAP_VALUE(0x1C)
++#define IDE_BUS_MASTER_DTP_REG			IDE_MEM_MAP_VALUE(0x20)
++#define IDE_FAST_PATH_ACCESS_WINDOW_REG		IDE_MEM_MAP_VALUE(0x24)
++#define IDE_FAST_PATH_DMA_BURST_SIZE_REG	IDE_MEM_MAP_VALUE(0x28)
++
++
++/*
++ * IDE Command Block Registers
++ */
++#define _IDE_DATA_REG				IDE_DATA_MEM_MAP_VALUE(0x20)
++#define _IDE_ERROR_REG				IDE_BUS_MEM_MAP_VALUE(0x24)
++#define _IDE_FEATURES_REG			IDE_BUS_MEM_MAP_VALUE(0x24)
++#define _IDE_SECTOR_COUNT_REG			IDE_BUS_MEM_MAP_VALUE(0x28)
++#define _IDE_LBA_LOW_REG			IDE_BUS_MEM_MAP_VALUE(0x2C)
++#define _IDE_LBA_MID_REG			IDE_BUS_MEM_MAP_VALUE(0x30)
++#define _IDE_LBA_HIGH_REG			IDE_BUS_MEM_MAP_VALUE(0x34)
++#define _IDE_DEVICE_REG				IDE_BUS_MEM_MAP_VALUE(0x38)
++#define _IDE_COMMAND_REG			IDE_BUS_MEM_MAP_VALUE(0x3C)
++#define _IDE_STATUS_REG				IDE_BUS_MEM_MAP_VALUE(0x3C)
++
++
++/*
++ * IDE Control Block Registers
++ */
++#define IDE_DEVICE_CONTROL_REG			IDE_BUS_MEM_MAP_VALUE(0x40)
++#define IDE_ALTERNATE_STATUS_REG		IDE_BUS_MEM_MAP_VALUE(0x40)
++
++
++#define IDE_CD					(0x01)
++#define IDE_IO					(0x02)
++#define IDE_REL					(0x04)
++#define IDE_OVL					(0x02)
++#define IDE_BSY					(0x80)
++#define IDE_DRQ					(0x08)
++#define IDE_SERV				(0x10)
++#define IDE_DMRD				(0x20)
++#define IDE_ERR					(0x01)
++#define IDE_SRST				(0x04)
++
++/*
++ * macro declarations for IDE Controller
++ */
++#define HAL_IDE_DRIVE0_IORDY_SAMPLE_ENABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) |= (0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE0_IORDY_SAMPLE_DISABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE1_IORDY_SAMPLE_ENABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) |= (0x1 << 1); \
++}
++
++#define HAL_IDE_DRIVE1_IORDY_SAMPLE_DISABLE() \
++{ \
++    (IDE_PIO_CONTROL_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_IDE_DRIVE0_UDMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 0); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 2); \
++}
++
++#define HAL_IDE_DRIVE0_UDMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE1_UDMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 1); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_IDE_DRIVE1_UDMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_IDE_DRIVE0_DMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 2); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_IDE_DRIVE0_DMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 2); \
++}
++
++#define HAL_IDE_DRIVE1_DMA_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 3); \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_IDE_TO_USB_FAST_PATH_ENABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) |= (0x1 << 4); \
++}
++
++#define HAL_IDE_TO_USB_FAST_PATH_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 4); \
++}
++
++#define HAL_IDE_DRIVE1_DMA_DISABLE() \
++{ \
++    (IDE_DMA_UDMA_CONTROL_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_IDE_DMA_UDMA_START() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1); \
++}
++
++#define HAL_IDE_DMA_UDMA_STOP() \
++{ \
++    (IDE_STATUS_CONTROL_REG) &= ~(0x1); \
++}
++
++#define HAL_IDE_CLEAR_PRD_INTERRUPT_STATUS() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 2); \
++}
++
++#define HAL_IDE_CLEAR_INTRQ_INTERRUPT_STATUS() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 1); \
++}
++
++#define HAL_IDE_HOST_TRANSFER_WRITE_OUT() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 3); \
++}
++
++#define HAL_IDE_HOST_TRANSFER_READ_IN() \
++{ \
++    (IDE_STATUS_CONTROL_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_IDE_MASK_PRD_INTERRUPT() \
++{ \
++    (IDE_STATUS_CONTROL_REG) |= (0x1 << 6); \
++}
++
++#define HAL_IDE_UNMASK_PRD_INTERRUPT() \
++{ \
++    (IDE_STATUS_CONTROL_REG) &= ~(0x1 << 6); \
++}
++
++#define HAL_IDE_SET_DESCRIPTOR_TABLE_POINTER(dtp) \
++{ \
++    (IDE_BUS_MASTER_DTP_REG) = (dtp); \
++}
++
++#define HAL_IDE_SET_FAST_PATH_ACCESS_WINDOW(fp_access_window) \
++{ \
++    (IDE_FAST_PATH_ACCESS_WINDOW_REG) = (fp_access_window); \
++}
++
++/*
++ * macro declarations for IDE Device
++ */
++#define HAL_IDE_SELECT_DEVICE_0() \
++{ \
++    (_IDE_DEVICE_REG) = 0; \
++}
++
++#define HAL_IDE_SELECT_DEVICE_1() \
++{ \
++    (_IDE_DEVICE_REG) = (0x1 << 4); \
++}
++
++#define HAL_IDE_ENABLE_DEVICE_INTRQ() \
++{ \
++    (IDE_DEVICE_CONTROL_REG) = (0); \
++}
++
++#define HAL_IDE_DISABLE_DEVICE_INTRQ() \
++{ \
++    (IDE_DEVICE_CONTROL_REG) = (0x2); \
++}
++
++
++#endif  // end of #ifndef _STAR_IDE_H_
++
+diff -rupN linux-2.6.35.11/include/asm/arch/star_intc.h linux-2.6.35.11-ts7500/include/asm/arch/star_intc.h
+--- linux-2.6.35.11/include/asm/arch/star_intc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_intc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,328 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_INTC_H_
++#define	_STAR_INTC_H_
++
++
++//#include <mach/star_sys_memory_map.h>
++#include <mach/star_sys_memory_map.h>
++
++#if defined(__UBOOT__)
++#define	INTC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_VIC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	INTC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_VIC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	INTC_INTERRUPT_RAW_STATUS_REG		INTC_MEM_MAP_VALUE(0x000)
++#define	INTC_EDGE_INTERRUPT_SOURCE_CLEAR_REG	INTC_MEM_MAP_VALUE(0x004)
++#define	INTC_INTERRUPT_MASK_REG			INTC_MEM_MAP_VALUE(0x008)
++#define	INTC_INTERRUPT_MASK_CLEAR_REG		INTC_MEM_MAP_VALUE(0x00C)
++#define	INTC_INTERRUPT_TRIGGER_MODE_REG		INTC_MEM_MAP_VALUE(0x010)
++#define	INTC_INTERRUPT_TRIGGER_LEVEL_REG	INTC_MEM_MAP_VALUE(0x014)
++#define	INTC_FIQ_SELECT_REG			INTC_MEM_MAP_VALUE(0x018)
++#define	INTC_IRQ_STATUS_REG			INTC_MEM_MAP_VALUE(0x01C)
++#define	INTC_FIQ_STATUS_REG			INTC_MEM_MAP_VALUE(0x020)
++#define	INTC_SOFTWARE_INTERRUPT_REG		INTC_MEM_MAP_VALUE(0x024)
++#define	INTC_SOFTWARE_INTERRUPT_CLEAR_REG	INTC_MEM_MAP_VALUE(0x028)
++#define	INTC_SOFTWARE_PRIORITY_MASK_REG		INTC_MEM_MAP_VALUE(0x02C)
++#define	INTC_POWER_MANAGEMENT_INTERRUPT_REG	INTC_MEM_MAP_VALUE(0x034)
++
++#define	INTC_VECTOR_ADDRESS_0_REG		INTC_MEM_MAP_VALUE(0x040)
++#define	INTC_VECTOR_ADDRESS_1_REG		INTC_MEM_MAP_VALUE(0x044)
++#define	INTC_VECTOR_ADDRESS_2_REG		INTC_MEM_MAP_VALUE(0x048)
++#define	INTC_VECTOR_ADDRESS_3_REG		INTC_MEM_MAP_VALUE(0x04C)
++#define	INTC_VECTOR_ADDRESS_4_REG		INTC_MEM_MAP_VALUE(0x050)
++#define	INTC_VECTOR_ADDRESS_5_REG		INTC_MEM_MAP_VALUE(0x054)
++#define	INTC_VECTOR_ADDRESS_6_REG		INTC_MEM_MAP_VALUE(0x058)
++#define	INTC_VECTOR_ADDRESS_7_REG		INTC_MEM_MAP_VALUE(0x05C)
++#define	INTC_VECTOR_ADDRESS_8_REG		INTC_MEM_MAP_VALUE(0x060)
++#define	INTC_VECTOR_ADDRESS_9_REG		INTC_MEM_MAP_VALUE(0x064)
++#define	INTC_VECTOR_ADDRESS_10_REG		INTC_MEM_MAP_VALUE(0x068)
++#define	INTC_VECTOR_ADDRESS_11_REG		INTC_MEM_MAP_VALUE(0x06C)
++#define	INTC_VECTOR_ADDRESS_12_REG		INTC_MEM_MAP_VALUE(0x070)
++#define	INTC_VECTOR_ADDRESS_13_REG		INTC_MEM_MAP_VALUE(0x074)
++#define	INTC_VECTOR_ADDRESS_14_REG		INTC_MEM_MAP_VALUE(0x078)
++#define	INTC_VECTOR_ADDRESS_15_REG		INTC_MEM_MAP_VALUE(0x07C)
++#define	INTC_VECTOR_ADDRESS_16_REG		INTC_MEM_MAP_VALUE(0x080)
++#define	INTC_VECTOR_ADDRESS_17_REG		INTC_MEM_MAP_VALUE(0x084)
++#define	INTC_VECTOR_ADDRESS_18_REG		INTC_MEM_MAP_VALUE(0x088)
++#define	INTC_VECTOR_ADDRESS_19_REG		INTC_MEM_MAP_VALUE(0x08C)
++#define	INTC_VECTOR_ADDRESS_20_REG		INTC_MEM_MAP_VALUE(0x090)
++#define	INTC_VECTOR_ADDRESS_21_REG		INTC_MEM_MAP_VALUE(0x094)
++#define	INTC_VECTOR_ADDRESS_22_REG		INTC_MEM_MAP_VALUE(0x098)
++#define	INTC_VECTOR_ADDRESS_23_REG		INTC_MEM_MAP_VALUE(0x09C)
++#define	INTC_VECTOR_ADDRESS_24_REG		INTC_MEM_MAP_VALUE(0x0A0)
++#define	INTC_VECTOR_ADDRESS_25_REG		INTC_MEM_MAP_VALUE(0x0A4)
++#define	INTC_VECTOR_ADDRESS_26_REG		INTC_MEM_MAP_VALUE(0x0A8)
++#define	INTC_VECTOR_ADDRESS_27_REG		INTC_MEM_MAP_VALUE(0x0AC)
++#define	INTC_VECTOR_ADDRESS_28_REG		INTC_MEM_MAP_VALUE(0x0B0)
++#define	INTC_VECTOR_ADDRESS_29_REG		INTC_MEM_MAP_VALUE(0x0B4)
++#define	INTC_VECTOR_ADDRESS_30_REG		INTC_MEM_MAP_VALUE(0x0B8)
++#define	INTC_VECTOR_ADDRESS_31_REG		INTC_MEM_MAP_VALUE(0x0BC)
++
++#define	INTC_INTERRUPT_PRIORITY_0_REG		INTC_MEM_MAP_VALUE(0x0C0)
++#define	INTC_INTERRUPT_PRIORITY_1_REG		INTC_MEM_MAP_VALUE(0x0C4)
++#define	INTC_INTERRUPT_PRIORITY_2_REG		INTC_MEM_MAP_VALUE(0x0C8)
++#define	INTC_INTERRUPT_PRIORITY_3_REG		INTC_MEM_MAP_VALUE(0x0CC)
++#define	INTC_INTERRUPT_PRIORITY_4_REG		INTC_MEM_MAP_VALUE(0x0D0)
++#define	INTC_INTERRUPT_PRIORITY_5_REG		INTC_MEM_MAP_VALUE(0x0D4)
++#define	INTC_INTERRUPT_PRIORITY_6_REG		INTC_MEM_MAP_VALUE(0x0D8)
++#define	INTC_INTERRUPT_PRIORITY_7_REG		INTC_MEM_MAP_VALUE(0x0DC)
++#define	INTC_INTERRUPT_PRIORITY_8_REG		INTC_MEM_MAP_VALUE(0x0E0)
++#define	INTC_INTERRUPT_PRIORITY_9_REG		INTC_MEM_MAP_VALUE(0x0E4)
++#define	INTC_INTERRUPT_PRIORITY_10_REG		INTC_MEM_MAP_VALUE(0x0E8)
++#define	INTC_INTERRUPT_PRIORITY_11_REG		INTC_MEM_MAP_VALUE(0x0EC)
++#define	INTC_INTERRUPT_PRIORITY_12_REG		INTC_MEM_MAP_VALUE(0x0F0)
++#define	INTC_INTERRUPT_PRIORITY_13_REG		INTC_MEM_MAP_VALUE(0x0F4)
++#define	INTC_INTERRUPT_PRIORITY_14_REG		INTC_MEM_MAP_VALUE(0x0F8)
++#define	INTC_INTERRUPT_PRIORITY_15_REG		INTC_MEM_MAP_VALUE(0x0FC)
++#define	INTC_INTERRUPT_PRIORITY_16_REG		INTC_MEM_MAP_VALUE(0x100)
++#define	INTC_INTERRUPT_PRIORITY_17_REG		INTC_MEM_MAP_VALUE(0x104)
++#define	INTC_INTERRUPT_PRIORITY_18_REG		INTC_MEM_MAP_VALUE(0x108)
++#define	INTC_INTERRUPT_PRIORITY_19_REG		INTC_MEM_MAP_VALUE(0x10C)
++#define	INTC_INTERRUPT_PRIORITY_20_REG		INTC_MEM_MAP_VALUE(0x110)
++#define	INTC_INTERRUPT_PRIORITY_21_REG		INTC_MEM_MAP_VALUE(0x114)
++#define	INTC_INTERRUPT_PRIORITY_22_REG		INTC_MEM_MAP_VALUE(0x118)
++#define	INTC_INTERRUPT_PRIORITY_23_REG		INTC_MEM_MAP_VALUE(0x11C)
++#define	INTC_INTERRUPT_PRIORITY_24_REG		INTC_MEM_MAP_VALUE(0x120)
++#define	INTC_INTERRUPT_PRIORITY_25_REG		INTC_MEM_MAP_VALUE(0x124)
++#define	INTC_INTERRUPT_PRIORITY_26_REG		INTC_MEM_MAP_VALUE(0x128)
++#define	INTC_INTERRUPT_PRIORITY_27_REG		INTC_MEM_MAP_VALUE(0x12C)
++#define	INTC_INTERRUPT_PRIORITY_28_REG		INTC_MEM_MAP_VALUE(0x130)
++#define	INTC_INTERRUPT_PRIORITY_29_REG		INTC_MEM_MAP_VALUE(0x134)
++#define	INTC_INTERRUPT_PRIORITY_30_REG		INTC_MEM_MAP_VALUE(0x138)
++#define	INTC_INTERRUPT_PRIORITY_31_REG		INTC_MEM_MAP_VALUE(0x13C)
++
++#define	INTC_IRQ_VECTOR_ADDRESS_REG		INTC_MEM_MAP_VALUE(0x140)
++
++#define	INTC_VECTOR_INTERRUPT_ENABLE_REG	INTC_MEM_MAP_VALUE(0x144)
++
++
++
++/*
++ * define constants macros
++ */
++#define	INTC_TIMER1_BIT_INDEX			(0)
++#define	INTC_TIMER2_BIT_INDEX			(1)
++
++#define	INTC_CLOCK_SCALE_BIT_INDEX		(2)
++
++#define	INTC_WATCHDOG_TIMER_BIT_INDEX		(3)
++
++#define	INTC_GPIO_EXTERNAL_INT_BIT_INDEX	(4)
++
++#define	INTC_PCI_INTA_BIT_INDEX			(5)
++#define	INTC_PCI_INTB_BIT_INDEX			(6)
++#define	INTC_PCI_BROKEN_BIT_INDEX		(7)
++#define	INTC_PCI_AHB2BRIDGE_BIT_INDEX		(8)
++
++#define	INTC_UART0_BIT_INDEX			(9)
++#define	INTC_UART1_BIT_INDEX			(10)
++
++#define	INTC_GDMAC_TC_BIT_INDEX			(11)
++#define	INTC_GDMAC_ERROR_BIT_INDEX		(12)
++
++#define	INTC_PCMCIA_BRIDGE_BIT_INDEX		(13)
++
++#define	INTC_RTC_BIT_INDEX			(14)
++
++#define	INTC_PCM_BIT_INDEX			(15)
++
++#define	INTC_USB20_DEVICE_BIT_INDEX		(16)
++
++#define	INTC_IDE_BIT_INDEX			(17)
++
++#define	INTC_NIC_STATUS_BIT_INDEX		(18)
++#define	INTC_NIC_TXTC_BIT_INDEX			(19)
++#define	INTC_NIC_RXRC_BIT_INDEX			(20)
++#define	INTC_NIC_TXQE_BIT_INDEX			(21)
++#define	INTC_NIC_RXQF_BIT_INDEX			(22)
++
++#define	INTC_USB11_BIT_INDEX			(23)
++#define	INTC_USB20_BIT_INDEX			(24)
++
++#define	INTC_I2S_BIT_INDEX			(25)
++#define	INTC_SPI_BIT_INDEX			(26)
++#define	INTC_I2C_BIT_INDEX			(27)
++
++#define	INTC_USB_DEVICE_VBUS_BIT_INDEX		(28)
++
++#define	INTC_EXT_INT29_BIT_INDEX		(29)
++#define	INTC_EXT_INT30_BIT_INDEX		(30)
++#define	INTC_HSDMAC_BIT_INDEX			(31)
++
++
++/*
++ * define interrupt types
++ */
++#define	INTC_IRQ_INTERRUPT			(0)
++#define	INTC_FIQ_INTERRUPT			(1)
++
++/*
++ * define interrupt trigger mode
++ */
++#define	INTC_LEVEL_TRIGGER			(0)
++#define	INTC_EDGE_TRIGGER			(1)
++
++/*
++ * define rising/falling edge for edge trigger mode
++ */
++#define	INTC_RISING_EDGE			(0)
++#define	INTC_FALLING_EDGE			(1)
++
++/*
++ * define active High/Low for level trigger mode
++ */
++#define	INTC_ACTIVE_HIGH			(0)
++#define	INTC_ACTIVE_LOW				(1)
++
++/*
++ * macro declarations
++ */
++#define	HAL_INTC_READ_INTERRUPT_RAW_STATUS(int_raw_status) \
++{ \
++    (int_raw_status) = (INTC_INTERRUPT_RAW_STATUS_REG);	\
++}
++
++
++#define	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(source_bit_index)	\
++{ \
++    (INTC_EDGE_INTERRUPT_SOURCE_CLEAR_REG) = (1	<< source_bit_index); \
++}
++
++
++#define	HAL_INTC_READ_INTERRUPT_MASK(int_mask) \
++{ \
++    (int_mask) = (INTC_INTERRUPT_MASK_REG); \
++}
++
++
++#define	HAL_INTC_WRITE_INTERRUPT_MASK(int_mask)	\
++{ \
++    (INTC_INTERRUPT_MASK_REG) =	(int_mask); \
++}
++
++
++#define	HAL_INTC_DISABLE_INTERRUPT_SOURCE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_MASK_REG) =	(1 << source_bit_index); \
++}
++
++
++#define	HAL_INTC_ENABLE_INTERRUPT_SOURCE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_MASK_CLEAR_REG) = (1 << source_bit_index); \
++}
++
++
++#define	HAL_INTC_SET_EDGE_TRIGGER_MODE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_MODE_REG) |= (1 << source_bit_index);\
++}
++
++
++#define	HAL_INTC_SET_LEVEL_TRIGGER_MODE(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_MODE_REG) &= (~(1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_SET_RISING_EDGE_TRIGGER_LEVEL(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) &= (~(1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_SET_FALLING_EDGE_TRIGGER_LEVEL(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) |= (1 <<	source_bit_index); \
++}
++
++
++#define	HAL_INTC_SET_ACTIVE_HIGH_TRIGGER_LEVEL(source_bit_index) \
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) &= (~(1 << source_bit_index));\
++}
++
++
++#define	HAL_INTC_SET_ACTIVE_LOW_TRIGGER_LEVEL(source_bit_index)	\
++{ \
++    (INTC_INTERRUPT_TRIGGER_LEVEL_REG) |= ((1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_ASSIGN_INTERRUPT_TO_IRQ(source_bit_index) \
++{ \
++    (INTC_FIQ_SELECT_REG) &= (~(1 << source_bit_index)); \
++}
++
++
++#define	HAL_INTC_ASSIGN_INTERRUPT_TO_FIQ(source_bit_index) \
++{ \
++    (INTC_FIQ_SELECT_REG) |= (1	<< source_bit_index); \
++}
++
++
++#define	HAL_INTC_READ_IRQ_STATUS(int_irq_status) \
++{ \
++    (int_irq_status) = (INTC_IRQ_STATUS_REG); \
++}
++
++
++#define	HAL_INTC_READ_FIQ_STATUS(int_fiq_status) \
++{ \
++    (int_fiq_status) = (INTC_FIQ_STATUS_REG); \
++}
++
++
++#define	HAL_INTC_READ_SOFTWARE_INTERRUPT(software_interrupt) \
++{ \
++    (software_interrupt) = (INTC_SOFTWARE_INTERRUPT_REG); \
++}
++
++
++#define	HAL_INTC_ENABLE_SOFTWARE_INTERRUPT(source_bit_index) \
++{ \
++    (INTC_SOFTWARE_INTERRUPT_REG) = (1 << source_bit_index); \
++}
++
++
++#define	HAL_INTC_CLEAR_SOFTWARE_INTERRUPT(source_bit_index) \
++{ \
++    (INTC_SOFTWARE_INTERRUPT_CLEAR_REG)	= (1 <<	source_bit_index); \
++}
++
++
++#define	HAL_INTC_SELECT_INTERRUPT_SOURCE_FOR_SLEEP_WAKEUP(source_bit_index) \
++{ \
++    (INTC_POWER_MANAGEMENT_INTERRUPT_REG) = (1 << source_bit_index); \
++}
++
++#endif	// end of #ifndef _STAR_INTC_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_misc.h linux-2.6.35.11-ts7500/include/asm/arch/star_misc.h
+--- linux-2.6.35.11/include/asm/arch/star_misc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_misc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,402 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_MISC_H_
++#define	_STAR_MISC_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	MISC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_MISC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	MISC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_MISC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	MISC_MEMORY_REMAP_REG				MISC_MEM_MAP_VALUE(0x00)
++#define	MISC_CHIP_CONFIG_REG				MISC_MEM_MAP_VALUE(0x04)
++#define	MISC_DEBUG_PROBE_DATA_REG			MISC_MEM_MAP_VALUE(0x08)
++#define	MISC_DEBUG_PROBE_SELECTION_REG			MISC_MEM_MAP_VALUE(0x0C)
++#define	MISC_PCI_CONTROL_BROKEN_MASK_REG		MISC_MEM_MAP_VALUE(0x10)
++#define	MISC_PCI_BROKEN_STATUS_REG			MISC_MEM_MAP_VALUE(0x14)
++#define	MISC_PCI_DEVICE_VENDOR_ID_REG			MISC_MEM_MAP_VALUE(0x18)
++#define	MISC_USB_HOST_PHY_CONTROL_TEST_REG		MISC_MEM_MAP_VALUE(0x1C)
++#define	MISC_GPIOA_PIN_ENABLE_REG			MISC_MEM_MAP_VALUE(0x20)
++#define	MISC_GPIOB_PIN_ENABLE_REG			MISC_MEM_MAP_VALUE(0x24)
++#define	MISC_GPIOA_RESISTOR_CONFIG_REG			MISC_MEM_MAP_VALUE(0x28)
++#define	MISC_GPIOA_DRIVE_STRENGTH_CONFIG_REG		MISC_MEM_MAP_VALUE(0x2C)
++#define	MISC_FAST_ETHERNET_PHY_CONFIG_REG		MISC_MEM_MAP_VALUE(0x30)
++#define	MISC_SOFTWARE_TEST_1_REG			MISC_MEM_MAP_VALUE(0x38)
++#define	MISC_SOFTWARE_TEST_2_REG			MISC_MEM_MAP_VALUE(0x3C)
++
++#define	MISC_E_FUSE_0_REG				MISC_MEM_MAP_VALUE(0x60)
++#define	MISC_E_FUSE_1_REG				MISC_MEM_MAP_VALUE(0x64)
++
++
++/*
++ * define constants macros
++ */
++#define	MISC_PARALLEL_FLASH_BOOT		(0)
++#define	MISC_SPI_SERIAL_FLASH_BOOT		(1)
++
++#define	MISC_LITTLE_ENDIAN			(0)
++#define	MISC_BIG_ENDIAN				(1)
++
++#define	MISC_FARADAY_ICE			(0)
++#define	MISC_ARM_ICE				(1)
++
++#define	MISC_EXT_INT29_PINS			((0x1 << 0))
++#define	MISC_EXT_INT30_PINS			((0x1 << 1))
++#define	MISC_EXT_INT31_PINS			((0x1 << 2))
++#define	MISC_I2C_PINS				((0x1 << 13) | (0x1 << 14))
++#define	MISC_I2S_PINS				((0x1 << 15) | (0x1 << 16) | (0x1 << 17))
++#define	MISC_PCM_PINS				((0x1 << 18) | (0x1 << 19) | (0x1 << 20) | (0x1 << 21))
++#define	MISC_LED0_PINS				((0x1 << 22))
++#define	MISC_LED1_PINS				((0x1 << 23))
++#define	MISC_LED2_PINS				((0x1 << 24))
++#define	MISC_LED012_PINS			((0x1 << 22) | (0x1 << 23) | (0x1 << 24))
++#define	MISC_WDTIMER_RESET_PINS			((0x1 << 25))
++#define	MISC_SPI_PINS				((0x1 << 26) | (0x1 << 27) | (0x1 << 28) | (0x1 << 29) | (0x1 << 30) | (0x1 << 31))
++#define	MISC_MDC_MDIO_PINS			((0x1 << 0) | (0x1 << 1))
++#define	MISC_NIC_COL_PINS			((0x1 << 2))
++#define	MISC_IDE_PINS				((0xFF << 3))
++#define	MISC_SRAM_BANK1_PINS			((0x1 << 11) | (0x1 << 14))
++#define	MISC_SRAM_BANK2_PINS			((0x1 << 12) | (0x1 << 15))
++#define	MISC_SRAM_BANK3_PINS			((0x1 << 13) | (0x1 << 16))
++#define	MISC_PCMCIA_PINS			((0x1 << 17) | (0x1 << 18) | (0x1 << 19) | (0x1 << 20))
++#define	MISC_UART1_PINS				((0x1 << 21) | (0x1 << 22))
++#define	MISC_PCI_PINS				(((u32)0x1FF << 23))
++
++#define	MISC_UART0_ACT0_Pin			(0x1 << 2)
++#define	MISC_UART1_ACT1_Pin			(0x1 << 3)
++
++#define	MISC_GPIOA_PIN_0			(0)
++#define	MISC_GPIOA_PIN_1			(1)
++#define	MISC_GPIOA_PIN_2			(2)
++#define	MISC_GPIOA_PIN_3			(3)
++#define	MISC_GPIOA_PIN_4			(4)
++#define	MISC_GPIOA_PIN_5			(5)
++#define	MISC_GPIOA_PIN_6			(6)
++#define	MISC_GPIOA_PIN_7			(7)
++#define	MISC_GPIOA_PIN_8			(8)
++#define	MISC_GPIOA_PIN_9			(9)
++#define	MISC_GPIOA_PIN_10			(10)
++
++#define	MISC_GPIOA_75K_RESISTOR_PULL_DOWN	(1)
++#define	MISC_GPIOA_75K_RESISTOR_PULL_UP		(2)
++#define	MISC_GPIOA_75K_RESISTOR_PULL_KEEPER	(3)
++
++#define	MISC_GPIOA_DRIVE_STRENGTH_4MA		(0)
++#define	MISC_GPIOA_DRIVE_STRENGTH_8MA		(1)
++
++
++/*
++ * macro declarations
++ */
++#define	HAL_MISC_ENABLE_SPI_SERIAL_FLASH_BANK_ACCESS() \
++{ \
++    (MISC_CHIP_CONFIG_REG) |= (0x1 << 4); \
++}
++
++#define	HAL_MISC_DISABLE_SPI_SERIAL_FLASH_BANK_ACCESS()	\
++{ \
++    (MISC_CHIP_CONFIG_REG) &= ~(0x1 << 4); \
++}
++
++
++/*
++ * Macro defines for GPIOA and GPIOB Pin Enable	Register
++ */
++#define	HAL_MISC_ENABLE_EXT_INT29_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_EXT_INT29_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_EXT_INT29_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_EXT_INT29_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_EXT_INT30_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_EXT_INT30_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_EXT_INT30_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_EXT_INT30_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_I2C_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_I2C_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_I2C_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_I2C_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_I2S_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_I2S_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_I2S_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_I2S_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_PCM_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_PCM_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_PCM_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_PCM_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED0_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED0_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED0_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED0_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED1_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED1_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED1_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED1_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED2_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED2_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED2_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED2_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_LED012_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_LED012_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_LED012_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_LED012_PINS);	\
++}
++
++#define	HAL_MISC_ENABLE_WDTIMER_RESET_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_WDTIMER_RESET_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_WDTIMER_RESET_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_WDTIMER_RESET_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SPI_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_SPI_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SPI_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_SPI_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_UART0_ACT0_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_UART0_ACT0_Pin); \
++}
++
++#define	HAL_MISC_DISABLE_UART0_ACT0_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_UART0_ACT0_Pin); \
++}
++
++#define	HAL_MISC_ENABLE_UART1_ACT1_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	|= (MISC_UART1_ACT1_Pin); \
++}
++
++#define	HAL_MISC_DISABLE_UART1_ACT1_PIN() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	&= ~(MISC_UART1_ACT1_Pin); \
++}
++
++#define	HAL_MISC_ENABLE_MDC_MDIO_PINS()	\
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_MDC_MDIO_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_MDC_MDIO_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_MDC_MDIO_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_NIC_COL_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_NIC_COL_PINS);	\
++}
++
++#define	HAL_MISC_DISABLE_NIC_COL_PINS()	\
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_NIC_COL_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_IDE_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_IDE_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_IDE_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_IDE_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SRAM_BANK1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_SRAM_BANK1_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SRAM_BANK1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_SRAM_BANK1_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SRAM_BANK2_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_SRAM_BANK2_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SRAM_BANK2_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_SRAM_BANK2_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_SRAM_BANK3_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_SRAM_BANK3_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_SRAM_BANK3_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_SRAM_BANK3_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_PCMCIA_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_PCMCIA_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_PCMCIA_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_PCMCIA_PINS);	\
++}
++
++#define	HAL_MISC_ENABLE_UART1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_UART1_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_UART1_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_UART1_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_PCI_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	|= (MISC_PCI_PINS); \
++}
++
++#define	HAL_MISC_DISABLE_PCI_PINS() \
++{ \
++    (MISC_GPIOB_PIN_ENABLE_REG)	&= ~(MISC_PCI_PINS); \
++}
++
++#define	HAL_MISC_ENABLE_ALL_SHARED_GPIO_PINS() \
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	= (0x0); \
++    (MISC_GPIOB_PIN_ENABLE_REG)	= (0x0); \
++}
++
++#define	HAL_MISC_DISABLE_ALL_SHARED_GPIO_PINS()	\
++{ \
++    (MISC_GPIOA_PIN_ENABLE_REG)	= (0xFFFFFFFF);	\
++    (MISC_GPIOB_PIN_ENABLE_REG)	= (0xFFFFFFFF);	\
++}
++
++#define	HAL_MISC_CONFIGURE_GPIOA_RESISTOR(pin_index, value) \
++{ \
++    (MISC_GPIOA_RESISTOR_CONFIG_REG) &=	~(0x3 << (2 * pin_index)); \
++    (MISC_GPIOA_RESISTOR_CONFIG_REG) |=	((value	& 0x3) << (2 * pin_index)); \
++}
++
++#define	HAL_MISC_CONFIGURE_GPIOA_DRIVE_STRENGTH(pin_index, value) \
++{ \
++    (MISC_GPIOA_DRIVE_STRENGTH_CONFIG_REG) &= ~(0x1 << pin_index); \
++    (MISC_GPIOA_DRIVE_STRENGTH_CONFIG_REG) |= (value <<	pin_index); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE0() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x0); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE1() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x1); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE2() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x2); \
++}
++
++#define	HAL_MISC_SELECT_FAST_ETHERNET_PHY_LED_MODE3() \
++{ \
++    (MISC_FAST_ETHERNET_PHY_CONFIG_REG)	= (0x3); \
++}
++
++
++#endif	// end of #ifndef _STAR_MISC_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_nic.h linux-2.6.35.11-ts7500/include/asm/arch/star_nic.h
+--- linux-2.6.35.11/include/asm/arch/star_nic.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_nic.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,346 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_NIC_H_
++#define	_STAR_NIC_H_
++
++
++#include <asm/arch/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	NIC_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSPA_NIC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	NIC_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSVA_NIC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	NIC_PHY_CONTROL_REG0			NIC_MEM_MAP_VALUE(0x000)
++#define	NIC_PHY_CONTROL_REG1			NIC_MEM_MAP_VALUE(0x004)
++
++#define	NIC_MAC_CONTROL_REG			NIC_MEM_MAP_VALUE(0x008)
++#define	NIC_FLOW_CONTROL_CONFIG_REG		NIC_MEM_MAP_VALUE(0x00C)
++
++#define	NIC_ARL_CONFIG_REG			NIC_MEM_MAP_VALUE(0x010)
++
++#define	NIC_MY_MAC_HIGH_BYTE_REG		NIC_MEM_MAP_VALUE(0x014)
++#define	NIC_MY_MAC_LOW_BYTE_REG			NIC_MEM_MAP_VALUE(0x018)
++
++#define	NIC_HASH_TABLE_CONTROL_REG		NIC_MEM_MAP_VALUE(0x01C)
++
++#define	NIC_MY_VLANID_CONTROL_REG		NIC_MEM_MAP_VALUE(0x020)
++
++#define	NIC_MY_VLANID_0_1			NIC_MEM_MAP_VALUE(0x024)
++#define	NIC_MY_VLANID_2_3			NIC_MEM_MAP_VALUE(0x028)
++
++#define	NIC_DMA_CONFIG_REG			NIC_MEM_MAP_VALUE(0x030)
++#define	NIC_TX_DMA_CONTROL_REG			NIC_MEM_MAP_VALUE(0x034)
++#define	NIC_RX_DMA_CONTROL_REG			NIC_MEM_MAP_VALUE(0x038)
++#define	NIC_TX_DESC_PTR_REG			NIC_MEM_MAP_VALUE(0x03C)
++#define	NIC_RX_DESC_PTR_REG			NIC_MEM_MAP_VALUE(0x040)
++
++#define	NIC_TX_DESC_BASE_ADDR_REG		NIC_MEM_MAP_VALUE(0x044)
++#define	NIC_RX_DESC_BASE_ADDR_REG		NIC_MEM_MAP_VALUE(0x048)
++#define	NIC_DELAYED_INT_CONFIG_REG		NIC_MEM_MAP_VALUE(0x04C)
++
++#define	NIC_INT_STATUS_REG			NIC_MEM_MAP_VALUE(0x050)
++#define	NIC_INT_MASK_REG			NIC_MEM_MAP_VALUE(0x054)
++
++#define	NIC_TEST_0_REG				NIC_MEM_MAP_VALUE(0x058)
++#define	NIC_TEST_1_REG				NIC_MEM_MAP_VALUE(0x05C)
++
++#define	NIC_MIB_RX_OK_PKT_CNTR			NIC_MEM_MAP_VALUE(0x100)
++#define	NIC_MIB_RX_OK_BYTE_CNTR			NIC_MEM_MAP_VALUE(0x104)
++#define	NIC_MIB_RX_RUNT_BYTE_CNTR		NIC_MEM_MAP_VALUE(0x108)
++#define	NIC_MIB_RX_OSIZE_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x10C)
++
++#define	NIC_MIB_RX_NO_BUF_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x110)
++
++#define	NIC_MIB_RX_CRC_ERR_PKT_CNTR		NIC_MEM_MAP_VALUE(0x114)
++
++#define	NIC_MIB_RX_ARL_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x118)
++
++#define	NIC_MIB_MYVLANID_MISMATCH_DROP_PKT_CNTR	NIC_MEM_MAP_VALUE(0x11C)
++
++#define	NIC_MIB_RX_CHKSUM_ERR_PKT_CNTR		NIC_MEM_MAP_VALUE(0x120)
++
++#define	NIC_MIB_RX_PAUSE_FRAME_PKT_CNTR		NIC_MEM_MAP_VALUE(0x124)
++
++#define	NIC_MIB_TX_OK_PKT_CNTR			NIC_MEM_MAP_VALUE(0x128)
++#define	NIC_MIB_TX_OK_BYTE_CNTR			NIC_MEM_MAP_VALUE(0x12C)
++
++#define	NIC_MIB_TX_COLLISION_CNTR		NIC_MEM_MAP_VALUE(0x130)
++#define	NIC_MIB_TX_PAUSE_FRAME_CNTR		NIC_MEM_MAP_VALUE(0x130)
++
++#define	NIC_MIB_TX_FIFO_UNDERRUN_RETX_CNTR	NIC_MEM_MAP_VALUE(0x134)
++
++
++
++
++/*
++ * define constants macros
++ */
++
++#define	NIC_PHY_ADDRESS		1 //the phy addr const	value
++#define	NIC_PHY_ID		0x0243	//the phy id
++
++#define	GW_NIC_MAX_TFD_NUM	(32)
++#define	GW_NIC_MAX_RFD_NUM	(32)
++#define	MAX_BUFFERS		(64)
++
++
++
++#define	MMU_OFF			(0)
++#define	MMU_ON			(1)
++#define	OS_NULL			(0)
++
++
++#define	NET_BUFFER_PACKET_SIZE		(512)
++#define	NET_BUFFER_SHIFT_BIT_NUM	(9)	// 2*n9=512
++
++#define	MAX_PACKET_LEN		(1536)
++
++#define	INTERNAL_LOOPBACK_MODE	(1)
++#define	SOFTWARE_REPEATER_MODE	(2)
++
++#define	TXTC_INT_BIT		(0x08000000)
++#define	TX_INSV_BIT		(0x04000000)
++
++#define	LS_BIT			(0x10000000)
++#define	FS_BIT			(0x20000000)
++#define	EOR_BIT			(0x40000000)
++#define	FS_LS_BIT		(0x30000000)
++#define	C_BIT			(0x80000000)
++#define	FS_LS_C_BIT		(0xB0000000)
++#define	FS_LS_INT_BIT		(0x38000000)
++
++
++
++// HASH	TABLE CONTROL REGISTER
++#define	NIC_HASH_TABLE_BIST_DONE_BIT	(0x1 <<	17)
++#define	NIC_HASH_TABLE_BIST_OK_BIT	(0x1 <<	16)
++#define	NIC_HASH_COMMAND_START_BIT	(0x1 <<	14)
++#define	NIC_HASH_COMMAND_BIT		(0x1 <<	13)
++#define	NIC_HASH_BIT_DATA		(0x1 <<	12)
++#define	NIC_HASH_BIT_ADDRESS_BIT	(0x1ff)
++
++
++#define	NIC_REG_CNT			((0x48 << 2) + 1)
++
++/*
++ * macro access
++ */
++
++#define	GW_NIC_TX_TFD_NEXT(work_tfd_ptr) \
++    work_tfd_ptr = NIC_TX_TFD_Ring.head	+ (((u32)(work_tfd_ptr - NIC_TX_TFD_Ring.head) + 1) % GW_NIC_MAX_TFD_NUM)
++
++
++#define	GW_NIC_TX_TFD_PREVIOUS(work_tfd_ptr) \
++    work_tfd_ptr = NIC_TX_TFD_Ring.head	+ ((GW_NIC_MAX_TFD_NUM + (u32)(work_tfd_ptr - NIC_TX_TFD_Ring.head) - 1) % GW_NIC_MAX_TFD_NUM)
++
++
++#define	GW_NIC_RX_RFD_NEXT(work_rfd_ptr) \
++    work_rfd_ptr = NIC_RX_RFD_Ring.head	+ (((u32)(work_rfd_ptr - NIC_RX_RFD_Ring.head) + 1) % GW_NIC_MAX_RFD_NUM)
++
++
++#define	GW_NIC_RX_RFD_PREVIOUS(work_rfd_ptr) \
++    work_rfd_ptr = NIC_RX_RFD_Ring.head	+ ((GW_NIC_MAX_RFD_NUM + (u32)(work_rfd_ptr - NIC_RX_RFD_Ring.head) - 1) % GW_NIC_MAX_RFD_NUM)
++
++
++/*
++ * PHY register	defines
++ */
++#define	PHY_MII_CONTROL_REG_ADDR		0x00
++#define	PHY_MII_STATUS_REG_ADDR			0x01
++#define	PHY_ID1_REG_ADDR			0x02
++#define	PHY_ID2_REG_ADDR			0x03
++#define	PHY_AN_ADVERTISEMENT_REG_ADDR		0x04
++#define	PHY_AN_REAMOTE_CAP_REG_ADDR		0x05
++
++
++#define	PHY_RESERVED1_REG_ADDR			0x10
++#define	PHY_RESERVED2_REG_ADDR			0x11
++#define	PHY_CH_STATUS_OUTPUT_REG_ADDR		0x12
++#define	PHY_RESERVED3_REG_ADDR			0x13
++#define	PHY_RESERVED4_REG_ADDR			0x14
++
++
++#define	PHY_SPEC_CONTROL_REG_ADDR		0x16
++#define	PHY_INTC_CONTROL_STATUS_REG_ADDR	0x17
++
++/*
++ * NIC registers access	macros defines
++ */
++
++//0x004
++#define	HAL_NIC_WRITE_PHY_CONTROL1(config_value) \
++    ((NIC_PHY_CONTROL_REG1) = (config_value))
++
++#define	HAL_NIC_READ_PHY_CONTROL1(config_value)	\
++    ((config_value) = (NIC_PHY_CONTROL_REG1))
++
++//0x008
++#define	HAL_NIC_WRITE_MAC_CONFIGURATION(config_value) \
++    ((NIC_MAC_CONTROL_REG) = (config_value))
++
++#define	HAL_NIC_READ_MAC_CONFIGURATION(config_value) \
++    ((config_value) = (NIC_MAC_CONTROL_REG))
++
++//0x00C
++#define	HAL_NIC_WRITE_FLOW_CONTROL_CONFIG(fc_cfg) \
++    ((NIC_FLOW_CONTROL_CONFIG_REG) = (fc_cfg))
++
++#define	HAL_NIC_READ_FLOW_CONTROL_CONFIG(fc_cfg) \
++    ((fc_cfg) =	(NIC_FLOW_CONTROL_CONFIG_REG))
++
++//0x010
++#define	HAL_NIC_WRITE_ARL_CONFIGURATION(cfg) \
++    ((NIC_ARL_CONFIG_REG) = (cfg))
++
++#define	HAL_NIC_READ_ARL_CONFIGURATION(cfg) \
++    ((cfg) = (NIC_ARL_CONFIG_REG))
++
++//0x014,
++#define	HAL_NIC_WRITE_MY_MAC_HIGH_BYTE(cfg) \
++    ((NIC_MY_MAC_HIGH_BYTE_REG)	= (cfg & 0x0000FFFF ) )
++
++#define	HAL_NIC_READ_MY_MAC_HIGH_BYTE(cfg) \
++    ((cfg) = (NIC_MY_MAC_HIGH_BYTE_REG & 0x0000FFFF ))
++
++//0x018
++#define	HAL_NIC_WRITE_MY_MAC_LOW_BYTE(cfg) \
++    ((NIC_MY_MAC_LOW_BYTE_REG) = (cfg))
++
++#define	HAL_NIC_READ_MY_MAC_LOW_BYTE(cfg) \
++    ((cfg) = (NIC_MY_MAC_LOW_BYTE_REG))
++
++//0x03C
++#define	HAL_NIC_READ_INTERRUPT_STATUS(int_status) \
++    ((int_status) = (NIC_INT_STATUS_REG))
++
++#define	HAL_NIC_CLEAR_ALL_INTERRUPT_STATUS_SOURCES()\
++    ((NIC_INT_STATUS_REG) = (0xFFFFFFFF))
++
++#define	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCES(source) \
++    ((NIC_INT_STATUS_REG) |= (source))
++
++#define	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_STATUS_REG) |= (1	<< (source_bit_index)))
++
++//0x040
++#define	HAL_NIC_DISABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++    ((NIC_INT_MASK_REG)	= (0xFFFFFFFF))
++
++#define	HAL_NIC_ENABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++    ((NIC_INT_MASK_REG)	= (0x00000000))
++
++#define	HAL_NIC_DISABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_MASK_REG)	|= (1 << (source_bit_index)))
++
++#define	HAL_NIC_ENABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_MASK_REG)	&= ~(1 << (source_bit_index)))
++
++//0x44
++#define	HAL_NIC_WRITE_TEST0_REG(cfg) \
++    ((NIC_TEST_0_REG) =	(cfg))
++
++#define	HAL_NIC_READ_TEST0_REG(cfg) \
++    ((cfg) = (NIC_TEST_0_REG))
++
++//0x48
++#define	HAL_NIC_WRITE_TEST1_REG(cfg) \
++    ((NIC_TEST_1_REG) =	(cfg))
++
++#define	HAL_NIC_READ_TEST1_REG(cfg) \
++    ((cfg) = (NIC_TEST_1_REG))
++
++
++
++/*
++ * NIC's DMA macros defines
++ */
++#define	HAL_NIC_TX_DMA_START() \
++    ((NIC_TX_DMA_CONTROL_REG) =	(1))
++
++
++#define	HAL_NIC_TX_DMA_STOP() \
++    ((NIC_TX_DMA_CONTROL_REG) =	(0))
++
++
++#define	HAL_NIC_READ_TX_DMA_STATE(state) \
++    ((state) = (NIC_TX_DMA_CONTROL_REG))
++
++
++#define	HAL_NIC_RX_DMA_START() \
++    ((NIC_RX_DMA_CONTROL_REG) =	(1))
++
++
++#define	HAL_NIC_RX_DMA_STOP() \
++    ((NIC_RX_DMA_CONTROL_REG) =	(0))
++
++
++#define	HAL_NIC_WRITE_TXSD(tssd_value) \
++    ((NIC_TX_DESC_PTR_REG) = (tssd_value))
++
++
++#define	HAL_NIC_READ_TXSD(tssd_value) \
++    ((tssd_value) = (NIC_TX_DESC_PTR_REG))
++
++
++#define	HAL_NIC_WRITE_RXSD(fssd_value) \
++    ((NIC_RX_DESC_PTR_REG) = (fssd_value))
++
++
++#define	HAL_NIC_READ_RXSD(fssd_value) \
++    ((fssd_value) = (NIC_RX_DESC_PTR_REG))
++
++
++#define	HAL_NIC_WRITE_TX_BASE(ts_base_value) \
++    ((NIC_TX_DESC_BASE_ADDR_REG) = (ts_base_value))
++
++
++#define	HAL_NIC_READ_TX_BASE(ts_base_value) \
++    ((ts_base_value) = (NIC_TX_DESC_BASE_ADDR_REG))
++
++
++#define	HAL_NIC_WRITE_RX_BASE(fs_base_value) \
++    ((NIC_RX_DESC_BASE_ADDR_REG) = (fs_base_value))
++
++
++#define	HAL_NIC_READ_RX_BASE(fs_base_value) \
++    ((fs_base_value) = (NIC_RX_DESC_BASE_ADDR_REG))
++
++
++#define	HAL_NIC_WRITE_DELAYED_INTERRUPT_CONFIG(delayed_interrupt_config) \
++    ((NIC_DELAYED_INT_CONFIG_REG) = (delayed_interrupt_config))
++
++
++#define	HAL_NIC_READ_DELAYED_INTERRUPT_CONFIG(delayed_interrupt_config)	\
++    ((delayed_interrupt_config)	= (NIC_DELAYED_INT_CONFIG_REG))
++
++#endif	// end of #ifndef _STAR_NIC_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_pci_bridge.h linux-2.6.35.11-ts7500/include/asm/arch/star_pci_bridge.h
+--- linux-2.6.35.11/include/asm/arch/star_pci_bridge.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_pci_bridge.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,132 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_PCI_DRIDGE_H_
++#define	_STAR_PCI_DRIDGE_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#define	PCI_IO_SPACE_BASE_ADDR			(SYSPA_PCI_IO_SPACE_BASE_ADDR)
++#define PCI_IO_SPACE_SIZE			0x08000000 /* 64MB */
++#define PCI_IO_SPACE_START			PCI_IO_SPACE_BASE_ADDR
++#define PCI_IO_SPACE_END			(PCI_IO_SPACE_BASE_ADDR + PCI_IO_SPACE_SIZE - 1)
++#define	PCI_MEMORY_SPACE_BASE_ADDR		(SYSPA_PCI_MEMORY_SPACE_BASE_ADDR)
++#define PCI_MEMORY_SPACE_SIZE			0x10000000 /* 256MB */
++#define PCI_NPREFETCH_MEMORY_SPACE_START	PCI_MEMORY_SPACE_BASE_ADDR
++#define PCI_NPREFETCH_MEMORY_SPACE_SIZE		0x00800000 /* 8MB */
++#define PCI_NPREFETCH_MEMORY_SPACE_END		(PCI_NPREFETCH_MEMORY_SPACE_START + PCI_NPREFETCH_MEMORY_SPACE_SIZE - 1)
++#define PCI_PREFETCH_MEMORY_SPACE_START		(PCI_NPREFETCH_MEMORY_SPACE_START + PCI_NPREFETCH_MEMORY_SPACE_SIZE)
++#define PCI_PREFETCH_MEMORY_SPACE_SIZE		0x00800000 /* 8MB */
++#define PCI_PREFETCH_MEMORY_SPACE_END		(PCI_PREFETCH_MEMORY_SPACE_START + PCI_PREFETCH_MEMORY_SPACE_SIZE - 1)
++
++
++#if defined(__UBOOT__)
++#define	PCIB_MEM_MAP_VALUE(base, reg_offset)	(*((u32 volatile *)(SYSPA_PCI_##base##_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	PCIB_MEM_MAP_VALUE(base, reg_offset)	(*((u32 volatile *)(SYSVA_PCI_##base##_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	PCI_BRIDGE_CONFIG_DATA			PCIB_MEM_MAP_VALUE(CONFIG_DATA_BASE, 0x2C)
++#define	PCI_BRIDGE_CONFIG_ADDR			PCIB_MEM_MAP_VALUE(CONFIG_ADDR_BASE, 0x28)
++
++#define PCI_BRIDGE_CONFIG_DATA_REG_OFFSET	0x2C
++#define PCI_BRIDGE_CONFIG_ADDR_REG_OFFSET	0x28
++
++/*
++ * define constants macros
++ */
++#define	PCIB_BUS_CLOCK_33M			1
++
++#define	PCIB_BUS_CLOCK_66M			2
++
++#define	PCIB_DEVICE_ID				0x8131
++
++#define	PCIB_VENDOR_ID				0xEEEE
++
++#define	PCIB_CLASS_CODE				0xFF0000
++
++#define	PCIB_REVISION_ID			0x00
++
++#define	PCIB_BAR0_MEMORY_SPACE_BASE		0x20000000
++
++#define	PCIB_BAR1_IO_SPACE_BASE			0x20000000
++
++
++#define	PCI_MEMORY_SPACE_BASE			0xB0000000
++
++#define	PCI_IO_SPACE_BASE			0xA8000000
++
++
++#define	PCI_MAX_BUS_NUM				0x01
++#define	PCI_MAX_DEVICE_NUM			0x14
++#define	PCI_MAX_FUNCTION_NUM			0x01
++#define	PCI_MAX_REG_NUM				0x3C
++
++
++#define	PCI_MAX_DEVICE_TYPE_NUM			0x13
++#define	PCI_MAX_BAR_NUM				0x06
++
++
++#define	PCI_CSH_VENDOR_ID_REG_ADDR		0x00
++#define	PCI_CSH_DEVICE_ID_REG_ADDR		0x02
++#define	PCI_CSH_COMMAND_REG_ADDR		0x04
++#define	PCI_CSH_STATUS_REG_ADDR			0x06
++#define	PCI_CSH_REVISION_CLASS_REG_ADDR		0x08
++#define	PCI_CSH_CACHE_LINE_SIZE_REG_ADDR	0x0C
++#define	PCI_CSH_LATENCY_TIMER_REG_ADDR		0x0D
++#define	PCI_CSH_HEADER_TYPE_REG_ADDR		0x0E
++#define	PCI_CSH_BIST_REG_ADDR			0x0F
++#define	PCI_CSH_BAR_REG_ADDR			0x10
++
++
++#define	PCI_IO_SPACE_SIZE_1M			0x00
++#define	PCI_IO_SPACE_SIZE_2M			0x01
++#define	PCI_IO_SPACE_SIZE_4M			0x02
++#define	PCI_IO_SPACE_SIZE_8M			0x03
++#define	PCI_IO_SPACE_SIZE_16M			0x04
++#define	PCI_IO_SPACE_SIZE_32M			0x05
++#define	PCI_IO_SPACE_SIZE_64M			0x06
++#define	PCI_IO_SPACE_SIZE_128M			0x07
++#define	PCI_IO_SPACE_SIZE_256M			0x08
++#define	PCI_IO_SPACE_SIZE_512M			0x09
++#define	PCI_IO_SPACE_SIZE_1G			0x0A
++#define	PCI_IO_SPACE_SIZE_2G			0x0B
++
++
++#define	PCI_MEMORY_SPACE_TYPE			0
++#define	PCI_IO_SPACE_TYPE			1
++
++#define	PCI_BROKEN_FLAG				1
++#define	PCI_AHB2PCIB_FLAG			2
++
++
++#endif	// end of #ifndef _STAR_PCI_DRIDGE_H_
++
+diff -rupN linux-2.6.35.11/include/asm/arch/star_pcmcia_bridge.h linux-2.6.35.11-ts7500/include/asm/arch/star_pcmcia_bridge.h
+--- linux-2.6.35.11/include/asm/arch/star_pcmcia_bridge.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_pcmcia_bridge.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,231 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_PCMCIA_DRIDGE_H_
++#define	_STAR_PCMCIA_DRIDGE_H_
++
++/******************************************************************************
++ * MODULE NAME:	   star_pcmcia_bridge.h
++ * PROJECT CODE:   Equuleus
++ * DESCRIPTION:
++ * MAINTAINER:	   Eric	Yang
++ * DATE:	   15 September	2005
++ *
++ * SOURCE CONTROL:
++ *
++ * LICENSE:
++ *     This source code	is copyright (c) 2005 Star Semi	Inc.
++ *     All rights reserved.
++ *
++ * REVISION HISTORY:
++ *     15 September 2005  -  Eric Yang	- Initial Version v1.0
++ *
++ *
++ * SOURCE:
++ * ISSUES:
++ * NOTES TO USERS:
++ ******************************************************************************/
++
++#include "star_sys_memory_map.h"
++
++
++#if defined(__UBOOT__)
++#define	PCMCIA_BRIDGE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_PCMCIA_CONTROL_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	PCMCIA_BRIDGE_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_PCMCIA_CONTROL_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	PCMCIA_CONFIGURATION_REG			PCMCIA_BRIDGE_MEM_MAP_VALUE(0x20)
++#define	PCMCIA_MEMORY_ACCESS_TIMING_PARAM_REG		PCMCIA_BRIDGE_MEM_MAP_VALUE(0x24)
++#define	PCMCIA_IO_ACCESS_TIMING_PARAM_REG		PCMCIA_BRIDGE_MEM_MAP_VALUE(0x28)
++
++
++#define	PCMCIA_ATTRIBUTE_MEMORY_SPACE_BASE_ADDR		(SYSPA_PCMCIA_ATTRIBUTE_MEMORY_BASE_ADDR)
++#define	PCMCIA_COMMOM_MEMORY_SPACE_BASE_ADDR		(SYSPA_PCMCIA_COMMON_MEMORY_BASE_ADDR)
++#define	PCMCIA_IO_SPACE_BASE_ADDR			(SYSPA_PCMCIA_IO_SPACE_BASE_ADDR)
++
++
++
++/*
++ * define constants macros
++ */
++#define	PCMCIA_DATA_BUS_WIDTH_8		(0)
++
++#define	PCMCIA_DATA_BUS_WIDTH_16	(1)
++
++
++/*
++ * Flags for PCMCIA_STATUS
++ */
++#define	FLAG_STATUS_BVD1		0x01
++#define	FLAG_STATUS_STSCHG		0x01
++#define	FLAG_STATUS_BVD2		0x02
++#define	FLAG_STATUS_SPKR		0x02
++#define	FLAG_STATUS_DETECT		0xf3	  /* bit 2=0,3=0 ,0x0c bit 2=1,3=1 */
++#define	FLAG_STATUS_WRPROT		0x10
++#define	FLAG_STATUS_READY		0x20
++#define	FLAG_STATUS_INPACK		0x40
++
++
++/*
++ * Flags for PCMCIA_CSC
++ */
++#define	FLAG_CSC_BVD1			0x01
++#define	FLAG_CSC_BVD2			0x02
++#define	FLAG_CSC_READY			0x04
++#define	FLAG_CSC_INPACK			0x08
++#define	FLAG_CSC_STSCHG			0x10
++#define	FLAG_CSC_CARDINT		0x20
++#define	FLAG_CSC_DETECT			0x40
++#define	FLAG_CSC_SWCDC			0x80
++
++
++/*
++ * Flags for PCMCIA_POWER
++ */
++#define	FLAG_POWER_OFF			0x00	  /* Turn off the socket */
++#define	FLAG_POWER_3V			0x01	  /* 1:Vcc = 3.3v 0:Vcc	= 5.0v */
++#define	FLAG_POWER_SWH			0x02	  /* Direct 5V/3V switch enable	*/
++#define	FLAG_POWER_CTL			0x10	  /* Socket power control */
++#define	FLAG_POWER_AUTO			0x20	  /* Auto power	switch enable */
++#define	FLAG_POWER_OUTENA		0x40	  /* Output enable */
++
++
++/*
++ * Flags for PCMCIA_GBLCTL
++ */
++#define	FLAG_GBLCTL_PWRDOWN		0x01
++#define	FLAG_GBLCTL_WBACK		0x02
++#define	FLAG_GBLCTL_16BITS		0x04
++#define	FLAG_GBLCTL_IOCARD		0x08
++#define	FLAG_GBLCTL_SWCDINT		0x10
++#define	FLAG_GBLCTL_RESET		0x20
++
++
++/*
++ * Flags for PCMCIA_INTCFG
++ */
++#define	FLAG_INTCFG_BDEAD		0x01
++#define	FLAG_INTCFG_BWARN		0x02
++#define	FLAG_INTCFG_READY		0x04
++#define	FLAG_INTCFG_INPACK		0x08
++#define	FLAG_INTCFG_LEVEL		0x10
++#define	FLAG_INTCFG_FEDGE		0x20
++#define	FLAG_INTCFG_REDGE		0x30
++#define	FLAG_INTCFG_DETECT		0x40
++#define	FLAG_INTCFG_STSCHG		0x80
++
++
++/*
++ * Definitions for Card	Status flags for GetStatus
++ */
++#define	STATUS_BATDEAD			0x0001
++#define	STATUS_BATWARN			0x0002
++#define	STATUS_DETECT			0x0004
++#define	STATUS_WRPROT			0x0008
++#define	STATUS_READY			0x0010
++#define	STATUS_INPACK			0x0020
++#define	STATUS_STSCHG			0x0040    /* just for	CSC */
++#define	SOFTWARE_STATUS_DETECT		0x0040    /* just for	CSC */
++
++
++/*
++ * Set Socket configuration flags
++ */
++#define	SS_PWR_AUTO			0x0001
++#define	SS_PWR_SWH			0x0002
++#define	SS_PWR_SEL			0x0004
++#define	SS_POWER_ON			0x0008
++#define	SS_OUTPUT_ENA			0x0010
++#define	SS_IOCARD			0x0020
++#define	SS_RESET			0x0040
++#define	SS_WBACK			0x0080
++#define	SS_16BITS			0x0100
++#define	SS_PWR_DOWN_MODE		0x0200
++#define	SS_SWCDINT			0x0400
++
++
++/*
++ * Set Interrupt Configuration flags
++ */
++#define	INTR_BATDEAD			0x0001
++#define	INTR_BATWARN			0x0002
++#define	INTR_READY			0x0004
++#define	INTR_INPACK			0x0008
++#define	INTR_CARDINT			0x0010
++#define	INTR_DETECT			0x0020
++#define	INTR_STSCHG			0x0040
++
++
++/*
++ * tuple code
++ */
++#define	CISTPL_NULL			0x00
++#define	CISTPL_DEVICE			0x01
++#define	CISTPL_NO_LINK			0x14
++#define	CISTPL_VERS_1			0x15
++#define	CISTPL_CONFIG			0x1a
++#define	CISTPL_CFTABLE_ENTRY		0x1b
++#define	CISTPL_MANFID			0x20
++#define	CISTPL_END			0xff
++
++
++/*
++ * Return codes
++ */
++#define	CS_SUCCESS			0x00
++#define	CS_UNSUPPORTED_FUNCTION		0x15
++#define	CS_NO_MORE_ITEMS		0x1f
++#define	CS_BAD_TUPLE			0x40
++
++
++/*
++ * Attributes for tuple	calls
++ */
++#define	TUPLE_RETURN_LINK		0x01
++#define	TUPLE_RETURN_COMMON		0x02
++
++#define	RETURN_FIRST_TUPLE		0xff
++
++
++/*
++ * macro declarations
++ */
++#define	HAL_PCMCIA_ENABLE_PCMCIA_CONTROLLER() \
++{ \
++    (PCMCIA_CONFIGURATION_REG) |= (0x1 << 1); \
++}
++
++#define	HAL_PCMCIA_DISABLE_PCMCIA_CONTROLLER() \
++{ \
++    (PCMCIA_CONFIGURATION_REG) &= ~(0x1	<< 1); \
++}
++
++
++#endif	// end of #ifndef _STAR_PCMCIA_DRIDGE_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_pcm.h linux-2.6.35.11-ts7500/include/asm/arch/star_pcm.h
+--- linux-2.6.35.11/include/asm/arch/star_pcm.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_pcm.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,277 @@
++/******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_PCM_H_
++#define _STAR_PCM_H_
++
++/******************************************************************************
++ * MODULE NAME:    star_pcm.h
++ * PROJECT CODE:   Orion
++ * DESCRIPTION:    
++ * MAINTAINER:     MJLIU
++ * DATE:           15 September 2005
++ *
++ * SOURCE CONTROL: 
++ *
++ * LICENSE:
++ *     This source code is copyright (c) 2005 Star Semi Inc.
++ *     All rights reserved.
++ *
++ * REVISION HISTORY:
++ *     15 September 2005  -  MJLIU	- Initial Version v1.0
++ *
++ *
++ * SOURCE:
++ * ISSUES:
++ * NOTES TO USERS:
++ ******************************************************************************/
++
++#include <mach/star_sys_memory_map.h>
++
++#define PCM_BASE_ADDR                         (SYSVA_PCM_BASE_ADDR)
++#define PCM_MEM_MAP_ADDR(reg_offset)          (PCM_BASE_ADDR + reg_offset)
++#define PCM_MEM_MAP_VALUE(reg_offset)         (*((u32 volatile *)PCM_MEM_MAP_ADDR(reg_offset)))
++
++
++/*
++ * define access macros
++ */
++#define PCM_CONFIGURATION_0_REG               PCM_MEM_MAP_VALUE(0x80)
++#define PCM_CONFIGURATION_1_REG               PCM_MEM_MAP_VALUE(0x84)
++
++#define PCM_CHANNEL_0_CONFIG_REG              PCM_MEM_MAP_VALUE(0x88)
++#define PCM_CHANNEL_1_CONFIG_REG              PCM_MEM_MAP_VALUE(0x8C)
++#define PCM_CHANNEL_2_CONFIG_REG              PCM_MEM_MAP_VALUE(0x90)
++#define PCM_CHANNEL_3_CONFIG_REG              PCM_MEM_MAP_VALUE(0x94)
++
++#define PCM_TX_DATA_31_0_REG                  PCM_MEM_MAP_VALUE(0x98)
++#define PCM_TX_DATA_63_32_REG                 PCM_MEM_MAP_VALUE(0x9C)
++
++#define PCM_RX_DATA_31_0_REG                  PCM_MEM_MAP_VALUE(0xA0)
++#define PCM_RX_DATA_63_32_REG                 PCM_MEM_MAP_VALUE(0xA4)
++
++#define PCM_INTERRUPT_STATUS_REG              PCM_MEM_MAP_VALUE(0xA8)
++#define PCM_INTERRUPT_ENABLE_REG              PCM_MEM_MAP_VALUE(0xAC)
++
++
++
++/*
++ * define constants macros
++ */
++#define CH0_BIT_INDEX                         (0x1)
++#define CH1_BIT_INDEX                         (0x2)
++#define CH2_BIT_INDEX                         (0x4)
++#define CH3_BIT_INDEX                         (0x8)
++
++#define PCM_RXBUF_FULL_FG                     (0x1)
++#define PCM_TXBUF_EMPTY_FG                    (0x2)
++#define PCM_RXBUF_OVERRUN_FG                  (0x4)
++#define PCM_TXBUF_UNDERRUN_FG                 (0x8)
++
++#define PCM_ENABLE_FG                         (0x1 << 23)
++
++#define PCM_IDL_MODE                          (0)
++#define PCM_GCI_MODE                          (1)
++
++#define PCM_DATA_BIT_8                        (0)
++#define PCM_DATA_BIT_16                       (1)
++
++
++/*
++ * Set Commands Variables
++ */
++#define        Software_Reset                               (0x02)
++#define        Hardware_Reset                               (0x04)
++#define        Write_Transmit_Time_Slot                     (0x40)
++#define        Read_Transmit_Time_Slot                      (0x41)
++#define        Write_Receive_Time_Slot                      (0x42)
++#define        Read_Receive_Time_Slot                       (0x43)
++#define        Write_Tx_Rx_CLK_Slot_Tx_CLK_Edge             (0x44)
++#define        Read_Tx_Rx_CLK_Slot_Tx_CLK_Edge              (0x45)
++#define        Write_Device_Configure_Reg                   (0x46)
++#define        Read_Device_Configure_Reg                    (0x47)
++#define        Write_Channel_Enable_Operating_Mode_Reg      (0x4A)
++#define        Read_Channel_Enable_Operating_Mode_Reg       (0x4B)
++#define        Read_Signal_Reg                              (0x4D)
++#define        Input_Data_Reg                               (0x52)
++#define        Output_Data_Reg                              (0x53)
++#define        Input_Direction_Reg                          (0x54)
++#define        Output_Direction_Reg                         (0x55)
++#define        Write_System_State                           (0x56)
++#define        Read_System_State                            (0x57)
++#define        Write_Operating_Functon                      (0x60)
++#define        Read_Operating_Functon                       (0x61)
++#define        Write_System_State_Config                    (0x68)
++#define        Read_System_State_Config                     (0x69)
++#define        Write_Interrupt_Mask_Reg                     (0x6C)
++#define        Read_Interrupt_Mask_Reg                      (0x6D)
++#define        Write_Operating_Condition                    (0x70)
++#define        Write_Loop_Supervision_Parameter             (0xC2)
++#define        Write_DC_Feed_Parameter                      (0xC6)
++#define        Write_Signal_A_B_Parameter                   (0xD2)
++#define        Write_Switching_Reg_Parameter                (0xE4)
++#define        Write_Switching_Reg_Control                  (0xE6)
++
++
++/*
++ * define data structure
++ */
++typedef struct _PCM_CHANNEL_OBJECT_    PCM_CHANNEL_OBJECT_T;
++
++struct _PCM_CHANNEL_OBJECT_
++{
++    u16          channel_0_tx_data;
++    u16          channel_0_rx_data;
++    u32          channel_0_data_width;     /* 0 : 8-bit, 1 : 16-bit */
++
++    u16          channel_1_tx_data;
++    u16          channel_1_rx_data;
++    u32          channel_1_data_width;
++
++    u16          channel_2_tx_data;
++    u16          channel_2_rx_data;
++    u32          channel_2_data_width;
++
++    u16          channel_3_tx_data;
++    u16          channel_3_rx_data;
++    u32          channel_3_data_width;
++    
++    u32          channel_enable_config;    /* bit[0] = 0 : channel 0 disabled
++                                                     [0] = 1 : channel 0 enabled
++                                                  bit[1] = 0 : channel 1 disabled
++                                                     [1] = 1 : channel 1 enabled
++                                                  bit[2] = 0 : channel 2 disabled
++                                                     [2] = 1 : channel 2 enabled
++                                                  bit[3] = 0 : channel 3 disabled
++                                                     [3] = 1 : channel 3 enabled */
++};
++
++
++typedef struct _PCM_OBJECT_    PCM_OBJECT_T;
++
++struct _PCM_OBJECT_
++{
++    u32          config_0;
++    u32          config_1; 
++    
++    u32          channel_0_config;
++    u32          channel_1_config;
++    u32          channel_2_config;
++    u32          channel_3_config;
++    
++    u32          interrupt_config;
++    
++    /* 
++     * For interrupt setting
++     */
++//    INTC_OBJECT_T    intc_obj;
++};
++
++
++
++/*
++ * function declarations
++ */
++void       Hal_Pcm_Initialize(PCM_OBJECT_T *);
++
++                                                                           
++/*
++ * macro declarations
++ */
++#define HAL_PCM_ENABLE_PCM() \
++{ \
++    (PCM_CONFIGURATION_0_REG) |= ((u32)0x1 << 31); \
++}
++
++#define HAL_PCM_DISABLE_PCM() \
++{ \
++    (PCM_CONFIGURATION_0_REG) &= ~((u32)0x1 << 31); \
++}
++
++#define HAL_PCM_ENABLE_DATA_SWAP() \
++{ \
++    (PCM_CONFIGURATION_0_REG) |= (0x1 << 24); \
++}
++
++#define HAL_PCM_DISABLE_DATA_SWAP() \
++{ \
++    (PCM_CONFIGURATION_0_REG) &= ~(0x1 << 24); \
++}
++
++#define HAL_PCM_WRITE_TX_DATA_0(tx_data_0) \
++{ \
++    (PCM_TX_DATA_31_0_REG) = tx_data_0; \
++}
++
++#define HAL_PCM_WRITE_TX_DATA_1(tx_data_1) \
++{ \
++    (PCM_TX_DATA_63_32_REG) = tx_data_1; \
++}
++
++#define HAL_PCM_READ_RX_DATA_0(rx_data_0) \
++{ \
++    (rx_data_0) = PCM_RX_DATA_31_0_REG; \
++}
++
++#define HAL_PCM_READ_RX_DATA_1(rx_data_1) \
++{ \
++    (rx_data_1) = PCM_RX_DATA_63_32_REG; \
++}
++
++#define HAL_PCM_READ_INTERRUPT_STATUS(status) \
++{ \
++    (status) = PCM_INTERRUPT_STATUS_REG; \
++}
++
++#define HAL_PCM_CLEAR_INTERRUPT_STATUS(status) \
++{ \
++    (PCM_INTERRUPT_STATUS_REG) = (status & 0xC0); \
++}
++
++#define HAL_PCM_DISABLE_RECEIVE_BUFFER_FULL_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_PCM_DISABLE_TRANSMIT_BUFFER_EMPTY_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_PCM_DISABLE_RECEIVE_BUFFER_OVERRUN_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 2); \
++}
++
++#define HAL_PCM_DISABLE_TRANSMIT_BUFFER_UNDERRUN_INTERRUPT() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) &= ~(0x1 << 3); \
++}
++
++#define HAL_PCM_DISABLE_ALL_INTERRUPT_SOURCES() \
++{ \
++    (PCM_INTERRUPT_ENABLE_REG) = 0; \
++}
++
++#endif  // end of #ifndef _STAR_PCM_H_
++
+diff -rupN linux-2.6.35.11/include/asm/arch/star_powermgt.h linux-2.6.35.11-ts7500/include/asm/arch/star_powermgt.h
+--- linux-2.6.35.11/include/asm/arch/star_powermgt.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_powermgt.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,616 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_POWERMGT_H_
++#define	_STAR_POWERMGT_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	PWRMGT_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSPA_POWER_MANAGEMENT_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	PWRMGT_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSVA_POWER_MANAGEMENT_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	PWRMGT_CLOCK_GATE_CONTROL0_REG			PWRMGT_MEM_MAP_VALUE(0x00)
++#define	PWRMGT_CLOCK_GATE_CONTROL1_REG			PWRMGT_MEM_MAP_VALUE(0x04)
++#define	PWRMGT_SOFTWARE_RESET_CONTROL_REG		PWRMGT_MEM_MAP_VALUE(0x08)
++#define	PWRMGT_SYSTEM_CLOCK_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x0C)
++#define	PWRMGT_PLL_POWER_DOWN_CONTROL_REG		PWRMGT_MEM_MAP_VALUE(0x10)
++#define	PWRMGT_CPU_INITIALIZATION_REG			PWRMGT_MEM_MAP_VALUE(0x14)
++#define	PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG		PWRMGT_MEM_MAP_VALUE(0x1C)
++#define	PWRMGT_USB_DEVICE_POWERMGT_REG			PWRMGT_MEM_MAP_VALUE(0x20)
++#define	PWRMGT_REGULATOR_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x24)
++#define	PWRMGT_RTC_XTAL_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x28)
++#define	PWRMGT_PLL250_CONTROL_REG			PWRMGT_MEM_MAP_VALUE(0x2C)
++
++
++/*
++ * define constants macros
++ */
++#define	PWRMGT_PCMCIA_SOFTWARE_RESET_BIT_INDEX			(1)
++#define	PWRMGT_IDE_SOFTWARE_RESET_BIT_INDEX			(2)
++#define	PWRMGT_VIC_SOFTWARE_RESET_BIT_INDEX			(3)
++#define	PWRMGT_DMA_SOFTWARE_RESET_BIT_INDEX			(4)
++#define	PWRMGT_NIC_SOFTWARE_RESET_BIT_INDEX			(5)
++#define	PWRMGT_USB_HOST_SOFTWARE_RESET_BIT_INDEX		(6)
++#define	PWRMGT_PCI_BRIDGE_SOFTWARE_RESET_BIT_INDEX		(7)
++#define	PWRMGT_P2S_SOFTWARE_RESET_BIT_INDEX			(8)
++#define	PWRMGT_UART0_SOFTWARE_RESET_BIT_INDEX			(9)
++#define	PWRMGT_UART1_SOFTWARE_RESET_BIT_INDEX			(10)
++#define	PWRMGT_TIMER_SOFTWARE_RESET_BIT_INDEX			(11)
++#define	PWRMGT_WDTIMER_SOFTWARE_RESET_BIT_INDEX			(12)
++#define	PWRMGT_GPIO_SOFTWARE_RESET_BIT_INDEX			(13)
++#define	PWRMGT_USB_DEVICE_SOFTWARE_RESET_BIT_INDEX		(14)
++#define	PWRMGT_FAST_ETHERNET_PHY_SOFTWARE_RESET_BIT_INDEX	(15)
++#define	PWRMGT_HSDMA_SOFTWARE_RESET_BIT_INDEX			(16)
++
++
++#define	PWRMGT_PLL_FREQUENCY_175MHZ			(0 << 0)
++#define	PWRMGT_PLL_FREQUENCY_200MHZ			(1 << 0)
++#define	PWRMGT_PLL_FREQUENCY_225MHZ			(2 << 0)
++#define	PWRMGT_PLL_FREQUENCY_250MHZ			(3 << 0)
++
++#define	PWRMGT_CPUCLK_DIVIDER_BY_1			(0 << 2)
++#define	PWRMGT_CPUCLK_DIVIDER_BY_2			(1 << 2)
++#define	PWRMGT_CPUCLK_DIVIDER_BY_3			(2 << 2)
++#define	PWRMGT_CPUCLK_DIVIDER_BY_4			(3 << 2)
++
++#define	PWRMGT_HCLK_DIVIDER_BY_1			(0 << 4)
++#define	PWRMGT_HCLK_DIVIDER_BY_2			(1 << 4)
++#define	PWRMGT_HCLK_DIVIDER_BY_3			(2 << 4)
++#define	PWRMGT_HCLK_DIVIDER_BY_4			(3 << 4)
++
++#define	PWRMGT_HCLK_SOURCE_FCLK				(0 << 6)
++#define	PWRMGT_HCLK_SOURCE_125MHZ			(1 << 6)
++
++#define	PWRMGT_PCLK_DIVIDER_BY_1			(0 << 8)
++#define	PWRMGT_PCLK_DIVIDER_BY_2			(1 << 8)
++#define	PWRMGT_PCLK_DIVIDER_BY_3			(2 << 8)
++#define	PWRMGT_PCLK_DIVIDER_BY_4			(3 << 8)
++
++#define	PWRMGT_PCICLK_DIVIDER_BY_1			(0 << 10)
++#define	PWRMGT_PCICLK_DIVIDER_BY_2			(1 << 10)
++#define	PWRMGT_PCICLK_DIVIDER_BY_3			(2 << 10)
++#define	PWRMGT_PCICLK_DIVIDER_BY_4			(3 << 10)
++
++
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_1		(1)
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_2		(2)
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_3		(3)
++#define	PWRMGT_PLLCLK_TO_CPUCLK_RATIO_BY_4		(4)
++
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_1		(1)
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_2		(2)
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_3		(3)
++#define	PWRMGT_CPUCLK_TO_HCLK_RATIO_BY_4		(4)
++
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_1			(1)
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_2			(2)
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_3			(3)
++#define	PWRMGT_HCLK_TO_PCLK_RATIO_BY_4			(4)
++
++/*
++ * Macro defines for Clock Gate	Control
++ */
++#define	HAL_PWRMGT_DISABLE_DRAMC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_NIC_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 0); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x0F << 20); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 5); \
++}
++
++#define	HAL_PWRMGT_DISABLE_NIC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x0F <<	20); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_PCI_BRIDGE_33M_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 1); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	10); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 10); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 28) | (0x1 << 30); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 7); \
++}
++
++#define	HAL_PWRMGT_ENABLE_PCI_BRIDGE_66M_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 1); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	10); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x0 << 10); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 28) | (0x1 << 30); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 7); \
++}
++
++#define	HAL_PWRMGT_DISABLE_PCI_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	28) | (0x1 << 30)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_USB_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0xF << 1); \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 24); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 28); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 6) | (0x1 << 14); \
++}
++
++#define	HAL_PWRMGT_DISABLE_USB_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1 << 24); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 28); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_DMA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 16); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 4); \
++}
++
++#define	HAL_PWRMGT_DISABLE_DMA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1 << 16); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_IDE_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 8) | (0x1	<< 9); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 2); \
++}
++
++#define	HAL_PWRMGT_DISABLE_IDE_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	8) | (0x1 << 9)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_UART0_CLOCK()	\
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~((0x1	<< 1) |	(0x1 <<	2) | (0x1 << 5)); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 12); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 9); \
++}
++
++#define	HAL_PWRMGT_DISABLE_UART0_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 12); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_UART1_CLOCK()	\
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~((0x1	<< 1) |	(0x1 <<	2) | (0x1 << 5)); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 13); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 10); \
++}
++
++#define	HAL_PWRMGT_DISABLE_UART1_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 13); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_PCMCIA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 4) | (0x1	<< 5); \
++}
++
++#define	HAL_PWRMGT_DISABLE_PCMCIA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	4) | (0x1 << 5)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_GPIO_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 25); \
++}
++
++#define	HAL_PWRMGT_DISABLE_GPIO_CLOCK()	\
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 25); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_WDTIMER_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 21) | (0x1 << 22); \
++}
++
++#define	HAL_PWRMGT_DISABLE_WDTIMER_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	21) | (0x1 << 22)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_RTC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 23); \
++}
++
++#define	HAL_PWRMGT_DISABLE_RTC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 23); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_TIMER_CLOCK()	\
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 17) | (0x1 << 18)	| (0x1 << 19); \
++}
++
++#define	HAL_PWRMGT_DISABLE_TIMER_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	17) | (0x1 << 18) | (0x1 << 19)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_I2C_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 1); \
++}
++
++#define	HAL_PWRMGT_DISABLE_I2C_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 1); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_I2S_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~((0x1	<< 5) |	(0x1 <<	6)); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 1) | (0x1	<< 10);	\
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 8); \
++}
++
++#define	HAL_PWRMGT_DISABLE_I2S_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	1) | (0x1 << 10)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_PCM_CLOCK() \
++{ \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 5); \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 1) | (0x1	<< 6); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 8); \
++}
++
++#define	HAL_PWRMGT_DISABLE_PCM_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	1) | (0x1 << 6)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_SPI_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 0) | (0x1	<< 1); \
++}
++
++#define	HAL_PWRMGT_DISABLE_SPI_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~((0x1 <<	0) | (0x1 << 1)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_VIC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 12); \
++}
++
++#define	HAL_PWRMGT_DISABLE_VIC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~(0x1 << 12); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_SMC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG |= (0x1 << 4) | (0x1	<< 5); \
++}
++
++#define	HAL_PWRMGT_DISABLE_SMC_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL0_REG &= ~((0x1 <<	4) | (0x1 << 5)); \
++}
++
++
++#define	HAL_PWRMGT_ENABLE_HSDMA_CLOCK()	\
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG |= (0x1 << 29); \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1 << 16); \
++}
++
++#define	HAL_PWRMGT_DISABLE_HSDMA_CLOCK() \
++{ \
++    PWRMGT_CLOCK_GATE_CONTROL1_REG &= ~(0x1 << 29); \
++}
++
++
++
++/*
++ * Macro defines for Reset Control
++ */
++#define	HAL_PWRMGT_GLOBAL_SOFTWARE_RESET() \
++{ \
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG |= (0x1);	\
++    PWRMGT_SOFTWARE_RESET_CONTROL_REG &= ~(0x1); \
++}
++
++
++/*
++ * Macro defines for System Clock Control
++ */
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_175MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++}
++
++
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_200MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= 0x1; \
++}
++
++
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_225MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= 0x2; \
++}
++
++
++#define	HAL_PWRMGT_SET_PLL_FREQUENCY_250MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~0x3; \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= 0x3; \
++}
++
++
++#define	HAL_PWRMGT_CONFIG_PLLCLK_TO_CPUCLK_RATIO(ratio)	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	2); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (((ratio	- 1) & 0x3) << 2); \
++}
++
++
++#define	HAL_PWRMGT_CONFIG_CPUCLK_TO_HCLK_RATIO(ratio) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	4); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (((ratio	- 1) & 0x3) << 4); \
++}
++
++
++#define	HAL_PWRMGT_HCLK_SOURCE_FCLK() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x1 <<	6); \
++}
++
++
++#define	HAL_PWRMGT_HCLK_SOURCE_125MHZ()	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 6); \
++}
++
++
++#define	HAL_PWRMGT_GIGA_NIC_CLOCK_SOURCE_HCLK()	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x1 <<	7); \
++}
++
++
++#define	HAL_PWRMGT_GIGA_NIC_CLOCK_SOURCE_62_5MHZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 7); \
++}
++
++
++#define	HAL_PWRMGT_CONFIG_HCLK_TO_PCLK_RATIO(ratio) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	8); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (((ratio	- 1) & 0x3) << 8); \
++}
++
++
++#define	HAL_PWRMGT_I2S_CLOCK_SOURCE_8192000HZ()	\
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	12); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x0 << 12); \
++}
++
++
++#define	HAL_PWRMGT_I2S_CLOCK_SOURCE_11289600HZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	12); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x1 << 12); \
++}
++
++
++#define	HAL_PWRMGT_I2S_CLOCK_SOURCE_12288000HZ() \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	12); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= (0x2 << 12); \
++}
++
++
++#define	HAL_PWRMGT_CONFIGURE_MDC_CLOCK_DIVIDER(divided_value) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3 <<	14); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= ((divided_value & 0x3) << 14); \
++}
++
++
++#define	HAL_PWRMGT_CONFIGURE_CLOCK_OUT_PIN(pin_source_select, divided_value) \
++{ \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG &= ~(0x3F << 16); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= ((pin_source_select & 0xF) << 16); \
++    PWRMGT_SYSTEM_CLOCK_CONTROL_REG |= ((divided_value & 0x3) << 20); \
++}
++
++
++/*
++ * Macro defines for PLL Power Down Control
++ */
++#define	HAL_PWRMGT_POWER_DOWN_SYSTEM_XTAL_PAD()	\
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 7)
++
++#define	HAL_PWRMGT_POWER_ON_SYSTEM_XTAL_PAD() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 7)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X5() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 0)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X5() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 0)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X8() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 1)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X8() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 1)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X3() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 2)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X3() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 2)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_USBH_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 3)
++
++#define	HAL_PWRMGT_POWER_ON_USBH_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 3)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_USBD_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 4)
++
++#define	HAL_PWRMGT_POWER_ON_USBD_PHY_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 4)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X2250() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 5)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X2250()	\
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 5)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_PLL_X7() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG |= (0x1 << 6)
++
++#define	HAL_PWRMGT_POWER_ON_PLL_X7() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG &= ~(0x1 << 6)
++
++
++#define	HAL_PWRMGT_POWER_DOWN_ALL_PLL()	\
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG =	0x7F;
++
++#define	HAL_PWRMGT_POWER_ON_ALL_PLL() \
++    PWRMGT_PLL_POWER_DOWN_CONTROL_REG =	0;
++
++
++/*
++ * Macro defines for Pad Drive Strength	Control
++ */
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_PCMCIA_CARDBUS_MODE() \
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x3 << 0); \
++}
++
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_PCI_MODE()	\
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x3 << 0); \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG |= (0x1 << 0); \
++}
++
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_MII_MODE()	\
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG |= (0x1 << 2); \
++}
++
++#define	HAL_PWRMGT_SELECT_PAD_DRIVE_STRENGTH_RGMII_MODE() \
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x1 << 2); \
++}
++
++#define	HAL_PWRMGT_ENABLE_MII_PAD_SIGNAL_NOT_BOUNDED() \
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG |= (0x1 << 3); \
++}
++
++#define	HAL_PWRMGT_DISABLE_MII_PAD_SIGNAL_NOT_BOUNDED()	\
++{ \
++    PWRMGT_PAD_DRIVE_STRENGTH_CONTROL_REG &= ~(0x1 << 3); \
++}
++
++
++/*
++ * Macro defines for USB Device	Power Management
++ */
++#define	HAL_PWRMGT_REMOTE_WAKEUP_USB_HOST() \
++{ \
++    PWRMGT_USB_DEVICE_POWERMGT_REG |= (0x1 << 4); \
++}
++
++#define	HAL_PWRMGT_USB_DEVICE_PHY_CLOCK_SOURCE_EXTERNAL_12MHZ()	\
++{ \
++    PWRMGT_USB_DEVICE_POWERMGT_REG &= ~(0x1 << 5); \
++}
++
++#define	HAL_PWRMGT_USB_DEVICE_PHY_CLOCK_SOURCE_INTERNAL_12MHZ()	\
++{ \
++    PWRMGT_USB_DEVICE_POWERMGT_REG |= (0x1 << 5); \
++}
++
++
++/*
++ * Macro defines for Regulator Control
++ */
++
++
++#endif	// end of #ifndef _STAR_POWERMGT_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_rtc.h linux-2.6.35.11-ts7500/include/asm/arch/star_rtc.h
+--- linux-2.6.35.11/include/asm/arch/star_rtc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_rtc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,87 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_RTC_H_
++#define	_STAR_RTC_H_
++
++#include <mach/star_sys_memory_map.h>
++
++#define	RTC_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_RTC_BASE_ADDR + reg_offset)))
++
++#define	RTC_SECOND_REG				RTC_MEM_MAP_VALUE(0x00)
++#define	RTC_MINUTE_REG				RTC_MEM_MAP_VALUE(0x04)
++#define	RTC_HOUR_REG				RTC_MEM_MAP_VALUE(0x08)
++#define	RTC_DAY_REG				RTC_MEM_MAP_VALUE(0x0C)
++#define	RTC_SECOND_ALARM_REG			RTC_MEM_MAP_VALUE(0x10)
++#define	RTC_MINUTE_ALARM_REG			RTC_MEM_MAP_VALUE(0x14)
++#define	RTC_HOUR_ALARM_REG			RTC_MEM_MAP_VALUE(0x18)
++#define	RTC_RECORD_REG				RTC_MEM_MAP_VALUE(0x1C)
++#define	RTC_CONTROL_REG				RTC_MEM_MAP_VALUE(0x20)
++#define	RTC_INTERRUPT_STATUS_REG		RTC_MEM_MAP_VALUE(0x34)
++
++#define	RTC_ENABLE_BIT				(1 << 0)
++#define	RTC_AUTO_SECOND_ALARM_ENABLE_BIT	(1 << 1)
++#define	RTC_AUTO_MINUTE_ALARM_ENABLE_BIT	(1 << 2)
++#define	RTC_AUTO_HOUR_ALARM_ENABLE_BIT		(1 << 3)
++#define	RTC_AUTO_DAY_ALARM_ENABLE_BIT		(1 << 4)
++#define	RTC_MATCH_ALARM_ENABLE_BIT		(1 << 5)
++#define	RTC_BATTERY_LOW_VOLTAGE_ENABLE_BIT	(1 << 6)
++
++#define RTC_AUTO_SECOND_ALARM_INTR_BIT      (1 << 0)
++#define RTC_AUTO_MINUTE_ALARM_INTR_BIT      (1 << 1)
++#define RTC_AUTO_HOUR_ALARM_INTR_BIT        (1 << 2)
++#define RTC_AUTO_DAY_ALARM_INTR_BIT         (1 << 3)
++#define RTC_MATCH_ALARM_INTR_BIT            (1 << 4)
++#define RTC_BATTERY_LOW_VOLTAGE_INTR_BIT    (1 << 5)
++
++#define	HAL_RTC_READ_SECOND(second)         ((second) = (RTC_SECOND_REG) & 0x3F);
++#define	HAL_RTC_READ_MINUTE(minute)         ((minute) = (RTC_MINUTE_REG) & 0x3F);
++#define	HAL_RTC_READ_HOUR(hour)	            ((hour) = (RTC_HOUR_REG) & 0x1F);
++#define	HAL_RTC_READ_DAY(day)               ((day) = (RTC_DAY_REG) & 0xFFFF);
++#define	HAL_RTC_ENABLE()                    ((RTC_CONTROL_REG) |= (RTC_ENABLE_BIT));
++#define	HAL_RTC_DISABLE()                   ((RTC_CONTROL_REG) &= ~(RTC_ENABLE_BIT));
++#define	HAL_RTC_AUTO_SECOND_ALARM_ENABLE()  ((RTC_CONTROL_REG) |= (RTC_AUTO_SECOND_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_SECOND_ALARM_DISABLE() ((RTC_CONTROL_REG) &= ~(RTC_AUTO_SECOND_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_MINUTE_ALARM_ENABLE()  ((RTC_CONTROL_REG) |= (RTC_AUTO_MINUTE_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_MINUTE_ALARM_DISABLE() ((RTC_CONTROL_REG) &= ~(RTC_AUTO_MINUTE_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_HOUR_ALARM_ENABLE()    ((RTC_CONTROL_REG) |= (RTC_AUTO_HOUR_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_HOUR_ALARM_DISABLE()   ((RTC_CONTROL_REG) &= ~(RTC_AUTO_HOUR_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_DAY_ALARM_ENABLE()	    ((RTC_CONTROL_REG) |= (RTC_AUTO_DAY_ALARM_ENABLE_BIT));
++#define	HAL_RTC_AUTO_DAY_ALARM_DISABLE()    ((RTC_CONTROL_REG) &= ~(RTC_AUTO_DAY_ALARM_ENABLE_BIT));
++#define	HAL_RTC_MATCH_ALARM_ENABLE()        ((RTC_CONTROL_REG) |= (RTC_MATCH_ALARM_ENABLE_BIT));
++#define	HAL_RTC_MATCH_ALARM_DISABLE()       ((RTC_CONTROL_REG) &= ~(RTC_MATCH_ALARM_ENABLE_BIT));
++#define	HAL_RTC_BATTERY_LOW_VOLTAGE_INTERRUPT_ENABLE()   ((RTC_CONTROL_REG) |= (RTC_BATTERY_LOW_VOLTAGE_ENABLE_BIT));
++#define	HAL_RTC_BATTERY_LOW_VOLTAGE_INTERRUPT_DISABLE()	 ((RTC_CONTROL_REG) &= ~(RTC_BATTERY_LOW_VOLTAGE_ENABLE_BIT));
++#define	HAL_RTC_WRITE_RECORD(record)        ((RTC_RECORD_REG) =	(record));
++#define	HAL_RTC_READ_RECORD(record)         ((record) =	(RTC_RECORD_REG)); 
++#define	HAL_RTC_WRITE_MATCHED_ALARM_SECOND(second)  ((RTC_SECOND_ALARM_REG) = (second &	0x3F));
++#define	HAL_RTC_READ_MATCHED_ALARM_SECOND(second)   ((second) =	(RTC_SECOND_ALARM_REG) & 0x3F);
++#define	HAL_RTC_WRITE_MATCHED_ALARM_MINUTE(minute)  ((RTC_MINUTE_ALARM_REG) = (minute &	0x3F));
++#define	HAL_RTC_READ_MATCHED_ALARM_MINUTE(minute)   ((minute) =	(RTC_MINUTE_ALARM_REG) & 0x3F);
++#define	HAL_RTC_WRITE_MATCHED_ALARM_HOUR(hour)      ((RTC_HOUR_ALARM_REG) = (hour & 0x1F));
++#define	HAL_RTC_READ_MATCHED_ALARM_HOUR(hour)       ((hour) = (RTC_HOUR_ALARM_REG) & 0x1F);
++#define	HAL_RTC_READ_INTERRUPT_STATUS(status)       ((status) =	(RTC_INTERRUPT_STATUS_REG) & 0x3F);
++#define	HAL_RTC_WRITE_INTERRUPT_STATUS(status)      ((RTC_INTERRUPT_STATUS_REG)	= (status) & 0x3F);
++
++#endif
++
+diff -rupN linux-2.6.35.11/include/asm/arch/star_smc.h linux-2.6.35.11-ts7500/include/asm/arch/star_smc.h
+--- linux-2.6.35.11/include/asm/arch/star_smc.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_smc.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,57 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_SMC_H_
++#define	_STAR_SMC_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	SMC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSPA_SMC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	SMC_MEM_MAP_VALUE(reg_offset)	(*((u32 volatile *)(SYSVA_SMC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++
++/*
++ * Static Memory Controller Registers
++ */
++#define	SMC_MEM_BANK0_CONFIG_REG	SMC_MEM_MAP_VALUE(0x00)
++#define	SMC_MEM_BANK0_TIMING_REG	SMC_MEM_MAP_VALUE(0x04)
++#define	SMC_MEM_BANK1_CONFIG_REG	SMC_MEM_MAP_VALUE(0x08)
++#define	SMC_MEM_BANK1_TIMING_REG	SMC_MEM_MAP_VALUE(0x0C)
++#define	SMC_MEM_BANK2_CONFIG_REG	SMC_MEM_MAP_VALUE(0x10)
++#define	SMC_MEM_BANK2_TIMING_REG	SMC_MEM_MAP_VALUE(0x14)
++#define	SMC_MEM_BANK3_CONFIG_REG	SMC_MEM_MAP_VALUE(0x18)
++#define	SMC_MEM_BANK3_TIMING_REG	SMC_MEM_MAP_VALUE(0x1C)
++
++/*
++ * macros declarations
++ */
++
++#endif	// end of #ifndef _STAR_SMC_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_spi.h linux-2.6.35.11-ts7500/include/asm/arch/star_spi.h
+--- linux-2.6.35.11/include/asm/arch/star_spi.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_spi.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,169 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef _STAR_SPI_H_
++#define _STAR_SPI_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define SPI_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_SPI_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define SPI_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_SPI_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define SPI_CONFIGURATION_REG			SPI_MEM_MAP_VALUE(0x40)
++#define SPI_SERVICE_STATUS_REG			SPI_MEM_MAP_VALUE(0x44)
++#define SPI_BIT_RATE_CONTROL_REG		SPI_MEM_MAP_VALUE(0x48)
++#define SPI_TRANSMIT_CONTROL_REG		SPI_MEM_MAP_VALUE(0x4C)
++#define SPI_TRANSMIT_BUFFER_REG			SPI_MEM_MAP_VALUE(0x50)
++#define SPI_RECEIVE_CONTROL_REG			SPI_MEM_MAP_VALUE(0x54)
++#define SPI_RECEIVE_BUFFER_REG			SPI_MEM_MAP_VALUE(0x58)
++#define SPI_FIFO_TRANSMIT_CONFIG_REG		SPI_MEM_MAP_VALUE(0x5C)
++#define SPI_FIFO_TRANSMIT_CONTROL_REG		SPI_MEM_MAP_VALUE(0x60)
++#define SPI_FIFO_RECEIVE_CONFIG_REG		SPI_MEM_MAP_VALUE(0x64)
++#define SPI_INTERRUPT_STATUS_REG		SPI_MEM_MAP_VALUE(0x68)
++#define SPI_INTERRUPT_ENABLE_REG		SPI_MEM_MAP_VALUE(0x6C)
++
++
++/*
++ * define constants macros
++ */
++#define SPI_TX_RX_FIFO_DEPTH			(8)
++
++#define SPI_CH0					(0)
++#define SPI_CH1					(1)
++#define SPI_CH2					(2)
++#define SPI_CH3					(3)
++
++
++#define SPI_RXFIFO_OT_FG			(0x01)
++#define SPI_TXFIFO_UT_FG			(0x02)
++#define SPI_RXBUF_FULL_FG			(0x04)
++#define SPI_TXBUF_EMPTY_FG			(0x08)
++
++#define SPI_RXFIFO_OR_FG			(0x10)
++#define SPI_TXFIFO_UR_FG			(0x20)
++#define SPI_RXBUF_OR_FG				(0x40)
++#define SPI_TXBUF_UR_FG				(0x80)
++
++/*
++ * define Character Length Control
++ */
++#define SPI_LEN_BIT_8				(0)
++#define SPI_LEN_BIT_16				(1)
++#define SPI_LEN_BIT_24				(2)
++#define SPI_LEN_BIT_32				(3)
++
++
++/*
++ * macro declarations
++ */
++#define HAL_SPI_ENABLE_SPI() \
++{ \
++    (SPI_CONFIGURATION_REG) |= ((u_int32)0x1 << 31); \
++}
++
++#define HAL_SPI_DISABLE_SPI() \
++{ \
++    (SPI_CONFIGURATION_REG) &= ~((u_int32)0x1 << 31); \
++}
++
++#define HAL_SPI_ENABLE_DATA_SWAP() \
++{ \
++    (SPI_CONFIGURATION_REG) |= (0x1 << 24); \
++}
++
++#define HAL_SPI_DISABLE_DATA_SWAP() \
++{ \
++    (SPI_CONFIGURATION_REG) &= ~(0x1 << 24); \
++}
++
++#define HAL_SPI_TRANSMIT_DATA(tx_data) \
++{ \
++    (SPI_TRANSMIT_BUFFER_REG) = tx_data; \
++}
++
++#define HAL_SPI_RECEIVE_DATA(rx_data) \
++{ \
++    (rx_data) = SPI_RECEIVE_BUFFER_REG; \
++}
++
++#define HAL_SPI_GET_TRANSMIT_FIFO_WORDS_NUMBER(tx_fifo_words_num) \
++{ \
++    (tx_fifo_words_num) = SPI_FIFO_TRANSMIT_CONFIG_REG & 0xF; \
++}
++
++#define HAL_SPI_GET_RECEIVE_FIFO_WORDS_NUMBER(rx_fifo_words_num) \
++{ \
++    (rx_fifo_words_num) = SPI_FIFO_RECEIVE_CONFIG_REG & 0xF; \
++}
++
++#define HAL_SPI_DISABLE_ALL_INTERRUPT_SOURCES() \
++{ \
++    (SPI_INTERRUPT_ENABLE_REG) = 0; \
++}
++
++#define HAL_SPI_DISABLE_TX_FIFO_THRESHOLD_INTERRUPT() \
++{ \
++    (SPI_INTERRUPT_ENABLE_REG) &= ~(0x1 << 1); \
++}
++
++#define HAL_SPI_DISABLE_RX_FIFO_THRESHOLD_INTERRUPT() \
++{ \
++    (SPI_INTERRUPT_ENABLE_REG) &= ~(0x1 << 0); \
++}
++
++#define HAL_SPI_READ_INTERRUPT_STATUS(status) \
++{ \
++    (status) = SPI_INTERRUPT_STATUS_REG; \
++}
++
++#define HAL_SPI_CLEAR_INTERRUPT_STATUS(status) \
++{ \
++    (SPI_INTERRUPT_STATUS_REG) = (status & 0xF0); \
++}
++
++#define HAL_SPI_SET_FIFO_TRANSMIT_DELAY(delay) \
++{ \
++    (SPI_FIFO_TRANSMIT_CONTROL_REG) = (delay & 0x1F); \
++}
++
++#define STR8100_SPI_SERIAL_MODE_GENERAL              0x0
++#define STR8100_SPI_SERIAL_MODE_MICROPROCESSOR       0x1
++ 
++struct str8100_spi_dev_attr
++{ 
++	int spi_serial_mode;
++};
++
++#endif // end of #ifndef _STAR_SPI_H_
++
+diff -rupN linux-2.6.35.11/include/asm/arch/star_sys_memory_map.h linux-2.6.35.11-ts7500/include/asm/arch/star_sys_memory_map.h
+--- linux-2.6.35.11/include/asm/arch/star_sys_memory_map.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_sys_memory_map.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,109 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_SYS_MEMORY_MAP_H_
++#define	_STAR_SYS_MEMORY_MAP_H_
++
++
++#if 0
++#define __UBOOT__
++#else
++#define __LINUX__
++#endif
++
++
++/*
++ * sytem memory	mapping	after reset
++ */
++#define SYSPA_FLASH_SRAM_BANK0_BASE_ADDR	0x10000000
++#define SYSPA_FLASH_SRAM_BANK1_BASE_ADDR	0x11000000
++#define SYSPA_FLASH_SRAM_BANK2_BASE_ADDR	0x12000000
++#define SYSPA_FLASH_SRAM_BANK3_BASE_ADDR	0x13000000
++#define	SYSPA_PCMCIA_ATTRIBUTE_MEMORY_BASE_ADDR	0x14000000
++#define	SYSPA_PCMCIA_COMMON_MEMORY_BASE_ADDR	0x15000000
++#define	SYSPA_PCMCIA_IO_SPACE_BASE_ADDR		0x16000000
++#define	SYSPA_IDE_DEVICE_BASE_ADDR		0x18000000
++#define	SYSPA_SDRAM_MEMORY_BASE_ADDR		0x20000000
++#define	SYSPA_GDMAC_BASE_ADDR			0x60000000
++#define	SYSPA_NIC_BASE_ADDR			0x70000000
++#define	SYSPA_SPI_BASE_ADDR			0x71000000
++#define	SYSPA_PCM_BASE_ADDR			0x71000000
++#define	SYSPA_I2C_BASE_ADDR			0x71000000
++#define	SYSPA_I2S_BASE_ADDR			0x71000000
++#define	SYSPA_DDRC_SDRC_BASE_ADDR		0x72000000
++#define	SYSPA_SMC_BASE_ADDR			0x73000000
++#define	SYSPA_PCMCIA_CONTROL_BASE_ADDR		0x73000000
++#define	SYSPA_IDE_CONTROLLER_BASE_ADDR		0x74000000
++#define	SYSPA_MISC_BASE_ADDR			0x76000000
++#define	SYSPA_POWER_MANAGEMENT_BASE_ADDR	0x77000000
++#define	SYSPA_UART0_BASE_ADDR			0x78000000
++#define	SYSPA_UART1_BASE_ADDR			0x78800000
++#define	SYSPA_TIMER_BASE_ADDR			0x79000000
++#define	SYSPA_WATCHDOG_TIMER_BASE_ADDR		0x7A000000
++#define	SYSPA_RTC_BASE_ADDR			0x7B000000
++#define	SYSPA_GPIOA_BASE_ADDR			0x7C000000
++#define	SYSPA_GPIOB_BASE_ADDR			0x7C800000
++#define	SYSPA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR	0xA0000000
++#define	SYSPA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR	0xA4000000
++#define	SYSPA_PCI_IO_SPACE_BASE_ADDR		0xA8000000
++#define	SYSPA_PCI_MEMORY_SPACE_BASE_ADDR	0xB0000000
++#define	SYSPA_USB11_CONFIG_BASE_ADDR		0xC0000000
++#define	SYSPA_USB11_OPERATION_BASE_ADDR		0xC4000000
++#define	SYSPA_USB20_CONFIG_BASE_ADDR		0xC8000000
++#define	SYSPA_USB20_OPERATION_BASE_ADDR		0xCC000000
++#define	SYSPA_USB20_DEVICE_BASE_ADDR		0xD0000000
++#define	SYSPA_VIC_BASE_ADDR			0xFFFFF000
++
++#if defined(__LINUX__)
++#define	SYSVA_FLASH_BASE_ADDR				0xFF000000
++#define SYSVA_IDE_DEVICE_BASE_ADDR		0xFFF00000
++#define SYSVA_GDMAC_BASE_ADDR			0xFFF01000
++#define SYSVA_NIC_BASE_ADDR			0xFFF02000
++#define SYSVA_SPI_BASE_ADDR			0xFFF03000
++#define SYSVA_PCM_BASE_ADDR			0xFFF04000
++#define SYSVA_I2C_BASE_ADDR			0xFFF05000
++#define SYSVA_I2S_BASE_ADDR			0xFFF06000
++#define SYSVA_DDRC_SDRC_BASE_ADDR		0xFFF07000
++#define SYSVA_SMC_BASE_ADDR			0xFFF08000
++#define SYSVA_PCMCIA_CONTROL_BASE_ADDR		0xFFF09000
++#define SYSVA_IDE_CONTROLLER_BASE_ADDR		0xFFF0A000
++#define SYSVA_MISC_BASE_ADDR			0xFFF0B000
++#define SYSVA_POWER_MANAGEMENT_BASE_ADDR	0xFFF0C000
++#define SYSVA_UART0_BASE_ADDR			0xFFF0D000
++#define SYSVA_UART1_BASE_ADDR			0xFFF0E000
++#define SYSVA_TIMER_BASE_ADDR			0xFFF0F000
++#define SYSVA_WATCHDOG_TIMER_BASE_ADDR		0xFFF10000
++#define SYSVA_RTC_BASE_ADDR			0xFFF11000
++#define SYSVA_GPIOA_BASE_ADDR			0xFFF12000
++#define SYSVA_GPIOB_BASE_ADDR			0xFFF13000
++#define SYSVA_PCI_BRIDGE_CONFIG_DATA_BASE_ADDR	0xFFF14000
++#define SYSVA_PCI_BRIDGE_CONFIG_ADDR_BASE_ADDR	0xFFF15000
++#define SYSVA_USB11_CONFIG_BASE_ADDR		0xFFF16000
++#define SYSVA_USB11_OPERATION_BASE_ADDR		0xFFF17000
++#define SYSVA_USB20_CONFIG_BASE_ADDR		0xFFF18000
++#define SYSVA_USB20_OPERATION_BASE_ADDR		0xFFF19000
++#define SYSVA_USB20_DEVICE_BASE_ADDR		0xFFF1A000
++#define SYSVA_VIC_BASE_ADDR			0xFFF1B000
++#endif //__LINUX__
++
++#endif // end of #ifndef _STAR_SYS_MEMORY_MAP_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_timer.h linux-2.6.35.11-ts7500/include/asm/arch/star_timer.h
+--- linux-2.6.35.11/include/asm/arch/star_timer.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_timer.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,312 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_TIMER_H_
++#define	_STAR_TIMER_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	TIMER_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSPA_TIMER_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	TIMER_MEM_MAP_VALUE(reg_offset)		(*((u32 volatile *)(SYSVA_TIMER_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	TIMER1_COUNTER_REG			TIMER_MEM_MAP_VALUE(0x00)
++#define	TIMER1_AUTO_RELOAD_VALUE_REG		TIMER_MEM_MAP_VALUE(0x04)
++#define	TIMER1_MATCH_VALUE1_REG			TIMER_MEM_MAP_VALUE(0x08)
++#define	TIMER1_MATCH_VALUE2_REG			TIMER_MEM_MAP_VALUE(0x0C)
++
++#define	TIMER2_COUNTER_REG			TIMER_MEM_MAP_VALUE(0x10)
++#define	TIMER2_AUTO_RELOAD_VALUE_REG		TIMER_MEM_MAP_VALUE(0x14)
++#define	TIMER2_MATCH_VALUE1_REG			TIMER_MEM_MAP_VALUE(0x18)
++#define	TIMER2_MATCH_VALUE2_REG			TIMER_MEM_MAP_VALUE(0x1C)
++
++#define	TIMER1_TIMER2_CONTROL_REG		TIMER_MEM_MAP_VALUE(0x30)
++#define	TIMER1_TIMER2_INTERRUPT_STATUS_REG	TIMER_MEM_MAP_VALUE(0x34)
++#define	TIMER1_TIMER2_INTERRUPT_MASK_REG	TIMER_MEM_MAP_VALUE(0x38)
++
++#define	TIMER3_COUNTER_LOW_REG			TIMER_MEM_MAP_VALUE(0x40)
++#define	TIMER3_CONTROL_REG			TIMER_MEM_MAP_VALUE(0x44)
++
++
++/*
++ * define constants macros
++ */
++#define	TIMER1_ENABLE_BIT_INDEX			0
++#define	TIMER1_CLOCK_SOURCE_BIT_INDEX		1
++#define	TIMER1_OVERFLOW_ENABLE_BIT_INDEX	2
++
++#define	TIMER2_ENABLE_BIT_INDEX			3
++#define	TIMER2_CLOCK_SOURCE_BIT_INDEX		4
++#define	TIMER2_OVERFLOW_ENABLE_BIT_INDEX	5
++
++#define	TIMER1_UP_DOWN_COUNT_BIT_INDEX		9
++#define	TIMER2_UP_DOWN_COUNT_BIT_INDEX		10
++
++#define	TIMER1_MATCH1_INTERRUPT_BIT_INDEX	0
++#define	TIMER1_MATCH2_INTERRUPT_BIT_INDEX	1
++#define	TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX	2
++
++#define	TIMER2_MATCH1_INTERRUPT_BIT_INDEX	3
++#define	TIMER2_MATCH2_INTERRUPT_BIT_INDEX	4
++#define	TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX	5
++
++#define TIMER3_ENABLE_BIT_INDEX			17
++#define TIMER3_RESET_BIT_INDEX			16
++
++#define	TIMER_CLOCK_SOURCE_PCLK			0
++#define	TIMER_CLOCK_SOURCE_EXT_CLK		1
++
++
++#define	TIMER_OVERFLOW_MODE_DISABLE		0
++#define	TIMER_OVERFLOW_MODE_ENABLE		1
++
++
++#define	TIMER_COUNTER_MODE_UP			0
++#define	TIMER_COUNTER_MODE_DOWN			1
++
++
++#define	MATCH1_MASK_ENABLE			(1 << 0)
++
++#define	MATCH2_MASK_ENABLE			(1 << 1)
++
++#define	OVERFLOW_MASK_ENABLE			(1 << 2)
++
++
++/*
++ * macro declarations
++ */
++#define	HAL_TIMER_ENABLE_TIMER1() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER1_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER1() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER1_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER2() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER2_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER2() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER2_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER1_OVERFLOW_MODE()	\
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER1_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER1_OVERFLOW_MODE() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER1_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER2_OVERFLOW_MODE()	\
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER2_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER2_OVERFLOW_MODE() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER2_OVERFLOW_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER1_DOWNCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER1_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER1_UPCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER1_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER2_DOWNCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) |= (1 << TIMER2_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_SET_TIMER2_UPCOUNT() \
++{ \
++    ((TIMER1_TIMER2_CONTROL_REG) &= ~(1	<< TIMER2_UP_DOWN_COUNT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_READ_INTERRUPT_STATUS(interrupt_status) \
++{ \
++    ((interrupt_status)	= (TIMER1_TIMER2_INTERRUPT_STATUS_REG)); \
++}
++
++
++#define	HAL_TIMER_WRITE_INTERRUPT_STATUS(interrupt_status) \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_STATUS_REG) = (interrupt_status)); \
++}
++
++
++#define	HAL_TIMER_READ_INTERRUPT_MASK(interrupt_mask) \
++{ \
++    ((interrupt_mask) =	(TIMER1_TIMER2_INTERRUPT_MASK_REG)); \
++}
++
++
++#define	HAL_TIMER_WRITE_INTERRUPT_MASK(interrupt_mask) \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	= (interrupt_mask)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_TIMER2_ALL_INTERRUPTS() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	= (0x3F));\
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER1_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER1_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER1_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER1_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER1_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER1_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER1_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER1_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER1_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER2_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER2_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER2_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER2_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_MASK_TIMER2_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	|= (1 << TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER2_MATCH1_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER2_MATCH1_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER2_MATCH2_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER2_MATCH2_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_UNMASK_TIMER2_OVERFLOW_INTERRUPT() \
++{ \
++    ((TIMER1_TIMER2_INTERRUPT_MASK_REG)	&= ~(1 << TIMER2_OVERFLOW_INTERRUPT_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_DISABLE_TIMER3() \
++{ \
++    ((TIMER3_CONTROL_REG) = 0); \
++}
++
++
++#define	HAL_TIMER_ENABLE_TIMER3() \
++{ \
++    ((TIMER3_CONTROL_REG) = (1 << TIMER3_ENABLE_BIT_INDEX)); \
++}
++
++
++#define	HAL_TIMER_RESET_TIMER3() \
++{ \
++    ((TIMER3_CONTROL_REG) = (1 << TIMER3_RESET_BIT_INDEX)); \
++}
++
++#ifndef __ASSEMBLY__
++static inline unsigned long long HAL_TIMER_GET_TIMER3_COUNTER(void)
++{
++	unsigned long h;
++	unsigned long l;
++
++	h = TIMER3_CONTROL_REG & 0xFFFF;
++	l = TIMER3_COUNTER_LOW_REG;
++
++	return ((((unsigned long long)h) << 32) | l);
++}
++#endif
++
++#endif	// end of #ifndef _STAR_TIMER_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_uart.h linux-2.6.35.11-ts7500/include/asm/arch/star_uart.h
+--- linux-2.6.35.11/include/asm/arch/star_uart.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_uart.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,350 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_UART_H_
++#define	_STAR_UART_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#define	UART_MEM_MAP_VALUE_PHY(reg_offset)	(*((u32	volatile *)(SYSPA_UART0_BASE_ADDR + reg_offset)))
++#define	UART_MEM_MAP_VALUE_VIR(reg_offset)	(*((u32	volatile *)(SYSVA_UART0_BASE_ADDR + reg_offset)))
++
++
++#define	UART1_OFFSET		0x800000  //SYS_UART1_BASE_ADDR	= 0x78800000 = (UART1_OFFSET+ SYS_UART0_BASE_ADDR)
++
++#define	__UART_RBR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	__UART_THR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	__UART_DLL(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++
++#define	__UART_IER(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++#define	__UART_DLM(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++
++#define	__UART_IIR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	__UART_FCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	__UART_PSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++
++#define	__UART_LCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x0C)
++#define	__UART_MCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x10) //UART(n) Control Reg
++#define	__UART_LSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x14)
++#define	__UART_SPR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x1C)
++
++#if defined(__UBOOT__)
++#define	_UART_RBR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	_UART_THR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++#define	_UART_DLL(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x00)
++
++#define	_UART_IER(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++#define	_UART_DLM(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x04)
++
++#define	_UART_IIR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	_UART_FCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++#define	_UART_PSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x08)
++
++#define	_UART_LCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x0C)
++#define	_UART_MCR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x10) //UART(n) Control Reg
++#define	_UART_LSR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x14)
++#define	_UART_SPR(idx)		UART_MEM_MAP_VALUE_PHY((UART1_OFFSET * idx) + 0x1C)
++#elif defined(__LINUX__)
++#define	_UART_RBR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x00)
++#define	_UART_THR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x00)
++#define	_UART_DLL(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x00)
++
++#define	_UART_IER(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x04)
++#define	_UART_DLM(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x04)
++
++#define	_UART_IIR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x08)
++#define	_UART_FCR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x08)
++#define	_UART_PSR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x08)
++
++#define	_UART_LCR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x0C)
++#define	_UART_MCR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x10) //UART(n) Control Reg
++#define	_UART_LSR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x14)
++#define	_UART_SPR(idx)		UART_MEM_MAP_VALUE_VIR((UART1_OFFSET * idx) + 0x1C)
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define constants macros
++ */
++#define	UART_INPUT_CLOCK		(13000000)
++
++
++#define	UART_FIFO_DEPTH			16
++
++
++#define	RX_DATA_READY_INT		(1 << 0)
++#define	THR_EMPTY_INT			(1 << 1)
++#define	RX_LINE_STATUS_INT		(1 << 2)
++#define	MODEM_STATUS_INT		(1 << 3)
++
++
++#define	NO_INT_PENDING_MASK		(0x1)
++#define	RX_LINE_STATUS_INT_MASK		(0x6)
++#define	RX_DATA_READY_INT_MASK		(0x4)
++#define	RX_DATA_TIMEOUT_INT_MASK	(0xC)
++#define	THR_EMPTY_INT_MASK		(0x2)
++#define	MODEM_STATUS_CHANGE_MASK	(0x0)
++
++
++/* FCR Register	*/
++#define	FIFO_ENABLE			(1 << 0)
++#define	RX_FIFO_RESET			(1 << 1)
++#define	TX_FIFO_RESET			(1 << 2)
++#define	DMA_MODE			(1 << 3)
++
++
++#define	RX_FIFO_TRIGGER_LEVEL_1		(0 << 6)
++#define	RX_FIFO_TRIGGER_LEVEL_4		(1 << 6)
++#define	RX_FIFO_TRIGGER_LEVEL_8		(2 << 6)
++#define	RX_FIFO_TRIGGER_LEVEL_14	(3 << 6)
++
++
++#define	TX_FIFO_TRIGGER_LEVEL_1		(0 << 4)
++#define	TX_FIFO_TRIGGER_LEVEL_3		(1 << 4)
++#define	TX_FIFO_TRIGGER_LEVEL_9		(2 << 4)
++#define	TX_FIFO_TRIGGER_LEVEL_13	(3 << 4)
++
++
++
++/* LCR Register	*/
++#define	WORD_LENGTH_5			(0 << 0)
++#define	WORD_LENGTH_6			(1 << 0)
++#define	WORD_LENGTH_7			(2 << 0)
++#define	WORD_LENGTH_8			(3 << 0)
++
++#define	STOP_BIT_1			(0 << 2)
++#define	STOP_BIT_1_5			(1 << 2)
++#define	STOP_BIT_2			(1 << 2)
++
++#define	PARITY_CHECK_NONE		(0 << 3)
++#define	PARITY_CHECK_EVEN		(3 << 3)
++#define	PARITY_CHECK_ODD		(1 << 3)
++#define	PARITY_CHECK_STICK_ONE		(5 << 3)
++#define	PARITY_CHECK_STICK_ZERO		(7 << 3)
++
++#define	SET_BREAK			(1 << 6)
++
++#define	DLAB_ENABLE			(1 << 7)
++
++/* MCR Register	*/
++//#define UART_MCR_DTR			0x1		/* Data	Terminal Ready */
++//#define UART_MCR_RTS			0x2		/* Request to Send */
++//#define UART_MCR_OUT1			0x4		/* output1 */
++//#define UART_MCR_OUT2			0x8		/* output2 or global interrupt enable */
++#define	UART_MCR_LPBK			0x10		/* loopback mode */
++
++
++/* LSR Register	*/
++#define	_DATA_READY			(1 << 0)
++#define	OVERRUN_ERROR			(1 << 1)
++#define	PARITY_ERROR			(1 << 2)
++#define	FRAMING_ERROR			(1 << 3)
++#define	BREAK_INTERRUPT			(1 << 4)
++#define	THR_EMPTY			(1 << 5)
++#define	TRANSMITTER_EMPTY		(1 << 6)
++#define	FIFO_DATA_ERROR			(1 << 7)
++
++#define	TEST_PARITY_ERROR		(1 << 0)
++#define	TEST_FRAMING_ERROR		(1 << 1)
++#define	TEST_BAUD_GEN			(1 << 2)
++#define	TEST_LOOPBACK_ENABLE		(1 << 3)
++
++
++#define	WORD_FIVE_BITS			5
++#define	WORD_SIX_BITS			6
++#define	WORD_SEVEN_BITS			7
++#define	WORD_EIGHT_BITS			8
++
++#define	NONE_PARITY			1
++#define	EVEN_PARITY			2
++#define	ODD_PARITY			3
++#define	ONE_PARITY			4
++#define	ZERO_PARITY			5
++
++#define	ONE_STOP_BIT			1
++#define	ONE_HALF_STOP_BIT		2
++#define	TWO_STOP_BIT			3
++
++#define	TX_RX_FIFO_DISABLE		0
++#define	TX_RX_FIFO_ENABLE		1
++
++
++/*
++ * macros declarations
++ */
++
++#define	HAL_UART_READ_DATA(idx,data) \
++{ \
++    ((data) = (_UART_RBR(idx)) & 0xFF);	\
++}
++
++
++#define	HAL_UART_WRITE_DATA(idx,data) \
++{ \
++    ((_UART_THR(idx)) =	(data) & 0xFF);	\
++}
++
++
++#define	HAL_UART_ENABLE_INTERRUPT_TYPE(idx,interrupt_type) \
++{ \
++    ((_UART_IER(idx)) |= (interrupt_type & 0xF)); \
++}
++
++
++#define	HAL_UART_DISABLE_INTERRUPT_TYPE(idx,interrupt_type) \
++{ \
++    ((_UART_IER(idx)) &= ~(interrupt_type & 0xF)); \
++}
++
++
++#define	HAL_UART_READ_INTERRUPT_IDENTIFICATION(idx,uart_IIR) \
++{ \
++    ((uart_IIR)	= (_UART_IIR(idx))); \
++}
++
++
++#define	HAL_UART_CHECK_NO_INT_PENDING(idx,uart_IIR) \
++{ \
++    (((uart_IIR) & 0xF)	== (NO_INT_PENDING_MASK)); \
++}
++
++
++#define	HAL_UART_CHECK_RX_LINE_STATUS_INT(idx,uart_IIR)	\
++    (((uart_IIR) & 0xF)	== (RX_LINE_STATUS_INT_MASK))
++
++
++#define	HAL_UART_CHECK_RX_DATA_READY_INT(idx,uart_IIR) \
++    (((uart_IIR) & 0xF)	== (RX_DATA_READY_INT_MASK))
++
++
++#define	HAL_UART_CHECK_RX_DATA_TIMEOUT_INT(idx,uart_IIR) \
++    (((uart_IIR) & 0xF)	== (RX_DATA_TIMEOUT_INT_MASK))
++
++
++#define	HAL_UART_CHECK_THR_EMPTY_INT(idx,uart_IIR) \
++    (((uart_IIR) & 0xF)	== (THR_EMPTY_INT_MASK))
++
++
++#define	HAL_UART_FIFO_ENABLE(idx) \
++{ \
++    ((_UART_FCR(idx)) |= (FIFO_ENABLE)); \
++}
++
++
++#define	HAL_UART_FIFO_DISABLE(idx) \
++{ \
++    ((_UART_FCR(idx)) &= ~(FIFO_ENABLE)); \
++}
++
++
++#define	HAL_UART_RESET_RX_FIFO(idx) \
++{ \
++   ((_UART_FCR(idx)) |=	(RX_FIFO_RESET)); \
++}
++
++
++#define	HAL_UART_RESET_TX_FIFO(idx) \
++{ \
++    ((_UART_FCR(idx)) |= (TX_FIFO_RESET)); \
++}
++
++
++#define	HAL_UART_DLAB_ENABLE(idx) \
++{ \
++    ((_UART_LCR(idx)) |= (DLAB_ENABLE)); \
++}
++
++
++#define	HAL_UART_DLAB_DISABLE(idx) \
++{ \
++    ((_UART_LCR(idx)) &= ~(DLAB_ENABLE)); \
++}
++
++
++#define	HAL_UART_ENABLE_LOOPBACK_MODE(idx) \
++{ \
++    ((_UART_MCR(idx)) |= (UART_MCR_LPBK)); \
++}
++
++
++#define	HAL_UART_DISABLE_LOOPBACK_MODE(idx) \
++{ \
++    ((_UART_MCR(idx)) &= ~(UART_MCR_LPBK)); \
++}
++
++
++#define	HAL_UART_READ_LINE_STATUS(idx,uart_LSR)	\
++{ \
++    ((uart_LSR)	= (_UART_LSR(idx))); \
++}
++
++
++#define	HAL_UART_WRITE_DLL(idx,dll_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    _UART_DLL(idx) = (u32)dll_value; \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_WRITE_DLM(idx,dlm_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    _UART_DLM(idx) = (u32)dlm_value; \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_WRITE_PSR(idx,psr_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    _UART_PSR(idx) = (u32)(psr_value & 0x3); \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_READ_PSR(idx,psr_value) \
++{ \
++    HAL_UART_DLAB_ENABLE(idx); \
++    (psr_value)	= (u32)((_UART_PSR(idx)) & 0x3); \
++    HAL_UART_DLAB_DISABLE(idx);	\
++}
++
++
++#define	HAL_UART_CHECK_RX_DATA_READY(idx) \
++    (((_UART_LSR(idx)) & _DATA_READY) == (_DATA_READY))
++
++
++#define	HAL_UART_CHECK_TX_FIFO_EMPTY(idx) \
++    (((_UART_LSR(idx)) & THR_EMPTY) == (THR_EMPTY))
++
++
++#define	HAL_UART_CHECK_TRANSMITTER_EMPTY(idx) \
++    (((_UART_LSR(idx)) & TRANSMITTER_EMPTY) == (TRANSMITTER_EMPTY))
++
++
++#endif	// end of #ifndef _STAR_UART_H_
+diff -rupN linux-2.6.35.11/include/asm/arch/star_wdtimer.h linux-2.6.35.11-ts7500/include/asm/arch/star_wdtimer.h
+--- linux-2.6.35.11/include/asm/arch/star_wdtimer.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/arch/star_wdtimer.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,170 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_WATCHDOG_TIMER_H_
++#define	_STAR_WATCHDOG_TIMER_H_
++
++
++#include <mach/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	WDTIMER_MEM_MAP_VALUE(reg_offset)	(*((u32	volatile *)(SYSPA_WATCHDOG_TIMER_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	WDTIMER_MEM_MAP_VALUE(reg_offset)	(*((u32	volatile *)(SYSVA_WATCHDOG_TIMER_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	WDTIMER_COUNTER_REG			WDTIMER_MEM_MAP_VALUE(0x00)
++#define	WDTIMER_AUTO_RELOAD_REG			WDTIMER_MEM_MAP_VALUE(0x04)
++#define	WDTIMER_COUNTER_RESTART_REG		WDTIMER_MEM_MAP_VALUE(0x08)
++#define	WDTIMER_CONTROL_REG			WDTIMER_MEM_MAP_VALUE(0x0C)
++#define	WDTIMER_STATUS_REG			WDTIMER_MEM_MAP_VALUE(0x10)
++#define	WDTIMER_CLEAR_REG			WDTIMER_MEM_MAP_VALUE(0x14)
++#define	WDTIMER_INTERRUPT_LENGTH_REG		WDTIMER_MEM_MAP_VALUE(0x18)
++
++
++/*
++ * define constants macros
++ */
++#define	WDTIMER_ENABLE_BIT			(1 << 0)
++#define	WDTIMER_SYSTEM_RESET_ENABLE_BIT		(1 << 1)
++#define	WDTIMER_SYSTEM_INTERRUPT_ENABLE_BIT	(1 << 2)
++#define	WDTIMER_EXTERNAL_SIGNAL_ENABLE_BIT	(1 << 3)
++#define	WDTIMER_EXTERNAL_CLOCK_ENABLE_BIT	(1 << 4)
++
++
++#define	WDTIMER_MAGIC_RESTART_VALUE		(0x5AB9)
++
++
++/*
++ * macros declarations
++ */
++#define	HAL_WDTIMER_READ_COUNTER(counter) \
++{ \
++    ((counter) = (WDTIMER_COUNTER_REG)); \
++}
++
++
++#define	HAL_WDTIMER_WRITE_AUTO_RELOAD_COUNTER(counter) \
++{ \
++    ((WDTIMER_AUTO_RELOAD_REG) = (counter)); \
++}
++
++
++#define	HAL_WDTIMER_READ_AUTO_RELOAD_COUNTER(counter) \
++{ \
++    ((counter) = (WDTIMER_AUTO_RELOAD_REG)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_RESTART_RELOAD() \
++{ \
++    ((WDTIMER_COUNTER_RESTART_REG) = (WDTIMER_MAGIC_RESTART_VALUE)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_SYSTEM_RESET() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_SYSTEM_RESET_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE_SYSTEM_RESET() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_SYSTEM_RESET_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_SYSTEM_INTERRUPT() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_SYSTEM_INTERRUPT_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE_SYSTEM_INTERRUPT() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_SYSTEM_INTERRUPT_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_ENABLE_EXTERNAL_SIGNAL() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_EXTERNAL_SIGNAL_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_DISABLE_EXTERNAL_SIGNAL() \
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_EXTERNAL_SIGNAL_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_CLOCK_SOURCE_PCLK()	\
++{ \
++    ((WDTIMER_CONTROL_REG) &= ~(WDTIMER_EXTERNAL_CLOCK_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_CLOCK_SOURCE_EXTCLK() \
++{ \
++    ((WDTIMER_CONTROL_REG) |= (WDTIMER_EXTERNAL_CLOCK_ENABLE_BIT)); \
++}
++
++
++#define	HAL_WDTIMER_READ_STATUS(status)	\
++{ \
++    ((status) =	(WDTIMER_STATUS_REG) & 0x00000001); \
++}
++
++
++#define	HAL_WDTIMER_CLEAR_STATUS() \
++{ \
++    ((WDTIMER_CLEAR_REG) = (1)); \
++}
++
++
++#define	HAL_WDTIMER_WRITE_INTERRUPT_LENGTH(length) \
++{ \
++    ((WDTIMER_INTERRUPT_LENGTH_REG) = (length) & 0x000000FF); \
++}
++
++
++#endif	// end of #ifndef _STAR_WATCHDOG_TIMER_H_
+diff -rupN linux-2.6.35.11/include/asm/hardware.h linux-2.6.35.11-ts7500/include/asm/hardware.h
+--- linux-2.6.35.11/include/asm/hardware.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm/hardware.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,18 @@
++/*
++ *  linux/include/asm-arm/hardware.h
++ *
++ *  Copyright (C) 1996 Russell King
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  Common hardware definitions
++ */
++
++#ifndef __ASM_HARDWARE_H
++#define __ASM_HARDWARE_H
++
++#include <asm/arch/hardware.h>
++
++#endif
+diff -rupN linux-2.6.35.11/include/asm-arm/arch-str8100/star_nic.h linux-2.6.35.11-ts7500/include/asm-arm/arch-str8100/star_nic.h
+--- linux-2.6.35.11/include/asm-arm/arch-str8100/star_nic.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm-arm/arch-str8100/star_nic.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,346 @@
++/*******************************************************************************
++ *
++ *  Copyright (c) 2008 Cavium Networks 
++ * 
++ *  This file is free software; you can redistribute it and/or modify 
++ *  it under the terms of the GNU General Public License, Version 2, as 
++ *  published by the Free Software Foundation. 
++ *
++ *  This file is distributed in the hope that it will be useful, 
++ *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
++ *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
++ *
++ *  You should have received a copy of the GNU General Public License 
++ *  along with this file; if not, write to the Free Software 
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
++ *  visit http://www.gnu.org/licenses/. 
++ *
++ *  This file may also be available under a different license from Cavium. 
++ *  Contact Cavium Networks for more information
++ *
++ ******************************************************************************/
++
++#ifndef	_STAR_NIC_H_
++#define	_STAR_NIC_H_
++
++
++#include <asm/arch/star_sys_memory_map.h>
++
++
++#if defined(__UBOOT__)
++#define	NIC_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSPA_NIC_BASE_ADDR + reg_offset)))
++#elif defined(__LINUX__)
++#define	NIC_MEM_MAP_VALUE(reg_offset)		(*((u32	volatile *)(SYSVA_NIC_BASE_ADDR + reg_offset)))
++#else
++#error "NO SYSTEM DEFINED"
++#endif
++
++
++/*
++ * define access macros
++ */
++#define	NIC_PHY_CONTROL_REG0			NIC_MEM_MAP_VALUE(0x000)
++#define	NIC_PHY_CONTROL_REG1			NIC_MEM_MAP_VALUE(0x004)
++
++#define	NIC_MAC_CONTROL_REG			NIC_MEM_MAP_VALUE(0x008)
++#define	NIC_FLOW_CONTROL_CONFIG_REG		NIC_MEM_MAP_VALUE(0x00C)
++
++#define	NIC_ARL_CONFIG_REG			NIC_MEM_MAP_VALUE(0x010)
++
++#define	NIC_MY_MAC_HIGH_BYTE_REG		NIC_MEM_MAP_VALUE(0x014)
++#define	NIC_MY_MAC_LOW_BYTE_REG			NIC_MEM_MAP_VALUE(0x018)
++
++#define	NIC_HASH_TABLE_CONTROL_REG		NIC_MEM_MAP_VALUE(0x01C)
++
++#define	NIC_MY_VLANID_CONTROL_REG		NIC_MEM_MAP_VALUE(0x020)
++
++#define	NIC_MY_VLANID_0_1			NIC_MEM_MAP_VALUE(0x024)
++#define	NIC_MY_VLANID_2_3			NIC_MEM_MAP_VALUE(0x028)
++
++#define	NIC_DMA_CONFIG_REG			NIC_MEM_MAP_VALUE(0x030)
++#define	NIC_TX_DMA_CONTROL_REG			NIC_MEM_MAP_VALUE(0x034)
++#define	NIC_RX_DMA_CONTROL_REG			NIC_MEM_MAP_VALUE(0x038)
++#define	NIC_TX_DESC_PTR_REG			NIC_MEM_MAP_VALUE(0x03C)
++#define	NIC_RX_DESC_PTR_REG			NIC_MEM_MAP_VALUE(0x040)
++
++#define	NIC_TX_DESC_BASE_ADDR_REG		NIC_MEM_MAP_VALUE(0x044)
++#define	NIC_RX_DESC_BASE_ADDR_REG		NIC_MEM_MAP_VALUE(0x048)
++#define	NIC_DELAYED_INT_CONFIG_REG		NIC_MEM_MAP_VALUE(0x04C)
++
++#define	NIC_INT_STATUS_REG			NIC_MEM_MAP_VALUE(0x050)
++#define	NIC_INT_MASK_REG			NIC_MEM_MAP_VALUE(0x054)
++
++#define	NIC_TEST_0_REG				NIC_MEM_MAP_VALUE(0x058)
++#define	NIC_TEST_1_REG				NIC_MEM_MAP_VALUE(0x05C)
++
++#define	NIC_MIB_RX_OK_PKT_CNTR			NIC_MEM_MAP_VALUE(0x100)
++#define	NIC_MIB_RX_OK_BYTE_CNTR			NIC_MEM_MAP_VALUE(0x104)
++#define	NIC_MIB_RX_RUNT_BYTE_CNTR		NIC_MEM_MAP_VALUE(0x108)
++#define	NIC_MIB_RX_OSIZE_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x10C)
++
++#define	NIC_MIB_RX_NO_BUF_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x110)
++
++#define	NIC_MIB_RX_CRC_ERR_PKT_CNTR		NIC_MEM_MAP_VALUE(0x114)
++
++#define	NIC_MIB_RX_ARL_DROP_PKT_CNTR		NIC_MEM_MAP_VALUE(0x118)
++
++#define	NIC_MIB_MYVLANID_MISMATCH_DROP_PKT_CNTR	NIC_MEM_MAP_VALUE(0x11C)
++
++#define	NIC_MIB_RX_CHKSUM_ERR_PKT_CNTR		NIC_MEM_MAP_VALUE(0x120)
++
++#define	NIC_MIB_RX_PAUSE_FRAME_PKT_CNTR		NIC_MEM_MAP_VALUE(0x124)
++
++#define	NIC_MIB_TX_OK_PKT_CNTR			NIC_MEM_MAP_VALUE(0x128)
++#define	NIC_MIB_TX_OK_BYTE_CNTR			NIC_MEM_MAP_VALUE(0x12C)
++
++#define	NIC_MIB_TX_COLLISION_CNTR		NIC_MEM_MAP_VALUE(0x130)
++#define	NIC_MIB_TX_PAUSE_FRAME_CNTR		NIC_MEM_MAP_VALUE(0x130)
++
++#define	NIC_MIB_TX_FIFO_UNDERRUN_RETX_CNTR	NIC_MEM_MAP_VALUE(0x134)
++
++
++
++
++/*
++ * define constants macros
++ */
++
++#define	NIC_PHY_ADDRESS		1 //the phy addr const	value
++#define	NIC_PHY_ID		0x0243	//the phy id
++
++#define	GW_NIC_MAX_TFD_NUM	(32)
++#define	GW_NIC_MAX_RFD_NUM	(32)
++#define	MAX_BUFFERS		(64)
++
++
++
++#define	MMU_OFF			(0)
++#define	MMU_ON			(1)
++#define	OS_NULL			(0)
++
++
++#define	NET_BUFFER_PACKET_SIZE		(512)
++#define	NET_BUFFER_SHIFT_BIT_NUM	(9)	// 2*n9=512
++
++#define	MAX_PACKET_LEN		(1536)
++
++#define	INTERNAL_LOOPBACK_MODE	(1)
++#define	SOFTWARE_REPEATER_MODE	(2)
++
++#define	TXTC_INT_BIT		(0x08000000)
++#define	TX_INSV_BIT		(0x04000000)
++
++#define	LS_BIT			(0x10000000)
++#define	FS_BIT			(0x20000000)
++#define	EOR_BIT			(0x40000000)
++#define	FS_LS_BIT		(0x30000000)
++#define	C_BIT			(0x80000000)
++#define	FS_LS_C_BIT		(0xB0000000)
++#define	FS_LS_INT_BIT		(0x38000000)
++
++
++
++// HASH	TABLE CONTROL REGISTER
++#define	NIC_HASH_TABLE_BIST_DONE_BIT	(0x1 <<	17)
++#define	NIC_HASH_TABLE_BIST_OK_BIT	(0x1 <<	16)
++#define	NIC_HASH_COMMAND_START_BIT	(0x1 <<	14)
++#define	NIC_HASH_COMMAND_BIT		(0x1 <<	13)
++#define	NIC_HASH_BIT_DATA		(0x1 <<	12)
++#define	NIC_HASH_BIT_ADDRESS_BIT	(0x1ff)
++
++
++#define	NIC_REG_CNT			((0x48 << 2) + 1)
++
++/*
++ * macro access
++ */
++
++#define	GW_NIC_TX_TFD_NEXT(work_tfd_ptr) \
++    work_tfd_ptr = NIC_TX_TFD_Ring.head	+ (((u32)(work_tfd_ptr - NIC_TX_TFD_Ring.head) + 1) % GW_NIC_MAX_TFD_NUM)
++
++
++#define	GW_NIC_TX_TFD_PREVIOUS(work_tfd_ptr) \
++    work_tfd_ptr = NIC_TX_TFD_Ring.head	+ ((GW_NIC_MAX_TFD_NUM + (u32)(work_tfd_ptr - NIC_TX_TFD_Ring.head) - 1) % GW_NIC_MAX_TFD_NUM)
++
++
++#define	GW_NIC_RX_RFD_NEXT(work_rfd_ptr) \
++    work_rfd_ptr = NIC_RX_RFD_Ring.head	+ (((u32)(work_rfd_ptr - NIC_RX_RFD_Ring.head) + 1) % GW_NIC_MAX_RFD_NUM)
++
++
++#define	GW_NIC_RX_RFD_PREVIOUS(work_rfd_ptr) \
++    work_rfd_ptr = NIC_RX_RFD_Ring.head	+ ((GW_NIC_MAX_RFD_NUM + (u32)(work_rfd_ptr - NIC_RX_RFD_Ring.head) - 1) % GW_NIC_MAX_RFD_NUM)
++
++
++/*
++ * PHY register	defines
++ */
++#define	PHY_MII_CONTROL_REG_ADDR		0x00
++#define	PHY_MII_STATUS_REG_ADDR			0x01
++#define	PHY_ID1_REG_ADDR			0x02
++#define	PHY_ID2_REG_ADDR			0x03
++#define	PHY_AN_ADVERTISEMENT_REG_ADDR		0x04
++#define	PHY_AN_REAMOTE_CAP_REG_ADDR		0x05
++
++
++#define	PHY_RESERVED1_REG_ADDR			0x10
++#define	PHY_RESERVED2_REG_ADDR			0x11
++#define	PHY_CH_STATUS_OUTPUT_REG_ADDR		0x12
++#define	PHY_RESERVED3_REG_ADDR			0x13
++#define	PHY_RESERVED4_REG_ADDR			0x14
++
++
++#define	PHY_SPEC_CONTROL_REG_ADDR		0x16
++#define	PHY_INTC_CONTROL_STATUS_REG_ADDR	0x17
++
++/*
++ * NIC registers access	macros defines
++ */
++
++//0x004
++#define	HAL_NIC_WRITE_PHY_CONTROL1(config_value) \
++    ((NIC_PHY_CONTROL_REG1) = (config_value))
++
++#define	HAL_NIC_READ_PHY_CONTROL1(config_value)	\
++    ((config_value) = (NIC_PHY_CONTROL_REG1))
++
++//0x008
++#define	HAL_NIC_WRITE_MAC_CONFIGURATION(config_value) \
++    ((NIC_MAC_CONTROL_REG) = (config_value))
++
++#define	HAL_NIC_READ_MAC_CONFIGURATION(config_value) \
++    ((config_value) = (NIC_MAC_CONTROL_REG))
++
++//0x00C
++#define	HAL_NIC_WRITE_FLOW_CONTROL_CONFIG(fc_cfg) \
++    ((NIC_FLOW_CONTROL_CONFIG_REG) = (fc_cfg))
++
++#define	HAL_NIC_READ_FLOW_CONTROL_CONFIG(fc_cfg) \
++    ((fc_cfg) =	(NIC_FLOW_CONTROL_CONFIG_REG))
++
++//0x010
++#define	HAL_NIC_WRITE_ARL_CONFIGURATION(cfg) \
++    ((NIC_ARL_CONFIG_REG) = (cfg))
++
++#define	HAL_NIC_READ_ARL_CONFIGURATION(cfg) \
++    ((cfg) = (NIC_ARL_CONFIG_REG))
++
++//0x014,
++#define	HAL_NIC_WRITE_MY_MAC_HIGH_BYTE(cfg) \
++    ((NIC_MY_MAC_HIGH_BYTE_REG)	= (cfg & 0x0000FFFF ) )
++
++#define	HAL_NIC_READ_MY_MAC_HIGH_BYTE(cfg) \
++    ((cfg) = (NIC_MY_MAC_HIGH_BYTE_REG & 0x0000FFFF ))
++
++//0x018
++#define	HAL_NIC_WRITE_MY_MAC_LOW_BYTE(cfg) \
++    ((NIC_MY_MAC_LOW_BYTE_REG) = (cfg))
++
++#define	HAL_NIC_READ_MY_MAC_LOW_BYTE(cfg) \
++    ((cfg) = (NIC_MY_MAC_LOW_BYTE_REG))
++
++//0x03C
++#define	HAL_NIC_READ_INTERRUPT_STATUS(int_status) \
++    ((int_status) = (NIC_INT_STATUS_REG))
++
++#define	HAL_NIC_CLEAR_ALL_INTERRUPT_STATUS_SOURCES()\
++    ((NIC_INT_STATUS_REG) = (0xFFFFFFFF))
++
++#define	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCES(source) \
++    ((NIC_INT_STATUS_REG) |= (source))
++
++#define	HAL_NIC_CLEAR_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_STATUS_REG) |= (1	<< (source_bit_index)))
++
++//0x040
++#define	HAL_NIC_DISABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++    ((NIC_INT_MASK_REG)	= (0xFFFFFFFF))
++
++#define	HAL_NIC_ENABLE_ALL_INTERRUPT_STATUS_SOURCES() \
++    ((NIC_INT_MASK_REG)	= (0x00000000))
++
++#define	HAL_NIC_DISABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_MASK_REG)	|= (1 << (source_bit_index)))
++
++#define	HAL_NIC_ENABLE_INTERRUPT_STATUS_SOURCE_BIT(source_bit_index) \
++    ((NIC_INT_MASK_REG)	&= ~(1 << (source_bit_index)))
++
++//0x44
++#define	HAL_NIC_WRITE_TEST0_REG(cfg) \
++    ((NIC_TEST_0_REG) =	(cfg))
++
++#define	HAL_NIC_READ_TEST0_REG(cfg) \
++    ((cfg) = (NIC_TEST_0_REG))
++
++//0x48
++#define	HAL_NIC_WRITE_TEST1_REG(cfg) \
++    ((NIC_TEST_1_REG) =	(cfg))
++
++#define	HAL_NIC_READ_TEST1_REG(cfg) \
++    ((cfg) = (NIC_TEST_1_REG))
++
++
++
++/*
++ * NIC's DMA macros defines
++ */
++#define	HAL_NIC_TX_DMA_START() \
++    ((NIC_TX_DMA_CONTROL_REG) =	(1))
++
++
++#define	HAL_NIC_TX_DMA_STOP() \
++    ((NIC_TX_DMA_CONTROL_REG) =	(0))
++
++
++#define	HAL_NIC_READ_TX_DMA_STATE(state) \
++    ((state) = (NIC_TX_DMA_CONTROL_REG))
++
++
++#define	HAL_NIC_RX_DMA_START() \
++    ((NIC_RX_DMA_CONTROL_REG) =	(1))
++
++
++#define	HAL_NIC_RX_DMA_STOP() \
++    ((NIC_RX_DMA_CONTROL_REG) =	(0))
++
++
++#define	HAL_NIC_WRITE_TXSD(tssd_value) \
++    ((NIC_TX_DESC_PTR_REG) = (tssd_value))
++
++
++#define	HAL_NIC_READ_TXSD(tssd_value) \
++    ((tssd_value) = (NIC_TX_DESC_PTR_REG))
++
++
++#define	HAL_NIC_WRITE_RXSD(fssd_value) \
++    ((NIC_RX_DESC_PTR_REG) = (fssd_value))
++
++
++#define	HAL_NIC_READ_RXSD(fssd_value) \
++    ((fssd_value) = (NIC_RX_DESC_PTR_REG))
++
++
++#define	HAL_NIC_WRITE_TX_BASE(ts_base_value) \
++    ((NIC_TX_DESC_BASE_ADDR_REG) = (ts_base_value))
++
++
++#define	HAL_NIC_READ_TX_BASE(ts_base_value) \
++    ((ts_base_value) = (NIC_TX_DESC_BASE_ADDR_REG))
++
++
++#define	HAL_NIC_WRITE_RX_BASE(fs_base_value) \
++    ((NIC_RX_DESC_BASE_ADDR_REG) = (fs_base_value))
++
++
++#define	HAL_NIC_READ_RX_BASE(fs_base_value) \
++    ((fs_base_value) = (NIC_RX_DESC_BASE_ADDR_REG))
++
++
++#define	HAL_NIC_WRITE_DELAYED_INTERRUPT_CONFIG(delayed_interrupt_config) \
++    ((NIC_DELAYED_INT_CONFIG_REG) = (delayed_interrupt_config))
++
++
++#define	HAL_NIC_READ_DELAYED_INTERRUPT_CONFIG(delayed_interrupt_config)	\
++    ((delayed_interrupt_config)	= (NIC_DELAYED_INT_CONFIG_REG))
++
++#endif	// end of #ifndef _STAR_NIC_H_
+diff -rupN linux-2.6.35.11/include/asm-arm/hardware.h linux-2.6.35.11-ts7500/include/asm-arm/hardware.h
+--- linux-2.6.35.11/include/asm-arm/hardware.h	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm-arm/hardware.h	2011-03-14 11:18:24.000000000 -0400
+@@ -0,0 +1,18 @@
++/*
++ *  linux/include/asm-arm/hardware.h
++ *
++ *  Copyright (C) 1996 Russell King
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  Common hardware definitions
++ */
++
++#ifndef __ASM_HARDWARE_H
++#define __ASM_HARDWARE_H
++
++#include <asm/arch/hardware.h>
++
++#endif
+diff -rupN linux-2.6.35.11/include/asm-generic/pci.h linux-2.6.35.11-ts7500/include/asm-generic/pci.h
+--- linux-2.6.35.11/include/asm-generic/pci.h	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/asm-generic/pci.h	2011-03-14 11:18:24.000000000 -0400
+@@ -43,6 +43,15 @@ pcibios_select_root(struct pci_dev *pdev
+ 	return root;
+ }
+ 
++#if defined(CONFIG_ARCH_STR9100) || defined(CONFIG_ARCH_STR8100)
++#define HAVE_ARCH_PCI_MWI
++static inline int pcibios_prep_mwi(struct pci_dev *dev)
++{
++	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x08);
++	return 0;
++}
++#endif
++
+ #ifndef HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ
+ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
+ {
+diff -rupN linux-2.6.35.11/include/linux/decompress/mm.h linux-2.6.35.11-ts7500/include/linux/decompress/mm.h
+--- linux-2.6.35.11/include/linux/decompress/mm.h	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/linux/decompress/mm.h	2011-03-14 11:18:24.000000000 -0400
+@@ -33,7 +33,7 @@ STATIC_RW_DATA int malloc_count;
+ static void *malloc(int size)
+ {
+ 	void *p;
+-
++   
+ 	if (size < 0)
+ 		return NULL;
+ 	if (!malloc_ptr)
+@@ -58,6 +58,7 @@ static void free(void *where)
+ 		malloc_ptr = free_mem_ptr;
+ }
+ 
++
+ #define large_malloc(a) malloc(a)
+ #define large_free(a) free(a)
+ 
+diff -rupN linux-2.6.35.11/include/linux/i2c.h linux-2.6.35.11-ts7500/include/linux/i2c.h
+--- linux-2.6.35.11/include/linux/i2c.h	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/linux/i2c.h	2011-03-14 11:18:24.000000000 -0400
+@@ -334,6 +334,13 @@ struct i2c_algorithm {
+ 			   unsigned short flags, char read_write,
+ 			   u8 command, int size, union i2c_smbus_data *data);
+ 
++/* Eileen , for linux kernel 2.6.24 , 20080413 */
++/* Lifted from 2.6.24-cavium */
++#ifdef CONFIG_ARCH_STR8100
++	/* --- ioctl like call to set div. parameters. */
++	int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long);
++#endif
++
+ 	/* To determine what the adapter supports */
+ 	u32 (*functionality) (struct i2c_adapter *);
+ };
+diff -rupN linux-2.6.35.11/include/linux/i2c.h.orig linux-2.6.35.11-ts7500/include/linux/i2c.h.orig
+--- linux-2.6.35.11/include/linux/i2c.h.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/linux/i2c.h.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,585 @@
++/* ------------------------------------------------------------------------- */
++/*									     */
++/* i2c.h - definitions for the i2c-bus interface			     */
++/*									     */
++/* ------------------------------------------------------------------------- */
++/*   Copyright (C) 1995-2000 Simon G. Vogl
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You 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.		     */
++/* ------------------------------------------------------------------------- */
++
++/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
++   Frodo Looijaard <frodol@dds.nl> */
++
++#ifndef _LINUX_I2C_H
++#define _LINUX_I2C_H
++
++#include <linux/types.h>
++#ifdef __KERNEL__
++#include <linux/module.h>
++#include <linux/i2c-id.h>
++#include <linux/mod_devicetable.h>
++#include <linux/device.h>	/* for struct device */
++#include <linux/sched.h>	/* for completion */
++#include <linux/mutex.h>
++#include <linux/of.h>		/* for struct device_node */
++
++extern struct bus_type i2c_bus_type;
++
++/* --- General options ------------------------------------------------	*/
++
++struct i2c_msg;
++struct i2c_algorithm;
++struct i2c_adapter;
++struct i2c_client;
++struct i2c_driver;
++union i2c_smbus_data;
++struct i2c_board_info;
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++/*
++ * The master routines are the ones normally used to transmit data to devices
++ * on a bus (or read from them). Apart from two basic transfer functions to
++ * transmit one message at a time, a more complex version can be used to
++ * transmit an arbitrary number of messages without interruption.
++ * @count must be be less than 64k since msg.len is u16.
++ */
++extern int i2c_master_send(struct i2c_client *client, const char *buf,
++			   int count);
++extern int i2c_master_recv(struct i2c_client *client, char *buf, int count);
++
++/* Transfer num messages.
++ */
++extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
++			int num);
++
++/* This is the very generalized SMBus access routine. You probably do not
++   want to use this, though; one of the functions below may be much easier,
++   and probably just as fast.
++   Note that we use i2c_adapter here, because you do not need a specific
++   smbus adapter to call this function. */
++extern s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
++			  unsigned short flags, char read_write, u8 command,
++			  int size, union i2c_smbus_data *data);
++
++/* Now follow the 'nice' access routines. These also document the calling
++   conventions of i2c_smbus_xfer. */
++
++extern s32 i2c_smbus_read_byte(struct i2c_client *client);
++extern s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value);
++extern s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command);
++extern s32 i2c_smbus_write_byte_data(struct i2c_client *client,
++				     u8 command, u8 value);
++extern s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command);
++extern s32 i2c_smbus_write_word_data(struct i2c_client *client,
++				     u8 command, u16 value);
++/* Returns the number of read bytes */
++extern s32 i2c_smbus_read_block_data(struct i2c_client *client,
++				     u8 command, u8 *values);
++extern s32 i2c_smbus_write_block_data(struct i2c_client *client,
++				      u8 command, u8 length, const u8 *values);
++/* Returns the number of read bytes */
++extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client,
++					 u8 command, u8 length, u8 *values);
++extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client,
++					  u8 command, u8 length,
++					  const u8 *values);
++#endif /* I2C */
++
++/**
++ * struct i2c_driver - represent an I2C device driver
++ * @class: What kind of i2c device we instantiate (for detect)
++ * @attach_adapter: Callback for bus addition (for legacy drivers)
++ * @detach_adapter: Callback for bus removal (for legacy drivers)
++ * @probe: Callback for device binding
++ * @remove: Callback for device unbinding
++ * @shutdown: Callback for device shutdown
++ * @suspend: Callback for device suspend
++ * @resume: Callback for device resume
++ * @command: Callback for bus-wide signaling (optional)
++ * @driver: Device driver model driver
++ * @id_table: List of I2C devices supported by this driver
++ * @detect: Callback for device detection
++ * @address_list: The I2C addresses to probe (for detect)
++ * @clients: List of detected clients we created (for i2c-core use only)
++ *
++ * The driver.owner field should be set to the module owner of this driver.
++ * The driver.name field should be set to the name of this driver.
++ *
++ * For automatic device detection, both @detect and @address_data must
++ * be defined. @class should also be set, otherwise only devices forced
++ * with module parameters will be created. The detect function must
++ * fill at least the name field of the i2c_board_info structure it is
++ * handed upon successful detection, and possibly also the flags field.
++ *
++ * If @detect is missing, the driver will still work fine for enumerated
++ * devices. Detected devices simply won't be supported. This is expected
++ * for the many I2C/SMBus devices which can't be detected reliably, and
++ * the ones which can always be enumerated in practice.
++ *
++ * The i2c_client structure which is handed to the @detect callback is
++ * not a real i2c_client. It is initialized just enough so that you can
++ * call i2c_smbus_read_byte_data and friends on it. Don't do anything
++ * else with it. In particular, calling dev_dbg and friends on it is
++ * not allowed.
++ */
++struct i2c_driver {
++	unsigned int class;
++
++	/* Notifies the driver that a new bus has appeared or is about to be
++	 * removed. You should avoid using this if you can, it will probably
++	 * be removed in a near future.
++	 */
++	int (*attach_adapter)(struct i2c_adapter *);
++	int (*detach_adapter)(struct i2c_adapter *);
++
++	/* Standard driver model interfaces */
++	int (*probe)(struct i2c_client *, const struct i2c_device_id *);
++	int (*remove)(struct i2c_client *);
++
++	/* driver model interfaces that don't relate to enumeration  */
++	void (*shutdown)(struct i2c_client *);
++	int (*suspend)(struct i2c_client *, pm_message_t mesg);
++	int (*resume)(struct i2c_client *);
++
++	/* Alert callback, for example for the SMBus alert protocol.
++	 * The format and meaning of the data value depends on the protocol.
++	 * For the SMBus alert protocol, there is a single bit of data passed
++	 * as the alert response's low bit ("event flag").
++	 */
++	void (*alert)(struct i2c_client *, unsigned int data);
++
++	/* a ioctl like command that can be used to perform specific functions
++	 * with the device.
++	 */
++	int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
++
++	struct device_driver driver;
++	const struct i2c_device_id *id_table;
++
++	/* Device detection callback for automatic device creation */
++	int (*detect)(struct i2c_client *, struct i2c_board_info *);
++	const unsigned short *address_list;
++	struct list_head clients;
++};
++#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
++
++/**
++ * struct i2c_client - represent an I2C slave device
++ * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
++ *	I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking
++ * @addr: Address used on the I2C bus connected to the parent adapter.
++ * @name: Indicates the type of the device, usually a chip name that's
++ *	generic enough to hide second-sourcing and compatible revisions.
++ * @adapter: manages the bus segment hosting this I2C device
++ * @driver: device's driver, hence pointer to access routines
++ * @dev: Driver model device node for the slave.
++ * @irq: indicates the IRQ generated by this device (if any)
++ * @detected: member of an i2c_driver.clients list or i2c-core's
++ *	userspace_devices list
++ *
++ * An i2c_client identifies a single device (i.e. chip) connected to an
++ * i2c bus. The behaviour exposed to Linux is defined by the driver
++ * managing the device.
++ */
++struct i2c_client {
++	unsigned short flags;		/* div., see below		*/
++	unsigned short addr;		/* chip address - NOTE: 7bit	*/
++					/* addresses are stored in the	*/
++					/* _LOWER_ 7 bits		*/
++	char name[I2C_NAME_SIZE];
++	struct i2c_adapter *adapter;	/* the adapter we sit on	*/
++	struct i2c_driver *driver;	/* and our access routines	*/
++	struct device dev;		/* the device structure		*/
++	int irq;			/* irq issued by device		*/
++	struct list_head detected;
++};
++#define to_i2c_client(d) container_of(d, struct i2c_client, dev)
++
++extern struct i2c_client *i2c_verify_client(struct device *dev);
++
++static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj)
++{
++	struct device * const dev = container_of(kobj, struct device, kobj);
++	return to_i2c_client(dev);
++}
++
++static inline void *i2c_get_clientdata(const struct i2c_client *dev)
++{
++	return dev_get_drvdata(&dev->dev);
++}
++
++static inline void i2c_set_clientdata(struct i2c_client *dev, void *data)
++{
++	dev_set_drvdata(&dev->dev, data);
++}
++
++/**
++ * struct i2c_board_info - template for device creation
++ * @type: chip type, to initialize i2c_client.name
++ * @flags: to initialize i2c_client.flags
++ * @addr: stored in i2c_client.addr
++ * @platform_data: stored in i2c_client.dev.platform_data
++ * @archdata: copied into i2c_client.dev.archdata
++ * @irq: stored in i2c_client.irq
++ *
++ * I2C doesn't actually support hardware probing, although controllers and
++ * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's
++ * a device at a given address.  Drivers commonly need more information than
++ * that, such as chip type, configuration, associated IRQ, and so on.
++ *
++ * i2c_board_info is used to build tables of information listing I2C devices
++ * that are present.  This information is used to grow the driver model tree.
++ * For mainboards this is done statically using i2c_register_board_info();
++ * bus numbers identify adapters that aren't yet available.  For add-on boards,
++ * i2c_new_device() does this dynamically with the adapter already known.
++ */
++struct i2c_board_info {
++	char		type[I2C_NAME_SIZE];
++	unsigned short	flags;
++	unsigned short	addr;
++	void		*platform_data;
++	struct dev_archdata	*archdata;
++#ifdef CONFIG_OF
++	struct device_node *of_node;
++#endif
++	int		irq;
++};
++
++/**
++ * I2C_BOARD_INFO - macro used to list an i2c device and its address
++ * @dev_type: identifies the device type
++ * @dev_addr: the device's address on the bus.
++ *
++ * This macro initializes essential fields of a struct i2c_board_info,
++ * declaring what has been provided on a particular board.  Optional
++ * fields (such as associated irq, or device-specific platform_data)
++ * are provided using conventional syntax.
++ */
++#define I2C_BOARD_INFO(dev_type, dev_addr) \
++	.type = dev_type, .addr = (dev_addr)
++
++
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++/* Add-on boards should register/unregister their devices; e.g. a board
++ * with integrated I2C, a config eeprom, sensors, and a codec that's
++ * used in conjunction with the primary hardware.
++ */
++extern struct i2c_client *
++i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
++
++/* If you don't know the exact address of an I2C device, use this variant
++ * instead, which can probe for device presence in a list of possible
++ * addresses.
++ */
++extern struct i2c_client *
++i2c_new_probed_device(struct i2c_adapter *adap,
++		      struct i2c_board_info *info,
++		      unsigned short const *addr_list);
++
++/* For devices that use several addresses, use i2c_new_dummy() to make
++ * client handles for the extra addresses.
++ */
++extern struct i2c_client *
++i2c_new_dummy(struct i2c_adapter *adap, u16 address);
++
++extern void i2c_unregister_device(struct i2c_client *);
++#endif /* I2C */
++
++/* Mainboard arch_initcall() code should register all its I2C devices.
++ * This is done at arch_initcall time, before declaring any i2c adapters.
++ * Modules for add-on boards must use other calls.
++ */
++#ifdef CONFIG_I2C_BOARDINFO
++extern int
++i2c_register_board_info(int busnum, struct i2c_board_info const *info,
++			unsigned n);
++#else
++static inline int
++i2c_register_board_info(int busnum, struct i2c_board_info const *info,
++			unsigned n)
++{
++	return 0;
++}
++#endif /* I2C_BOARDINFO */
++
++/*
++ * The following structs are for those who like to implement new bus drivers:
++ * i2c_algorithm is the interface to a class of hardware solutions which can
++ * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584
++ * to name two of the most common.
++ */
++struct i2c_algorithm {
++	/* If an adapter algorithm can't do I2C-level access, set master_xfer
++	   to NULL. If an adapter algorithm can do SMBus access, set
++	   smbus_xfer. If set to NULL, the SMBus protocol is simulated
++	   using common I2C messages */
++	/* master_xfer should return the number of messages successfully
++	   processed, or a negative value on error */
++	int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
++			   int num);
++	int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
++			   unsigned short flags, char read_write,
++			   u8 command, int size, union i2c_smbus_data *data);
++
++	/* To determine what the adapter supports */
++	u32 (*functionality) (struct i2c_adapter *);
++};
++
++/*
++ * i2c_adapter is the structure used to identify a physical i2c bus along
++ * with the access algorithms necessary to access it.
++ */
++struct i2c_adapter {
++	struct module *owner;
++	unsigned int id;
++	unsigned int class;		  /* classes to allow probing for */
++	const struct i2c_algorithm *algo; /* the algorithm to access the bus */
++	void *algo_data;
++
++	/* data fields that are valid for all devices	*/
++	struct rt_mutex bus_lock;
++
++	int timeout;			/* in jiffies */
++	int retries;
++	struct device dev;		/* the adapter device */
++
++	int nr;
++	char name[48];
++	struct completion dev_released;
++
++	struct list_head userspace_clients;
++};
++#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
++
++static inline void *i2c_get_adapdata(const struct i2c_adapter *dev)
++{
++	return dev_get_drvdata(&dev->dev);
++}
++
++static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data)
++{
++	dev_set_drvdata(&dev->dev, data);
++}
++
++/**
++ * i2c_lock_adapter - Prevent access to an I2C bus segment
++ * @adapter: Target I2C bus segment
++ */
++static inline void i2c_lock_adapter(struct i2c_adapter *adapter)
++{
++	rt_mutex_lock(&adapter->bus_lock);
++}
++
++/**
++ * i2c_unlock_adapter - Reauthorize access to an I2C bus segment
++ * @adapter: Target I2C bus segment
++ */
++static inline void i2c_unlock_adapter(struct i2c_adapter *adapter)
++{
++	rt_mutex_unlock(&adapter->bus_lock);
++}
++
++/*flags for the client struct: */
++#define I2C_CLIENT_PEC	0x04		/* Use Packet Error Checking */
++#define I2C_CLIENT_TEN	0x10		/* we have a ten bit chip address */
++					/* Must equal I2C_M_TEN below */
++#define I2C_CLIENT_WAKE	0x80		/* for board_info; true iff can wake */
++
++/* i2c adapter classes (bitmask) */
++#define I2C_CLASS_HWMON		(1<<0)	/* lm_sensors, ... */
++#define I2C_CLASS_TV_ANALOG	(1<<1)	/* bttv + friends */
++#define I2C_CLASS_TV_DIGITAL	(1<<2)	/* dvb cards */
++#define I2C_CLASS_DDC		(1<<3)	/* DDC bus on graphics adapters */
++#define I2C_CLASS_SPD		(1<<7)	/* SPD EEPROMs and similar */
++
++/* Internal numbers to terminate lists */
++#define I2C_CLIENT_END		0xfffeU
++
++/* The numbers to use to set I2C bus address */
++#define ANY_I2C_BUS		0xffff
++
++/* Construct an I2C_CLIENT_END-terminated array of i2c addresses */
++#define I2C_ADDRS(addr, addrs...) \
++	((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END })
++
++
++/* ----- functions exported by i2c.o */
++
++/* administration...
++ */
++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
++extern int i2c_add_adapter(struct i2c_adapter *);
++extern int i2c_del_adapter(struct i2c_adapter *);
++extern int i2c_add_numbered_adapter(struct i2c_adapter *);
++
++extern int i2c_register_driver(struct module *, struct i2c_driver *);
++extern void i2c_del_driver(struct i2c_driver *);
++
++static inline int i2c_add_driver(struct i2c_driver *driver)
++{
++	return i2c_register_driver(THIS_MODULE, driver);
++}
++
++extern struct i2c_client *i2c_use_client(struct i2c_client *client);
++extern void i2c_release_client(struct i2c_client *client);
++
++/* call the i2c_client->command() of all attached clients with
++ * the given arguments */
++extern void i2c_clients_command(struct i2c_adapter *adap,
++				unsigned int cmd, void *arg);
++
++extern struct i2c_adapter *i2c_get_adapter(int id);
++extern void i2c_put_adapter(struct i2c_adapter *adap);
++
++
++/* Return the functionality mask */
++static inline u32 i2c_get_functionality(struct i2c_adapter *adap)
++{
++	return adap->algo->functionality(adap);
++}
++
++/* Return 1 if adapter supports everything we need, 0 if not. */
++static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func)
++{
++	return (func & i2c_get_functionality(adap)) == func;
++}
++
++/* Return the adapter number for a specific adapter */
++static inline int i2c_adapter_id(struct i2c_adapter *adap)
++{
++	return adap->nr;
++}
++#endif /* I2C */
++#endif /* __KERNEL__ */
++
++/**
++ * struct i2c_msg - an I2C transaction segment beginning with START
++ * @addr: Slave address, either seven or ten bits.  When this is a ten
++ *	bit address, I2C_M_TEN must be set in @flags and the adapter
++ *	must support I2C_FUNC_10BIT_ADDR.
++ * @flags: I2C_M_RD is handled by all adapters.  No other flags may be
++ *	provided unless the adapter exported the relevant I2C_FUNC_*
++ *	flags through i2c_check_functionality().
++ * @len: Number of data bytes in @buf being read from or written to the
++ *	I2C slave address.  For read transactions where I2C_M_RECV_LEN
++ *	is set, the caller guarantees that this buffer can hold up to
++ *	32 bytes in addition to the initial length byte sent by the
++ *	slave (plus, if used, the SMBus PEC); and this value will be
++ *	incremented by the number of block data bytes received.
++ * @buf: The buffer into which data is read, or from which it's written.
++ *
++ * An i2c_msg is the low level representation of one segment of an I2C
++ * transaction.  It is visible to drivers in the @i2c_transfer() procedure,
++ * to userspace from i2c-dev, and to I2C adapter drivers through the
++ * @i2c_adapter.@master_xfer() method.
++ *
++ * Except when I2C "protocol mangling" is used, all I2C adapters implement
++ * the standard rules for I2C transactions.  Each transaction begins with a
++ * START.  That is followed by the slave address, and a bit encoding read
++ * versus write.  Then follow all the data bytes, possibly including a byte
++ * with SMBus PEC.  The transfer terminates with a NAK, or when all those
++ * bytes have been transferred and ACKed.  If this is the last message in a
++ * group, it is followed by a STOP.  Otherwise it is followed by the next
++ * @i2c_msg transaction segment, beginning with a (repeated) START.
++ *
++ * Alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then
++ * passing certain @flags may have changed those standard protocol behaviors.
++ * Those flags are only for use with broken/nonconforming slaves, and with
++ * adapters which are known to support the specific mangling options they
++ * need (one or more of IGNORE_NAK, NO_RD_ACK, NOSTART, and REV_DIR_ADDR).
++ */
++struct i2c_msg {
++	__u16 addr;	/* slave address			*/
++	__u16 flags;
++#define I2C_M_TEN		0x0010	/* this is a ten bit chip address */
++#define I2C_M_RD		0x0001	/* read data, from slave to master */
++#define I2C_M_NOSTART		0x4000	/* if I2C_FUNC_PROTOCOL_MANGLING */
++#define I2C_M_REV_DIR_ADDR	0x2000	/* if I2C_FUNC_PROTOCOL_MANGLING */
++#define I2C_M_IGNORE_NAK	0x1000	/* if I2C_FUNC_PROTOCOL_MANGLING */
++#define I2C_M_NO_RD_ACK		0x0800	/* if I2C_FUNC_PROTOCOL_MANGLING */
++#define I2C_M_RECV_LEN		0x0400	/* length will be first received byte */
++	__u16 len;		/* msg length				*/
++	__u8 *buf;		/* pointer to msg data			*/
++};
++
++/* To determine what functionality is present */
++
++#define I2C_FUNC_I2C			0x00000001
++#define I2C_FUNC_10BIT_ADDR		0x00000002
++#define I2C_FUNC_PROTOCOL_MANGLING	0x00000004 /* I2C_M_NOSTART etc. */
++#define I2C_FUNC_SMBUS_PEC		0x00000008
++#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL	0x00008000 /* SMBus 2.0 */
++#define I2C_FUNC_SMBUS_QUICK		0x00010000
++#define I2C_FUNC_SMBUS_READ_BYTE	0x00020000
++#define I2C_FUNC_SMBUS_WRITE_BYTE	0x00040000
++#define I2C_FUNC_SMBUS_READ_BYTE_DATA	0x00080000
++#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA	0x00100000
++#define I2C_FUNC_SMBUS_READ_WORD_DATA	0x00200000
++#define I2C_FUNC_SMBUS_WRITE_WORD_DATA	0x00400000
++#define I2C_FUNC_SMBUS_PROC_CALL	0x00800000
++#define I2C_FUNC_SMBUS_READ_BLOCK_DATA	0x01000000
++#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
++#define I2C_FUNC_SMBUS_READ_I2C_BLOCK	0x04000000 /* I2C-like block xfer  */
++#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK	0x08000000 /* w/ 1-byte reg. addr. */
++
++#define I2C_FUNC_SMBUS_BYTE		(I2C_FUNC_SMBUS_READ_BYTE | \
++					 I2C_FUNC_SMBUS_WRITE_BYTE)
++#define I2C_FUNC_SMBUS_BYTE_DATA	(I2C_FUNC_SMBUS_READ_BYTE_DATA | \
++					 I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
++#define I2C_FUNC_SMBUS_WORD_DATA	(I2C_FUNC_SMBUS_READ_WORD_DATA | \
++					 I2C_FUNC_SMBUS_WRITE_WORD_DATA)
++#define I2C_FUNC_SMBUS_BLOCK_DATA	(I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
++					 I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
++#define I2C_FUNC_SMBUS_I2C_BLOCK	(I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
++					 I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
++
++#define I2C_FUNC_SMBUS_EMUL		(I2C_FUNC_SMBUS_QUICK | \
++					 I2C_FUNC_SMBUS_BYTE | \
++					 I2C_FUNC_SMBUS_BYTE_DATA | \
++					 I2C_FUNC_SMBUS_WORD_DATA | \
++					 I2C_FUNC_SMBUS_PROC_CALL | \
++					 I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
++					 I2C_FUNC_SMBUS_I2C_BLOCK | \
++					 I2C_FUNC_SMBUS_PEC)
++
++/*
++ * Data for SMBus Messages
++ */
++#define I2C_SMBUS_BLOCK_MAX	32	/* As specified in SMBus standard */
++union i2c_smbus_data {
++	__u8 byte;
++	__u16 word;
++	__u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
++			       /* and one more for user-space compatibility */
++};
++
++/* i2c_smbus_xfer read or write markers */
++#define I2C_SMBUS_READ	1
++#define I2C_SMBUS_WRITE	0
++
++/* SMBus transaction types (size parameter in the above functions)
++   Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
++#define I2C_SMBUS_QUICK		    0
++#define I2C_SMBUS_BYTE		    1
++#define I2C_SMBUS_BYTE_DATA	    2
++#define I2C_SMBUS_WORD_DATA	    3
++#define I2C_SMBUS_PROC_CALL	    4
++#define I2C_SMBUS_BLOCK_DATA	    5
++#define I2C_SMBUS_I2C_BLOCK_BROKEN  6
++#define I2C_SMBUS_BLOCK_PROC_CALL   7		/* SMBus 2.0 */
++#define I2C_SMBUS_I2C_BLOCK_DATA    8
++
++#endif /* _LINUX_I2C_H */
+diff -rupN linux-2.6.35.11/include/linux/spi/spi.h linux-2.6.35.11-ts7500/include/linux/spi/spi.h
+--- linux-2.6.35.11/include/linux/spi/spi.h	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/linux/spi/spi.h	2011-03-14 11:18:24.000000000 -0400
+@@ -432,6 +432,11 @@ struct spi_transfer {
+ 	u16		delay_usecs;
+ 	u32		speed_hz;
+ 
++#ifdef CONFIG_ARCH_STR8100
++   unsigned        last_in_message_list;
++#endif
++	
++	
+ 	struct list_head transfer_list;
+ };
+ 
+diff -rupN linux-2.6.35.11/include/linux/spi/spi.h.orig linux-2.6.35.11-ts7500/include/linux/spi/spi.h.orig
+--- linux-2.6.35.11/include/linux/spi/spi.h.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/linux/spi/spi.h.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,779 @@
++/*
++ * Copyright (C) 2005 David Brownell
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __LINUX_SPI_H
++#define __LINUX_SPI_H
++
++#include <linux/device.h>
++#include <linux/mod_devicetable.h>
++#include <linux/slab.h>
++
++/*
++ * INTERFACES between SPI master-side drivers and SPI infrastructure.
++ * (There's no SPI slave support for Linux yet...)
++ */
++extern struct bus_type spi_bus_type;
++
++/**
++ * struct spi_device - Master side proxy for an SPI slave device
++ * @dev: Driver model representation of the device.
++ * @master: SPI controller used with the device.
++ * @max_speed_hz: Maximum clock rate to be used with this chip
++ *	(on this board); may be changed by the device's driver.
++ *	The spi_transfer.speed_hz can override this for each transfer.
++ * @chip_select: Chipselect, distinguishing chips handled by @master.
++ * @mode: The spi mode defines how data is clocked out and in.
++ *	This may be changed by the device's driver.
++ *	The "active low" default for chipselect mode can be overridden
++ *	(by specifying SPI_CS_HIGH) as can the "MSB first" default for
++ *	each word in a transfer (by specifying SPI_LSB_FIRST).
++ * @bits_per_word: Data transfers involve one or more words; word sizes
++ *	like eight or 12 bits are common.  In-memory wordsizes are
++ *	powers of two bytes (e.g. 20 bit samples use 32 bits).
++ *	This may be changed by the device's driver, or left at the
++ *	default (0) indicating protocol words are eight bit bytes.
++ *	The spi_transfer.bits_per_word can override this for each transfer.
++ * @irq: Negative, or the number passed to request_irq() to receive
++ *	interrupts from this device.
++ * @controller_state: Controller's runtime state
++ * @controller_data: Board-specific definitions for controller, such as
++ *	FIFO initialization parameters; from board_info.controller_data
++ * @modalias: Name of the driver to use with this device, or an alias
++ *	for that name.  This appears in the sysfs "modalias" attribute
++ *	for driver coldplugging, and in uevents used for hotplugging
++ *
++ * A @spi_device is used to interchange data between an SPI slave
++ * (usually a discrete chip) and CPU memory.
++ *
++ * In @dev, the platform_data is used to hold information about this
++ * device that's meaningful to the device's protocol driver, but not
++ * to its controller.  One example might be an identifier for a chip
++ * variant with slightly different functionality; another might be
++ * information about how this particular board wires the chip's pins.
++ */
++struct spi_device {
++	struct device		dev;
++	struct spi_master	*master;
++	u32			max_speed_hz;
++	u8			chip_select;
++	u8			mode;
++#define	SPI_CPHA	0x01			/* clock phase */
++#define	SPI_CPOL	0x02			/* clock polarity */
++#define	SPI_MODE_0	(0|0)			/* (original MicroWire) */
++#define	SPI_MODE_1	(0|SPI_CPHA)
++#define	SPI_MODE_2	(SPI_CPOL|0)
++#define	SPI_MODE_3	(SPI_CPOL|SPI_CPHA)
++#define	SPI_CS_HIGH	0x04			/* chipselect active high? */
++#define	SPI_LSB_FIRST	0x08			/* per-word bits-on-wire */
++#define	SPI_3WIRE	0x10			/* SI/SO signals shared */
++#define	SPI_LOOP	0x20			/* loopback mode */
++#define	SPI_NO_CS	0x40			/* 1 dev/bus, no chipselect */
++#define	SPI_READY	0x80			/* slave pulls low to pause */
++	u8			bits_per_word;
++	int			irq;
++	void			*controller_state;
++	void			*controller_data;
++	char			modalias[SPI_NAME_SIZE];
++
++	/*
++	 * likely need more hooks for more protocol options affecting how
++	 * the controller talks to each chip, like:
++	 *  - memory packing (12 bit samples into low bits, others zeroed)
++	 *  - priority
++	 *  - drop chipselect after each word
++	 *  - chipselect delays
++	 *  - ...
++	 */
++};
++
++static inline struct spi_device *to_spi_device(struct device *dev)
++{
++	return dev ? container_of(dev, struct spi_device, dev) : NULL;
++}
++
++/* most drivers won't need to care about device refcounting */
++static inline struct spi_device *spi_dev_get(struct spi_device *spi)
++{
++	return (spi && get_device(&spi->dev)) ? spi : NULL;
++}
++
++static inline void spi_dev_put(struct spi_device *spi)
++{
++	if (spi)
++		put_device(&spi->dev);
++}
++
++/* ctldata is for the bus_master driver's runtime state */
++static inline void *spi_get_ctldata(struct spi_device *spi)
++{
++	return spi->controller_state;
++}
++
++static inline void spi_set_ctldata(struct spi_device *spi, void *state)
++{
++	spi->controller_state = state;
++}
++
++/* device driver data */
++
++static inline void spi_set_drvdata(struct spi_device *spi, void *data)
++{
++	dev_set_drvdata(&spi->dev, data);
++}
++
++static inline void *spi_get_drvdata(struct spi_device *spi)
++{
++	return dev_get_drvdata(&spi->dev);
++}
++
++struct spi_message;
++
++
++
++/**
++ * struct spi_driver - Host side "protocol" driver
++ * @id_table: List of SPI devices supported by this driver
++ * @probe: Binds this driver to the spi device.  Drivers can verify
++ *	that the device is actually present, and may need to configure
++ *	characteristics (such as bits_per_word) which weren't needed for
++ *	the initial configuration done during system setup.
++ * @remove: Unbinds this driver from the spi device
++ * @shutdown: Standard shutdown callback used during system state
++ *	transitions such as powerdown/halt and kexec
++ * @suspend: Standard suspend callback used during system state transitions
++ * @resume: Standard resume callback used during system state transitions
++ * @driver: SPI device drivers should initialize the name and owner
++ *	field of this structure.
++ *
++ * This represents the kind of device driver that uses SPI messages to
++ * interact with the hardware at the other end of a SPI link.  It's called
++ * a "protocol" driver because it works through messages rather than talking
++ * directly to SPI hardware (which is what the underlying SPI controller
++ * driver does to pass those messages).  These protocols are defined in the
++ * specification for the device(s) supported by the driver.
++ *
++ * As a rule, those device protocols represent the lowest level interface
++ * supported by a driver, and it will support upper level interfaces too.
++ * Examples of such upper levels include frameworks like MTD, networking,
++ * MMC, RTC, filesystem character device nodes, and hardware monitoring.
++ */
++struct spi_driver {
++	const struct spi_device_id *id_table;
++	int			(*probe)(struct spi_device *spi);
++	int			(*remove)(struct spi_device *spi);
++	void			(*shutdown)(struct spi_device *spi);
++	int			(*suspend)(struct spi_device *spi, pm_message_t mesg);
++	int			(*resume)(struct spi_device *spi);
++	struct device_driver	driver;
++};
++
++static inline struct spi_driver *to_spi_driver(struct device_driver *drv)
++{
++	return drv ? container_of(drv, struct spi_driver, driver) : NULL;
++}
++
++extern int spi_register_driver(struct spi_driver *sdrv);
++
++/**
++ * spi_unregister_driver - reverse effect of spi_register_driver
++ * @sdrv: the driver to unregister
++ * Context: can sleep
++ */
++static inline void spi_unregister_driver(struct spi_driver *sdrv)
++{
++	if (sdrv)
++		driver_unregister(&sdrv->driver);
++}
++
++
++/**
++ * struct spi_master - interface to SPI master controller
++ * @dev: device interface to this driver
++ * @bus_num: board-specific (and often SOC-specific) identifier for a
++ *	given SPI controller.
++ * @num_chipselect: chipselects are used to distinguish individual
++ *	SPI slaves, and are numbered from zero to num_chipselects.
++ *	each slave has a chipselect signal, but it's common that not
++ *	every chipselect is connected to a slave.
++ * @dma_alignment: SPI controller constraint on DMA buffers alignment.
++ * @mode_bits: flags understood by this controller driver
++ * @flags: other constraints relevant to this driver
++ * @setup: updates the device mode and clocking records used by a
++ *	device's SPI controller; protocol code may call this.  This
++ *	must fail if an unrecognized or unsupported mode is requested.
++ *	It's always safe to call this unless transfers are pending on
++ *	the device whose settings are being modified.
++ * @transfer: adds a message to the controller's transfer queue.
++ * @cleanup: frees controller-specific state
++ *
++ * Each SPI master controller can communicate with one or more @spi_device
++ * children.  These make a small bus, sharing MOSI, MISO and SCK signals
++ * but not chip select signals.  Each device may be configured to use a
++ * different clock rate, since those shared signals are ignored unless
++ * the chip is selected.
++ *
++ * The driver for an SPI controller manages access to those devices through
++ * a queue of spi_message transactions, copying data between CPU memory and
++ * an SPI slave device.  For each such message it queues, it calls the
++ * message's completion function when the transaction completes.
++ */
++struct spi_master {
++	struct device	dev;
++
++	/* other than negative (== assign one dynamically), bus_num is fully
++	 * board-specific.  usually that simplifies to being SOC-specific.
++	 * example:  one SOC has three SPI controllers, numbered 0..2,
++	 * and one board's schematics might show it using SPI-2.  software
++	 * would normally use bus_num=2 for that controller.
++	 */
++	s16			bus_num;
++
++	/* chipselects will be integral to many controllers; some others
++	 * might use board-specific GPIOs.
++	 */
++	u16			num_chipselect;
++
++	/* some SPI controllers pose alignment requirements on DMAable
++	 * buffers; let protocol drivers know about these requirements.
++	 */
++	u16			dma_alignment;
++
++	/* spi_device.mode flags understood by this controller driver */
++	u16			mode_bits;
++
++	/* other constraints relevant to this driver */
++	u16			flags;
++#define SPI_MASTER_HALF_DUPLEX	BIT(0)		/* can't do full duplex */
++#define SPI_MASTER_NO_RX	BIT(1)		/* can't do buffer read */
++#define SPI_MASTER_NO_TX	BIT(2)		/* can't do buffer write */
++
++	/* Setup mode and clock, etc (spi driver may call many times).
++	 *
++	 * IMPORTANT:  this may be called when transfers to another
++	 * device are active.  DO NOT UPDATE SHARED REGISTERS in ways
++	 * which could break those transfers.
++	 */
++	int			(*setup)(struct spi_device *spi);
++
++	/* bidirectional bulk transfers
++	 *
++	 * + The transfer() method may not sleep; its main role is
++	 *   just to add the message to the queue.
++	 * + For now there's no remove-from-queue operation, or
++	 *   any other request management
++	 * + To a given spi_device, message queueing is pure fifo
++	 *
++	 * + The master's main job is to process its message queue,
++	 *   selecting a chip then transferring data
++	 * + If there are multiple spi_device children, the i/o queue
++	 *   arbitration algorithm is unspecified (round robin, fifo,
++	 *   priority, reservations, preemption, etc)
++	 *
++	 * + Chipselect stays active during the entire message
++	 *   (unless modified by spi_transfer.cs_change != 0).
++	 * + The message transfers use clock and SPI mode parameters
++	 *   previously established by setup() for this device
++	 */
++	int			(*transfer)(struct spi_device *spi,
++						struct spi_message *mesg);
++
++	/* called on release() to free memory provided by spi_master */
++	void			(*cleanup)(struct spi_device *spi);
++};
++
++static inline void *spi_master_get_devdata(struct spi_master *master)
++{
++	return dev_get_drvdata(&master->dev);
++}
++
++static inline void spi_master_set_devdata(struct spi_master *master, void *data)
++{
++	dev_set_drvdata(&master->dev, data);
++}
++
++static inline struct spi_master *spi_master_get(struct spi_master *master)
++{
++	if (!master || !get_device(&master->dev))
++		return NULL;
++	return master;
++}
++
++static inline void spi_master_put(struct spi_master *master)
++{
++	if (master)
++		put_device(&master->dev);
++}
++
++
++/* the spi driver core manages memory for the spi_master classdev */
++extern struct spi_master *
++spi_alloc_master(struct device *host, unsigned size);
++
++extern int spi_register_master(struct spi_master *master);
++extern void spi_unregister_master(struct spi_master *master);
++
++extern struct spi_master *spi_busnum_to_master(u16 busnum);
++
++/*---------------------------------------------------------------------------*/
++
++/*
++ * I/O INTERFACE between SPI controller and protocol drivers
++ *
++ * Protocol drivers use a queue of spi_messages, each transferring data
++ * between the controller and memory buffers.
++ *
++ * The spi_messages themselves consist of a series of read+write transfer
++ * segments.  Those segments always read the same number of bits as they
++ * write; but one or the other is easily ignored by passing a null buffer
++ * pointer.  (This is unlike most types of I/O API, because SPI hardware
++ * is full duplex.)
++ *
++ * NOTE:  Allocation of spi_transfer and spi_message memory is entirely
++ * up to the protocol driver, which guarantees the integrity of both (as
++ * well as the data buffers) for as long as the message is queued.
++ */
++
++/**
++ * struct spi_transfer - a read/write buffer pair
++ * @tx_buf: data to be written (dma-safe memory), or NULL
++ * @rx_buf: data to be read (dma-safe memory), or NULL
++ * @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped
++ * @rx_dma: DMA address of rx_buf, if @spi_message.is_dma_mapped
++ * @len: size of rx and tx buffers (in bytes)
++ * @speed_hz: Select a speed other than the device default for this
++ *      transfer. If 0 the default (from @spi_device) is used.
++ * @bits_per_word: select a bits_per_word other than the device default
++ *      for this transfer. If 0 the default (from @spi_device) is used.
++ * @cs_change: affects chipselect after this transfer completes
++ * @delay_usecs: microseconds to delay after this transfer before
++ *	(optionally) changing the chipselect status, then starting
++ *	the next transfer or completing this @spi_message.
++ * @transfer_list: transfers are sequenced through @spi_message.transfers
++ *
++ * SPI transfers always write the same number of bytes as they read.
++ * Protocol drivers should always provide @rx_buf and/or @tx_buf.
++ * In some cases, they may also want to provide DMA addresses for
++ * the data being transferred; that may reduce overhead, when the
++ * underlying driver uses dma.
++ *
++ * If the transmit buffer is null, zeroes will be shifted out
++ * while filling @rx_buf.  If the receive buffer is null, the data
++ * shifted in will be discarded.  Only "len" bytes shift out (or in).
++ * It's an error to try to shift out a partial word.  (For example, by
++ * shifting out three bytes with word size of sixteen or twenty bits;
++ * the former uses two bytes per word, the latter uses four bytes.)
++ *
++ * In-memory data values are always in native CPU byte order, translated
++ * from the wire byte order (big-endian except with SPI_LSB_FIRST).  So
++ * for example when bits_per_word is sixteen, buffers are 2N bytes long
++ * (@len = 2N) and hold N sixteen bit words in CPU byte order.
++ *
++ * When the word size of the SPI transfer is not a power-of-two multiple
++ * of eight bits, those in-memory words include extra bits.  In-memory
++ * words are always seen by protocol drivers as right-justified, so the
++ * undefined (rx) or unused (tx) bits are always the most significant bits.
++ *
++ * All SPI transfers start with the relevant chipselect active.  Normally
++ * it stays selected until after the last transfer in a message.  Drivers
++ * can affect the chipselect signal using cs_change.
++ *
++ * (i) If the transfer isn't the last one in the message, this flag is
++ * used to make the chipselect briefly go inactive in the middle of the
++ * message.  Toggling chipselect in this way may be needed to terminate
++ * a chip command, letting a single spi_message perform all of group of
++ * chip transactions together.
++ *
++ * (ii) When the transfer is the last one in the message, the chip may
++ * stay selected until the next transfer.  On multi-device SPI busses
++ * with nothing blocking messages going to other devices, this is just
++ * a performance hint; starting a message to another device deselects
++ * this one.  But in other cases, this can be used to ensure correctness.
++ * Some devices need protocol transactions to be built from a series of
++ * spi_message submissions, where the content of one message is determined
++ * by the results of previous messages and where the whole transaction
++ * ends when the chipselect goes intactive.
++ *
++ * The code that submits an spi_message (and its spi_transfers)
++ * to the lower layers is responsible for managing its memory.
++ * Zero-initialize every field you don't set up explicitly, to
++ * insulate against future API updates.  After you submit a message
++ * and its transfers, ignore them until its completion callback.
++ */
++struct spi_transfer {
++	/* it's ok if tx_buf == rx_buf (right?)
++	 * for MicroWire, one buffer must be null
++	 * buffers must work with dma_*map_single() calls, unless
++	 *   spi_message.is_dma_mapped reports a pre-existing mapping
++	 */
++	const void	*tx_buf;
++	void		*rx_buf;
++	unsigned	len;
++
++	dma_addr_t	tx_dma;
++	dma_addr_t	rx_dma;
++
++	unsigned	cs_change:1;
++	u8		bits_per_word;
++	u16		delay_usecs;
++	u32		speed_hz;
++
++	struct list_head transfer_list;
++};
++
++/**
++ * struct spi_message - one multi-segment SPI transaction
++ * @transfers: list of transfer segments in this transaction
++ * @spi: SPI device to which the transaction is queued
++ * @is_dma_mapped: if true, the caller provided both dma and cpu virtual
++ *	addresses for each transfer buffer
++ * @complete: called to report transaction completions
++ * @context: the argument to complete() when it's called
++ * @actual_length: the total number of bytes that were transferred in all
++ *	successful segments
++ * @status: zero for success, else negative errno
++ * @queue: for use by whichever driver currently owns the message
++ * @state: for use by whichever driver currently owns the message
++ *
++ * A @spi_message is used to execute an atomic sequence of data transfers,
++ * each represented by a struct spi_transfer.  The sequence is "atomic"
++ * in the sense that no other spi_message may use that SPI bus until that
++ * sequence completes.  On some systems, many such sequences can execute as
++ * as single programmed DMA transfer.  On all systems, these messages are
++ * queued, and might complete after transactions to other devices.  Messages
++ * sent to a given spi_device are alway executed in FIFO order.
++ *
++ * The code that submits an spi_message (and its spi_transfers)
++ * to the lower layers is responsible for managing its memory.
++ * Zero-initialize every field you don't set up explicitly, to
++ * insulate against future API updates.  After you submit a message
++ * and its transfers, ignore them until its completion callback.
++ */
++struct spi_message {
++	struct list_head	transfers;
++
++	struct spi_device	*spi;
++
++	unsigned		is_dma_mapped:1;
++
++	/* REVISIT:  we might want a flag affecting the behavior of the
++	 * last transfer ... allowing things like "read 16 bit length L"
++	 * immediately followed by "read L bytes".  Basically imposing
++	 * a specific message scheduling algorithm.
++	 *
++	 * Some controller drivers (message-at-a-time queue processing)
++	 * could provide that as their default scheduling algorithm.  But
++	 * others (with multi-message pipelines) could need a flag to
++	 * tell them about such special cases.
++	 */
++
++	/* completion is reported through a callback */
++	void			(*complete)(void *context);
++	void			*context;
++	unsigned		actual_length;
++	int			status;
++
++	/* for optional use by whatever driver currently owns the
++	 * spi_message ...  between calls to spi_async and then later
++	 * complete(), that's the spi_master controller driver.
++	 */
++	struct list_head	queue;
++	void			*state;
++};
++
++static inline void spi_message_init(struct spi_message *m)
++{
++	memset(m, 0, sizeof *m);
++	INIT_LIST_HEAD(&m->transfers);
++}
++
++static inline void
++spi_message_add_tail(struct spi_transfer *t, struct spi_message *m)
++{
++	list_add_tail(&t->transfer_list, &m->transfers);
++}
++
++static inline void
++spi_transfer_del(struct spi_transfer *t)
++{
++	list_del(&t->transfer_list);
++}
++
++/* It's fine to embed message and transaction structures in other data
++ * structures so long as you don't free them while they're in use.
++ */
++
++static inline struct spi_message *spi_message_alloc(unsigned ntrans, gfp_t flags)
++{
++	struct spi_message *m;
++
++	m = kzalloc(sizeof(struct spi_message)
++			+ ntrans * sizeof(struct spi_transfer),
++			flags);
++	if (m) {
++		int i;
++		struct spi_transfer *t = (struct spi_transfer *)(m + 1);
++
++		INIT_LIST_HEAD(&m->transfers);
++		for (i = 0; i < ntrans; i++, t++)
++			spi_message_add_tail(t, m);
++	}
++	return m;
++}
++
++static inline void spi_message_free(struct spi_message *m)
++{
++	kfree(m);
++}
++
++extern int spi_setup(struct spi_device *spi);
++extern int spi_async(struct spi_device *spi, struct spi_message *message);
++
++/*---------------------------------------------------------------------------*/
++
++/* All these synchronous SPI transfer routines are utilities layered
++ * over the core async transfer primitive.  Here, "synchronous" means
++ * they will sleep uninterruptibly until the async transfer completes.
++ */
++
++extern int spi_sync(struct spi_device *spi, struct spi_message *message);
++
++/**
++ * spi_write - SPI synchronous write
++ * @spi: device to which data will be written
++ * @buf: data buffer
++ * @len: data buffer size
++ * Context: can sleep
++ *
++ * This writes the buffer and returns zero or a negative error code.
++ * Callable only from contexts that can sleep.
++ */
++static inline int
++spi_write(struct spi_device *spi, const u8 *buf, size_t len)
++{
++	struct spi_transfer	t = {
++			.tx_buf		= buf,
++			.len		= len,
++		};
++	struct spi_message	m;
++
++	spi_message_init(&m);
++	spi_message_add_tail(&t, &m);
++	return spi_sync(spi, &m);
++}
++
++/**
++ * spi_read - SPI synchronous read
++ * @spi: device from which data will be read
++ * @buf: data buffer
++ * @len: data buffer size
++ * Context: can sleep
++ *
++ * This reads the buffer and returns zero or a negative error code.
++ * Callable only from contexts that can sleep.
++ */
++static inline int
++spi_read(struct spi_device *spi, u8 *buf, size_t len)
++{
++	struct spi_transfer	t = {
++			.rx_buf		= buf,
++			.len		= len,
++		};
++	struct spi_message	m;
++
++	spi_message_init(&m);
++	spi_message_add_tail(&t, &m);
++	return spi_sync(spi, &m);
++}
++
++/* this copies txbuf and rxbuf data; for small transfers only! */
++extern int spi_write_then_read(struct spi_device *spi,
++		const u8 *txbuf, unsigned n_tx,
++		u8 *rxbuf, unsigned n_rx);
++
++/**
++ * spi_w8r8 - SPI synchronous 8 bit write followed by 8 bit read
++ * @spi: device with which data will be exchanged
++ * @cmd: command to be written before data is read back
++ * Context: can sleep
++ *
++ * This returns the (unsigned) eight bit number returned by the
++ * device, or else a negative error code.  Callable only from
++ * contexts that can sleep.
++ */
++static inline ssize_t spi_w8r8(struct spi_device *spi, u8 cmd)
++{
++	ssize_t			status;
++	u8			result;
++
++	status = spi_write_then_read(spi, &cmd, 1, &result, 1);
++
++	/* return negative errno or unsigned value */
++	return (status < 0) ? status : result;
++}
++
++/**
++ * spi_w8r16 - SPI synchronous 8 bit write followed by 16 bit read
++ * @spi: device with which data will be exchanged
++ * @cmd: command to be written before data is read back
++ * Context: can sleep
++ *
++ * This returns the (unsigned) sixteen bit number returned by the
++ * device, or else a negative error code.  Callable only from
++ * contexts that can sleep.
++ *
++ * The number is returned in wire-order, which is at least sometimes
++ * big-endian.
++ */
++static inline ssize_t spi_w8r16(struct spi_device *spi, u8 cmd)
++{
++	ssize_t			status;
++	u16			result;
++
++	status = spi_write_then_read(spi, &cmd, 1, (u8 *) &result, 2);
++
++	/* return negative errno or unsigned value */
++	return (status < 0) ? status : result;
++}
++
++/*---------------------------------------------------------------------------*/
++
++/*
++ * INTERFACE between board init code and SPI infrastructure.
++ *
++ * No SPI driver ever sees these SPI device table segments, but
++ * it's how the SPI core (or adapters that get hotplugged) grows
++ * the driver model tree.
++ *
++ * As a rule, SPI devices can't be probed.  Instead, board init code
++ * provides a table listing the devices which are present, with enough
++ * information to bind and set up the device's driver.  There's basic
++ * support for nonstatic configurations too; enough to handle adding
++ * parport adapters, or microcontrollers acting as USB-to-SPI bridges.
++ */
++
++/**
++ * struct spi_board_info - board-specific template for a SPI device
++ * @modalias: Initializes spi_device.modalias; identifies the driver.
++ * @platform_data: Initializes spi_device.platform_data; the particular
++ *	data stored there is driver-specific.
++ * @controller_data: Initializes spi_device.controller_data; some
++ *	controllers need hints about hardware setup, e.g. for DMA.
++ * @irq: Initializes spi_device.irq; depends on how the board is wired.
++ * @max_speed_hz: Initializes spi_device.max_speed_hz; based on limits
++ *	from the chip datasheet and board-specific signal quality issues.
++ * @bus_num: Identifies which spi_master parents the spi_device; unused
++ *	by spi_new_device(), and otherwise depends on board wiring.
++ * @chip_select: Initializes spi_device.chip_select; depends on how
++ *	the board is wired.
++ * @mode: Initializes spi_device.mode; based on the chip datasheet, board
++ *	wiring (some devices support both 3WIRE and standard modes), and
++ *	possibly presence of an inverter in the chipselect path.
++ *
++ * When adding new SPI devices to the device tree, these structures serve
++ * as a partial device template.  They hold information which can't always
++ * be determined by drivers.  Information that probe() can establish (such
++ * as the default transfer wordsize) is not included here.
++ *
++ * These structures are used in two places.  Their primary role is to
++ * be stored in tables of board-specific device descriptors, which are
++ * declared early in board initialization and then used (much later) to
++ * populate a controller's device tree after the that controller's driver
++ * initializes.  A secondary (and atypical) role is as a parameter to
++ * spi_new_device() call, which happens after those controller drivers
++ * are active in some dynamic board configuration models.
++ */
++struct spi_board_info {
++	/* the device name and module name are coupled, like platform_bus;
++	 * "modalias" is normally the driver name.
++	 *
++	 * platform_data goes to spi_device.dev.platform_data,
++	 * controller_data goes to spi_device.controller_data,
++	 * irq is copied too
++	 */
++	char		modalias[SPI_NAME_SIZE];
++	const void	*platform_data;
++	void		*controller_data;
++	int		irq;
++
++	/* slower signaling on noisy or low voltage boards */
++	u32		max_speed_hz;
++
++
++	/* bus_num is board specific and matches the bus_num of some
++	 * spi_master that will probably be registered later.
++	 *
++	 * chip_select reflects how this chip is wired to that master;
++	 * it's less than num_chipselect.
++	 */
++	u16		bus_num;
++	u16		chip_select;
++
++	/* mode becomes spi_device.mode, and is essential for chips
++	 * where the default of SPI_CS_HIGH = 0 is wrong.
++	 */
++	u8		mode;
++
++	/* ... may need additional spi_device chip config data here.
++	 * avoid stuff protocol drivers can set; but include stuff
++	 * needed to behave without being bound to a driver:
++	 *  - quirks like clock rate mattering when not selected
++	 */
++};
++
++#ifdef	CONFIG_SPI
++extern int
++spi_register_board_info(struct spi_board_info const *info, unsigned n);
++#else
++/* board init code may ignore whether SPI is configured or not */
++static inline int
++spi_register_board_info(struct spi_board_info const *info, unsigned n)
++	{ return 0; }
++#endif
++
++
++/* If you're hotplugging an adapter with devices (parport, usb, etc)
++ * use spi_new_device() to describe each device.  You can also call
++ * spi_unregister_device() to start making that device vanish, but
++ * normally that would be handled by spi_unregister_master().
++ *
++ * You can also use spi_alloc_device() and spi_add_device() to use a two
++ * stage registration sequence for each spi_device.  This gives the caller
++ * some more control over the spi_device structure before it is registered,
++ * but requires that caller to initialize fields that would otherwise
++ * be defined using the board info.
++ */
++extern struct spi_device *
++spi_alloc_device(struct spi_master *master);
++
++extern int
++spi_add_device(struct spi_device *spi);
++
++extern struct spi_device *
++spi_new_device(struct spi_master *, struct spi_board_info *);
++
++static inline void
++spi_unregister_device(struct spi_device *spi)
++{
++	if (spi)
++		device_unregister(&spi->dev);
++}
++
++extern const struct spi_device_id *
++spi_get_device_id(const struct spi_device *sdev);
++
++#endif /* __LINUX_SPI_H */
+diff -rupN linux-2.6.35.11/include/linux/sysctl.h linux-2.6.35.11-ts7500/include/linux/sysctl.h
+--- linux-2.6.35.11/include/linux/sysctl.h	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/include/linux/sysctl.h	2011-03-14 11:18:24.000000000 -0400
+@@ -847,6 +847,9 @@ enum {
+ 	DEV_MAC_HID=5,
+ 	DEV_SCSI=6,
+ 	DEV_IPMI=7,
++#ifdef CONFIG_ARCH_STR8100
++	DEV_I2C=8,
++#endif   
+ };
+ 
+ /* /proc/sys/dev/cdrom */
+@@ -917,6 +920,14 @@ enum {
+ 	DEV_IPMI_POWEROFF_POWERCYCLE=1,
+ };
+ 
++#ifdef CONFIG_ARCH_STR8100
++enum {
++	DEV_I2C_CLOCK=1,
++	DEV_I2C_DEBUG=2,
++	DEV_I2C_END=3
++};
++#endif
++
+ /* /proc/sys/abi */
+ enum
+ {
+diff -rupN linux-2.6.35.11/init/do_mounts_rd.c linux-2.6.35.11-ts7500/init/do_mounts_rd.c
+--- linux-2.6.35.11/init/do_mounts_rd.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/init/do_mounts_rd.c	2011-03-14 11:18:24.000000000 -0400
+@@ -168,6 +168,8 @@ int __init rd_load_image(char *from)
+ 	char rotator[4] = { '|' , '/' , '-' , '\\' };
+ #endif
+ 
++   printk("rd_load_image()\n");
++
+ 	out_fd = sys_open("/dev/ram", O_RDWR, 0);
+ 	if (out_fd < 0)
+ 		goto out;
+@@ -224,7 +226,11 @@ int __init rd_load_image(char *from)
+ 		goto done;
+ 	}
+ 
++#ifdef CONFIG_ARCH_STR8100
++   buf = kmalloc(BLOCK_SIZE<<6, GFP_KERNEL);
++#else
+ 	buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
++#endif   
+ 	if (!buf) {
+ 		printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
+ 		goto done;
+@@ -232,7 +238,11 @@ int __init rd_load_image(char *from)
+ 
+ 	printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ",
+ 		nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
++#ifdef CONFIG_ARCH_STR8100
++   for (i = 0, disk = 1; i < (nblocks>>6); i++) {
++#else
+ 	for (i = 0, disk = 1; i < nblocks; i++) {
++#endif      
+ 		if (i && (i % devblocks == 0)) {
+ 			printk("done disk #%d.\n", disk++);
+ 			rotate = 0;
+@@ -248,8 +258,13 @@ int __init rd_load_image(char *from)
+ 			}
+ 			printk("Loading disk #%d... ", disk);
+ 		}
++#ifdef CONFIG_ARCH_STR8100
++      sys_read(in_fd, buf, BLOCK_SIZE<<6);
++ 		sys_write(out_fd, buf, BLOCK_SIZE<<6);
++#else
+ 		sys_read(in_fd, buf, BLOCK_SIZE);
+ 		sys_write(out_fd, buf, BLOCK_SIZE);
++#endif      
+ #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
+ 		if (!(i % 16)) {
+ 			printk("%c\b", rotator[rotate & 0x3]);
+diff -rupN linux-2.6.35.11/init/initramfs.c linux-2.6.35.11-ts7500/init/initramfs.c
+--- linux-2.6.35.11/init/initramfs.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/init/initramfs.c	2011-03-14 11:18:24.000000000 -0400
+@@ -464,6 +464,7 @@ static char * __init unpack_to_rootfs(ch
+ 		this_header = saved_offset + my_inptr;
+ 		buf += my_inptr;
+ 		len -= my_inptr;
++      break;
+ 	}
+ 	dir_utime();
+ 	kfree(name_buf);
+diff -rupN linux-2.6.35.11/init/main.c linux-2.6.35.11-ts7500/init/main.c
+--- linux-2.6.35.11/init/main.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/init/main.c	2011-03-14 11:18:24.000000000 -0400
+@@ -525,6 +525,7 @@ void __init __weak thread_info_cache_ini
+  */
+ static void __init mm_init(void)
+ {
++   
+ 	/*
+ 	 * page_cgroup requires countinous pages as memmap
+ 	 * and it's bigger than MAX_ORDER unless SPARSEMEM.
+@@ -541,12 +542,15 @@ asmlinkage void __init start_kernel(void
+ 	char * command_line;
+ 	extern struct kernel_param __start___param[], __stop___param[];
+ 
++   printk("start_kernel()\n");
++   
+ 	smp_setup_processor_id();
+ 
+ 	/*
+ 	 * Need to run as early as possible, to initialize the
+ 	 * lockdep hash:
+ 	 */
++ 
+ 	lockdep_init();
+ 	debug_objects_early_init();
+ 
+@@ -703,9 +707,7 @@ asmlinkage void __init start_kernel(void
+ 
+ 	acpi_early_init(); /* before LAPIC and SMP init */
+ 	sfi_init_late();
+-
+ 	ftrace_init();
+-
+ 	/* Do the rest non-__init'ed, we're now alive */
+ 	rest_init();
+ }
+@@ -779,9 +781,14 @@ extern initcall_t __initcall_start[], __
+ static void __init do_initcalls(void)
+ {
+ 	initcall_t *fn;
++	int i;
+ 
+ 	for (fn = __early_initcall_end; fn < __initcall_end; fn++)
++   {             
++    //  printk("Calling do_one_initcall(0x%08lX)\n", *fn);
++                 
+ 		do_one_initcall(*fn);
++   }
+ 
+ 	/* Make sure there is no pending stuff from the initcall sequence */
+ 	flush_scheduled_work();
+@@ -837,7 +844,7 @@ static noinline int init_post(void)
+ 
+ 	current->signal->flags |= SIGNAL_UNKILLABLE;
+ 
+-	if (ramdisk_execute_command) {
++	if (ramdisk_execute_command) {	   
+ 		run_init_process(ramdisk_execute_command);
+ 		printk(KERN_WARNING "Failed to execute %s\n",
+ 				ramdisk_execute_command);
+@@ -849,8 +856,8 @@ static noinline int init_post(void)
+ 	 * The Bourne shell can be used instead of init if we are
+ 	 * trying to recover a really broken machine.
+ 	 */
+-	if (execute_command) {
+-		run_init_process(execute_command);
++	if (execute_command) {	   	   
++		run_init_process(execute_command);		
+ 		printk(KERN_WARNING "Failed to execute %s.  Attempting "
+ 					"defaults...\n", execute_command);
+ 	}
+diff -rupN linux-2.6.35.11/init/main.c.orig linux-2.6.35.11-ts7500/init/main.c.orig
+--- linux-2.6.35.11/init/main.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/init/main.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,931 @@
++/*
++ *  linux/init/main.c
++ *
++ *  Copyright (C) 1991, 1992  Linus Torvalds
++ *
++ *  GK 2/5/95  -  Changed to support mounting root fs via NFS
++ *  Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96
++ *  Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96
++ *  Simplified starting of init:  Michael A. Griffith <grif@acm.org> 
++ */
++
++#include <linux/types.h>
++#include <linux/module.h>
++#include <linux/proc_fs.h>
++#include <linux/kernel.h>
++#include <linux/syscalls.h>
++#include <linux/stackprotector.h>
++#include <linux/string.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/init.h>
++#include <linux/smp_lock.h>
++#include <linux/initrd.h>
++#include <linux/bootmem.h>
++#include <linux/acpi.h>
++#include <linux/tty.h>
++#include <linux/percpu.h>
++#include <linux/kmod.h>
++#include <linux/vmalloc.h>
++#include <linux/kernel_stat.h>
++#include <linux/start_kernel.h>
++#include <linux/security.h>
++#include <linux/smp.h>
++#include <linux/workqueue.h>
++#include <linux/profile.h>
++#include <linux/rcupdate.h>
++#include <linux/moduleparam.h>
++#include <linux/kallsyms.h>
++#include <linux/writeback.h>
++#include <linux/cpu.h>
++#include <linux/cpuset.h>
++#include <linux/cgroup.h>
++#include <linux/efi.h>
++#include <linux/tick.h>
++#include <linux/interrupt.h>
++#include <linux/taskstats_kern.h>
++#include <linux/delayacct.h>
++#include <linux/unistd.h>
++#include <linux/rmap.h>
++#include <linux/mempolicy.h>
++#include <linux/key.h>
++#include <linux/buffer_head.h>
++#include <linux/page_cgroup.h>
++#include <linux/debug_locks.h>
++#include <linux/debugobjects.h>
++#include <linux/lockdep.h>
++#include <linux/kmemleak.h>
++#include <linux/pid_namespace.h>
++#include <linux/device.h>
++#include <linux/kthread.h>
++#include <linux/sched.h>
++#include <linux/signal.h>
++#include <linux/idr.h>
++#include <linux/kgdb.h>
++#include <linux/ftrace.h>
++#include <linux/async.h>
++#include <linux/kmemcheck.h>
++#include <linux/kmemtrace.h>
++#include <linux/sfi.h>
++#include <linux/shmem_fs.h>
++#include <linux/slab.h>
++#include <trace/boot.h>
++
++#include <asm/io.h>
++#include <asm/bugs.h>
++#include <asm/setup.h>
++#include <asm/sections.h>
++#include <asm/cacheflush.h>
++
++#ifdef CONFIG_X86_LOCAL_APIC
++#include <asm/smp.h>
++#endif
++
++static int kernel_init(void *);
++
++extern void init_IRQ(void);
++extern void fork_init(unsigned long);
++extern void mca_init(void);
++extern void sbus_init(void);
++extern void prio_tree_init(void);
++extern void radix_tree_init(void);
++extern void free_initmem(void);
++#ifndef CONFIG_DEBUG_RODATA
++static inline void mark_rodata_ro(void) { }
++#endif
++
++#ifdef CONFIG_TC
++extern void tc_init(void);
++#endif
++
++enum system_states system_state __read_mostly;
++EXPORT_SYMBOL(system_state);
++
++/*
++ * Boot command-line arguments
++ */
++#define MAX_INIT_ARGS CONFIG_INIT_ENV_ARG_LIMIT
++#define MAX_INIT_ENVS CONFIG_INIT_ENV_ARG_LIMIT
++
++extern void time_init(void);
++/* Default late time init is NULL. archs can override this later. */
++void (*__initdata late_time_init)(void);
++extern void softirq_init(void);
++
++/* Untouched command line saved by arch-specific code. */
++char __initdata boot_command_line[COMMAND_LINE_SIZE];
++/* Untouched saved command line (eg. for /proc) */
++char *saved_command_line;
++/* Command line for parameter parsing */
++static char *static_command_line;
++
++static char *execute_command;
++static char *ramdisk_execute_command;
++
++#ifdef CONFIG_SMP
++/* Setup configured maximum number of CPUs to activate */
++unsigned int setup_max_cpus = NR_CPUS;
++EXPORT_SYMBOL(setup_max_cpus);
++
++
++/*
++ * Setup routine for controlling SMP activation
++ *
++ * Command-line option of "nosmp" or "maxcpus=0" will disable SMP
++ * activation entirely (the MPS table probe still happens, though).
++ *
++ * Command-line option of "maxcpus=<NUM>", where <NUM> is an integer
++ * greater than 0, limits the maximum number of CPUs activated in
++ * SMP mode to <NUM>.
++ */
++
++void __weak arch_disable_smp_support(void) { }
++
++static int __init nosmp(char *str)
++{
++	setup_max_cpus = 0;
++	arch_disable_smp_support();
++
++	return 0;
++}
++
++early_param("nosmp", nosmp);
++
++/* this is hard limit */
++static int __init nrcpus(char *str)
++{
++	int nr_cpus;
++
++	get_option(&str, &nr_cpus);
++	if (nr_cpus > 0 && nr_cpus < nr_cpu_ids)
++		nr_cpu_ids = nr_cpus;
++
++	return 0;
++}
++
++early_param("nr_cpus", nrcpus);
++
++static int __init maxcpus(char *str)
++{
++	get_option(&str, &setup_max_cpus);
++	if (setup_max_cpus == 0)
++		arch_disable_smp_support();
++
++	return 0;
++}
++
++early_param("maxcpus", maxcpus);
++#else
++static const unsigned int setup_max_cpus = NR_CPUS;
++#endif
++
++/*
++ * If set, this is an indication to the drivers that reset the underlying
++ * device before going ahead with the initialization otherwise driver might
++ * rely on the BIOS and skip the reset operation.
++ *
++ * This is useful if kernel is booting in an unreliable environment.
++ * For ex. kdump situaiton where previous kernel has crashed, BIOS has been
++ * skipped and devices will be in unknown state.
++ */
++unsigned int reset_devices;
++EXPORT_SYMBOL(reset_devices);
++
++static int __init set_reset_devices(char *str)
++{
++	reset_devices = 1;
++	return 1;
++}
++
++__setup("reset_devices", set_reset_devices);
++
++static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
++char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
++static const char *panic_later, *panic_param;
++
++extern struct obs_kernel_param __setup_start[], __setup_end[];
++
++static int __init obsolete_checksetup(char *line)
++{
++	struct obs_kernel_param *p;
++	int had_early_param = 0;
++
++	p = __setup_start;
++	do {
++		int n = strlen(p->str);
++		if (!strncmp(line, p->str, n)) {
++			if (p->early) {
++				/* Already done in parse_early_param?
++				 * (Needs exact match on param part).
++				 * Keep iterating, as we can have early
++				 * params and __setups of same names 8( */
++				if (line[n] == '\0' || line[n] == '=')
++					had_early_param = 1;
++			} else if (!p->setup_func) {
++				printk(KERN_WARNING "Parameter %s is obsolete,"
++				       " ignored\n", p->str);
++				return 1;
++			} else if (p->setup_func(line + n))
++				return 1;
++		}
++		p++;
++	} while (p < __setup_end);
++
++	return had_early_param;
++}
++
++/*
++ * This should be approx 2 Bo*oMips to start (note initial shift), and will
++ * still work even if initially too large, it will just take slightly longer
++ */
++unsigned long loops_per_jiffy = (1<<12);
++
++EXPORT_SYMBOL(loops_per_jiffy);
++
++static int __init debug_kernel(char *str)
++{
++	console_loglevel = 10;
++	return 0;
++}
++
++static int __init quiet_kernel(char *str)
++{
++	console_loglevel = 4;
++	return 0;
++}
++
++early_param("debug", debug_kernel);
++early_param("quiet", quiet_kernel);
++
++static int __init loglevel(char *str)
++{
++	get_option(&str, &console_loglevel);
++	return 0;
++}
++
++early_param("loglevel", loglevel);
++
++/*
++ * Unknown boot options get handed to init, unless they look like
++ * unused parameters (modprobe will find them in /proc/cmdline).
++ */
++static int __init unknown_bootoption(char *param, char *val)
++{
++	/* Change NUL term back to "=", to make "param" the whole string. */
++	if (val) {
++		/* param=val or param="val"? */
++		if (val == param+strlen(param)+1)
++			val[-1] = '=';
++		else if (val == param+strlen(param)+2) {
++			val[-2] = '=';
++			memmove(val-1, val, strlen(val)+1);
++			val--;
++		} else
++			BUG();
++	}
++
++	/* Handle obsolete-style parameters */
++	if (obsolete_checksetup(param))
++		return 0;
++
++	/* Unused module parameter. */
++	if (strchr(param, '.') && (!val || strchr(param, '.') < val))
++		return 0;
++
++	if (panic_later)
++		return 0;
++
++	if (val) {
++		/* Environment option */
++		unsigned int i;
++		for (i = 0; envp_init[i]; i++) {
++			if (i == MAX_INIT_ENVS) {
++				panic_later = "Too many boot env vars at `%s'";
++				panic_param = param;
++			}
++			if (!strncmp(param, envp_init[i], val - param))
++				break;
++		}
++		envp_init[i] = param;
++	} else {
++		/* Command line option */
++		unsigned int i;
++		for (i = 0; argv_init[i]; i++) {
++			if (i == MAX_INIT_ARGS) {
++				panic_later = "Too many boot init vars at `%s'";
++				panic_param = param;
++			}
++		}
++		argv_init[i] = param;
++	}
++	return 0;
++}
++
++#ifdef CONFIG_DEBUG_PAGEALLOC
++int __read_mostly debug_pagealloc_enabled = 0;
++#endif
++
++static int __init init_setup(char *str)
++{
++	unsigned int i;
++
++	execute_command = str;
++	/*
++	 * In case LILO is going to boot us with default command line,
++	 * it prepends "auto" before the whole cmdline which makes
++	 * the shell think it should execute a script with such name.
++	 * So we ignore all arguments entered _before_ init=... [MJ]
++	 */
++	for (i = 1; i < MAX_INIT_ARGS; i++)
++		argv_init[i] = NULL;
++	return 1;
++}
++__setup("init=", init_setup);
++
++static int __init rdinit_setup(char *str)
++{
++	unsigned int i;
++
++	ramdisk_execute_command = str;
++	/* See "auto" comment in init_setup */
++	for (i = 1; i < MAX_INIT_ARGS; i++)
++		argv_init[i] = NULL;
++	return 1;
++}
++__setup("rdinit=", rdinit_setup);
++
++#ifndef CONFIG_SMP
++
++#ifdef CONFIG_X86_LOCAL_APIC
++static void __init smp_init(void)
++{
++	APIC_init_uniprocessor();
++}
++#else
++#define smp_init()	do { } while (0)
++#endif
++
++static inline void setup_nr_cpu_ids(void) { }
++static inline void smp_prepare_cpus(unsigned int maxcpus) { }
++
++#else
++
++/* Setup number of possible processor ids */
++int nr_cpu_ids __read_mostly = NR_CPUS;
++EXPORT_SYMBOL(nr_cpu_ids);
++
++/* An arch may set nr_cpu_ids earlier if needed, so this would be redundant */
++static void __init setup_nr_cpu_ids(void)
++{
++	nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1;
++}
++
++/* Called by boot processor to activate the rest. */
++static void __init smp_init(void)
++{
++	unsigned int cpu;
++
++	/* FIXME: This should be done in userspace --RR */
++	for_each_present_cpu(cpu) {
++		if (num_online_cpus() >= setup_max_cpus)
++			break;
++		if (!cpu_online(cpu))
++			cpu_up(cpu);
++	}
++
++	/* Any cleanup work */
++	printk(KERN_INFO "Brought up %ld CPUs\n", (long)num_online_cpus());
++	smp_cpus_done(setup_max_cpus);
++}
++
++#endif
++
++/*
++ * We need to store the untouched command line for future reference.
++ * We also need to store the touched command line since the parameter
++ * parsing is performed in place, and we should allow a component to
++ * store reference of name/value for future reference.
++ */
++static void __init setup_command_line(char *command_line)
++{
++	saved_command_line = alloc_bootmem(strlen (boot_command_line)+1);
++	static_command_line = alloc_bootmem(strlen (command_line)+1);
++	strcpy (saved_command_line, boot_command_line);
++	strcpy (static_command_line, command_line);
++}
++
++/*
++ * We need to finalize in a non-__init function or else race conditions
++ * between the root thread and the init thread may cause start_kernel to
++ * be reaped by free_initmem before the root thread has proceeded to
++ * cpu_idle.
++ *
++ * gcc-3.4 accidentally inlines this function, so use noinline.
++ */
++
++static __initdata DECLARE_COMPLETION(kthreadd_done);
++
++static noinline void __init_refok rest_init(void)
++	__releases(kernel_lock)
++{
++	int pid;
++
++	rcu_scheduler_starting();
++	/*
++	 * We need to spawn init first so that it obtains pid 1, however
++	 * the init task will end up wanting to create kthreads, which, if
++	 * we schedule it before we create kthreadd, will OOPS.
++	 */
++	kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
++	numa_default_policy();
++	pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
++	rcu_read_lock();
++	kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
++	rcu_read_unlock();
++	complete(&kthreadd_done);
++	unlock_kernel();
++
++	/*
++	 * The boot idle thread must execute schedule()
++	 * at least once to get things moving:
++	 */
++	init_idle_bootup_task(current);
++	preempt_enable_no_resched();
++	schedule();
++	preempt_disable();
++
++	/* Call into cpu_idle with preempt disabled */
++	cpu_idle();
++}
++
++/* Check for early params. */
++static int __init do_early_param(char *param, char *val)
++{
++	struct obs_kernel_param *p;
++
++	for (p = __setup_start; p < __setup_end; p++) {
++		if ((p->early && strcmp(param, p->str) == 0) ||
++		    (strcmp(param, "console") == 0 &&
++		     strcmp(p->str, "earlycon") == 0)
++		) {
++			if (p->setup_func(val) != 0)
++				printk(KERN_WARNING
++				       "Malformed early option '%s'\n", param);
++		}
++	}
++	/* We accept everything at this stage. */
++	return 0;
++}
++
++void __init parse_early_options(char *cmdline)
++{
++	parse_args("early options", cmdline, NULL, 0, do_early_param);
++}
++
++/* Arch code calls this early on, or if not, just before other parsing. */
++void __init parse_early_param(void)
++{
++	static __initdata int done = 0;
++	static __initdata char tmp_cmdline[COMMAND_LINE_SIZE];
++
++	if (done)
++		return;
++
++	/* All fall through to do_early_param. */
++	strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
++	parse_early_options(tmp_cmdline);
++	done = 1;
++}
++
++/*
++ *	Activate the first processor.
++ */
++
++static void __init boot_cpu_init(void)
++{
++	int cpu = smp_processor_id();
++	/* Mark the boot cpu "present", "online" etc for SMP and UP case */
++	set_cpu_online(cpu, true);
++	set_cpu_active(cpu, true);
++	set_cpu_present(cpu, true);
++	set_cpu_possible(cpu, true);
++}
++
++void __init __weak smp_setup_processor_id(void)
++{
++}
++
++void __init __weak thread_info_cache_init(void)
++{
++}
++
++/*
++ * Set up kernel memory allocators
++ */
++static void __init mm_init(void)
++{
++	/*
++	 * page_cgroup requires countinous pages as memmap
++	 * and it's bigger than MAX_ORDER unless SPARSEMEM.
++	 */
++	page_cgroup_init_flatmem();
++	mem_init();
++	kmem_cache_init();
++	pgtable_cache_init();
++	vmalloc_init();
++}
++
++asmlinkage void __init start_kernel(void)
++{
++	char * command_line;
++	extern struct kernel_param __start___param[], __stop___param[];
++
++	smp_setup_processor_id();
++
++	/*
++	 * Need to run as early as possible, to initialize the
++	 * lockdep hash:
++	 */
++	lockdep_init();
++	debug_objects_early_init();
++
++	/*
++	 * Set up the the initial canary ASAP:
++	 */
++	boot_init_stack_canary();
++
++	cgroup_init_early();
++
++	local_irq_disable();
++	early_boot_irqs_off();
++	early_init_irq_lock_class();
++
++/*
++ * Interrupts are still disabled. Do necessary setups, then
++ * enable them
++ */
++	lock_kernel();
++	tick_init();
++	boot_cpu_init();
++	page_address_init();
++	printk(KERN_NOTICE "%s", linux_banner);
++	setup_arch(&command_line);
++	mm_init_owner(&init_mm, &init_task);
++	setup_command_line(command_line);
++	setup_nr_cpu_ids();
++	setup_per_cpu_areas();
++	smp_prepare_boot_cpu();	/* arch-specific boot-cpu hooks */
++
++	build_all_zonelists(NULL);
++	page_alloc_init();
++
++	printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
++	parse_early_param();
++	parse_args("Booting kernel", static_command_line, __start___param,
++		   __stop___param - __start___param,
++		   &unknown_bootoption);
++	/*
++	 * These use large bootmem allocations and must precede
++	 * kmem_cache_init()
++	 */
++	pidhash_init();
++	vfs_caches_init_early();
++	sort_main_extable();
++	trap_init();
++	mm_init();
++	/*
++	 * Set up the scheduler prior starting any interrupts (such as the
++	 * timer interrupt). Full topology setup happens at smp_init()
++	 * time - but meanwhile we still have a functioning scheduler.
++	 */
++	sched_init();
++	/*
++	 * Disable preemption - early bootup scheduling is extremely
++	 * fragile until we cpu_idle() for the first time.
++	 */
++	preempt_disable();
++	if (!irqs_disabled()) {
++		printk(KERN_WARNING "start_kernel(): bug: interrupts were "
++				"enabled *very* early, fixing it\n");
++		local_irq_disable();
++	}
++	rcu_init();
++	radix_tree_init();
++	/* init some links before init_ISA_irqs() */
++	early_irq_init();
++	init_IRQ();
++	prio_tree_init();
++	init_timers();
++	hrtimers_init();
++	softirq_init();
++	timekeeping_init();
++	time_init();
++	profile_init();
++	if (!irqs_disabled())
++		printk(KERN_CRIT "start_kernel(): bug: interrupts were "
++				 "enabled early\n");
++	early_boot_irqs_on();
++	local_irq_enable();
++
++	/* Interrupts are enabled now so all GFP allocations are safe. */
++	gfp_allowed_mask = __GFP_BITS_MASK;
++
++	kmem_cache_init_late();
++
++	/*
++	 * HACK ALERT! This is early. We're enabling the console before
++	 * we've done PCI setups etc, and console_init() must be aware of
++	 * this. But we do want output early, in case something goes wrong.
++	 */
++	console_init();
++	if (panic_later)
++		panic(panic_later, panic_param);
++
++	lockdep_info();
++
++	/*
++	 * Need to run this when irqs are enabled, because it wants
++	 * to self-test [hard/soft]-irqs on/off lock inversion bugs
++	 * too:
++	 */
++	locking_selftest();
++
++#ifdef CONFIG_BLK_DEV_INITRD
++	if (initrd_start && !initrd_below_start_ok &&
++	    page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
++		printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
++		    "disabling it.\n",
++		    page_to_pfn(virt_to_page((void *)initrd_start)),
++		    min_low_pfn);
++		initrd_start = 0;
++	}
++#endif
++	page_cgroup_init();
++	enable_debug_pagealloc();
++	kmemtrace_init();
++	kmemleak_init();
++	debug_objects_mem_init();
++	idr_init_cache();
++	setup_per_cpu_pageset();
++	numa_policy_init();
++	if (late_time_init)
++		late_time_init();
++	sched_clock_init();
++	calibrate_delay();
++	pidmap_init();
++	anon_vma_init();
++#ifdef CONFIG_X86
++	if (efi_enabled)
++		efi_enter_virtual_mode();
++#endif
++	thread_info_cache_init();
++	cred_init();
++	fork_init(totalram_pages);
++	proc_caches_init();
++	buffer_init();
++	key_init();
++	security_init();
++	dbg_late_init();
++	vfs_caches_init(totalram_pages);
++	signals_init();
++	/* rootfs populating might need page-writeback */
++	page_writeback_init();
++#ifdef CONFIG_PROC_FS
++	proc_root_init();
++#endif
++	cgroup_init();
++	cpuset_init();
++	taskstats_init_early();
++	delayacct_init();
++
++	check_bugs();
++
++	acpi_early_init(); /* before LAPIC and SMP init */
++	sfi_init_late();
++
++	ftrace_init();
++
++	/* Do the rest non-__init'ed, we're now alive */
++	rest_init();
++}
++
++/* Call all constructor functions linked into the kernel. */
++static void __init do_ctors(void)
++{
++#ifdef CONFIG_CONSTRUCTORS
++	ctor_fn_t *fn = (ctor_fn_t *) __ctors_start;
++
++	for (; fn < (ctor_fn_t *) __ctors_end; fn++)
++		(*fn)();
++#endif
++}
++
++int initcall_debug;
++core_param(initcall_debug, initcall_debug, bool, 0644);
++
++static char msgbuf[64];
++static struct boot_trace_call call;
++static struct boot_trace_ret ret;
++
++int do_one_initcall(initcall_t fn)
++{
++	int count = preempt_count();
++	ktime_t calltime, delta, rettime;
++
++	if (initcall_debug) {
++		call.caller = task_pid_nr(current);
++		printk("calling  %pF @ %i\n", fn, call.caller);
++		calltime = ktime_get();
++		trace_boot_call(&call, fn);
++		enable_boot_trace();
++	}
++
++	ret.result = fn();
++
++	if (initcall_debug) {
++		disable_boot_trace();
++		rettime = ktime_get();
++		delta = ktime_sub(rettime, calltime);
++		ret.duration = (unsigned long long) ktime_to_ns(delta) >> 10;
++		trace_boot_ret(&ret, fn);
++		printk("initcall %pF returned %d after %Ld usecs\n", fn,
++			ret.result, ret.duration);
++	}
++
++	msgbuf[0] = 0;
++
++	if (ret.result && ret.result != -ENODEV && initcall_debug)
++		sprintf(msgbuf, "error code %d ", ret.result);
++
++	if (preempt_count() != count) {
++		strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
++		preempt_count() = count;
++	}
++	if (irqs_disabled()) {
++		strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
++		local_irq_enable();
++	}
++	if (msgbuf[0]) {
++		printk("initcall %pF returned with %s\n", fn, msgbuf);
++	}
++
++	return ret.result;
++}
++
++
++extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
++
++static void __init do_initcalls(void)
++{
++	initcall_t *fn;
++
++	for (fn = __early_initcall_end; fn < __initcall_end; fn++)
++		do_one_initcall(*fn);
++
++	/* Make sure there is no pending stuff from the initcall sequence */
++	flush_scheduled_work();
++}
++
++/*
++ * Ok, the machine is now initialized. None of the devices
++ * have been touched yet, but the CPU subsystem is up and
++ * running, and memory and process management works.
++ *
++ * Now we can finally start doing some real work..
++ */
++static void __init do_basic_setup(void)
++{
++	init_workqueues();
++	cpuset_init_smp();
++	usermodehelper_init();
++	init_tmpfs();
++	driver_init();
++	init_irq_proc();
++	do_ctors();
++	do_initcalls();
++}
++
++static void __init do_pre_smp_initcalls(void)
++{
++	initcall_t *fn;
++
++	for (fn = __initcall_start; fn < __early_initcall_end; fn++)
++		do_one_initcall(*fn);
++}
++
++static void run_init_process(char *init_filename)
++{
++	argv_init[0] = init_filename;
++	kernel_execve(init_filename, argv_init, envp_init);
++}
++
++/* This is a non __init function. Force it to be noinline otherwise gcc
++ * makes it inline to init() and it becomes part of init.text section
++ */
++static noinline int init_post(void)
++	__releases(kernel_lock)
++{
++	/* need to finish all async __init code before freeing the memory */
++	async_synchronize_full();
++	free_initmem();
++	unlock_kernel();
++	mark_rodata_ro();
++	system_state = SYSTEM_RUNNING;
++	numa_default_policy();
++
++
++	current->signal->flags |= SIGNAL_UNKILLABLE;
++
++	if (ramdisk_execute_command) {
++		run_init_process(ramdisk_execute_command);
++		printk(KERN_WARNING "Failed to execute %s\n",
++				ramdisk_execute_command);
++	}
++
++	/*
++	 * We try each of these until one succeeds.
++	 *
++	 * The Bourne shell can be used instead of init if we are
++	 * trying to recover a really broken machine.
++	 */
++	if (execute_command) {
++		run_init_process(execute_command);
++		printk(KERN_WARNING "Failed to execute %s.  Attempting "
++					"defaults...\n", execute_command);
++	}
++	run_init_process("/sbin/init");
++	run_init_process("/etc/init");
++	run_init_process("/bin/init");
++	run_init_process("/bin/sh");
++
++	panic("No init found.  Try passing init= option to kernel. "
++	      "See Linux Documentation/init.txt for guidance.");
++}
++
++static int __init kernel_init(void * unused)
++{
++	/*
++	 * Wait until kthreadd is all set-up.
++	 */
++	wait_for_completion(&kthreadd_done);
++	lock_kernel();
++
++	/*
++	 * init can allocate pages on any node
++	 */
++	set_mems_allowed(node_states[N_HIGH_MEMORY]);
++	/*
++	 * init can run on any cpu.
++	 */
++	set_cpus_allowed_ptr(current, cpu_all_mask);
++	/*
++	 * Tell the world that we're going to be the grim
++	 * reaper of innocent orphaned children.
++	 *
++	 * We don't want people to have to make incorrect
++	 * assumptions about where in the task array this
++	 * can be found.
++	 */
++	init_pid_ns.child_reaper = current;
++
++	cad_pid = task_pid(current);
++
++	smp_prepare_cpus(setup_max_cpus);
++
++	do_pre_smp_initcalls();
++	start_boot_trace();
++
++	smp_init();
++	sched_init_smp();
++
++	do_basic_setup();
++
++	/* Open the /dev/console on the rootfs, this should never fail */
++	if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
++		printk(KERN_WARNING "Warning: unable to open an initial console.\n");
++
++	(void) sys_dup(0);
++	(void) sys_dup(0);
++	/*
++	 * check if there is an early userspace init.  If yes, let it do all
++	 * the work
++	 */
++
++	if (!ramdisk_execute_command)
++		ramdisk_execute_command = "/init";
++
++	if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
++		ramdisk_execute_command = NULL;
++		prepare_namespace();
++	}
++
++	/*
++	 * Ok, we have completed the initial bootup, and
++	 * we're essentially up and running. Get rid of the
++	 * initmem segments and start the user-mode stuff..
++	 */
++
++	init_post();
++	return 0;
++}
+diff -rupN linux-2.6.35.11/kernel/hrtimer.c linux-2.6.35.11-ts7500/kernel/hrtimer.c
+--- linux-2.6.35.11/kernel/hrtimer.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/kernel/hrtimer.c	2011-03-14 11:18:24.000000000 -0400
+@@ -328,14 +328,13 @@ ktime_t ktime_add_safe(const ktime_t lhs
+ 	 */
+ 	if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64)
+ 		res = ktime_set(KTIME_SEC_MAX, 0);
+-
++ 
+ 	return res;
+ }
+ 
+ EXPORT_SYMBOL_GPL(ktime_add_safe);
+ 
+ #ifdef CONFIG_DEBUG_OBJECTS_TIMERS
+-
+ static struct debug_obj_descr hrtimer_debug_descr;
+ 
+ /*
+@@ -466,7 +465,6 @@ static inline void debug_deactivate(stru
+ 
+ /* High resolution timer related functions */
+ #ifdef CONFIG_HIGH_RES_TIMERS
+-
+ /*
+  * High resolution timer enabled ?
+  */
+@@ -715,6 +713,8 @@ static int hrtimer_switch_to_hres(void)
+ 	struct hrtimer_cpu_base *base = &per_cpu(hrtimer_bases, cpu);
+ 	unsigned long flags;
+ 
++	printk("hrtimer_switch_to_hres()\n");
++	
+ 	if (base->hres_active)
+ 		return 1;
+ 
+@@ -851,7 +851,7 @@ static int enqueue_hrtimer(struct hrtime
+ 	int leftmost = 1;
+ 
+ 	debug_activate(timer);
+-
++	
+ 	/*
+ 	 * Find the right place in the rbtree:
+ 	 */
+@@ -885,7 +885,7 @@ static int enqueue_hrtimer(struct hrtime
+ 	 * state of a possibly running callback.
+ 	 */
+ 	timer->state |= HRTIMER_STATE_ENQUEUED;
+-
++			
+ 	return leftmost;
+ }
+ 
+@@ -969,9 +969,10 @@ int __hrtimer_start_range_ns(struct hrti
+ 	struct hrtimer_clock_base *base, *new_base;
+ 	unsigned long flags;
+ 	int ret, leftmost;
+-
++	
+ 	base = lock_hrtimer_base(timer, &flags);
+ 
++		
+ 	/* Remove an active timer from the queue: */
+ 	ret = remove_hrtimer(timer, base);
+ 
+@@ -1008,7 +1009,7 @@ int __hrtimer_start_range_ns(struct hrti
+ 		hrtimer_enqueue_reprogram(timer, new_base, wakeup);
+ 
+ 	unlock_hrtimer_base(timer, &flags);
+-
++		
+ 	return ret;
+ }
+ 
+@@ -1184,7 +1185,7 @@ static void __hrtimer_init(struct hrtime
+  */
+ void hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
+ 		  enum hrtimer_mode mode)
+-{
++{   
+ 	debug_init(timer, clock_id, mode);
+ 	__hrtimer_init(timer, clock_id, mode);
+ }
+@@ -1216,6 +1217,8 @@ static void __run_hrtimer(struct hrtimer
+ 	enum hrtimer_restart (*fn)(struct hrtimer *);
+ 	int restart;
+ 
++	//printk("__run_hrtimer %lld\n", timer->_expires.tv64);
++	
+ 	WARN_ON(!irqs_disabled());
+ 
+ 	debug_deactivate(timer);
+@@ -1452,26 +1455,41 @@ void hrtimer_run_queues(void)
+ 	struct hrtimer_clock_base *base;
+ 	int index, gettime = 1;
+ 
++	
+ 	if (hrtimer_hres_active())
+ 		return;
+ 
++	
+ 	for (index = 0; index < HRTIMER_MAX_CLOCK_BASES; index++) {
+ 		base = &cpu_base->clock_base[index];
+ 
++		//printk("0\n");
++		
+ 		if (!base->first)
+ 			continue;
+ 
++		//printk("1\n");
++		
+ 		if (gettime) {
++		  // printk("2\n");
+ 			hrtimer_get_softirq_time(cpu_base);
++			//printk("3\n");
+ 			gettime = 0;
+ 		}
+ 
++		//printk("4\n");
++		
+ 		raw_spin_lock(&cpu_base->lock);
+ 
++		//printk("5\n");
++		
+ 		while ((node = base->first)) {
+ 			struct hrtimer *timer;
+-
++			 			
+ 			timer = rb_entry(node, struct hrtimer, node);
++			
++			//printk("timer %lld\n", timer->_expires.tv64);
++			
+ 			if (base->softirq_time.tv64 <=
+ 					hrtimer_get_expires_tv64(timer))
+ 				break;
+@@ -1507,22 +1525,28 @@ EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
+ 
+ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
+ {
+-	hrtimer_init_sleeper(t, current);
+-
++   //printk("do_nanosleep()\n");
++   
++	hrtimer_init_sleeper(t, current);	
++	
++	//printk("1\n");
++	
+ 	do {
+ 		set_current_state(TASK_INTERRUPTIBLE);
+ 		hrtimer_start_expires(&t->timer, mode);
+ 		if (!hrtimer_active(&t->timer))
+ 			t->task = NULL;
+-
++				
+ 		if (likely(t->task))
+ 			schedule();
+-
++		
+ 		hrtimer_cancel(&t->timer);
+ 		mode = HRTIMER_MODE_ABS;
+-
++			
+ 	} while (t->task && !signal_pending(current));
+ 
++	//printk("done\n");
++	
+ 	__set_current_state(TASK_RUNNING);
+ 
+ 	return t->task == NULL;
+diff -rupN linux-2.6.35.11/kernel/hrtimer.c.orig linux-2.6.35.11-ts7500/kernel/hrtimer.c.orig
+--- linux-2.6.35.11/kernel/hrtimer.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/kernel/hrtimer.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,1874 @@
++/*
++ *  linux/kernel/hrtimer.c
++ *
++ *  Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
++ *  Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
++ *  Copyright(C) 2006-2007  Timesys Corp., Thomas Gleixner
++ *
++ *  High-resolution kernel timers
++ *
++ *  In contrast to the low-resolution timeout API implemented in
++ *  kernel/timer.c, hrtimers provide finer resolution and accuracy
++ *  depending on system configuration and capabilities.
++ *
++ *  These timers are currently used for:
++ *   - itimers
++ *   - POSIX timers
++ *   - nanosleep
++ *   - precise in-kernel timing
++ *
++ *  Started by: Thomas Gleixner and Ingo Molnar
++ *
++ *  Credits:
++ *	based on kernel/timer.c
++ *
++ *	Help, testing, suggestions, bugfixes, improvements were
++ *	provided by:
++ *
++ *	George Anzinger, Andrew Morton, Steven Rostedt, Roman Zippel
++ *	et. al.
++ *
++ *  For licencing details see kernel-base/COPYING
++ */
++
++#include <linux/cpu.h>
++#include <linux/module.h>
++#include <linux/percpu.h>
++#include <linux/hrtimer.h>
++#include <linux/notifier.h>
++#include <linux/syscalls.h>
++#include <linux/kallsyms.h>
++#include <linux/interrupt.h>
++#include <linux/tick.h>
++#include <linux/seq_file.h>
++#include <linux/err.h>
++#include <linux/debugobjects.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++
++#include <asm/uaccess.h>
++
++#include <trace/events/timer.h>
++
++/*
++ * The timer bases:
++ *
++ * Note: If we want to add new timer bases, we have to skip the two
++ * clock ids captured by the cpu-timers. We do this by holding empty
++ * entries rather than doing math adjustment of the clock ids.
++ * This ensures that we capture erroneous accesses to these clock ids
++ * rather than moving them into the range of valid clock id's.
++ */
++DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
++{
++
++	.clock_base =
++	{
++		{
++			.index = CLOCK_REALTIME,
++			.get_time = &ktime_get_real,
++			.resolution = KTIME_LOW_RES,
++		},
++		{
++			.index = CLOCK_MONOTONIC,
++			.get_time = &ktime_get,
++			.resolution = KTIME_LOW_RES,
++		},
++	}
++};
++
++/*
++ * Get the coarse grained time at the softirq based on xtime and
++ * wall_to_monotonic.
++ */
++static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
++{
++	ktime_t xtim, tomono;
++	struct timespec xts, tom;
++	unsigned long seq;
++
++	do {
++		seq = read_seqbegin(&xtime_lock);
++		xts = __current_kernel_time();
++		tom = wall_to_monotonic;
++	} while (read_seqretry(&xtime_lock, seq));
++
++	xtim = timespec_to_ktime(xts);
++	tomono = timespec_to_ktime(tom);
++	base->clock_base[CLOCK_REALTIME].softirq_time = xtim;
++	base->clock_base[CLOCK_MONOTONIC].softirq_time =
++		ktime_add(xtim, tomono);
++}
++
++/*
++ * Functions and macros which are different for UP/SMP systems are kept in a
++ * single place
++ */
++#ifdef CONFIG_SMP
++
++/*
++ * We are using hashed locking: holding per_cpu(hrtimer_bases)[n].lock
++ * means that all timers which are tied to this base via timer->base are
++ * locked, and the base itself is locked too.
++ *
++ * So __run_timers/migrate_timers can safely modify all timers which could
++ * be found on the lists/queues.
++ *
++ * When the timer's base is locked, and the timer removed from list, it is
++ * possible to set timer->base = NULL and drop the lock: the timer remains
++ * locked.
++ */
++static
++struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer,
++					     unsigned long *flags)
++{
++	struct hrtimer_clock_base *base;
++
++	for (;;) {
++		base = timer->base;
++		if (likely(base != NULL)) {
++			raw_spin_lock_irqsave(&base->cpu_base->lock, *flags);
++			if (likely(base == timer->base))
++				return base;
++			/* The timer has migrated to another CPU: */
++			raw_spin_unlock_irqrestore(&base->cpu_base->lock, *flags);
++		}
++		cpu_relax();
++	}
++}
++
++
++/*
++ * Get the preferred target CPU for NOHZ
++ */
++static int hrtimer_get_target(int this_cpu, int pinned)
++{
++#ifdef CONFIG_NO_HZ
++	if (!pinned && get_sysctl_timer_migration() && idle_cpu(this_cpu)) {
++		int preferred_cpu = get_nohz_load_balancer();
++
++		if (preferred_cpu >= 0)
++			return preferred_cpu;
++	}
++#endif
++	return this_cpu;
++}
++
++/*
++ * With HIGHRES=y we do not migrate the timer when it is expiring
++ * before the next event on the target cpu because we cannot reprogram
++ * the target cpu hardware and we would cause it to fire late.
++ *
++ * Called with cpu_base->lock of target cpu held.
++ */
++static int
++hrtimer_check_target(struct hrtimer *timer, struct hrtimer_clock_base *new_base)
++{
++#ifdef CONFIG_HIGH_RES_TIMERS
++	ktime_t expires;
++
++	if (!new_base->cpu_base->hres_active)
++		return 0;
++
++	expires = ktime_sub(hrtimer_get_expires(timer), new_base->offset);
++	return expires.tv64 <= new_base->cpu_base->expires_next.tv64;
++#else
++	return 0;
++#endif
++}
++
++/*
++ * Switch the timer base to the current CPU when possible.
++ */
++static inline struct hrtimer_clock_base *
++switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base,
++		    int pinned)
++{
++	struct hrtimer_clock_base *new_base;
++	struct hrtimer_cpu_base *new_cpu_base;
++	int this_cpu = smp_processor_id();
++	int cpu = hrtimer_get_target(this_cpu, pinned);
++
++again:
++	new_cpu_base = &per_cpu(hrtimer_bases, cpu);
++	new_base = &new_cpu_base->clock_base[base->index];
++
++	if (base != new_base) {
++		/*
++		 * We are trying to move timer to new_base.
++		 * However we can't change timer's base while it is running,
++		 * so we keep it on the same CPU. No hassle vs. reprogramming
++		 * the event source in the high resolution case. The softirq
++		 * code will take care of this when the timer function has
++		 * completed. There is no conflict as we hold the lock until
++		 * the timer is enqueued.
++		 */
++		if (unlikely(hrtimer_callback_running(timer)))
++			return base;
++
++		/* See the comment in lock_timer_base() */
++		timer->base = NULL;
++		raw_spin_unlock(&base->cpu_base->lock);
++		raw_spin_lock(&new_base->cpu_base->lock);
++
++		if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) {
++			cpu = this_cpu;
++			raw_spin_unlock(&new_base->cpu_base->lock);
++			raw_spin_lock(&base->cpu_base->lock);
++			timer->base = base;
++			goto again;
++		}
++		timer->base = new_base;
++	}
++	return new_base;
++}
++
++#else /* CONFIG_SMP */
++
++static inline struct hrtimer_clock_base *
++lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
++{
++	struct hrtimer_clock_base *base = timer->base;
++
++	raw_spin_lock_irqsave(&base->cpu_base->lock, *flags);
++
++	return base;
++}
++
++# define switch_hrtimer_base(t, b, p)	(b)
++
++#endif	/* !CONFIG_SMP */
++
++/*
++ * Functions for the union type storage format of ktime_t which are
++ * too large for inlining:
++ */
++#if BITS_PER_LONG < 64
++# ifndef CONFIG_KTIME_SCALAR
++/**
++ * ktime_add_ns - Add a scalar nanoseconds value to a ktime_t variable
++ * @kt:		addend
++ * @nsec:	the scalar nsec value to add
++ *
++ * Returns the sum of kt and nsec in ktime_t format
++ */
++ktime_t ktime_add_ns(const ktime_t kt, u64 nsec)
++{
++	ktime_t tmp;
++
++	if (likely(nsec < NSEC_PER_SEC)) {
++		tmp.tv64 = nsec;
++	} else {
++		unsigned long rem = do_div(nsec, NSEC_PER_SEC);
++
++		tmp = ktime_set((long)nsec, rem);
++	}
++
++	return ktime_add(kt, tmp);
++}
++
++EXPORT_SYMBOL_GPL(ktime_add_ns);
++
++/**
++ * ktime_sub_ns - Subtract a scalar nanoseconds value from a ktime_t variable
++ * @kt:		minuend
++ * @nsec:	the scalar nsec value to subtract
++ *
++ * Returns the subtraction of @nsec from @kt in ktime_t format
++ */
++ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec)
++{
++	ktime_t tmp;
++
++	if (likely(nsec < NSEC_PER_SEC)) {
++		tmp.tv64 = nsec;
++	} else {
++		unsigned long rem = do_div(nsec, NSEC_PER_SEC);
++
++		tmp = ktime_set((long)nsec, rem);
++	}
++
++	return ktime_sub(kt, tmp);
++}
++
++EXPORT_SYMBOL_GPL(ktime_sub_ns);
++# endif /* !CONFIG_KTIME_SCALAR */
++
++/*
++ * Divide a ktime value by a nanosecond value
++ */
++u64 ktime_divns(const ktime_t kt, s64 div)
++{
++	u64 dclc;
++	int sft = 0;
++
++	dclc = ktime_to_ns(kt);
++	/* Make sure the divisor is less than 2^32: */
++	while (div >> 32) {
++		sft++;
++		div >>= 1;
++	}
++	dclc >>= sft;
++	do_div(dclc, (unsigned long) div);
++
++	return dclc;
++}
++#endif /* BITS_PER_LONG >= 64 */
++
++/*
++ * Add two ktime values and do a safety check for overflow:
++ */
++ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs)
++{
++	ktime_t res = ktime_add(lhs, rhs);
++
++	/*
++	 * We use KTIME_SEC_MAX here, the maximum timeout which we can
++	 * return to user space in a timespec:
++	 */
++	if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64)
++		res = ktime_set(KTIME_SEC_MAX, 0);
++
++	return res;
++}
++
++EXPORT_SYMBOL_GPL(ktime_add_safe);
++
++#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
++
++static struct debug_obj_descr hrtimer_debug_descr;
++
++/*
++ * fixup_init is called when:
++ * - an active object is initialized
++ */
++static int hrtimer_fixup_init(void *addr, enum debug_obj_state state)
++{
++	struct hrtimer *timer = addr;
++
++	switch (state) {
++	case ODEBUG_STATE_ACTIVE:
++		hrtimer_cancel(timer);
++		debug_object_init(timer, &hrtimer_debug_descr);
++		return 1;
++	default:
++		return 0;
++	}
++}
++
++/*
++ * fixup_activate is called when:
++ * - an active object is activated
++ * - an unknown object is activated (might be a statically initialized object)
++ */
++static int hrtimer_fixup_activate(void *addr, enum debug_obj_state state)
++{
++	switch (state) {
++
++	case ODEBUG_STATE_NOTAVAILABLE:
++		WARN_ON_ONCE(1);
++		return 0;
++
++	case ODEBUG_STATE_ACTIVE:
++		WARN_ON(1);
++
++	default:
++		return 0;
++	}
++}
++
++/*
++ * fixup_free is called when:
++ * - an active object is freed
++ */
++static int hrtimer_fixup_free(void *addr, enum debug_obj_state state)
++{
++	struct hrtimer *timer = addr;
++
++	switch (state) {
++	case ODEBUG_STATE_ACTIVE:
++		hrtimer_cancel(timer);
++		debug_object_free(timer, &hrtimer_debug_descr);
++		return 1;
++	default:
++		return 0;
++	}
++}
++
++static struct debug_obj_descr hrtimer_debug_descr = {
++	.name		= "hrtimer",
++	.fixup_init	= hrtimer_fixup_init,
++	.fixup_activate	= hrtimer_fixup_activate,
++	.fixup_free	= hrtimer_fixup_free,
++};
++
++static inline void debug_hrtimer_init(struct hrtimer *timer)
++{
++	debug_object_init(timer, &hrtimer_debug_descr);
++}
++
++static inline void debug_hrtimer_activate(struct hrtimer *timer)
++{
++	debug_object_activate(timer, &hrtimer_debug_descr);
++}
++
++static inline void debug_hrtimer_deactivate(struct hrtimer *timer)
++{
++	debug_object_deactivate(timer, &hrtimer_debug_descr);
++}
++
++static inline void debug_hrtimer_free(struct hrtimer *timer)
++{
++	debug_object_free(timer, &hrtimer_debug_descr);
++}
++
++static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
++			   enum hrtimer_mode mode);
++
++void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t clock_id,
++			   enum hrtimer_mode mode)
++{
++	debug_object_init_on_stack(timer, &hrtimer_debug_descr);
++	__hrtimer_init(timer, clock_id, mode);
++}
++EXPORT_SYMBOL_GPL(hrtimer_init_on_stack);
++
++void destroy_hrtimer_on_stack(struct hrtimer *timer)
++{
++	debug_object_free(timer, &hrtimer_debug_descr);
++}
++
++#else
++static inline void debug_hrtimer_init(struct hrtimer *timer) { }
++static inline void debug_hrtimer_activate(struct hrtimer *timer) { }
++static inline void debug_hrtimer_deactivate(struct hrtimer *timer) { }
++#endif
++
++static inline void
++debug_init(struct hrtimer *timer, clockid_t clockid,
++	   enum hrtimer_mode mode)
++{
++	debug_hrtimer_init(timer);
++	trace_hrtimer_init(timer, clockid, mode);
++}
++
++static inline void debug_activate(struct hrtimer *timer)
++{
++	debug_hrtimer_activate(timer);
++	trace_hrtimer_start(timer);
++}
++
++static inline void debug_deactivate(struct hrtimer *timer)
++{
++	debug_hrtimer_deactivate(timer);
++	trace_hrtimer_cancel(timer);
++}
++
++/* High resolution timer related functions */
++#ifdef CONFIG_HIGH_RES_TIMERS
++
++/*
++ * High resolution timer enabled ?
++ */
++static int hrtimer_hres_enabled __read_mostly  = 1;
++
++/*
++ * Enable / Disable high resolution mode
++ */
++static int __init setup_hrtimer_hres(char *str)
++{
++	if (!strcmp(str, "off"))
++		hrtimer_hres_enabled = 0;
++	else if (!strcmp(str, "on"))
++		hrtimer_hres_enabled = 1;
++	else
++		return 0;
++	return 1;
++}
++
++__setup("highres=", setup_hrtimer_hres);
++
++/*
++ * hrtimer_high_res_enabled - query, if the highres mode is enabled
++ */
++static inline int hrtimer_is_hres_enabled(void)
++{
++	return hrtimer_hres_enabled;
++}
++
++/*
++ * Is the high resolution mode active ?
++ */
++static inline int hrtimer_hres_active(void)
++{
++	return __get_cpu_var(hrtimer_bases).hres_active;
++}
++
++/*
++ * Reprogram the event source with checking both queues for the
++ * next event
++ * Called with interrupts disabled and base->lock held
++ */
++static void
++hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
++{
++	int i;
++	struct hrtimer_clock_base *base = cpu_base->clock_base;
++	ktime_t expires, expires_next;
++
++	expires_next.tv64 = KTIME_MAX;
++
++	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) {
++		struct hrtimer *timer;
++
++		if (!base->first)
++			continue;
++		timer = rb_entry(base->first, struct hrtimer, node);
++		expires = ktime_sub(hrtimer_get_expires(timer), base->offset);
++		/*
++		 * clock_was_set() has changed base->offset so the
++		 * result might be negative. Fix it up to prevent a
++		 * false positive in clockevents_program_event()
++		 */
++		if (expires.tv64 < 0)
++			expires.tv64 = 0;
++		if (expires.tv64 < expires_next.tv64)
++			expires_next = expires;
++	}
++
++	if (skip_equal && expires_next.tv64 == cpu_base->expires_next.tv64)
++		return;
++
++	cpu_base->expires_next.tv64 = expires_next.tv64;
++
++	if (cpu_base->expires_next.tv64 != KTIME_MAX)
++		tick_program_event(cpu_base->expires_next, 1);
++}
++
++/*
++ * Shared reprogramming for clock_realtime and clock_monotonic
++ *
++ * When a timer is enqueued and expires earlier than the already enqueued
++ * timers, we have to check, whether it expires earlier than the timer for
++ * which the clock event device was armed.
++ *
++ * Called with interrupts disabled and base->cpu_base.lock held
++ */
++static int hrtimer_reprogram(struct hrtimer *timer,
++			     struct hrtimer_clock_base *base)
++{
++	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
++	ktime_t expires = ktime_sub(hrtimer_get_expires(timer), base->offset);
++	int res;
++
++	WARN_ON_ONCE(hrtimer_get_expires_tv64(timer) < 0);
++
++	/*
++	 * When the callback is running, we do not reprogram the clock event
++	 * device. The timer callback is either running on a different CPU or
++	 * the callback is executed in the hrtimer_interrupt context. The
++	 * reprogramming is handled either by the softirq, which called the
++	 * callback or at the end of the hrtimer_interrupt.
++	 */
++	if (hrtimer_callback_running(timer))
++		return 0;
++
++	/*
++	 * CLOCK_REALTIME timer might be requested with an absolute
++	 * expiry time which is less than base->offset. Nothing wrong
++	 * about that, just avoid to call into the tick code, which
++	 * has now objections against negative expiry values.
++	 */
++	if (expires.tv64 < 0)
++		return -ETIME;
++
++	if (expires.tv64 >= cpu_base->expires_next.tv64)
++		return 0;
++
++	/*
++	 * If a hang was detected in the last timer interrupt then we
++	 * do not schedule a timer which is earlier than the expiry
++	 * which we enforced in the hang detection. We want the system
++	 * to make progress.
++	 */
++	if (cpu_base->hang_detected)
++		return 0;
++
++	/*
++	 * Clockevents returns -ETIME, when the event was in the past.
++	 */
++	res = tick_program_event(expires, 0);
++	if (!IS_ERR_VALUE(res))
++		cpu_base->expires_next = expires;
++	return res;
++}
++
++
++/*
++ * Retrigger next event is called after clock was set
++ *
++ * Called with interrupts disabled via on_each_cpu()
++ */
++static void retrigger_next_event(void *arg)
++{
++	struct hrtimer_cpu_base *base;
++	struct timespec realtime_offset;
++	unsigned long seq;
++
++	if (!hrtimer_hres_active())
++		return;
++
++	do {
++		seq = read_seqbegin(&xtime_lock);
++		set_normalized_timespec(&realtime_offset,
++					-wall_to_monotonic.tv_sec,
++					-wall_to_monotonic.tv_nsec);
++	} while (read_seqretry(&xtime_lock, seq));
++
++	base = &__get_cpu_var(hrtimer_bases);
++
++	/* Adjust CLOCK_REALTIME offset */
++	raw_spin_lock(&base->lock);
++	base->clock_base[CLOCK_REALTIME].offset =
++		timespec_to_ktime(realtime_offset);
++
++	hrtimer_force_reprogram(base, 0);
++	raw_spin_unlock(&base->lock);
++}
++
++/*
++ * Clock realtime was set
++ *
++ * Change the offset of the realtime clock vs. the monotonic
++ * clock.
++ *
++ * We might have to reprogram the high resolution timer interrupt. On
++ * SMP we call the architecture specific code to retrigger _all_ high
++ * resolution timer interrupts. On UP we just disable interrupts and
++ * call the high resolution interrupt code.
++ */
++void clock_was_set(void)
++{
++	/* Retrigger the CPU local events everywhere */
++	on_each_cpu(retrigger_next_event, NULL, 1);
++}
++
++/*
++ * During resume we might have to reprogram the high resolution timer
++ * interrupt (on the local CPU):
++ */
++void hres_timers_resume(void)
++{
++	WARN_ONCE(!irqs_disabled(),
++		  KERN_INFO "hres_timers_resume() called with IRQs enabled!");
++
++	retrigger_next_event(NULL);
++}
++
++/*
++ * Initialize the high resolution related parts of cpu_base
++ */
++static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base)
++{
++	base->expires_next.tv64 = KTIME_MAX;
++	base->hres_active = 0;
++}
++
++/*
++ * Initialize the high resolution related parts of a hrtimer
++ */
++static inline void hrtimer_init_timer_hres(struct hrtimer *timer)
++{
++}
++
++
++/*
++ * When High resolution timers are active, try to reprogram. Note, that in case
++ * the state has HRTIMER_STATE_CALLBACK set, no reprogramming and no expiry
++ * check happens. The timer gets enqueued into the rbtree. The reprogramming
++ * and expiry check is done in the hrtimer_interrupt or in the softirq.
++ */
++static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
++					    struct hrtimer_clock_base *base,
++					    int wakeup)
++{
++	if (base->cpu_base->hres_active && hrtimer_reprogram(timer, base)) {
++		if (wakeup) {
++			raw_spin_unlock(&base->cpu_base->lock);
++			raise_softirq_irqoff(HRTIMER_SOFTIRQ);
++			raw_spin_lock(&base->cpu_base->lock);
++		} else
++			__raise_softirq_irqoff(HRTIMER_SOFTIRQ);
++
++		return 1;
++	}
++
++	return 0;
++}
++
++/*
++ * Switch to high resolution mode
++ */
++static int hrtimer_switch_to_hres(void)
++{
++	int cpu = smp_processor_id();
++	struct hrtimer_cpu_base *base = &per_cpu(hrtimer_bases, cpu);
++	unsigned long flags;
++
++	if (base->hres_active)
++		return 1;
++
++	local_irq_save(flags);
++
++	if (tick_init_highres()) {
++		local_irq_restore(flags);
++		printk(KERN_WARNING "Could not switch to high resolution "
++				    "mode on CPU %d\n", cpu);
++		return 0;
++	}
++	base->hres_active = 1;
++	base->clock_base[CLOCK_REALTIME].resolution = KTIME_HIGH_RES;
++	base->clock_base[CLOCK_MONOTONIC].resolution = KTIME_HIGH_RES;
++
++	tick_setup_sched_timer();
++
++	/* "Retrigger" the interrupt to get things going */
++	retrigger_next_event(NULL);
++	local_irq_restore(flags);
++	return 1;
++}
++
++#else
++
++static inline int hrtimer_hres_active(void) { return 0; }
++static inline int hrtimer_is_hres_enabled(void) { return 0; }
++static inline int hrtimer_switch_to_hres(void) { return 0; }
++static inline void
++hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { }
++static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
++					    struct hrtimer_clock_base *base,
++					    int wakeup)
++{
++	return 0;
++}
++static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { }
++static inline void hrtimer_init_timer_hres(struct hrtimer *timer) { }
++
++#endif /* CONFIG_HIGH_RES_TIMERS */
++
++static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer)
++{
++#ifdef CONFIG_TIMER_STATS
++	if (timer->start_site)
++		return;
++	timer->start_site = __builtin_return_address(0);
++	memcpy(timer->start_comm, current->comm, TASK_COMM_LEN);
++	timer->start_pid = current->pid;
++#endif
++}
++
++static inline void timer_stats_hrtimer_clear_start_info(struct hrtimer *timer)
++{
++#ifdef CONFIG_TIMER_STATS
++	timer->start_site = NULL;
++#endif
++}
++
++static inline void timer_stats_account_hrtimer(struct hrtimer *timer)
++{
++#ifdef CONFIG_TIMER_STATS
++	if (likely(!timer_stats_active))
++		return;
++	timer_stats_update_stats(timer, timer->start_pid, timer->start_site,
++				 timer->function, timer->start_comm, 0);
++#endif
++}
++
++/*
++ * Counterpart to lock_hrtimer_base above:
++ */
++static inline
++void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
++{
++	raw_spin_unlock_irqrestore(&timer->base->cpu_base->lock, *flags);
++}
++
++/**
++ * hrtimer_forward - forward the timer expiry
++ * @timer:	hrtimer to forward
++ * @now:	forward past this time
++ * @interval:	the interval to forward
++ *
++ * Forward the timer expiry so it will expire in the future.
++ * Returns the number of overruns.
++ */
++u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval)
++{
++	u64 orun = 1;
++	ktime_t delta;
++
++	delta = ktime_sub(now, hrtimer_get_expires(timer));
++
++	if (delta.tv64 < 0)
++		return 0;
++
++	if (interval.tv64 < timer->base->resolution.tv64)
++		interval.tv64 = timer->base->resolution.tv64;
++
++	if (unlikely(delta.tv64 >= interval.tv64)) {
++		s64 incr = ktime_to_ns(interval);
++
++		orun = ktime_divns(delta, incr);
++		hrtimer_add_expires_ns(timer, incr * orun);
++		if (hrtimer_get_expires_tv64(timer) > now.tv64)
++			return orun;
++		/*
++		 * This (and the ktime_add() below) is the
++		 * correction for exact:
++		 */
++		orun++;
++	}
++	hrtimer_add_expires(timer, interval);
++
++	return orun;
++}
++EXPORT_SYMBOL_GPL(hrtimer_forward);
++
++/*
++ * enqueue_hrtimer - internal function to (re)start a timer
++ *
++ * The timer is inserted in expiry order. Insertion into the
++ * red black tree is O(log(n)). Must hold the base lock.
++ *
++ * Returns 1 when the new timer is the leftmost timer in the tree.
++ */
++static int enqueue_hrtimer(struct hrtimer *timer,
++			   struct hrtimer_clock_base *base)
++{
++	struct rb_node **link = &base->active.rb_node;
++	struct rb_node *parent = NULL;
++	struct hrtimer *entry;
++	int leftmost = 1;
++
++	debug_activate(timer);
++
++	/*
++	 * Find the right place in the rbtree:
++	 */
++	while (*link) {
++		parent = *link;
++		entry = rb_entry(parent, struct hrtimer, node);
++		/*
++		 * We dont care about collisions. Nodes with
++		 * the same expiry time stay together.
++		 */
++		if (hrtimer_get_expires_tv64(timer) <
++				hrtimer_get_expires_tv64(entry)) {
++			link = &(*link)->rb_left;
++		} else {
++			link = &(*link)->rb_right;
++			leftmost = 0;
++		}
++	}
++
++	/*
++	 * Insert the timer to the rbtree and check whether it
++	 * replaces the first pending timer
++	 */
++	if (leftmost)
++		base->first = &timer->node;
++
++	rb_link_node(&timer->node, parent, link);
++	rb_insert_color(&timer->node, &base->active);
++	/*
++	 * HRTIMER_STATE_ENQUEUED is or'ed to the current state to preserve the
++	 * state of a possibly running callback.
++	 */
++	timer->state |= HRTIMER_STATE_ENQUEUED;
++
++	return leftmost;
++}
++
++/*
++ * __remove_hrtimer - internal function to remove a timer
++ *
++ * Caller must hold the base lock.
++ *
++ * High resolution timer mode reprograms the clock event device when the
++ * timer is the one which expires next. The caller can disable this by setting
++ * reprogram to zero. This is useful, when the context does a reprogramming
++ * anyway (e.g. timer interrupt)
++ */
++static void __remove_hrtimer(struct hrtimer *timer,
++			     struct hrtimer_clock_base *base,
++			     unsigned long newstate, int reprogram)
++{
++	if (!(timer->state & HRTIMER_STATE_ENQUEUED))
++		goto out;
++
++	/*
++	 * Remove the timer from the rbtree and replace the first
++	 * entry pointer if necessary.
++	 */
++	if (base->first == &timer->node) {
++		base->first = rb_next(&timer->node);
++#ifdef CONFIG_HIGH_RES_TIMERS
++		/* Reprogram the clock event device. if enabled */
++		if (reprogram && hrtimer_hres_active()) {
++			ktime_t expires;
++
++			expires = ktime_sub(hrtimer_get_expires(timer),
++					    base->offset);
++			if (base->cpu_base->expires_next.tv64 == expires.tv64)
++				hrtimer_force_reprogram(base->cpu_base, 1);
++		}
++#endif
++	}
++	rb_erase(&timer->node, &base->active);
++out:
++	timer->state = newstate;
++}
++
++/*
++ * remove hrtimer, called with base lock held
++ */
++static inline int
++remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base)
++{
++	if (hrtimer_is_queued(timer)) {
++		unsigned long state;
++		int reprogram;
++
++		/*
++		 * Remove the timer and force reprogramming when high
++		 * resolution mode is active and the timer is on the current
++		 * CPU. If we remove a timer on another CPU, reprogramming is
++		 * skipped. The interrupt event on this CPU is fired and
++		 * reprogramming happens in the interrupt handler. This is a
++		 * rare case and less expensive than a smp call.
++		 */
++		debug_deactivate(timer);
++		timer_stats_hrtimer_clear_start_info(timer);
++		reprogram = base->cpu_base == &__get_cpu_var(hrtimer_bases);
++		/*
++		 * We must preserve the CALLBACK state flag here,
++		 * otherwise we could move the timer base in
++		 * switch_hrtimer_base.
++		 */
++		state = timer->state & HRTIMER_STATE_CALLBACK;
++		__remove_hrtimer(timer, base, state, reprogram);
++		return 1;
++	}
++	return 0;
++}
++
++int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
++		unsigned long delta_ns, const enum hrtimer_mode mode,
++		int wakeup)
++{
++	struct hrtimer_clock_base *base, *new_base;
++	unsigned long flags;
++	int ret, leftmost;
++
++	base = lock_hrtimer_base(timer, &flags);
++
++	/* Remove an active timer from the queue: */
++	ret = remove_hrtimer(timer, base);
++
++	/* Switch the timer base, if necessary: */
++	new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
++
++	if (mode & HRTIMER_MODE_REL) {
++		tim = ktime_add_safe(tim, new_base->get_time());
++		/*
++		 * CONFIG_TIME_LOW_RES is a temporary way for architectures
++		 * to signal that they simply return xtime in
++		 * do_gettimeoffset(). In this case we want to round up by
++		 * resolution when starting a relative timer, to avoid short
++		 * timeouts. This will go away with the GTOD framework.
++		 */
++#ifdef CONFIG_TIME_LOW_RES
++		tim = ktime_add_safe(tim, base->resolution);
++#endif
++	}
++
++	hrtimer_set_expires_range_ns(timer, tim, delta_ns);
++
++	timer_stats_hrtimer_set_start_info(timer);
++
++	leftmost = enqueue_hrtimer(timer, new_base);
++
++	/*
++	 * Only allow reprogramming if the new base is on this CPU.
++	 * (it might still be on another CPU if the timer was pending)
++	 *
++	 * XXX send_remote_softirq() ?
++	 */
++	if (leftmost && new_base->cpu_base == &__get_cpu_var(hrtimer_bases))
++		hrtimer_enqueue_reprogram(timer, new_base, wakeup);
++
++	unlock_hrtimer_base(timer, &flags);
++
++	return ret;
++}
++
++/**
++ * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU
++ * @timer:	the timer to be added
++ * @tim:	expiry time
++ * @delta_ns:	"slack" range for the timer
++ * @mode:	expiry mode: absolute (HRTIMER_ABS) or relative (HRTIMER_REL)
++ *
++ * Returns:
++ *  0 on success
++ *  1 when the timer was active
++ */
++int hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
++		unsigned long delta_ns, const enum hrtimer_mode mode)
++{
++	return __hrtimer_start_range_ns(timer, tim, delta_ns, mode, 1);
++}
++EXPORT_SYMBOL_GPL(hrtimer_start_range_ns);
++
++/**
++ * hrtimer_start - (re)start an hrtimer on the current CPU
++ * @timer:	the timer to be added
++ * @tim:	expiry time
++ * @mode:	expiry mode: absolute (HRTIMER_ABS) or relative (HRTIMER_REL)
++ *
++ * Returns:
++ *  0 on success
++ *  1 when the timer was active
++ */
++int
++hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
++{
++	return __hrtimer_start_range_ns(timer, tim, 0, mode, 1);
++}
++EXPORT_SYMBOL_GPL(hrtimer_start);
++
++
++/**
++ * hrtimer_try_to_cancel - try to deactivate a timer
++ * @timer:	hrtimer to stop
++ *
++ * Returns:
++ *  0 when the timer was not active
++ *  1 when the timer was active
++ * -1 when the timer is currently excuting the callback function and
++ *    cannot be stopped
++ */
++int hrtimer_try_to_cancel(struct hrtimer *timer)
++{
++	struct hrtimer_clock_base *base;
++	unsigned long flags;
++	int ret = -1;
++
++	base = lock_hrtimer_base(timer, &flags);
++
++	if (!hrtimer_callback_running(timer))
++		ret = remove_hrtimer(timer, base);
++
++	unlock_hrtimer_base(timer, &flags);
++
++	return ret;
++
++}
++EXPORT_SYMBOL_GPL(hrtimer_try_to_cancel);
++
++/**
++ * hrtimer_cancel - cancel a timer and wait for the handler to finish.
++ * @timer:	the timer to be cancelled
++ *
++ * Returns:
++ *  0 when the timer was not active
++ *  1 when the timer was active
++ */
++int hrtimer_cancel(struct hrtimer *timer)
++{
++	for (;;) {
++		int ret = hrtimer_try_to_cancel(timer);
++
++		if (ret >= 0)
++			return ret;
++		cpu_relax();
++	}
++}
++EXPORT_SYMBOL_GPL(hrtimer_cancel);
++
++/**
++ * hrtimer_get_remaining - get remaining time for the timer
++ * @timer:	the timer to read
++ */
++ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
++{
++	struct hrtimer_clock_base *base;
++	unsigned long flags;
++	ktime_t rem;
++
++	base = lock_hrtimer_base(timer, &flags);
++	rem = hrtimer_expires_remaining(timer);
++	unlock_hrtimer_base(timer, &flags);
++
++	return rem;
++}
++EXPORT_SYMBOL_GPL(hrtimer_get_remaining);
++
++#ifdef CONFIG_NO_HZ
++/**
++ * hrtimer_get_next_event - get the time until next expiry event
++ *
++ * Returns the delta to the next expiry event or KTIME_MAX if no timer
++ * is pending.
++ */
++ktime_t hrtimer_get_next_event(void)
++{
++	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
++	struct hrtimer_clock_base *base = cpu_base->clock_base;
++	ktime_t delta, mindelta = { .tv64 = KTIME_MAX };
++	unsigned long flags;
++	int i;
++
++	raw_spin_lock_irqsave(&cpu_base->lock, flags);
++
++	if (!hrtimer_hres_active()) {
++		for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) {
++			struct hrtimer *timer;
++
++			if (!base->first)
++				continue;
++
++			timer = rb_entry(base->first, struct hrtimer, node);
++			delta.tv64 = hrtimer_get_expires_tv64(timer);
++			delta = ktime_sub(delta, base->get_time());
++			if (delta.tv64 < mindelta.tv64)
++				mindelta.tv64 = delta.tv64;
++		}
++	}
++
++	raw_spin_unlock_irqrestore(&cpu_base->lock, flags);
++
++	if (mindelta.tv64 < 0)
++		mindelta.tv64 = 0;
++	return mindelta;
++}
++#endif
++
++static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
++			   enum hrtimer_mode mode)
++{
++	struct hrtimer_cpu_base *cpu_base;
++
++	memset(timer, 0, sizeof(struct hrtimer));
++
++	cpu_base = &__raw_get_cpu_var(hrtimer_bases);
++
++	if (clock_id == CLOCK_REALTIME && mode != HRTIMER_MODE_ABS)
++		clock_id = CLOCK_MONOTONIC;
++
++	timer->base = &cpu_base->clock_base[clock_id];
++	hrtimer_init_timer_hres(timer);
++
++#ifdef CONFIG_TIMER_STATS
++	timer->start_site = NULL;
++	timer->start_pid = -1;
++	memset(timer->start_comm, 0, TASK_COMM_LEN);
++#endif
++}
++
++/**
++ * hrtimer_init - initialize a timer to the given clock
++ * @timer:	the timer to be initialized
++ * @clock_id:	the clock to be used
++ * @mode:	timer mode abs/rel
++ */
++void hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
++		  enum hrtimer_mode mode)
++{
++	debug_init(timer, clock_id, mode);
++	__hrtimer_init(timer, clock_id, mode);
++}
++EXPORT_SYMBOL_GPL(hrtimer_init);
++
++/**
++ * hrtimer_get_res - get the timer resolution for a clock
++ * @which_clock: which clock to query
++ * @tp:		 pointer to timespec variable to store the resolution
++ *
++ * Store the resolution of the clock selected by @which_clock in the
++ * variable pointed to by @tp.
++ */
++int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp)
++{
++	struct hrtimer_cpu_base *cpu_base;
++
++	cpu_base = &__raw_get_cpu_var(hrtimer_bases);
++	*tp = ktime_to_timespec(cpu_base->clock_base[which_clock].resolution);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(hrtimer_get_res);
++
++static void __run_hrtimer(struct hrtimer *timer, ktime_t *now)
++{
++	struct hrtimer_clock_base *base = timer->base;
++	struct hrtimer_cpu_base *cpu_base = base->cpu_base;
++	enum hrtimer_restart (*fn)(struct hrtimer *);
++	int restart;
++
++	WARN_ON(!irqs_disabled());
++
++	debug_deactivate(timer);
++	__remove_hrtimer(timer, base, HRTIMER_STATE_CALLBACK, 0);
++	timer_stats_account_hrtimer(timer);
++	fn = timer->function;
++
++	/*
++	 * Because we run timers from hardirq context, there is no chance
++	 * they get migrated to another cpu, therefore its safe to unlock
++	 * the timer base.
++	 */
++	raw_spin_unlock(&cpu_base->lock);
++	trace_hrtimer_expire_entry(timer, now);
++	restart = fn(timer);
++	trace_hrtimer_expire_exit(timer);
++	raw_spin_lock(&cpu_base->lock);
++
++	/*
++	 * Note: We clear the CALLBACK bit after enqueue_hrtimer and
++	 * we do not reprogramm the event hardware. Happens either in
++	 * hrtimer_start_range_ns() or in hrtimer_interrupt()
++	 */
++	if (restart != HRTIMER_NORESTART) {
++		BUG_ON(timer->state != HRTIMER_STATE_CALLBACK);
++		enqueue_hrtimer(timer, base);
++	}
++
++	WARN_ON_ONCE(!(timer->state & HRTIMER_STATE_CALLBACK));
++
++	timer->state &= ~HRTIMER_STATE_CALLBACK;
++}
++
++#ifdef CONFIG_HIGH_RES_TIMERS
++
++/*
++ * High resolution timer interrupt
++ * Called with interrupts disabled
++ */
++void hrtimer_interrupt(struct clock_event_device *dev)
++{
++	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
++	struct hrtimer_clock_base *base;
++	ktime_t expires_next, now, entry_time, delta;
++	int i, retries = 0;
++
++	BUG_ON(!cpu_base->hres_active);
++	cpu_base->nr_events++;
++	dev->next_event.tv64 = KTIME_MAX;
++
++	entry_time = now = ktime_get();
++retry:
++	expires_next.tv64 = KTIME_MAX;
++
++	raw_spin_lock(&cpu_base->lock);
++	/*
++	 * We set expires_next to KTIME_MAX here with cpu_base->lock
++	 * held to prevent that a timer is enqueued in our queue via
++	 * the migration code. This does not affect enqueueing of
++	 * timers which run their callback and need to be requeued on
++	 * this CPU.
++	 */
++	cpu_base->expires_next.tv64 = KTIME_MAX;
++
++	base = cpu_base->clock_base;
++
++	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
++		ktime_t basenow;
++		struct rb_node *node;
++
++		basenow = ktime_add(now, base->offset);
++
++		while ((node = base->first)) {
++			struct hrtimer *timer;
++
++			timer = rb_entry(node, struct hrtimer, node);
++
++			/*
++			 * The immediate goal for using the softexpires is
++			 * minimizing wakeups, not running timers at the
++			 * earliest interrupt after their soft expiration.
++			 * This allows us to avoid using a Priority Search
++			 * Tree, which can answer a stabbing querry for
++			 * overlapping intervals and instead use the simple
++			 * BST we already have.
++			 * We don't add extra wakeups by delaying timers that
++			 * are right-of a not yet expired timer, because that
++			 * timer will have to trigger a wakeup anyway.
++			 */
++
++			if (basenow.tv64 < hrtimer_get_softexpires_tv64(timer)) {
++				ktime_t expires;
++
++				expires = ktime_sub(hrtimer_get_expires(timer),
++						    base->offset);
++				if (expires.tv64 < expires_next.tv64)
++					expires_next = expires;
++				break;
++			}
++
++			__run_hrtimer(timer, &basenow);
++		}
++		base++;
++	}
++
++	/*
++	 * Store the new expiry value so the migration code can verify
++	 * against it.
++	 */
++	cpu_base->expires_next = expires_next;
++	raw_spin_unlock(&cpu_base->lock);
++
++	/* Reprogramming necessary ? */
++	if (expires_next.tv64 == KTIME_MAX ||
++	    !tick_program_event(expires_next, 0)) {
++		cpu_base->hang_detected = 0;
++		return;
++	}
++
++	/*
++	 * The next timer was already expired due to:
++	 * - tracing
++	 * - long lasting callbacks
++	 * - being scheduled away when running in a VM
++	 *
++	 * We need to prevent that we loop forever in the hrtimer
++	 * interrupt routine. We give it 3 attempts to avoid
++	 * overreacting on some spurious event.
++	 */
++	now = ktime_get();
++	cpu_base->nr_retries++;
++	if (++retries < 3)
++		goto retry;
++	/*
++	 * Give the system a chance to do something else than looping
++	 * here. We stored the entry time, so we know exactly how long
++	 * we spent here. We schedule the next event this amount of
++	 * time away.
++	 */
++	cpu_base->nr_hangs++;
++	cpu_base->hang_detected = 1;
++	delta = ktime_sub(now, entry_time);
++	if (delta.tv64 > cpu_base->max_hang_time.tv64)
++		cpu_base->max_hang_time = delta;
++	/*
++	 * Limit it to a sensible value as we enforce a longer
++	 * delay. Give the CPU at least 100ms to catch up.
++	 */
++	if (delta.tv64 > 100 * NSEC_PER_MSEC)
++		expires_next = ktime_add_ns(now, 100 * NSEC_PER_MSEC);
++	else
++		expires_next = ktime_add(now, delta);
++	tick_program_event(expires_next, 1);
++	printk_once(KERN_WARNING "hrtimer: interrupt took %llu ns\n",
++		    ktime_to_ns(delta));
++}
++
++/*
++ * local version of hrtimer_peek_ahead_timers() called with interrupts
++ * disabled.
++ */
++static void __hrtimer_peek_ahead_timers(void)
++{
++	struct tick_device *td;
++
++	if (!hrtimer_hres_active())
++		return;
++
++	td = &__get_cpu_var(tick_cpu_device);
++	if (td && td->evtdev)
++		hrtimer_interrupt(td->evtdev);
++}
++
++/**
++ * hrtimer_peek_ahead_timers -- run soft-expired timers now
++ *
++ * hrtimer_peek_ahead_timers will peek at the timer queue of
++ * the current cpu and check if there are any timers for which
++ * the soft expires time has passed. If any such timers exist,
++ * they are run immediately and then removed from the timer queue.
++ *
++ */
++void hrtimer_peek_ahead_timers(void)
++{
++	unsigned long flags;
++
++	local_irq_save(flags);
++	__hrtimer_peek_ahead_timers();
++	local_irq_restore(flags);
++}
++
++static void run_hrtimer_softirq(struct softirq_action *h)
++{
++	hrtimer_peek_ahead_timers();
++}
++
++#else /* CONFIG_HIGH_RES_TIMERS */
++
++static inline void __hrtimer_peek_ahead_timers(void) { }
++
++#endif	/* !CONFIG_HIGH_RES_TIMERS */
++
++/*
++ * Called from timer softirq every jiffy, expire hrtimers:
++ *
++ * For HRT its the fall back code to run the softirq in the timer
++ * softirq context in case the hrtimer initialization failed or has
++ * not been done yet.
++ */
++void hrtimer_run_pending(void)
++{
++	if (hrtimer_hres_active())
++		return;
++
++	/*
++	 * This _is_ ugly: We have to check in the softirq context,
++	 * whether we can switch to highres and / or nohz mode. The
++	 * clocksource switch happens in the timer interrupt with
++	 * xtime_lock held. Notification from there only sets the
++	 * check bit in the tick_oneshot code, otherwise we might
++	 * deadlock vs. xtime_lock.
++	 */
++	if (tick_check_oneshot_change(!hrtimer_is_hres_enabled()))
++		hrtimer_switch_to_hres();
++}
++
++/*
++ * Called from hardirq context every jiffy
++ */
++void hrtimer_run_queues(void)
++{
++	struct rb_node *node;
++	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
++	struct hrtimer_clock_base *base;
++	int index, gettime = 1;
++
++	if (hrtimer_hres_active())
++		return;
++
++	for (index = 0; index < HRTIMER_MAX_CLOCK_BASES; index++) {
++		base = &cpu_base->clock_base[index];
++
++		if (!base->first)
++			continue;
++
++		if (gettime) {
++			hrtimer_get_softirq_time(cpu_base);
++			gettime = 0;
++		}
++
++		raw_spin_lock(&cpu_base->lock);
++
++		while ((node = base->first)) {
++			struct hrtimer *timer;
++
++			timer = rb_entry(node, struct hrtimer, node);
++			if (base->softirq_time.tv64 <=
++					hrtimer_get_expires_tv64(timer))
++				break;
++
++			__run_hrtimer(timer, &base->softirq_time);
++		}
++		raw_spin_unlock(&cpu_base->lock);
++	}
++}
++
++/*
++ * Sleep related functions:
++ */
++static enum hrtimer_restart hrtimer_wakeup(struct hrtimer *timer)
++{
++	struct hrtimer_sleeper *t =
++		container_of(timer, struct hrtimer_sleeper, timer);
++	struct task_struct *task = t->task;
++
++	t->task = NULL;
++	if (task)
++		wake_up_process(task);
++
++	return HRTIMER_NORESTART;
++}
++
++void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task)
++{
++	sl->timer.function = hrtimer_wakeup;
++	sl->task = task;
++}
++EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
++
++static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
++{
++	hrtimer_init_sleeper(t, current);
++
++	do {
++		set_current_state(TASK_INTERRUPTIBLE);
++		hrtimer_start_expires(&t->timer, mode);
++		if (!hrtimer_active(&t->timer))
++			t->task = NULL;
++
++		if (likely(t->task))
++			schedule();
++
++		hrtimer_cancel(&t->timer);
++		mode = HRTIMER_MODE_ABS;
++
++	} while (t->task && !signal_pending(current));
++
++	__set_current_state(TASK_RUNNING);
++
++	return t->task == NULL;
++}
++
++static int update_rmtp(struct hrtimer *timer, struct timespec __user *rmtp)
++{
++	struct timespec rmt;
++	ktime_t rem;
++
++	rem = hrtimer_expires_remaining(timer);
++	if (rem.tv64 <= 0)
++		return 0;
++	rmt = ktime_to_timespec(rem);
++
++	if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
++		return -EFAULT;
++
++	return 1;
++}
++
++long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
++{
++	struct hrtimer_sleeper t;
++	struct timespec __user  *rmtp;
++	int ret = 0;
++
++	hrtimer_init_on_stack(&t.timer, restart->nanosleep.index,
++				HRTIMER_MODE_ABS);
++	hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires);
++
++	if (do_nanosleep(&t, HRTIMER_MODE_ABS))
++		goto out;
++
++	rmtp = restart->nanosleep.rmtp;
++	if (rmtp) {
++		ret = update_rmtp(&t.timer, rmtp);
++		if (ret <= 0)
++			goto out;
++	}
++
++	/* The other values in restart are already filled in */
++	ret = -ERESTART_RESTARTBLOCK;
++out:
++	destroy_hrtimer_on_stack(&t.timer);
++	return ret;
++}
++
++long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
++		       const enum hrtimer_mode mode, const clockid_t clockid)
++{
++	struct restart_block *restart;
++	struct hrtimer_sleeper t;
++	int ret = 0;
++	unsigned long slack;
++
++	slack = current->timer_slack_ns;
++	if (rt_task(current))
++		slack = 0;
++
++	hrtimer_init_on_stack(&t.timer, clockid, mode);
++	hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack);
++	if (do_nanosleep(&t, mode))
++		goto out;
++
++	/* Absolute timers do not update the rmtp value and restart: */
++	if (mode == HRTIMER_MODE_ABS) {
++		ret = -ERESTARTNOHAND;
++		goto out;
++	}
++
++	if (rmtp) {
++		ret = update_rmtp(&t.timer, rmtp);
++		if (ret <= 0)
++			goto out;
++	}
++
++	restart = &current_thread_info()->restart_block;
++	restart->fn = hrtimer_nanosleep_restart;
++	restart->nanosleep.index = t.timer.base->index;
++	restart->nanosleep.rmtp = rmtp;
++	restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer);
++
++	ret = -ERESTART_RESTARTBLOCK;
++out:
++	destroy_hrtimer_on_stack(&t.timer);
++	return ret;
++}
++
++SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
++		struct timespec __user *, rmtp)
++{
++	struct timespec tu;
++
++	if (copy_from_user(&tu, rqtp, sizeof(tu)))
++		return -EFAULT;
++
++	if (!timespec_valid(&tu))
++		return -EINVAL;
++
++	return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
++}
++
++/*
++ * Functions related to boot-time initialization:
++ */
++static void __cpuinit init_hrtimers_cpu(int cpu)
++{
++	struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
++	int i;
++
++	raw_spin_lock_init(&cpu_base->lock);
++
++	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++)
++		cpu_base->clock_base[i].cpu_base = cpu_base;
++
++	hrtimer_init_hres(cpu_base);
++}
++
++#ifdef CONFIG_HOTPLUG_CPU
++
++static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
++				struct hrtimer_clock_base *new_base)
++{
++	struct hrtimer *timer;
++	struct rb_node *node;
++
++	while ((node = rb_first(&old_base->active))) {
++		timer = rb_entry(node, struct hrtimer, node);
++		BUG_ON(hrtimer_callback_running(timer));
++		debug_deactivate(timer);
++
++		/*
++		 * Mark it as STATE_MIGRATE not INACTIVE otherwise the
++		 * timer could be seen as !active and just vanish away
++		 * under us on another CPU
++		 */
++		__remove_hrtimer(timer, old_base, HRTIMER_STATE_MIGRATE, 0);
++		timer->base = new_base;
++		/*
++		 * Enqueue the timers on the new cpu. This does not
++		 * reprogram the event device in case the timer
++		 * expires before the earliest on this CPU, but we run
++		 * hrtimer_interrupt after we migrated everything to
++		 * sort out already expired timers and reprogram the
++		 * event device.
++		 */
++		enqueue_hrtimer(timer, new_base);
++
++		/* Clear the migration state bit */
++		timer->state &= ~HRTIMER_STATE_MIGRATE;
++	}
++}
++
++static void migrate_hrtimers(int scpu)
++{
++	struct hrtimer_cpu_base *old_base, *new_base;
++	int i;
++
++	BUG_ON(cpu_online(scpu));
++	tick_cancel_sched_timer(scpu);
++
++	local_irq_disable();
++	old_base = &per_cpu(hrtimer_bases, scpu);
++	new_base = &__get_cpu_var(hrtimer_bases);
++	/*
++	 * The caller is globally serialized and nobody else
++	 * takes two locks at once, deadlock is not possible.
++	 */
++	raw_spin_lock(&new_base->lock);
++	raw_spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
++
++	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
++		migrate_hrtimer_list(&old_base->clock_base[i],
++				     &new_base->clock_base[i]);
++	}
++
++	raw_spin_unlock(&old_base->lock);
++	raw_spin_unlock(&new_base->lock);
++
++	/* Check, if we got expired work to do */
++	__hrtimer_peek_ahead_timers();
++	local_irq_enable();
++}
++
++#endif /* CONFIG_HOTPLUG_CPU */
++
++static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self,
++					unsigned long action, void *hcpu)
++{
++	int scpu = (long)hcpu;
++
++	switch (action) {
++
++	case CPU_UP_PREPARE:
++	case CPU_UP_PREPARE_FROZEN:
++		init_hrtimers_cpu(scpu);
++		break;
++
++#ifdef CONFIG_HOTPLUG_CPU
++	case CPU_DYING:
++	case CPU_DYING_FROZEN:
++		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu);
++		break;
++	case CPU_DEAD:
++	case CPU_DEAD_FROZEN:
++	{
++		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DEAD, &scpu);
++		migrate_hrtimers(scpu);
++		break;
++	}
++#endif
++
++	default:
++		break;
++	}
++
++	return NOTIFY_OK;
++}
++
++static struct notifier_block __cpuinitdata hrtimers_nb = {
++	.notifier_call = hrtimer_cpu_notify,
++};
++
++void __init hrtimers_init(void)
++{
++	hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE,
++			  (void *)(long)smp_processor_id());
++	register_cpu_notifier(&hrtimers_nb);
++#ifdef CONFIG_HIGH_RES_TIMERS
++	open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq);
++#endif
++}
++
++/**
++ * schedule_hrtimeout_range_clock - sleep until timeout
++ * @expires:	timeout value (ktime_t)
++ * @delta:	slack in expires timeout (ktime_t)
++ * @mode:	timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
++ * @clock:	timer clock, CLOCK_MONOTONIC or CLOCK_REALTIME
++ */
++int __sched
++schedule_hrtimeout_range_clock(ktime_t *expires, unsigned long delta,
++			       const enum hrtimer_mode mode, int clock)
++{
++	struct hrtimer_sleeper t;
++
++	/*
++	 * Optimize when a zero timeout value is given. It does not
++	 * matter whether this is an absolute or a relative time.
++	 */
++	if (expires && !expires->tv64) {
++		__set_current_state(TASK_RUNNING);
++		return 0;
++	}
++
++	/*
++	 * A NULL parameter means "inifinte"
++	 */
++	if (!expires) {
++		schedule();
++		__set_current_state(TASK_RUNNING);
++		return -EINTR;
++	}
++
++	hrtimer_init_on_stack(&t.timer, clock, mode);
++	hrtimer_set_expires_range_ns(&t.timer, *expires, delta);
++
++	hrtimer_init_sleeper(&t, current);
++
++	hrtimer_start_expires(&t.timer, mode);
++	if (!hrtimer_active(&t.timer))
++		t.task = NULL;
++
++	if (likely(t.task))
++		schedule();
++
++	hrtimer_cancel(&t.timer);
++	destroy_hrtimer_on_stack(&t.timer);
++
++	__set_current_state(TASK_RUNNING);
++
++	return !t.task ? 0 : -EINTR;
++}
++
++/**
++ * schedule_hrtimeout_range - sleep until timeout
++ * @expires:	timeout value (ktime_t)
++ * @delta:	slack in expires timeout (ktime_t)
++ * @mode:	timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
++ *
++ * Make the current task sleep until the given expiry time has
++ * elapsed. The routine will return immediately unless
++ * the current task state has been set (see set_current_state()).
++ *
++ * The @delta argument gives the kernel the freedom to schedule the
++ * actual wakeup to a time that is both power and performance friendly.
++ * The kernel give the normal best effort behavior for "@expires+@delta",
++ * but may decide to fire the timer earlier, but no earlier than @expires.
++ *
++ * You can set the task state as follows -
++ *
++ * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to
++ * pass before the routine returns.
++ *
++ * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
++ * delivered to the current task.
++ *
++ * The current task state is guaranteed to be TASK_RUNNING when this
++ * routine returns.
++ *
++ * Returns 0 when the timer has expired otherwise -EINTR
++ */
++int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta,
++				     const enum hrtimer_mode mode)
++{
++	return schedule_hrtimeout_range_clock(expires, delta, mode,
++					      CLOCK_MONOTONIC);
++}
++EXPORT_SYMBOL_GPL(schedule_hrtimeout_range);
++
++/**
++ * schedule_hrtimeout - sleep until timeout
++ * @expires:	timeout value (ktime_t)
++ * @mode:	timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
++ *
++ * Make the current task sleep until the given expiry time has
++ * elapsed. The routine will return immediately unless
++ * the current task state has been set (see set_current_state()).
++ *
++ * You can set the task state as follows -
++ *
++ * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to
++ * pass before the routine returns.
++ *
++ * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
++ * delivered to the current task.
++ *
++ * The current task state is guaranteed to be TASK_RUNNING when this
++ * routine returns.
++ *
++ * Returns 0 when the timer has expired otherwise -EINTR
++ */
++int __sched schedule_hrtimeout(ktime_t *expires,
++			       const enum hrtimer_mode mode)
++{
++	return schedule_hrtimeout_range(expires, 0, mode);
++}
++EXPORT_SYMBOL_GPL(schedule_hrtimeout);
+diff -rupN linux-2.6.35.11/kernel/itimer.c linux-2.6.35.11-ts7500/kernel/itimer.c
+--- linux-2.6.35.11/kernel/itimer.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/kernel/itimer.c	2011-03-14 11:18:24.000000000 -0400
+@@ -220,6 +220,7 @@ again:
+ 		if (expires.tv64 != 0) {
+ 			tsk->signal->it_real_incr =
+ 				timeval_to_ktime(value->it_interval);
++								
+ 			hrtimer_start(timer, expires, HRTIMER_MODE_REL);
+ 		} else
+ 			tsk->signal->it_real_incr.tv64 = 0;
+@@ -255,6 +256,7 @@ unsigned int alarm_setitimer(unsigned in
+ {
+ 	struct itimerval it_new, it_old;
+ 
++		
+ #if BITS_PER_LONG < 64
+ 	if (seconds > INT_MAX)
+ 		seconds = INT_MAX;
+diff -rupN linux-2.6.35.11/kernel/sysctl_binary.c linux-2.6.35.11-ts7500/kernel/sysctl_binary.c
+--- linux-2.6.35.11/kernel/sysctl_binary.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/kernel/sysctl_binary.c	2011-03-14 11:18:24.000000000 -0400
+@@ -828,6 +828,13 @@ static const struct bin_table bin_ipmi_t
+ 	{}
+ };
+ 
++#ifdef CONFIG_ARCH_STR8100
++static struct trans_ctl_table trans_i2c_table[] = {
++	{DEV_I2C_CLOCK, "str8100_clock"},
++	{DEV_I2C_DEBUG, "str8100_debug"}
++};
++#endif
++
+ static const struct bin_table bin_mac_hid_files[] = {
+ 	/* DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES unused */
+ 	/* DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES unused */
+@@ -857,6 +864,9 @@ static const struct bin_table bin_dev_ta
+ 	{ CTL_DIR,	DEV_MAC_HID,	"mac_hid",	bin_mac_hid_files },
+ 	{ CTL_DIR,	DEV_SCSI,	"scsi",		bin_scsi_table },
+ 	{ CTL_DIR,	DEV_IPMI,	"ipmi",		bin_ipmi_table },
++#ifdef CONFIG_ARCH_STR8100
++	{ DEV_I2C, "i2c",	trans_i2c_table },
++#endif	
+ 	{}
+ };
+ 
+diff -rupN linux-2.6.35.11/kernel/time/tick-oneshot.c linux-2.6.35.11-ts7500/kernel/time/tick-oneshot.c
+--- linux-2.6.35.11/kernel/time/tick-oneshot.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/kernel/time/tick-oneshot.c	2011-03-14 11:18:24.000000000 -0400
+@@ -132,6 +132,8 @@ int tick_switch_to_oneshot(void (*handle
+ 	struct tick_device *td = &__get_cpu_var(tick_cpu_device);
+ 	struct clock_event_device *dev = td->evtdev;
+ 
++	printk("tick_switch_to_oneshot()\n");
++	
+ 	if (!dev || !(dev->features & CLOCK_EVT_FEAT_ONESHOT) ||
+ 		    !tick_device_is_functional(dev)) {
+ 
+diff -rupN linux-2.6.35.11/kernel/timer.c linux-2.6.35.11-ts7500/kernel/timer.c
+--- linux-2.6.35.11/kernel/timer.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/kernel/timer.c	2011-03-14 11:18:24.000000000 -0400
+@@ -590,7 +590,7 @@ static void __init_timer(struct timer_li
+ void init_timer_key(struct timer_list *timer,
+ 		    const char *name,
+ 		    struct lock_class_key *key)
+-{
++{     
+ 	debug_init(timer);
+ 	__init_timer(timer, name, key);
+ }
+@@ -795,7 +795,7 @@ unsigned long apply_slack(struct timer_l
+  * active timer returns 1.)
+  */
+ int mod_timer(struct timer_list *timer, unsigned long expires)
+-{
++{      
+ 	/*
+ 	 * This is a common optimization triggered by the
+ 	 * networking code - if the timer is re-modified
+@@ -847,7 +847,10 @@ EXPORT_SYMBOL(mod_timer_pinned);
+  * timer tick.
+  */
+ void add_timer(struct timer_list *timer)
+-{
++{        
++   
++   //printk("add_timer 0x%08lX %lu\n", timer->function, timer->expires - jiffies);
++   
+ 	BUG_ON(timer_pending(timer));
+ 	mod_timer(timer, timer->expires);
+ }
+@@ -864,7 +867,7 @@ void add_timer_on(struct timer_list *tim
+ {
+ 	struct tvec_base *base = per_cpu(tvec_bases, cpu);
+ 	unsigned long flags;
+-
++			
+ 	timer_stats_timer_set_start_info(timer);
+ 	BUG_ON(timer_pending(timer) || !timer->function);
+ 	spin_lock_irqsave(&base->lock, flags);
+@@ -1069,7 +1072,7 @@ static void call_timer_fn(struct timer_l
+ static inline void __run_timers(struct tvec_base *base)
+ {
+ 	struct timer_list *timer;
+-
++			
+ 	spin_lock_irq(&base->lock);
+ 	while (time_after_eq(jiffies, base->timer_jiffies)) {
+ 		struct list_head work_list;
+@@ -1423,7 +1426,7 @@ signed long __sched schedule_timeout(sig
+ {
+ 	struct timer_list timer;
+ 	unsigned long expire;
+-
++	
+ 	switch (timeout)
+ 	{
+ 	case MAX_SCHEDULE_TIMEOUT:
+@@ -1720,7 +1723,8 @@ void __init init_timers(void)
+ {
+ 	int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
+ 				(void *)(long)smp_processor_id());
+-
++		
++	
+ 	init_timer_stats();
+ 
+ 	BUG_ON(err != NOTIFY_OK);
+@@ -1734,8 +1738,10 @@ void __init init_timers(void)
+  */
+ void msleep(unsigned int msecs)
+ {
+-	unsigned long timeout = msecs_to_jiffies(msecs) + 1;
+-
++	unsigned long timeout = msecs_to_jiffies(msecs) + 1;	
++	
++	//printk("msleep %d\n", msecs);
++	
+ 	while (timeout)
+ 		timeout = schedule_timeout_uninterruptible(timeout);
+ }
+@@ -1749,7 +1755,9 @@ EXPORT_SYMBOL(msleep);
+ unsigned long msleep_interruptible(unsigned int msecs)
+ {
+ 	unsigned long timeout = msecs_to_jiffies(msecs) + 1;
+-
++		
++	//printk("msleep_interruptible %d\n", msecs);
++	
+ 	while (timeout && !signal_pending(current))
+ 		timeout = schedule_timeout_interruptible(timeout);
+ 	return jiffies_to_msecs(timeout);
+diff -rupN linux-2.6.35.11/kernel/timer.c.orig linux-2.6.35.11-ts7500/kernel/timer.c.orig
+--- linux-2.6.35.11/kernel/timer.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/kernel/timer.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,1758 @@
++/*
++ *  linux/kernel/timer.c
++ *
++ *  Kernel internal timers, basic process system calls
++ *
++ *  Copyright (C) 1991, 1992  Linus Torvalds
++ *
++ *  1997-01-28  Modified by Finn Arne Gangstad to make timers scale better.
++ *
++ *  1997-09-10  Updated NTP code according to technical memorandum Jan '96
++ *              "A Kernel Model for Precision Timekeeping" by Dave Mills
++ *  1998-12-24  Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
++ *              serialize accesses to xtime/lost_ticks).
++ *                              Copyright (C) 1998  Andrea Arcangeli
++ *  1999-03-10  Improved NTP compatibility by Ulrich Windl
++ *  2002-05-31	Move sys_sysinfo here and make its locking sane, Robert Love
++ *  2000-10-05  Implemented scalable SMP per-CPU timer handling.
++ *                              Copyright (C) 2000, 2001, 2002  Ingo Molnar
++ *              Designed by David S. Miller, Alexey Kuznetsov and Ingo Molnar
++ */
++
++#include <linux/kernel_stat.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/percpu.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/swap.h>
++#include <linux/pid_namespace.h>
++#include <linux/notifier.h>
++#include <linux/thread_info.h>
++#include <linux/time.h>
++#include <linux/jiffies.h>
++#include <linux/posix-timers.h>
++#include <linux/cpu.h>
++#include <linux/syscalls.h>
++#include <linux/delay.h>
++#include <linux/tick.h>
++#include <linux/kallsyms.h>
++#include <linux/perf_event.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++
++#include <asm/uaccess.h>
++#include <asm/unistd.h>
++#include <asm/div64.h>
++#include <asm/timex.h>
++#include <asm/io.h>
++
++#define CREATE_TRACE_POINTS
++#include <trace/events/timer.h>
++
++u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
++
++EXPORT_SYMBOL(jiffies_64);
++
++/*
++ * per-CPU timer vector definitions:
++ */
++#define TVN_BITS (CONFIG_BASE_SMALL ? 4 : 6)
++#define TVR_BITS (CONFIG_BASE_SMALL ? 6 : 8)
++#define TVN_SIZE (1 << TVN_BITS)
++#define TVR_SIZE (1 << TVR_BITS)
++#define TVN_MASK (TVN_SIZE - 1)
++#define TVR_MASK (TVR_SIZE - 1)
++
++struct tvec {
++	struct list_head vec[TVN_SIZE];
++};
++
++struct tvec_root {
++	struct list_head vec[TVR_SIZE];
++};
++
++struct tvec_base {
++	spinlock_t lock;
++	struct timer_list *running_timer;
++	unsigned long timer_jiffies;
++	unsigned long next_timer;
++	struct tvec_root tv1;
++	struct tvec tv2;
++	struct tvec tv3;
++	struct tvec tv4;
++	struct tvec tv5;
++} ____cacheline_aligned;
++
++struct tvec_base boot_tvec_bases;
++EXPORT_SYMBOL(boot_tvec_bases);
++static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases;
++
++/*
++ * Note that all tvec_bases are 2 byte aligned and lower bit of
++ * base in timer_list is guaranteed to be zero. Use the LSB for
++ * the new flag to indicate whether the timer is deferrable
++ */
++#define TBASE_DEFERRABLE_FLAG		(0x1)
++
++/* Functions below help us manage 'deferrable' flag */
++static inline unsigned int tbase_get_deferrable(struct tvec_base *base)
++{
++	return ((unsigned int)(unsigned long)base & TBASE_DEFERRABLE_FLAG);
++}
++
++static inline struct tvec_base *tbase_get_base(struct tvec_base *base)
++{
++	return ((struct tvec_base *)((unsigned long)base & ~TBASE_DEFERRABLE_FLAG));
++}
++
++static inline void timer_set_deferrable(struct timer_list *timer)
++{
++	timer->base = ((struct tvec_base *)((unsigned long)(timer->base) |
++				       TBASE_DEFERRABLE_FLAG));
++}
++
++static inline void
++timer_set_base(struct timer_list *timer, struct tvec_base *new_base)
++{
++	timer->base = (struct tvec_base *)((unsigned long)(new_base) |
++				      tbase_get_deferrable(timer->base));
++}
++
++static unsigned long round_jiffies_common(unsigned long j, int cpu,
++		bool force_up)
++{
++	int rem;
++	unsigned long original = j;
++
++	/*
++	 * We don't want all cpus firing their timers at once hitting the
++	 * same lock or cachelines, so we skew each extra cpu with an extra
++	 * 3 jiffies. This 3 jiffies came originally from the mm/ code which
++	 * already did this.
++	 * The skew is done by adding 3*cpunr, then round, then subtract this
++	 * extra offset again.
++	 */
++	j += cpu * 3;
++
++	rem = j % HZ;
++
++	/*
++	 * If the target jiffie is just after a whole second (which can happen
++	 * due to delays of the timer irq, long irq off times etc etc) then
++	 * we should round down to the whole second, not up. Use 1/4th second
++	 * as cutoff for this rounding as an extreme upper bound for this.
++	 * But never round down if @force_up is set.
++	 */
++	if (rem < HZ/4 && !force_up) /* round down */
++		j = j - rem;
++	else /* round up */
++		j = j - rem + HZ;
++
++	/* now that we have rounded, subtract the extra skew again */
++	j -= cpu * 3;
++
++	if (j <= jiffies) /* rounding ate our timeout entirely; */
++		return original;
++	return j;
++}
++
++/**
++ * __round_jiffies - function to round jiffies to a full second
++ * @j: the time in (absolute) jiffies that should be rounded
++ * @cpu: the processor number on which the timeout will happen
++ *
++ * __round_jiffies() rounds an absolute time in the future (in jiffies)
++ * up or down to (approximately) full seconds. This is useful for timers
++ * for which the exact time they fire does not matter too much, as long as
++ * they fire approximately every X seconds.
++ *
++ * By rounding these timers to whole seconds, all such timers will fire
++ * at the same time, rather than at various times spread out. The goal
++ * of this is to have the CPU wake up less, which saves power.
++ *
++ * The exact rounding is skewed for each processor to avoid all
++ * processors firing at the exact same time, which could lead
++ * to lock contention or spurious cache line bouncing.
++ *
++ * The return value is the rounded version of the @j parameter.
++ */
++unsigned long __round_jiffies(unsigned long j, int cpu)
++{
++	return round_jiffies_common(j, cpu, false);
++}
++EXPORT_SYMBOL_GPL(__round_jiffies);
++
++/**
++ * __round_jiffies_relative - function to round jiffies to a full second
++ * @j: the time in (relative) jiffies that should be rounded
++ * @cpu: the processor number on which the timeout will happen
++ *
++ * __round_jiffies_relative() rounds a time delta  in the future (in jiffies)
++ * up or down to (approximately) full seconds. This is useful for timers
++ * for which the exact time they fire does not matter too much, as long as
++ * they fire approximately every X seconds.
++ *
++ * By rounding these timers to whole seconds, all such timers will fire
++ * at the same time, rather than at various times spread out. The goal
++ * of this is to have the CPU wake up less, which saves power.
++ *
++ * The exact rounding is skewed for each processor to avoid all
++ * processors firing at the exact same time, which could lead
++ * to lock contention or spurious cache line bouncing.
++ *
++ * The return value is the rounded version of the @j parameter.
++ */
++unsigned long __round_jiffies_relative(unsigned long j, int cpu)
++{
++	unsigned long j0 = jiffies;
++
++	/* Use j0 because jiffies might change while we run */
++	return round_jiffies_common(j + j0, cpu, false) - j0;
++}
++EXPORT_SYMBOL_GPL(__round_jiffies_relative);
++
++/**
++ * round_jiffies - function to round jiffies to a full second
++ * @j: the time in (absolute) jiffies that should be rounded
++ *
++ * round_jiffies() rounds an absolute time in the future (in jiffies)
++ * up or down to (approximately) full seconds. This is useful for timers
++ * for which the exact time they fire does not matter too much, as long as
++ * they fire approximately every X seconds.
++ *
++ * By rounding these timers to whole seconds, all such timers will fire
++ * at the same time, rather than at various times spread out. The goal
++ * of this is to have the CPU wake up less, which saves power.
++ *
++ * The return value is the rounded version of the @j parameter.
++ */
++unsigned long round_jiffies(unsigned long j)
++{
++	return round_jiffies_common(j, raw_smp_processor_id(), false);
++}
++EXPORT_SYMBOL_GPL(round_jiffies);
++
++/**
++ * round_jiffies_relative - function to round jiffies to a full second
++ * @j: the time in (relative) jiffies that should be rounded
++ *
++ * round_jiffies_relative() rounds a time delta  in the future (in jiffies)
++ * up or down to (approximately) full seconds. This is useful for timers
++ * for which the exact time they fire does not matter too much, as long as
++ * they fire approximately every X seconds.
++ *
++ * By rounding these timers to whole seconds, all such timers will fire
++ * at the same time, rather than at various times spread out. The goal
++ * of this is to have the CPU wake up less, which saves power.
++ *
++ * The return value is the rounded version of the @j parameter.
++ */
++unsigned long round_jiffies_relative(unsigned long j)
++{
++	return __round_jiffies_relative(j, raw_smp_processor_id());
++}
++EXPORT_SYMBOL_GPL(round_jiffies_relative);
++
++/**
++ * __round_jiffies_up - function to round jiffies up to a full second
++ * @j: the time in (absolute) jiffies that should be rounded
++ * @cpu: the processor number on which the timeout will happen
++ *
++ * This is the same as __round_jiffies() except that it will never
++ * round down.  This is useful for timeouts for which the exact time
++ * of firing does not matter too much, as long as they don't fire too
++ * early.
++ */
++unsigned long __round_jiffies_up(unsigned long j, int cpu)
++{
++	return round_jiffies_common(j, cpu, true);
++}
++EXPORT_SYMBOL_GPL(__round_jiffies_up);
++
++/**
++ * __round_jiffies_up_relative - function to round jiffies up to a full second
++ * @j: the time in (relative) jiffies that should be rounded
++ * @cpu: the processor number on which the timeout will happen
++ *
++ * This is the same as __round_jiffies_relative() except that it will never
++ * round down.  This is useful for timeouts for which the exact time
++ * of firing does not matter too much, as long as they don't fire too
++ * early.
++ */
++unsigned long __round_jiffies_up_relative(unsigned long j, int cpu)
++{
++	unsigned long j0 = jiffies;
++
++	/* Use j0 because jiffies might change while we run */
++	return round_jiffies_common(j + j0, cpu, true) - j0;
++}
++EXPORT_SYMBOL_GPL(__round_jiffies_up_relative);
++
++/**
++ * round_jiffies_up - function to round jiffies up to a full second
++ * @j: the time in (absolute) jiffies that should be rounded
++ *
++ * This is the same as round_jiffies() except that it will never
++ * round down.  This is useful for timeouts for which the exact time
++ * of firing does not matter too much, as long as they don't fire too
++ * early.
++ */
++unsigned long round_jiffies_up(unsigned long j)
++{
++	return round_jiffies_common(j, raw_smp_processor_id(), true);
++}
++EXPORT_SYMBOL_GPL(round_jiffies_up);
++
++/**
++ * round_jiffies_up_relative - function to round jiffies up to a full second
++ * @j: the time in (relative) jiffies that should be rounded
++ *
++ * This is the same as round_jiffies_relative() except that it will never
++ * round down.  This is useful for timeouts for which the exact time
++ * of firing does not matter too much, as long as they don't fire too
++ * early.
++ */
++unsigned long round_jiffies_up_relative(unsigned long j)
++{
++	return __round_jiffies_up_relative(j, raw_smp_processor_id());
++}
++EXPORT_SYMBOL_GPL(round_jiffies_up_relative);
++
++/**
++ * set_timer_slack - set the allowed slack for a timer
++ * @slack_hz: the amount of time (in jiffies) allowed for rounding
++ *
++ * Set the amount of time, in jiffies, that a certain timer has
++ * in terms of slack. By setting this value, the timer subsystem
++ * will schedule the actual timer somewhere between
++ * the time mod_timer() asks for, and that time plus the slack.
++ *
++ * By setting the slack to -1, a percentage of the delay is used
++ * instead.
++ */
++void set_timer_slack(struct timer_list *timer, int slack_hz)
++{
++	timer->slack = slack_hz;
++}
++EXPORT_SYMBOL_GPL(set_timer_slack);
++
++
++static inline void set_running_timer(struct tvec_base *base,
++					struct timer_list *timer)
++{
++#ifdef CONFIG_SMP
++	base->running_timer = timer;
++#endif
++}
++
++static void internal_add_timer(struct tvec_base *base, struct timer_list *timer)
++{
++	unsigned long expires = timer->expires;
++	unsigned long idx = expires - base->timer_jiffies;
++	struct list_head *vec;
++
++	if (idx < TVR_SIZE) {
++		int i = expires & TVR_MASK;
++		vec = base->tv1.vec + i;
++	} else if (idx < 1 << (TVR_BITS + TVN_BITS)) {
++		int i = (expires >> TVR_BITS) & TVN_MASK;
++		vec = base->tv2.vec + i;
++	} else if (idx < 1 << (TVR_BITS + 2 * TVN_BITS)) {
++		int i = (expires >> (TVR_BITS + TVN_BITS)) & TVN_MASK;
++		vec = base->tv3.vec + i;
++	} else if (idx < 1 << (TVR_BITS + 3 * TVN_BITS)) {
++		int i = (expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK;
++		vec = base->tv4.vec + i;
++	} else if ((signed long) idx < 0) {
++		/*
++		 * Can happen if you add a timer with expires == jiffies,
++		 * or you set a timer to go off in the past
++		 */
++		vec = base->tv1.vec + (base->timer_jiffies & TVR_MASK);
++	} else {
++		int i;
++		/* If the timeout is larger than 0xffffffff on 64-bit
++		 * architectures then we use the maximum timeout:
++		 */
++		if (idx > 0xffffffffUL) {
++			idx = 0xffffffffUL;
++			expires = idx + base->timer_jiffies;
++		}
++		i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
++		vec = base->tv5.vec + i;
++	}
++	/*
++	 * Timers are FIFO:
++	 */
++	list_add_tail(&timer->entry, vec);
++}
++
++#ifdef CONFIG_TIMER_STATS
++void __timer_stats_timer_set_start_info(struct timer_list *timer, void *addr)
++{
++	if (timer->start_site)
++		return;
++
++	timer->start_site = addr;
++	memcpy(timer->start_comm, current->comm, TASK_COMM_LEN);
++	timer->start_pid = current->pid;
++}
++
++static void timer_stats_account_timer(struct timer_list *timer)
++{
++	unsigned int flag = 0;
++
++	if (likely(!timer->start_site))
++		return;
++	if (unlikely(tbase_get_deferrable(timer->base)))
++		flag |= TIMER_STATS_FLAG_DEFERRABLE;
++
++	timer_stats_update_stats(timer, timer->start_pid, timer->start_site,
++				 timer->function, timer->start_comm, flag);
++}
++
++#else
++static void timer_stats_account_timer(struct timer_list *timer) {}
++#endif
++
++#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
++
++static struct debug_obj_descr timer_debug_descr;
++
++/*
++ * fixup_init is called when:
++ * - an active object is initialized
++ */
++static int timer_fixup_init(void *addr, enum debug_obj_state state)
++{
++	struct timer_list *timer = addr;
++
++	switch (state) {
++	case ODEBUG_STATE_ACTIVE:
++		del_timer_sync(timer);
++		debug_object_init(timer, &timer_debug_descr);
++		return 1;
++	default:
++		return 0;
++	}
++}
++
++/*
++ * fixup_activate is called when:
++ * - an active object is activated
++ * - an unknown object is activated (might be a statically initialized object)
++ */
++static int timer_fixup_activate(void *addr, enum debug_obj_state state)
++{
++	struct timer_list *timer = addr;
++
++	switch (state) {
++
++	case ODEBUG_STATE_NOTAVAILABLE:
++		/*
++		 * This is not really a fixup. The timer was
++		 * statically initialized. We just make sure that it
++		 * is tracked in the object tracker.
++		 */
++		if (timer->entry.next == NULL &&
++		    timer->entry.prev == TIMER_ENTRY_STATIC) {
++			debug_object_init(timer, &timer_debug_descr);
++			debug_object_activate(timer, &timer_debug_descr);
++			return 0;
++		} else {
++			WARN_ON_ONCE(1);
++		}
++		return 0;
++
++	case ODEBUG_STATE_ACTIVE:
++		WARN_ON(1);
++
++	default:
++		return 0;
++	}
++}
++
++/*
++ * fixup_free is called when:
++ * - an active object is freed
++ */
++static int timer_fixup_free(void *addr, enum debug_obj_state state)
++{
++	struct timer_list *timer = addr;
++
++	switch (state) {
++	case ODEBUG_STATE_ACTIVE:
++		del_timer_sync(timer);
++		debug_object_free(timer, &timer_debug_descr);
++		return 1;
++	default:
++		return 0;
++	}
++}
++
++static struct debug_obj_descr timer_debug_descr = {
++	.name		= "timer_list",
++	.fixup_init	= timer_fixup_init,
++	.fixup_activate	= timer_fixup_activate,
++	.fixup_free	= timer_fixup_free,
++};
++
++static inline void debug_timer_init(struct timer_list *timer)
++{
++	debug_object_init(timer, &timer_debug_descr);
++}
++
++static inline void debug_timer_activate(struct timer_list *timer)
++{
++	debug_object_activate(timer, &timer_debug_descr);
++}
++
++static inline void debug_timer_deactivate(struct timer_list *timer)
++{
++	debug_object_deactivate(timer, &timer_debug_descr);
++}
++
++static inline void debug_timer_free(struct timer_list *timer)
++{
++	debug_object_free(timer, &timer_debug_descr);
++}
++
++static void __init_timer(struct timer_list *timer,
++			 const char *name,
++			 struct lock_class_key *key);
++
++void init_timer_on_stack_key(struct timer_list *timer,
++			     const char *name,
++			     struct lock_class_key *key)
++{
++	debug_object_init_on_stack(timer, &timer_debug_descr);
++	__init_timer(timer, name, key);
++}
++EXPORT_SYMBOL_GPL(init_timer_on_stack_key);
++
++void destroy_timer_on_stack(struct timer_list *timer)
++{
++	debug_object_free(timer, &timer_debug_descr);
++}
++EXPORT_SYMBOL_GPL(destroy_timer_on_stack);
++
++#else
++static inline void debug_timer_init(struct timer_list *timer) { }
++static inline void debug_timer_activate(struct timer_list *timer) { }
++static inline void debug_timer_deactivate(struct timer_list *timer) { }
++#endif
++
++static inline void debug_init(struct timer_list *timer)
++{
++	debug_timer_init(timer);
++	trace_timer_init(timer);
++}
++
++static inline void
++debug_activate(struct timer_list *timer, unsigned long expires)
++{
++	debug_timer_activate(timer);
++	trace_timer_start(timer, expires);
++}
++
++static inline void debug_deactivate(struct timer_list *timer)
++{
++	debug_timer_deactivate(timer);
++	trace_timer_cancel(timer);
++}
++
++static void __init_timer(struct timer_list *timer,
++			 const char *name,
++			 struct lock_class_key *key)
++{
++	timer->entry.next = NULL;
++	timer->base = __raw_get_cpu_var(tvec_bases);
++	timer->slack = -1;
++#ifdef CONFIG_TIMER_STATS
++	timer->start_site = NULL;
++	timer->start_pid = -1;
++	memset(timer->start_comm, 0, TASK_COMM_LEN);
++#endif
++	lockdep_init_map(&timer->lockdep_map, name, key, 0);
++}
++
++/**
++ * init_timer_key - initialize a timer
++ * @timer: the timer to be initialized
++ * @name: name of the timer
++ * @key: lockdep class key of the fake lock used for tracking timer
++ *       sync lock dependencies
++ *
++ * init_timer_key() must be done to a timer prior calling *any* of the
++ * other timer functions.
++ */
++void init_timer_key(struct timer_list *timer,
++		    const char *name,
++		    struct lock_class_key *key)
++{
++	debug_init(timer);
++	__init_timer(timer, name, key);
++}
++EXPORT_SYMBOL(init_timer_key);
++
++void init_timer_deferrable_key(struct timer_list *timer,
++			       const char *name,
++			       struct lock_class_key *key)
++{
++	init_timer_key(timer, name, key);
++	timer_set_deferrable(timer);
++}
++EXPORT_SYMBOL(init_timer_deferrable_key);
++
++static inline void detach_timer(struct timer_list *timer,
++				int clear_pending)
++{
++	struct list_head *entry = &timer->entry;
++
++	debug_deactivate(timer);
++
++	__list_del(entry->prev, entry->next);
++	if (clear_pending)
++		entry->next = NULL;
++	entry->prev = LIST_POISON2;
++}
++
++/*
++ * We are using hashed locking: holding per_cpu(tvec_bases).lock
++ * means that all timers which are tied to this base via timer->base are
++ * locked, and the base itself is locked too.
++ *
++ * So __run_timers/migrate_timers can safely modify all timers which could
++ * be found on ->tvX lists.
++ *
++ * When the timer's base is locked, and the timer removed from list, it is
++ * possible to set timer->base = NULL and drop the lock: the timer remains
++ * locked.
++ */
++static struct tvec_base *lock_timer_base(struct timer_list *timer,
++					unsigned long *flags)
++	__acquires(timer->base->lock)
++{
++	struct tvec_base *base;
++
++	for (;;) {
++		struct tvec_base *prelock_base = timer->base;
++		base = tbase_get_base(prelock_base);
++		if (likely(base != NULL)) {
++			spin_lock_irqsave(&base->lock, *flags);
++			if (likely(prelock_base == timer->base))
++				return base;
++			/* The timer has migrated to another CPU */
++			spin_unlock_irqrestore(&base->lock, *flags);
++		}
++		cpu_relax();
++	}
++}
++
++static inline int
++__mod_timer(struct timer_list *timer, unsigned long expires,
++						bool pending_only, int pinned)
++{
++	struct tvec_base *base, *new_base;
++	unsigned long flags;
++	int ret = 0 , cpu;
++
++	timer_stats_timer_set_start_info(timer);
++	BUG_ON(!timer->function);
++
++	base = lock_timer_base(timer, &flags);
++
++	if (timer_pending(timer)) {
++		detach_timer(timer, 0);
++		if (timer->expires == base->next_timer &&
++		    !tbase_get_deferrable(timer->base))
++			base->next_timer = base->timer_jiffies;
++		ret = 1;
++	} else {
++		if (pending_only)
++			goto out_unlock;
++	}
++
++	debug_activate(timer, expires);
++
++	cpu = smp_processor_id();
++
++#if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP)
++	if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu)) {
++		int preferred_cpu = get_nohz_load_balancer();
++
++		if (preferred_cpu >= 0)
++			cpu = preferred_cpu;
++	}
++#endif
++	new_base = per_cpu(tvec_bases, cpu);
++
++	if (base != new_base) {
++		/*
++		 * We are trying to schedule the timer on the local CPU.
++		 * However we can't change timer's base while it is running,
++		 * otherwise del_timer_sync() can't detect that the timer's
++		 * handler yet has not finished. This also guarantees that
++		 * the timer is serialized wrt itself.
++		 */
++		if (likely(base->running_timer != timer)) {
++			/* See the comment in lock_timer_base() */
++			timer_set_base(timer, NULL);
++			spin_unlock(&base->lock);
++			base = new_base;
++			spin_lock(&base->lock);
++			timer_set_base(timer, base);
++		}
++	}
++
++	timer->expires = expires;
++	if (time_before(timer->expires, base->next_timer) &&
++	    !tbase_get_deferrable(timer->base))
++		base->next_timer = timer->expires;
++	internal_add_timer(base, timer);
++
++out_unlock:
++	spin_unlock_irqrestore(&base->lock, flags);
++
++	return ret;
++}
++
++/**
++ * mod_timer_pending - modify a pending timer's timeout
++ * @timer: the pending timer to be modified
++ * @expires: new timeout in jiffies
++ *
++ * mod_timer_pending() is the same for pending timers as mod_timer(),
++ * but will not re-activate and modify already deleted timers.
++ *
++ * It is useful for unserialized use of timers.
++ */
++int mod_timer_pending(struct timer_list *timer, unsigned long expires)
++{
++	return __mod_timer(timer, expires, true, TIMER_NOT_PINNED);
++}
++EXPORT_SYMBOL(mod_timer_pending);
++
++/*
++ * Decide where to put the timer while taking the slack into account
++ *
++ * Algorithm:
++ *   1) calculate the maximum (absolute) time
++ *   2) calculate the highest bit where the expires and new max are different
++ *   3) use this bit to make a mask
++ *   4) use the bitmask to round down the maximum time, so that all last
++ *      bits are zeros
++ */
++static inline
++unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
++{
++	unsigned long expires_limit, mask;
++	int bit;
++
++	expires_limit = expires;
++
++	if (timer->slack >= 0) {
++		expires_limit = expires + timer->slack;
++	} else {
++		unsigned long now = jiffies;
++
++		/* No slack, if already expired else auto slack 0.4% */
++		if (time_after(expires, now))
++			expires_limit = expires + (expires - now)/256;
++	}
++	mask = expires ^ expires_limit;
++	if (mask == 0)
++		return expires;
++
++	bit = find_last_bit(&mask, BITS_PER_LONG);
++
++	mask = (1 << bit) - 1;
++
++	expires_limit = expires_limit & ~(mask);
++
++	return expires_limit;
++}
++
++/**
++ * mod_timer - modify a timer's timeout
++ * @timer: the timer to be modified
++ * @expires: new timeout in jiffies
++ *
++ * mod_timer() is a more efficient way to update the expire field of an
++ * active timer (if the timer is inactive it will be activated)
++ *
++ * mod_timer(timer, expires) is equivalent to:
++ *
++ *     del_timer(timer); timer->expires = expires; add_timer(timer);
++ *
++ * Note that if there are multiple unserialized concurrent users of the
++ * same timer, then mod_timer() is the only safe way to modify the timeout,
++ * since add_timer() cannot modify an already running timer.
++ *
++ * The function returns whether it has modified a pending timer or not.
++ * (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an
++ * active timer returns 1.)
++ */
++int mod_timer(struct timer_list *timer, unsigned long expires)
++{
++	/*
++	 * This is a common optimization triggered by the
++	 * networking code - if the timer is re-modified
++	 * to be the same thing then just return:
++	 */
++	if (timer_pending(timer) && timer->expires == expires)
++		return 1;
++
++	expires = apply_slack(timer, expires);
++
++	return __mod_timer(timer, expires, false, TIMER_NOT_PINNED);
++}
++EXPORT_SYMBOL(mod_timer);
++
++/**
++ * mod_timer_pinned - modify a timer's timeout
++ * @timer: the timer to be modified
++ * @expires: new timeout in jiffies
++ *
++ * mod_timer_pinned() is a way to update the expire field of an
++ * active timer (if the timer is inactive it will be activated)
++ * and not allow the timer to be migrated to a different CPU.
++ *
++ * mod_timer_pinned(timer, expires) is equivalent to:
++ *
++ *     del_timer(timer); timer->expires = expires; add_timer(timer);
++ */
++int mod_timer_pinned(struct timer_list *timer, unsigned long expires)
++{
++	if (timer->expires == expires && timer_pending(timer))
++		return 1;
++
++	return __mod_timer(timer, expires, false, TIMER_PINNED);
++}
++EXPORT_SYMBOL(mod_timer_pinned);
++
++/**
++ * add_timer - start a timer
++ * @timer: the timer to be added
++ *
++ * The kernel will do a ->function(->data) callback from the
++ * timer interrupt at the ->expires point in the future. The
++ * current time is 'jiffies'.
++ *
++ * The timer's ->expires, ->function (and if the handler uses it, ->data)
++ * fields must be set prior calling this function.
++ *
++ * Timers with an ->expires field in the past will be executed in the next
++ * timer tick.
++ */
++void add_timer(struct timer_list *timer)
++{
++	BUG_ON(timer_pending(timer));
++	mod_timer(timer, timer->expires);
++}
++EXPORT_SYMBOL(add_timer);
++
++/**
++ * add_timer_on - start a timer on a particular CPU
++ * @timer: the timer to be added
++ * @cpu: the CPU to start it on
++ *
++ * This is not very scalable on SMP. Double adds are not possible.
++ */
++void add_timer_on(struct timer_list *timer, int cpu)
++{
++	struct tvec_base *base = per_cpu(tvec_bases, cpu);
++	unsigned long flags;
++
++	timer_stats_timer_set_start_info(timer);
++	BUG_ON(timer_pending(timer) || !timer->function);
++	spin_lock_irqsave(&base->lock, flags);
++	timer_set_base(timer, base);
++	debug_activate(timer, timer->expires);
++	if (time_before(timer->expires, base->next_timer) &&
++	    !tbase_get_deferrable(timer->base))
++		base->next_timer = timer->expires;
++	internal_add_timer(base, timer);
++	/*
++	 * Check whether the other CPU is idle and needs to be
++	 * triggered to reevaluate the timer wheel when nohz is
++	 * active. We are protected against the other CPU fiddling
++	 * with the timer by holding the timer base lock. This also
++	 * makes sure that a CPU on the way to idle can not evaluate
++	 * the timer wheel.
++	 */
++	wake_up_idle_cpu(cpu);
++	spin_unlock_irqrestore(&base->lock, flags);
++}
++EXPORT_SYMBOL_GPL(add_timer_on);
++
++/**
++ * del_timer - deactive a timer.
++ * @timer: the timer to be deactivated
++ *
++ * del_timer() deactivates a timer - this works on both active and inactive
++ * timers.
++ *
++ * The function returns whether it has deactivated a pending timer or not.
++ * (ie. del_timer() of an inactive timer returns 0, del_timer() of an
++ * active timer returns 1.)
++ */
++int del_timer(struct timer_list *timer)
++{
++	struct tvec_base *base;
++	unsigned long flags;
++	int ret = 0;
++
++	timer_stats_timer_clear_start_info(timer);
++	if (timer_pending(timer)) {
++		base = lock_timer_base(timer, &flags);
++		if (timer_pending(timer)) {
++			detach_timer(timer, 1);
++			if (timer->expires == base->next_timer &&
++			    !tbase_get_deferrable(timer->base))
++				base->next_timer = base->timer_jiffies;
++			ret = 1;
++		}
++		spin_unlock_irqrestore(&base->lock, flags);
++	}
++
++	return ret;
++}
++EXPORT_SYMBOL(del_timer);
++
++#ifdef CONFIG_SMP
++/**
++ * try_to_del_timer_sync - Try to deactivate a timer
++ * @timer: timer do del
++ *
++ * This function tries to deactivate a timer. Upon successful (ret >= 0)
++ * exit the timer is not queued and the handler is not running on any CPU.
++ *
++ * It must not be called from interrupt contexts.
++ */
++int try_to_del_timer_sync(struct timer_list *timer)
++{
++	struct tvec_base *base;
++	unsigned long flags;
++	int ret = -1;
++
++	base = lock_timer_base(timer, &flags);
++
++	if (base->running_timer == timer)
++		goto out;
++
++	timer_stats_timer_clear_start_info(timer);
++	ret = 0;
++	if (timer_pending(timer)) {
++		detach_timer(timer, 1);
++		if (timer->expires == base->next_timer &&
++		    !tbase_get_deferrable(timer->base))
++			base->next_timer = base->timer_jiffies;
++		ret = 1;
++	}
++out:
++	spin_unlock_irqrestore(&base->lock, flags);
++
++	return ret;
++}
++EXPORT_SYMBOL(try_to_del_timer_sync);
++
++/**
++ * del_timer_sync - deactivate a timer and wait for the handler to finish.
++ * @timer: the timer to be deactivated
++ *
++ * This function only differs from del_timer() on SMP: besides deactivating
++ * the timer it also makes sure the handler has finished executing on other
++ * CPUs.
++ *
++ * Synchronization rules: Callers must prevent restarting of the timer,
++ * otherwise this function is meaningless. It must not be called from
++ * interrupt contexts. The caller must not hold locks which would prevent
++ * completion of the timer's handler. The timer's handler must not call
++ * add_timer_on(). Upon exit the timer is not queued and the handler is
++ * not running on any CPU.
++ *
++ * The function returns whether it has deactivated a pending timer or not.
++ */
++int del_timer_sync(struct timer_list *timer)
++{
++#ifdef CONFIG_LOCKDEP
++	unsigned long flags;
++
++	local_irq_save(flags);
++	lock_map_acquire(&timer->lockdep_map);
++	lock_map_release(&timer->lockdep_map);
++	local_irq_restore(flags);
++#endif
++
++	for (;;) {
++		int ret = try_to_del_timer_sync(timer);
++		if (ret >= 0)
++			return ret;
++		cpu_relax();
++	}
++}
++EXPORT_SYMBOL(del_timer_sync);
++#endif
++
++static int cascade(struct tvec_base *base, struct tvec *tv, int index)
++{
++	/* cascade all the timers from tv up one level */
++	struct timer_list *timer, *tmp;
++	struct list_head tv_list;
++
++	list_replace_init(tv->vec + index, &tv_list);
++
++	/*
++	 * We are removing _all_ timers from the list, so we
++	 * don't have to detach them individually.
++	 */
++	list_for_each_entry_safe(timer, tmp, &tv_list, entry) {
++		BUG_ON(tbase_get_base(timer->base) != base);
++		internal_add_timer(base, timer);
++	}
++
++	return index;
++}
++
++static void call_timer_fn(struct timer_list *timer, void (*fn)(unsigned long),
++			  unsigned long data)
++{
++	int preempt_count = preempt_count();
++
++#ifdef CONFIG_LOCKDEP
++	/*
++	 * It is permissible to free the timer from inside the
++	 * function that is called from it, this we need to take into
++	 * account for lockdep too. To avoid bogus "held lock freed"
++	 * warnings as well as problems when looking into
++	 * timer->lockdep_map, make a copy and use that here.
++	 */
++	struct lockdep_map lockdep_map = timer->lockdep_map;
++#endif
++	/*
++	 * Couple the lock chain with the lock chain at
++	 * del_timer_sync() by acquiring the lock_map around the fn()
++	 * call here and in del_timer_sync().
++	 */
++	lock_map_acquire(&lockdep_map);
++
++	trace_timer_expire_entry(timer);
++	fn(data);
++	trace_timer_expire_exit(timer);
++
++	lock_map_release(&lockdep_map);
++
++	if (preempt_count != preempt_count()) {
++		WARN_ONCE(1, "timer: %pF preempt leak: %08x -> %08x\n",
++			  fn, preempt_count, preempt_count());
++		/*
++		 * Restore the preempt count. That gives us a decent
++		 * chance to survive and extract information. If the
++		 * callback kept a lock held, bad luck, but not worse
++		 * than the BUG() we had.
++		 */
++		preempt_count() = preempt_count;
++	}
++}
++
++#define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)
++
++/**
++ * __run_timers - run all expired timers (if any) on this CPU.
++ * @base: the timer vector to be processed.
++ *
++ * This function cascades all vectors and executes all expired timer
++ * vectors.
++ */
++static inline void __run_timers(struct tvec_base *base)
++{
++	struct timer_list *timer;
++
++	spin_lock_irq(&base->lock);
++	while (time_after_eq(jiffies, base->timer_jiffies)) {
++		struct list_head work_list;
++		struct list_head *head = &work_list;
++		int index = base->timer_jiffies & TVR_MASK;
++
++		/*
++		 * Cascade timers:
++		 */
++		if (!index &&
++			(!cascade(base, &base->tv2, INDEX(0))) &&
++				(!cascade(base, &base->tv3, INDEX(1))) &&
++					!cascade(base, &base->tv4, INDEX(2)))
++			cascade(base, &base->tv5, INDEX(3));
++		++base->timer_jiffies;
++		list_replace_init(base->tv1.vec + index, &work_list);
++		while (!list_empty(head)) {
++			void (*fn)(unsigned long);
++			unsigned long data;
++
++			timer = list_first_entry(head, struct timer_list,entry);
++			fn = timer->function;
++			data = timer->data;
++
++			timer_stats_account_timer(timer);
++
++			set_running_timer(base, timer);
++			detach_timer(timer, 1);
++
++			spin_unlock_irq(&base->lock);
++			call_timer_fn(timer, fn, data);
++			spin_lock_irq(&base->lock);
++		}
++	}
++	set_running_timer(base, NULL);
++	spin_unlock_irq(&base->lock);
++}
++
++#ifdef CONFIG_NO_HZ
++/*
++ * Find out when the next timer event is due to happen. This
++ * is used on S/390 to stop all activity when a CPU is idle.
++ * This function needs to be called with interrupts disabled.
++ */
++static unsigned long __next_timer_interrupt(struct tvec_base *base)
++{
++	unsigned long timer_jiffies = base->timer_jiffies;
++	unsigned long expires = timer_jiffies + NEXT_TIMER_MAX_DELTA;
++	int index, slot, array, found = 0;
++	struct timer_list *nte;
++	struct tvec *varray[4];
++
++	/* Look for timer events in tv1. */
++	index = slot = timer_jiffies & TVR_MASK;
++	do {
++		list_for_each_entry(nte, base->tv1.vec + slot, entry) {
++			if (tbase_get_deferrable(nte->base))
++				continue;
++
++			found = 1;
++			expires = nte->expires;
++			/* Look at the cascade bucket(s)? */
++			if (!index || slot < index)
++				goto cascade;
++			return expires;
++		}
++		slot = (slot + 1) & TVR_MASK;
++	} while (slot != index);
++
++cascade:
++	/* Calculate the next cascade event */
++	if (index)
++		timer_jiffies += TVR_SIZE - index;
++	timer_jiffies >>= TVR_BITS;
++
++	/* Check tv2-tv5. */
++	varray[0] = &base->tv2;
++	varray[1] = &base->tv3;
++	varray[2] = &base->tv4;
++	varray[3] = &base->tv5;
++
++	for (array = 0; array < 4; array++) {
++		struct tvec *varp = varray[array];
++
++		index = slot = timer_jiffies & TVN_MASK;
++		do {
++			list_for_each_entry(nte, varp->vec + slot, entry) {
++				if (tbase_get_deferrable(nte->base))
++					continue;
++
++				found = 1;
++				if (time_before(nte->expires, expires))
++					expires = nte->expires;
++			}
++			/*
++			 * Do we still search for the first timer or are
++			 * we looking up the cascade buckets ?
++			 */
++			if (found) {
++				/* Look at the cascade bucket(s)? */
++				if (!index || slot < index)
++					break;
++				return expires;
++			}
++			slot = (slot + 1) & TVN_MASK;
++		} while (slot != index);
++
++		if (index)
++			timer_jiffies += TVN_SIZE - index;
++		timer_jiffies >>= TVN_BITS;
++	}
++	return expires;
++}
++
++/*
++ * Check, if the next hrtimer event is before the next timer wheel
++ * event:
++ */
++static unsigned long cmp_next_hrtimer_event(unsigned long now,
++					    unsigned long expires)
++{
++	ktime_t hr_delta = hrtimer_get_next_event();
++	struct timespec tsdelta;
++	unsigned long delta;
++
++	if (hr_delta.tv64 == KTIME_MAX)
++		return expires;
++
++	/*
++	 * Expired timer available, let it expire in the next tick
++	 */
++	if (hr_delta.tv64 <= 0)
++		return now + 1;
++
++	tsdelta = ktime_to_timespec(hr_delta);
++	delta = timespec_to_jiffies(&tsdelta);
++
++	/*
++	 * Limit the delta to the max value, which is checked in
++	 * tick_nohz_stop_sched_tick():
++	 */
++	if (delta > NEXT_TIMER_MAX_DELTA)
++		delta = NEXT_TIMER_MAX_DELTA;
++
++	/*
++	 * Take rounding errors in to account and make sure, that it
++	 * expires in the next tick. Otherwise we go into an endless
++	 * ping pong due to tick_nohz_stop_sched_tick() retriggering
++	 * the timer softirq
++	 */
++	if (delta < 1)
++		delta = 1;
++	now += delta;
++	if (time_before(now, expires))
++		return now;
++	return expires;
++}
++
++/**
++ * get_next_timer_interrupt - return the jiffy of the next pending timer
++ * @now: current time (in jiffies)
++ */
++unsigned long get_next_timer_interrupt(unsigned long now)
++{
++	struct tvec_base *base = __get_cpu_var(tvec_bases);
++	unsigned long expires;
++
++	/*
++	 * Pretend that there is no timer pending if the cpu is offline.
++	 * Possible pending timers will be migrated later to an active cpu.
++	 */
++	if (cpu_is_offline(smp_processor_id()))
++		return now + NEXT_TIMER_MAX_DELTA;
++	spin_lock(&base->lock);
++	if (time_before_eq(base->next_timer, base->timer_jiffies))
++		base->next_timer = __next_timer_interrupt(base);
++	expires = base->next_timer;
++	spin_unlock(&base->lock);
++
++	if (time_before_eq(expires, now))
++		return now;
++
++	return cmp_next_hrtimer_event(now, expires);
++}
++#endif
++
++/*
++ * Called from the timer interrupt handler to charge one tick to the current
++ * process.  user_tick is 1 if the tick is user time, 0 for system.
++ */
++void update_process_times(int user_tick)
++{
++	struct task_struct *p = current;
++	int cpu = smp_processor_id();
++
++	/* Note: this timer irq context must be accounted for as well. */
++	account_process_tick(p, user_tick);
++	run_local_timers();
++	rcu_check_callbacks(cpu, user_tick);
++	printk_tick();
++	perf_event_do_pending();
++	scheduler_tick();
++	run_posix_cpu_timers(p);
++}
++
++/*
++ * This function runs timers and the timer-tq in bottom half context.
++ */
++static void run_timer_softirq(struct softirq_action *h)
++{
++	struct tvec_base *base = __get_cpu_var(tvec_bases);
++
++	hrtimer_run_pending();
++
++	if (time_after_eq(jiffies, base->timer_jiffies))
++		__run_timers(base);
++}
++
++/*
++ * Called by the local, per-CPU timer interrupt on SMP.
++ */
++void run_local_timers(void)
++{
++	hrtimer_run_queues();
++	raise_softirq(TIMER_SOFTIRQ);
++	softlockup_tick();
++}
++
++/*
++ * The 64-bit jiffies value is not atomic - you MUST NOT read it
++ * without sampling the sequence number in xtime_lock.
++ * jiffies is defined in the linker script...
++ */
++
++void do_timer(unsigned long ticks)
++{
++	jiffies_64 += ticks;
++	update_wall_time();
++	calc_global_load(ticks);
++}
++
++#ifdef __ARCH_WANT_SYS_ALARM
++
++/*
++ * For backwards compatibility?  This can be done in libc so Alpha
++ * and all newer ports shouldn't need it.
++ */
++SYSCALL_DEFINE1(alarm, unsigned int, seconds)
++{
++	return alarm_setitimer(seconds);
++}
++
++#endif
++
++#ifndef __alpha__
++
++/*
++ * The Alpha uses getxpid, getxuid, and getxgid instead.  Maybe this
++ * should be moved into arch/i386 instead?
++ */
++
++/**
++ * sys_getpid - return the thread group id of the current process
++ *
++ * Note, despite the name, this returns the tgid not the pid.  The tgid and
++ * the pid are identical unless CLONE_THREAD was specified on clone() in
++ * which case the tgid is the same in all threads of the same group.
++ *
++ * This is SMP safe as current->tgid does not change.
++ */
++SYSCALL_DEFINE0(getpid)
++{
++	return task_tgid_vnr(current);
++}
++
++/*
++ * Accessing ->real_parent is not SMP-safe, it could
++ * change from under us. However, we can use a stale
++ * value of ->real_parent under rcu_read_lock(), see
++ * release_task()->call_rcu(delayed_put_task_struct).
++ */
++SYSCALL_DEFINE0(getppid)
++{
++	int pid;
++
++	rcu_read_lock();
++	pid = task_tgid_vnr(current->real_parent);
++	rcu_read_unlock();
++
++	return pid;
++}
++
++SYSCALL_DEFINE0(getuid)
++{
++	/* Only we change this so SMP safe */
++	return current_uid();
++}
++
++SYSCALL_DEFINE0(geteuid)
++{
++	/* Only we change this so SMP safe */
++	return current_euid();
++}
++
++SYSCALL_DEFINE0(getgid)
++{
++	/* Only we change this so SMP safe */
++	return current_gid();
++}
++
++SYSCALL_DEFINE0(getegid)
++{
++	/* Only we change this so SMP safe */
++	return  current_egid();
++}
++
++#endif
++
++static void process_timeout(unsigned long __data)
++{
++	wake_up_process((struct task_struct *)__data);
++}
++
++/**
++ * schedule_timeout - sleep until timeout
++ * @timeout: timeout value in jiffies
++ *
++ * Make the current task sleep until @timeout jiffies have
++ * elapsed. The routine will return immediately unless
++ * the current task state has been set (see set_current_state()).
++ *
++ * You can set the task state as follows -
++ *
++ * %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to
++ * pass before the routine returns. The routine will return 0
++ *
++ * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
++ * delivered to the current task. In this case the remaining time
++ * in jiffies will be returned, or 0 if the timer expired in time
++ *
++ * The current task state is guaranteed to be TASK_RUNNING when this
++ * routine returns.
++ *
++ * Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule
++ * the CPU away without a bound on the timeout. In this case the return
++ * value will be %MAX_SCHEDULE_TIMEOUT.
++ *
++ * In all cases the return value is guaranteed to be non-negative.
++ */
++signed long __sched schedule_timeout(signed long timeout)
++{
++	struct timer_list timer;
++	unsigned long expire;
++
++	switch (timeout)
++	{
++	case MAX_SCHEDULE_TIMEOUT:
++		/*
++		 * These two special cases are useful to be comfortable
++		 * in the caller. Nothing more. We could take
++		 * MAX_SCHEDULE_TIMEOUT from one of the negative value
++		 * but I' d like to return a valid offset (>=0) to allow
++		 * the caller to do everything it want with the retval.
++		 */
++		schedule();
++		goto out;
++	default:
++		/*
++		 * Another bit of PARANOID. Note that the retval will be
++		 * 0 since no piece of kernel is supposed to do a check
++		 * for a negative retval of schedule_timeout() (since it
++		 * should never happens anyway). You just have the printk()
++		 * that will tell you if something is gone wrong and where.
++		 */
++		if (timeout < 0) {
++			printk(KERN_ERR "schedule_timeout: wrong timeout "
++				"value %lx\n", timeout);
++			dump_stack();
++			current->state = TASK_RUNNING;
++			goto out;
++		}
++	}
++
++	expire = timeout + jiffies;
++
++	setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);
++	__mod_timer(&timer, expire, false, TIMER_NOT_PINNED);
++	schedule();
++	del_singleshot_timer_sync(&timer);
++
++	/* Remove the timer from the object tracker */
++	destroy_timer_on_stack(&timer);
++
++	timeout = expire - jiffies;
++
++ out:
++	return timeout < 0 ? 0 : timeout;
++}
++EXPORT_SYMBOL(schedule_timeout);
++
++/*
++ * We can use __set_current_state() here because schedule_timeout() calls
++ * schedule() unconditionally.
++ */
++signed long __sched schedule_timeout_interruptible(signed long timeout)
++{
++	__set_current_state(TASK_INTERRUPTIBLE);
++	return schedule_timeout(timeout);
++}
++EXPORT_SYMBOL(schedule_timeout_interruptible);
++
++signed long __sched schedule_timeout_killable(signed long timeout)
++{
++	__set_current_state(TASK_KILLABLE);
++	return schedule_timeout(timeout);
++}
++EXPORT_SYMBOL(schedule_timeout_killable);
++
++signed long __sched schedule_timeout_uninterruptible(signed long timeout)
++{
++	__set_current_state(TASK_UNINTERRUPTIBLE);
++	return schedule_timeout(timeout);
++}
++EXPORT_SYMBOL(schedule_timeout_uninterruptible);
++
++/* Thread ID - the internal kernel "pid" */
++SYSCALL_DEFINE0(gettid)
++{
++	return task_pid_vnr(current);
++}
++
++/**
++ * do_sysinfo - fill in sysinfo struct
++ * @info: pointer to buffer to fill
++ */
++int do_sysinfo(struct sysinfo *info)
++{
++	unsigned long mem_total, sav_total;
++	unsigned int mem_unit, bitcount;
++	struct timespec tp;
++
++	memset(info, 0, sizeof(struct sysinfo));
++
++	ktime_get_ts(&tp);
++	monotonic_to_bootbased(&tp);
++	info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0);
++
++	get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT);
++
++	info->procs = nr_threads;
++
++	si_meminfo(info);
++	si_swapinfo(info);
++
++	/*
++	 * If the sum of all the available memory (i.e. ram + swap)
++	 * is less than can be stored in a 32 bit unsigned long then
++	 * we can be binary compatible with 2.2.x kernels.  If not,
++	 * well, in that case 2.2.x was broken anyways...
++	 *
++	 *  -Erik Andersen <andersee@debian.org>
++	 */
++
++	mem_total = info->totalram + info->totalswap;
++	if (mem_total < info->totalram || mem_total < info->totalswap)
++		goto out;
++	bitcount = 0;
++	mem_unit = info->mem_unit;
++	while (mem_unit > 1) {
++		bitcount++;
++		mem_unit >>= 1;
++		sav_total = mem_total;
++		mem_total <<= 1;
++		if (mem_total < sav_total)
++			goto out;
++	}
++
++	/*
++	 * If mem_total did not overflow, multiply all memory values by
++	 * info->mem_unit and set it to 1.  This leaves things compatible
++	 * with 2.2.x, and also retains compatibility with earlier 2.4.x
++	 * kernels...
++	 */
++
++	info->mem_unit = 1;
++	info->totalram <<= bitcount;
++	info->freeram <<= bitcount;
++	info->sharedram <<= bitcount;
++	info->bufferram <<= bitcount;
++	info->totalswap <<= bitcount;
++	info->freeswap <<= bitcount;
++	info->totalhigh <<= bitcount;
++	info->freehigh <<= bitcount;
++
++out:
++	return 0;
++}
++
++SYSCALL_DEFINE1(sysinfo, struct sysinfo __user *, info)
++{
++	struct sysinfo val;
++
++	do_sysinfo(&val);
++
++	if (copy_to_user(info, &val, sizeof(struct sysinfo)))
++		return -EFAULT;
++
++	return 0;
++}
++
++static int __cpuinit init_timers_cpu(int cpu)
++{
++	int j;
++	struct tvec_base *base;
++	static char __cpuinitdata tvec_base_done[NR_CPUS];
++
++	if (!tvec_base_done[cpu]) {
++		static char boot_done;
++
++		if (boot_done) {
++			/*
++			 * The APs use this path later in boot
++			 */
++			base = kmalloc_node(sizeof(*base),
++						GFP_KERNEL | __GFP_ZERO,
++						cpu_to_node(cpu));
++			if (!base)
++				return -ENOMEM;
++
++			/* Make sure that tvec_base is 2 byte aligned */
++			if (tbase_get_deferrable(base)) {
++				WARN_ON(1);
++				kfree(base);
++				return -ENOMEM;
++			}
++			per_cpu(tvec_bases, cpu) = base;
++		} else {
++			/*
++			 * This is for the boot CPU - we use compile-time
++			 * static initialisation because per-cpu memory isn't
++			 * ready yet and because the memory allocators are not
++			 * initialised either.
++			 */
++			boot_done = 1;
++			base = &boot_tvec_bases;
++		}
++		tvec_base_done[cpu] = 1;
++	} else {
++		base = per_cpu(tvec_bases, cpu);
++	}
++
++	spin_lock_init(&base->lock);
++
++	for (j = 0; j < TVN_SIZE; j++) {
++		INIT_LIST_HEAD(base->tv5.vec + j);
++		INIT_LIST_HEAD(base->tv4.vec + j);
++		INIT_LIST_HEAD(base->tv3.vec + j);
++		INIT_LIST_HEAD(base->tv2.vec + j);
++	}
++	for (j = 0; j < TVR_SIZE; j++)
++		INIT_LIST_HEAD(base->tv1.vec + j);
++
++	base->timer_jiffies = jiffies;
++	base->next_timer = base->timer_jiffies;
++	return 0;
++}
++
++#ifdef CONFIG_HOTPLUG_CPU
++static void migrate_timer_list(struct tvec_base *new_base, struct list_head *head)
++{
++	struct timer_list *timer;
++
++	while (!list_empty(head)) {
++		timer = list_first_entry(head, struct timer_list, entry);
++		detach_timer(timer, 0);
++		timer_set_base(timer, new_base);
++		if (time_before(timer->expires, new_base->next_timer) &&
++		    !tbase_get_deferrable(timer->base))
++			new_base->next_timer = timer->expires;
++		internal_add_timer(new_base, timer);
++	}
++}
++
++static void __cpuinit migrate_timers(int cpu)
++{
++	struct tvec_base *old_base;
++	struct tvec_base *new_base;
++	int i;
++
++	BUG_ON(cpu_online(cpu));
++	old_base = per_cpu(tvec_bases, cpu);
++	new_base = get_cpu_var(tvec_bases);
++	/*
++	 * The caller is globally serialized and nobody else
++	 * takes two locks at once, deadlock is not possible.
++	 */
++	spin_lock_irq(&new_base->lock);
++	spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
++
++	BUG_ON(old_base->running_timer);
++
++	for (i = 0; i < TVR_SIZE; i++)
++		migrate_timer_list(new_base, old_base->tv1.vec + i);
++	for (i = 0; i < TVN_SIZE; i++) {
++		migrate_timer_list(new_base, old_base->tv2.vec + i);
++		migrate_timer_list(new_base, old_base->tv3.vec + i);
++		migrate_timer_list(new_base, old_base->tv4.vec + i);
++		migrate_timer_list(new_base, old_base->tv5.vec + i);
++	}
++
++	spin_unlock(&old_base->lock);
++	spin_unlock_irq(&new_base->lock);
++	put_cpu_var(tvec_bases);
++}
++#endif /* CONFIG_HOTPLUG_CPU */
++
++static int __cpuinit timer_cpu_notify(struct notifier_block *self,
++				unsigned long action, void *hcpu)
++{
++	long cpu = (long)hcpu;
++	int err;
++
++	switch(action) {
++	case CPU_UP_PREPARE:
++	case CPU_UP_PREPARE_FROZEN:
++		err = init_timers_cpu(cpu);
++		if (err < 0)
++			return notifier_from_errno(err);
++		break;
++#ifdef CONFIG_HOTPLUG_CPU
++	case CPU_DEAD:
++	case CPU_DEAD_FROZEN:
++		migrate_timers(cpu);
++		break;
++#endif
++	default:
++		break;
++	}
++	return NOTIFY_OK;
++}
++
++static struct notifier_block __cpuinitdata timers_nb = {
++	.notifier_call	= timer_cpu_notify,
++};
++
++
++void __init init_timers(void)
++{
++	int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
++				(void *)(long)smp_processor_id());
++
++	init_timer_stats();
++
++	BUG_ON(err != NOTIFY_OK);
++	register_cpu_notifier(&timers_nb);
++	open_softirq(TIMER_SOFTIRQ, run_timer_softirq);
++}
++
++/**
++ * msleep - sleep safely even with waitqueue interruptions
++ * @msecs: Time in milliseconds to sleep for
++ */
++void msleep(unsigned int msecs)
++{
++	unsigned long timeout = msecs_to_jiffies(msecs) + 1;
++
++	while (timeout)
++		timeout = schedule_timeout_uninterruptible(timeout);
++}
++
++EXPORT_SYMBOL(msleep);
++
++/**
++ * msleep_interruptible - sleep waiting for signals
++ * @msecs: Time in milliseconds to sleep for
++ */
++unsigned long msleep_interruptible(unsigned int msecs)
++{
++	unsigned long timeout = msecs_to_jiffies(msecs) + 1;
++
++	while (timeout && !signal_pending(current))
++		timeout = schedule_timeout_interruptible(timeout);
++	return jiffies_to_msecs(timeout);
++}
++
++EXPORT_SYMBOL(msleep_interruptible);
+diff -rupN linux-2.6.35.11/lib/decompress_inflate.c linux-2.6.35.11-ts7500/lib/decompress_inflate.c
+--- linux-2.6.35.11/lib/decompress_inflate.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/lib/decompress_inflate.c	2011-03-14 11:18:24.000000000 -0400
+@@ -25,6 +25,8 @@
+ 
+ #include <linux/decompress/mm.h>
+ 
++
++
+ #define GZIP_IOBUF_SIZE (16*1024)
+ 
+ static int nofill(void *buffer, unsigned int len)
+@@ -32,6 +34,7 @@ static int nofill(void *buffer, unsigned
+ 	return -1;
+ }
+ 
++
+ /* Included from initramfs et al code */
+ STATIC int INIT gunzip(unsigned char *buf, int len,
+ 		       int(*fill)(void*, unsigned int),
+@@ -39,6 +42,7 @@ STATIC int INIT gunzip(unsigned char *bu
+ 		       unsigned char *out_buf,
+ 		       int *pos,
+ 		       void(*error_fn)(char *x)) {
++                
+ 	u8 *zbuf;
+ 	struct z_stream_s *strm;
+ 	int rc;
+@@ -51,6 +55,7 @@ STATIC int INIT gunzip(unsigned char *bu
+ 		out_buf = malloc(out_len);
+ 	} else {
+ 		out_len = 0x7fffffff; /* no limit */
++      
+ 	}
+ 	if (!out_buf) {
+ 		error("Out of memory while allocating output buffer");
+@@ -69,6 +74,7 @@ STATIC int INIT gunzip(unsigned char *bu
+ 	}
+ 
+ 	strm = malloc(sizeof(*strm));
++   
+ 	if (strm == NULL) {
+ 		error("Out of memory while allocating z_stream");
+ 		goto gunzip_nomem3;
+@@ -143,7 +149,7 @@ STATIC int INIT gunzip(unsigned char *bu
+ 			strm->next_out = out_buf;
+ 			strm->avail_out = out_len;
+ 		}
+-
++      
+ 		/* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
+ 		if (rc == Z_STREAM_END) {
+ 			rc = 0;
+@@ -169,7 +175,7 @@ gunzip_nomem3:
+ gunzip_nomem2:
+ 	if (flush)
+ 		free(out_buf);
+-gunzip_nomem1:
++gunzip_nomem1:   
+ 	return rc; /* returns Z_OK (0) if successful */
+ }
+ 
+diff -rupN linux-2.6.35.11/lib/inflate.c linux-2.6.35.11-ts7500/lib/inflate.c
+--- linux-2.6.35.11/lib/inflate.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/lib/inflate.c	2011-03-14 11:18:24.000000000 -0400
+@@ -243,6 +243,7 @@ static void *malloc(int size)
+ {
+        void *p;
+ 
++      
+        if (size < 0)
+ 		error("Malloc error");
+        if (!malloc_ptr)
+@@ -268,6 +269,7 @@ static void free(void *where)
+ }
+ #else
+ #define malloc(a) kmalloc(a, GFP_KERNEL)
++
+ #define free(a) kfree(a)
+ #endif
+ 
+diff -rupN linux-2.6.35.11/lib/inflate.c.orig linux-2.6.35.11-ts7500/lib/inflate.c.orig
+--- linux-2.6.35.11/lib/inflate.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/lib/inflate.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,1307 @@
++#define DEBG(x)
++#define DEBG1(x)
++/* inflate.c -- Not copyrighted 1992 by Mark Adler
++   version c10p1, 10 January 1993 */
++
++/* 
++ * Adapted for booting Linux by Hannu Savolainen 1993
++ * based on gzip-1.0.3 
++ *
++ * Nicolas Pitre <nico@fluxnic.net>, 1999/04/14 :
++ *   Little mods for all variable to reside either into rodata or bss segments
++ *   by marking constant variables with 'const' and initializing all the others
++ *   at run-time only.  This allows for the kernel uncompressor to run
++ *   directly from Flash or ROM memory on embedded systems.
++ */
++
++/*
++   Inflate deflated (PKZIP's method 8 compressed) data.  The compression
++   method searches for as much of the current string of bytes (up to a
++   length of 258) in the previous 32 K bytes.  If it doesn't find any
++   matches (of at least length 3), it codes the next byte.  Otherwise, it
++   codes the length of the matched string and its distance backwards from
++   the current position.  There is a single Huffman code that codes both
++   single bytes (called "literals") and match lengths.  A second Huffman
++   code codes the distance information, which follows a length code.  Each
++   length or distance code actually represents a base value and a number
++   of "extra" (sometimes zero) bits to get to add to the base value.  At
++   the end of each deflated block is a special end-of-block (EOB) literal/
++   length code.  The decoding process is basically: get a literal/length
++   code; if EOB then done; if a literal, emit the decoded byte; if a
++   length then get the distance and emit the referred-to bytes from the
++   sliding window of previously emitted data.
++
++   There are (currently) three kinds of inflate blocks: stored, fixed, and
++   dynamic.  The compressor deals with some chunk of data at a time, and
++   decides which method to use on a chunk-by-chunk basis.  A chunk might
++   typically be 32 K or 64 K.  If the chunk is incompressible, then the
++   "stored" method is used.  In this case, the bytes are simply stored as
++   is, eight bits per byte, with none of the above coding.  The bytes are
++   preceded by a count, since there is no longer an EOB code.
++
++   If the data is compressible, then either the fixed or dynamic methods
++   are used.  In the dynamic method, the compressed data is preceded by
++   an encoding of the literal/length and distance Huffman codes that are
++   to be used to decode this block.  The representation is itself Huffman
++   coded, and so is preceded by a description of that code.  These code
++   descriptions take up a little space, and so for small blocks, there is
++   a predefined set of codes, called the fixed codes.  The fixed method is
++   used if the block codes up smaller that way (usually for quite small
++   chunks), otherwise the dynamic method is used.  In the latter case, the
++   codes are customized to the probabilities in the current block, and so
++   can code it much better than the pre-determined fixed codes.
++ 
++   The Huffman codes themselves are decoded using a multi-level table
++   lookup, in order to maximize the speed of decoding plus the speed of
++   building the decoding tables.  See the comments below that precede the
++   lbits and dbits tuning parameters.
++ */
++
++
++/*
++   Notes beyond the 1.93a appnote.txt:
++
++   1. Distance pointers never point before the beginning of the output
++      stream.
++   2. Distance pointers can point back across blocks, up to 32k away.
++   3. There is an implied maximum of 7 bits for the bit length table and
++      15 bits for the actual data.
++   4. If only one code exists, then it is encoded using one bit.  (Zero
++      would be more efficient, but perhaps a little confusing.)  If two
++      codes exist, they are coded using one bit each (0 and 1).
++   5. There is no way of sending zero distance codes--a dummy must be
++      sent if there are none.  (History: a pre 2.0 version of PKZIP would
++      store blocks with no distance codes, but this was discovered to be
++      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
++      zero distance codes, which is sent as one code of zero bits in
++      length.
++   6. There are up to 286 literal/length codes.  Code 256 represents the
++      end-of-block.  Note however that the static length tree defines
++      288 codes just to fill out the Huffman codes.  Codes 286 and 287
++      cannot be used though, since there is no length base or extra bits
++      defined for them.  Similarly, there are up to 30 distance codes.
++      However, static trees define 32 codes (all 5 bits) to fill out the
++      Huffman codes, but the last two had better not show up in the data.
++   7. Unzip can check dynamic Huffman blocks for complete code sets.
++      The exception is that a single code would not be complete (see #4).
++   8. The five bits following the block type is really the number of
++      literal codes sent minus 257.
++   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
++      (1+6+6).  Therefore, to output three times the length, you output
++      three codes (1+1+1), whereas to output four times the same length,
++      you only need two codes (1+3).  Hmm.
++  10. In the tree reconstruction algorithm, Code = Code + Increment
++      only if BitLength(i) is not zero.  (Pretty obvious.)
++  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
++  12. Note: length code 284 can represent 227-258, but length code 285
++      really is 258.  The last length deserves its own, short code
++      since it gets used a lot in very redundant files.  The length
++      258 is special since 258 - 3 (the min match length) is 255.
++  13. The literal/length and distance code bit lengths are read as a
++      single stream of lengths.  It is possible (and advantageous) for
++      a repeat code (16, 17, or 18) to go across the boundary between
++      the two sets of lengths.
++ */
++#include <linux/compiler.h>
++#include <linux/slab.h>
++
++#ifdef RCSID
++static char rcsid[] = "#Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp #";
++#endif
++
++#ifndef STATIC
++
++#if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H)
++#  include <sys/types.h>
++#  include <stdlib.h>
++#endif
++
++#include "gzip.h"
++#define STATIC
++#endif /* !STATIC */
++
++#ifndef INIT
++#define INIT
++#endif
++	
++#define slide window
++
++/* Huffman code lookup table entry--this entry is four bytes for machines
++   that have 16-bit pointers (e.g. PC's in the small or medium model).
++   Valid extra bits are 0..13.  e == 15 is EOB (end of block), e == 16
++   means that v is a literal, 16 < e < 32 means that v is a pointer to
++   the next table, which codes e - 16 bits, and lastly e == 99 indicates
++   an unused code.  If a code with e == 99 is looked up, this implies an
++   error in the data. */
++struct huft {
++  uch e;                /* number of extra bits or operation */
++  uch b;                /* number of bits in this code or subcode */
++  union {
++    ush n;              /* literal, length base, or distance base */
++    struct huft *t;     /* pointer to next level of table */
++  } v;
++};
++
++
++/* Function prototypes */
++STATIC int INIT huft_build OF((unsigned *, unsigned, unsigned, 
++		const ush *, const ush *, struct huft **, int *));
++STATIC int INIT huft_free OF((struct huft *));
++STATIC int INIT inflate_codes OF((struct huft *, struct huft *, int, int));
++STATIC int INIT inflate_stored OF((void));
++STATIC int INIT inflate_fixed OF((void));
++STATIC int INIT inflate_dynamic OF((void));
++STATIC int INIT inflate_block OF((int *));
++STATIC int INIT inflate OF((void));
++
++
++/* The inflate algorithm uses a sliding 32 K byte window on the uncompressed
++   stream to find repeated byte strings.  This is implemented here as a
++   circular buffer.  The index is updated simply by incrementing and then
++   ANDing with 0x7fff (32K-1). */
++/* It is left to other modules to supply the 32 K area.  It is assumed
++   to be usable as if it were declared "uch slide[32768];" or as just
++   "uch *slide;" and then malloc'ed in the latter case.  The definition
++   must be in unzip.h, included above. */
++/* unsigned wp;             current position in slide */
++#define wp outcnt
++#define flush_output(w) (wp=(w),flush_window())
++
++/* Tables for deflate from PKZIP's appnote.txt. */
++static const unsigned border[] = {    /* Order of the bit length code lengths */
++        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
++static const ush cplens[] = {         /* Copy lengths for literal codes 257..285 */
++        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
++        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
++        /* note: see note #13 above about the 258 in this list. */
++static const ush cplext[] = {         /* Extra bits for literal codes 257..285 */
++        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
++        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
++static const ush cpdist[] = {         /* Copy offsets for distance codes 0..29 */
++        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
++        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
++        8193, 12289, 16385, 24577};
++static const ush cpdext[] = {         /* Extra bits for distance codes */
++        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
++        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
++        12, 12, 13, 13};
++
++
++
++/* Macros for inflate() bit peeking and grabbing.
++   The usage is:
++   
++        NEEDBITS(j)
++        x = b & mask_bits[j];
++        DUMPBITS(j)
++
++   where NEEDBITS makes sure that b has at least j bits in it, and
++   DUMPBITS removes the bits from b.  The macros use the variable k
++   for the number of bits in b.  Normally, b and k are register
++   variables for speed, and are initialized at the beginning of a
++   routine that uses these macros from a global bit buffer and count.
++
++   If we assume that EOB will be the longest code, then we will never
++   ask for bits with NEEDBITS that are beyond the end of the stream.
++   So, NEEDBITS should not read any more bytes than are needed to
++   meet the request.  Then no bytes need to be "returned" to the buffer
++   at the end of the last block.
++
++   However, this assumption is not true for fixed blocks--the EOB code
++   is 7 bits, but the other literal/length codes can be 8 or 9 bits.
++   (The EOB code is shorter than other codes because fixed blocks are
++   generally short.  So, while a block always has an EOB, many other
++   literal/length codes have a significantly lower probability of
++   showing up at all.)  However, by making the first table have a
++   lookup of seven bits, the EOB code will be found in that first
++   lookup, and so will not require that too many bits be pulled from
++   the stream.
++ */
++
++STATIC ulg bb;                         /* bit buffer */
++STATIC unsigned bk;                    /* bits in bit buffer */
++
++STATIC const ush mask_bits[] = {
++    0x0000,
++    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
++    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
++};
++
++#define NEXTBYTE()  ({ int v = get_byte(); if (v < 0) goto underrun; (uch)v; })
++#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}}
++#define DUMPBITS(n) {b>>=(n);k-=(n);}
++
++#ifndef NO_INFLATE_MALLOC
++/* A trivial malloc implementation, adapted from
++ *  malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
++ */
++
++static unsigned long malloc_ptr;
++static int malloc_count;
++
++static void *malloc(int size)
++{
++       void *p;
++
++       if (size < 0)
++		error("Malloc error");
++       if (!malloc_ptr)
++		malloc_ptr = free_mem_ptr;
++
++       malloc_ptr = (malloc_ptr + 3) & ~3;     /* Align */
++
++       p = (void *)malloc_ptr;
++       malloc_ptr += size;
++
++       if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
++		error("Out of memory");
++
++       malloc_count++;
++       return p;
++}
++
++static void free(void *where)
++{
++       malloc_count--;
++       if (!malloc_count)
++		malloc_ptr = free_mem_ptr;
++}
++#else
++#define malloc(a) kmalloc(a, GFP_KERNEL)
++#define free(a) kfree(a)
++#endif
++
++/*
++   Huffman code decoding is performed using a multi-level table lookup.
++   The fastest way to decode is to simply build a lookup table whose
++   size is determined by the longest code.  However, the time it takes
++   to build this table can also be a factor if the data being decoded
++   is not very long.  The most common codes are necessarily the
++   shortest codes, so those codes dominate the decoding time, and hence
++   the speed.  The idea is you can have a shorter table that decodes the
++   shorter, more probable codes, and then point to subsidiary tables for
++   the longer codes.  The time it costs to decode the longer codes is
++   then traded against the time it takes to make longer tables.
++
++   This results of this trade are in the variables lbits and dbits
++   below.  lbits is the number of bits the first level table for literal/
++   length codes can decode in one step, and dbits is the same thing for
++   the distance codes.  Subsequent tables are also less than or equal to
++   those sizes.  These values may be adjusted either when all of the
++   codes are shorter than that, in which case the longest code length in
++   bits is used, or when the shortest code is *longer* than the requested
++   table size, in which case the length of the shortest code in bits is
++   used.
++
++   There are two different values for the two tables, since they code a
++   different number of possibilities each.  The literal/length table
++   codes 286 possible values, or in a flat code, a little over eight
++   bits.  The distance table codes 30 possible values, or a little less
++   than five bits, flat.  The optimum values for speed end up being
++   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
++   The optimum values may differ though from machine to machine, and
++   possibly even between compilers.  Your mileage may vary.
++ */
++
++
++STATIC const int lbits = 9;          /* bits in base literal/length lookup table */
++STATIC const int dbits = 6;          /* bits in base distance lookup table */
++
++
++/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
++#define BMAX 16         /* maximum bit length of any code (16 for explode) */
++#define N_MAX 288       /* maximum number of codes in any set */
++
++
++STATIC unsigned hufts;         /* track memory usage */
++
++
++STATIC int INIT huft_build(
++	unsigned *b,            /* code lengths in bits (all assumed <= BMAX) */
++	unsigned n,             /* number of codes (assumed <= N_MAX) */
++	unsigned s,             /* number of simple-valued codes (0..s-1) */
++	const ush *d,           /* list of base values for non-simple codes */
++	const ush *e,           /* list of extra bits for non-simple codes */
++	struct huft **t,        /* result: starting table */
++	int *m                  /* maximum lookup bits, returns actual */
++	)
++/* Given a list of code lengths and a maximum table size, make a set of
++   tables to decode that set of codes.  Return zero on success, one if
++   the given code set is incomplete (the tables are still built in this
++   case), two if the input is invalid (all zero length codes or an
++   oversubscribed set of lengths), and three if not enough memory. */
++{
++  unsigned a;                   /* counter for codes of length k */
++  unsigned f;                   /* i repeats in table every f entries */
++  int g;                        /* maximum code length */
++  int h;                        /* table level */
++  register unsigned i;          /* counter, current code */
++  register unsigned j;          /* counter */
++  register int k;               /* number of bits in current code */
++  int l;                        /* bits per table (returned in m) */
++  register unsigned *p;         /* pointer into c[], b[], or v[] */
++  register struct huft *q;      /* points to current table */
++  struct huft r;                /* table entry for structure assignment */
++  register int w;               /* bits before this table == (l * h) */
++  unsigned *xp;                 /* pointer into x */
++  int y;                        /* number of dummy codes added */
++  unsigned z;                   /* number of entries in current table */
++  struct {
++    unsigned c[BMAX+1];           /* bit length count table */
++    struct huft *u[BMAX];         /* table stack */
++    unsigned v[N_MAX];            /* values in order of bit length */
++    unsigned x[BMAX+1];           /* bit offsets, then code stack */
++  } *stk;
++  unsigned *c, *v, *x;
++  struct huft **u;
++  int ret;
++
++DEBG("huft1 ");
++
++  stk = malloc(sizeof(*stk));
++  if (stk == NULL)
++    return 3;			/* out of memory */
++
++  c = stk->c;
++  v = stk->v;
++  x = stk->x;
++  u = stk->u;
++
++  /* Generate counts for each bit length */
++  memzero(stk->c, sizeof(stk->c));
++  p = b;  i = n;
++  do {
++    Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), 
++	    n-i, *p));
++    c[*p]++;                    /* assume all entries <= BMAX */
++    p++;                      /* Can't combine with above line (Solaris bug) */
++  } while (--i);
++  if (c[0] == n)                /* null input--all zero length codes */
++  {
++    *t = (struct huft *)NULL;
++    *m = 0;
++    ret = 2;
++    goto out;
++  }
++
++DEBG("huft2 ");
++
++  /* Find minimum and maximum length, bound *m by those */
++  l = *m;
++  for (j = 1; j <= BMAX; j++)
++    if (c[j])
++      break;
++  k = j;                        /* minimum code length */
++  if ((unsigned)l < j)
++    l = j;
++  for (i = BMAX; i; i--)
++    if (c[i])
++      break;
++  g = i;                        /* maximum code length */
++  if ((unsigned)l > i)
++    l = i;
++  *m = l;
++
++DEBG("huft3 ");
++
++  /* Adjust last length count to fill out codes, if needed */
++  for (y = 1 << j; j < i; j++, y <<= 1)
++    if ((y -= c[j]) < 0) {
++      ret = 2;                 /* bad input: more codes than bits */
++      goto out;
++    }
++  if ((y -= c[i]) < 0) {
++    ret = 2;
++    goto out;
++  }
++  c[i] += y;
++
++DEBG("huft4 ");
++
++  /* Generate starting offsets into the value table for each length */
++  x[1] = j = 0;
++  p = c + 1;  xp = x + 2;
++  while (--i) {                 /* note that i == g from above */
++    *xp++ = (j += *p++);
++  }
++
++DEBG("huft5 ");
++
++  /* Make a table of values in order of bit lengths */
++  p = b;  i = 0;
++  do {
++    if ((j = *p++) != 0)
++      v[x[j]++] = i;
++  } while (++i < n);
++  n = x[g];                   /* set n to length of v */
++
++DEBG("h6 ");
++
++  /* Generate the Huffman codes and for each, make the table entries */
++  x[0] = i = 0;                 /* first Huffman code is zero */
++  p = v;                        /* grab values in bit order */
++  h = -1;                       /* no tables yet--level -1 */
++  w = -l;                       /* bits decoded == (l * h) */
++  u[0] = (struct huft *)NULL;   /* just to keep compilers happy */
++  q = (struct huft *)NULL;      /* ditto */
++  z = 0;                        /* ditto */
++DEBG("h6a ");
++
++  /* go through the bit lengths (k already is bits in shortest code) */
++  for (; k <= g; k++)
++  {
++DEBG("h6b ");
++    a = c[k];
++    while (a--)
++    {
++DEBG("h6b1 ");
++      /* here i is the Huffman code of length k bits for value *p */
++      /* make tables up to required level */
++      while (k > w + l)
++      {
++DEBG1("1 ");
++        h++;
++        w += l;                 /* previous table always l bits */
++
++        /* compute minimum size table less than or equal to l bits */
++        z = (z = g - w) > (unsigned)l ? l : z;  /* upper limit on table size */
++        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
++        {                       /* too few codes for k-w bit table */
++DEBG1("2 ");
++          f -= a + 1;           /* deduct codes from patterns left */
++          xp = c + k;
++          if (j < z)
++            while (++j < z)       /* try smaller tables up to z bits */
++            {
++              if ((f <<= 1) <= *++xp)
++                break;            /* enough codes to use up j bits */
++              f -= *xp;           /* else deduct codes from patterns */
++            }
++        }
++DEBG1("3 ");
++        z = 1 << j;             /* table entries for j-bit table */
++
++        /* allocate and link in new table */
++        if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) ==
++            (struct huft *)NULL)
++        {
++          if (h)
++            huft_free(u[0]);
++          ret = 3;             /* not enough memory */
++	  goto out;
++        }
++DEBG1("4 ");
++        hufts += z + 1;         /* track memory usage */
++        *t = q + 1;             /* link to list for huft_free() */
++        *(t = &(q->v.t)) = (struct huft *)NULL;
++        u[h] = ++q;             /* table starts after link */
++
++DEBG1("5 ");
++        /* connect to last table, if there is one */
++        if (h)
++        {
++          x[h] = i;             /* save pattern for backing up */
++          r.b = (uch)l;         /* bits to dump before this table */
++          r.e = (uch)(16 + j);  /* bits in this table */
++          r.v.t = q;            /* pointer to this table */
++          j = i >> (w - l);     /* (get around Turbo C bug) */
++          u[h-1][j] = r;        /* connect to last table */
++        }
++DEBG1("6 ");
++      }
++DEBG("h6c ");
++
++      /* set up table entry in r */
++      r.b = (uch)(k - w);
++      if (p >= v + n)
++        r.e = 99;               /* out of values--invalid code */
++      else if (*p < s)
++      {
++        r.e = (uch)(*p < 256 ? 16 : 15);    /* 256 is end-of-block code */
++        r.v.n = (ush)(*p);             /* simple code is just the value */
++	p++;                           /* one compiler does not like *p++ */
++      }
++      else
++      {
++        r.e = (uch)e[*p - s];   /* non-simple--look up in lists */
++        r.v.n = d[*p++ - s];
++      }
++DEBG("h6d ");
++
++      /* fill code-like entries with r */
++      f = 1 << (k - w);
++      for (j = i >> w; j < z; j += f)
++        q[j] = r;
++
++      /* backwards increment the k-bit code i */
++      for (j = 1 << (k - 1); i & j; j >>= 1)
++        i ^= j;
++      i ^= j;
++
++      /* backup over finished tables */
++      while ((i & ((1 << w) - 1)) != x[h])
++      {
++        h--;                    /* don't need to update q */
++        w -= l;
++      }
++DEBG("h6e ");
++    }
++DEBG("h6f ");
++  }
++
++DEBG("huft7 ");
++
++  /* Return true (1) if we were given an incomplete table */
++  ret = y != 0 && g != 1;
++
++  out:
++  free(stk);
++  return ret;
++}
++
++
++
++STATIC int INIT huft_free(
++	struct huft *t         /* table to free */
++	)
++/* Free the malloc'ed tables built by huft_build(), which makes a linked
++   list of the tables it made, with the links in a dummy first entry of
++   each table. */
++{
++  register struct huft *p, *q;
++
++
++  /* Go through linked list, freeing from the malloced (t[-1]) address. */
++  p = t;
++  while (p != (struct huft *)NULL)
++  {
++    q = (--p)->v.t;
++    free((char*)p);
++    p = q;
++  } 
++  return 0;
++}
++
++
++STATIC int INIT inflate_codes(
++	struct huft *tl,    /* literal/length decoder tables */
++	struct huft *td,    /* distance decoder tables */
++	int bl,             /* number of bits decoded by tl[] */
++	int bd              /* number of bits decoded by td[] */
++	)
++/* inflate (decompress) the codes in a deflated (compressed) block.
++   Return an error code or zero if it all goes ok. */
++{
++  register unsigned e;  /* table entry flag/number of extra bits */
++  unsigned n, d;        /* length and index for copy */
++  unsigned w;           /* current window position */
++  struct huft *t;       /* pointer to table entry */
++  unsigned ml, md;      /* masks for bl and bd bits */
++  register ulg b;       /* bit buffer */
++  register unsigned k;  /* number of bits in bit buffer */
++
++
++  /* make local copies of globals */
++  b = bb;                       /* initialize bit buffer */
++  k = bk;
++  w = wp;                       /* initialize window position */
++
++  /* inflate the coded data */
++  ml = mask_bits[bl];           /* precompute masks for speed */
++  md = mask_bits[bd];
++  for (;;)                      /* do until end of block */
++  {
++    NEEDBITS((unsigned)bl)
++    if ((e = (t = tl + ((unsigned)b & ml))->e) > 16)
++      do {
++        if (e == 99)
++          return 1;
++        DUMPBITS(t->b)
++        e -= 16;
++        NEEDBITS(e)
++      } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
++    DUMPBITS(t->b)
++    if (e == 16)                /* then it's a literal */
++    {
++      slide[w++] = (uch)t->v.n;
++      Tracevv((stderr, "%c", slide[w-1]));
++      if (w == WSIZE)
++      {
++        flush_output(w);
++        w = 0;
++      }
++    }
++    else                        /* it's an EOB or a length */
++    {
++      /* exit if end of block */
++      if (e == 15)
++        break;
++
++      /* get length of block to copy */
++      NEEDBITS(e)
++      n = t->v.n + ((unsigned)b & mask_bits[e]);
++      DUMPBITS(e);
++
++      /* decode distance of block to copy */
++      NEEDBITS((unsigned)bd)
++      if ((e = (t = td + ((unsigned)b & md))->e) > 16)
++        do {
++          if (e == 99)
++            return 1;
++          DUMPBITS(t->b)
++          e -= 16;
++          NEEDBITS(e)
++        } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16);
++      DUMPBITS(t->b)
++      NEEDBITS(e)
++      d = w - t->v.n - ((unsigned)b & mask_bits[e]);
++      DUMPBITS(e)
++      Tracevv((stderr,"\\[%d,%d]", w-d, n));
++
++      /* do the copy */
++      do {
++        n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e);
++#if !defined(NOMEMCPY) && !defined(DEBUG)
++        if (w - d >= e)         /* (this test assumes unsigned comparison) */
++        {
++          memcpy(slide + w, slide + d, e);
++          w += e;
++          d += e;
++        }
++        else                      /* do it slow to avoid memcpy() overlap */
++#endif /* !NOMEMCPY */
++          do {
++            slide[w++] = slide[d++];
++	    Tracevv((stderr, "%c", slide[w-1]));
++          } while (--e);
++        if (w == WSIZE)
++        {
++          flush_output(w);
++          w = 0;
++        }
++      } while (n);
++    }
++  }
++
++
++  /* restore the globals from the locals */
++  wp = w;                       /* restore global window pointer */
++  bb = b;                       /* restore global bit buffer */
++  bk = k;
++
++  /* done */
++  return 0;
++
++ underrun:
++  return 4;			/* Input underrun */
++}
++
++
++
++STATIC int INIT inflate_stored(void)
++/* "decompress" an inflated type 0 (stored) block. */
++{
++  unsigned n;           /* number of bytes in block */
++  unsigned w;           /* current window position */
++  register ulg b;       /* bit buffer */
++  register unsigned k;  /* number of bits in bit buffer */
++
++DEBG("<stor");
++
++  /* make local copies of globals */
++  b = bb;                       /* initialize bit buffer */
++  k = bk;
++  w = wp;                       /* initialize window position */
++
++
++  /* go to byte boundary */
++  n = k & 7;
++  DUMPBITS(n);
++
++
++  /* get the length and its complement */
++  NEEDBITS(16)
++  n = ((unsigned)b & 0xffff);
++  DUMPBITS(16)
++  NEEDBITS(16)
++  if (n != (unsigned)((~b) & 0xffff))
++    return 1;                   /* error in compressed data */
++  DUMPBITS(16)
++
++
++  /* read and output the compressed data */
++  while (n--)
++  {
++    NEEDBITS(8)
++    slide[w++] = (uch)b;
++    if (w == WSIZE)
++    {
++      flush_output(w);
++      w = 0;
++    }
++    DUMPBITS(8)
++  }
++
++
++  /* restore the globals from the locals */
++  wp = w;                       /* restore global window pointer */
++  bb = b;                       /* restore global bit buffer */
++  bk = k;
++
++  DEBG(">");
++  return 0;
++
++ underrun:
++  return 4;			/* Input underrun */
++}
++
++
++/*
++ * We use `noinline' here to prevent gcc-3.5 from using too much stack space
++ */
++STATIC int noinline INIT inflate_fixed(void)
++/* decompress an inflated type 1 (fixed Huffman codes) block.  We should
++   either replace this with a custom decoder, or at least precompute the
++   Huffman tables. */
++{
++  int i;                /* temporary variable */
++  struct huft *tl;      /* literal/length code table */
++  struct huft *td;      /* distance code table */
++  int bl;               /* lookup bits for tl */
++  int bd;               /* lookup bits for td */
++  unsigned *l;          /* length list for huft_build */
++
++DEBG("<fix");
++
++  l = malloc(sizeof(*l) * 288);
++  if (l == NULL)
++    return 3;			/* out of memory */
++
++  /* set up literal table */
++  for (i = 0; i < 144; i++)
++    l[i] = 8;
++  for (; i < 256; i++)
++    l[i] = 9;
++  for (; i < 280; i++)
++    l[i] = 7;
++  for (; i < 288; i++)          /* make a complete, but wrong code set */
++    l[i] = 8;
++  bl = 7;
++  if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) {
++    free(l);
++    return i;
++  }
++
++  /* set up distance table */
++  for (i = 0; i < 30; i++)      /* make an incomplete code set */
++    l[i] = 5;
++  bd = 5;
++  if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1)
++  {
++    huft_free(tl);
++    free(l);
++
++    DEBG(">");
++    return i;
++  }
++
++
++  /* decompress until an end-of-block code */
++  if (inflate_codes(tl, td, bl, bd)) {
++    free(l);
++    return 1;
++  }
++
++  /* free the decoding tables, return */
++  free(l);
++  huft_free(tl);
++  huft_free(td);
++  return 0;
++}
++
++
++/*
++ * We use `noinline' here to prevent gcc-3.5 from using too much stack space
++ */
++STATIC int noinline INIT inflate_dynamic(void)
++/* decompress an inflated type 2 (dynamic Huffman codes) block. */
++{
++  int i;                /* temporary variables */
++  unsigned j;
++  unsigned l;           /* last length */
++  unsigned m;           /* mask for bit lengths table */
++  unsigned n;           /* number of lengths to get */
++  struct huft *tl;      /* literal/length code table */
++  struct huft *td;      /* distance code table */
++  int bl;               /* lookup bits for tl */
++  int bd;               /* lookup bits for td */
++  unsigned nb;          /* number of bit length codes */
++  unsigned nl;          /* number of literal/length codes */
++  unsigned nd;          /* number of distance codes */
++  unsigned *ll;         /* literal/length and distance code lengths */
++  register ulg b;       /* bit buffer */
++  register unsigned k;  /* number of bits in bit buffer */
++  int ret;
++
++DEBG("<dyn");
++
++#ifdef PKZIP_BUG_WORKAROUND
++  ll = malloc(sizeof(*ll) * (288+32));  /* literal/length and distance code lengths */
++#else
++  ll = malloc(sizeof(*ll) * (286+30));  /* literal/length and distance code lengths */
++#endif
++
++  if (ll == NULL)
++    return 1;
++
++  /* make local bit buffer */
++  b = bb;
++  k = bk;
++
++
++  /* read in table lengths */
++  NEEDBITS(5)
++  nl = 257 + ((unsigned)b & 0x1f);      /* number of literal/length codes */
++  DUMPBITS(5)
++  NEEDBITS(5)
++  nd = 1 + ((unsigned)b & 0x1f);        /* number of distance codes */
++  DUMPBITS(5)
++  NEEDBITS(4)
++  nb = 4 + ((unsigned)b & 0xf);         /* number of bit length codes */
++  DUMPBITS(4)
++#ifdef PKZIP_BUG_WORKAROUND
++  if (nl > 288 || nd > 32)
++#else
++  if (nl > 286 || nd > 30)
++#endif
++  {
++    ret = 1;             /* bad lengths */
++    goto out;
++  }
++
++DEBG("dyn1 ");
++
++  /* read in bit-length-code lengths */
++  for (j = 0; j < nb; j++)
++  {
++    NEEDBITS(3)
++    ll[border[j]] = (unsigned)b & 7;
++    DUMPBITS(3)
++  }
++  for (; j < 19; j++)
++    ll[border[j]] = 0;
++
++DEBG("dyn2 ");
++
++  /* build decoding table for trees--single level, 7 bit lookup */
++  bl = 7;
++  if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0)
++  {
++    if (i == 1)
++      huft_free(tl);
++    ret = i;                   /* incomplete code set */
++    goto out;
++  }
++
++DEBG("dyn3 ");
++
++  /* read in literal and distance code lengths */
++  n = nl + nd;
++  m = mask_bits[bl];
++  i = l = 0;
++  while ((unsigned)i < n)
++  {
++    NEEDBITS((unsigned)bl)
++    j = (td = tl + ((unsigned)b & m))->b;
++    DUMPBITS(j)
++    j = td->v.n;
++    if (j < 16)                 /* length of code in bits (0..15) */
++      ll[i++] = l = j;          /* save last length in l */
++    else if (j == 16)           /* repeat last length 3 to 6 times */
++    {
++      NEEDBITS(2)
++      j = 3 + ((unsigned)b & 3);
++      DUMPBITS(2)
++      if ((unsigned)i + j > n) {
++        ret = 1;
++	goto out;
++      }
++      while (j--)
++        ll[i++] = l;
++    }
++    else if (j == 17)           /* 3 to 10 zero length codes */
++    {
++      NEEDBITS(3)
++      j = 3 + ((unsigned)b & 7);
++      DUMPBITS(3)
++      if ((unsigned)i + j > n) {
++        ret = 1;
++	goto out;
++      }
++      while (j--)
++        ll[i++] = 0;
++      l = 0;
++    }
++    else                        /* j == 18: 11 to 138 zero length codes */
++    {
++      NEEDBITS(7)
++      j = 11 + ((unsigned)b & 0x7f);
++      DUMPBITS(7)
++      if ((unsigned)i + j > n) {
++        ret = 1;
++	goto out;
++      }
++      while (j--)
++        ll[i++] = 0;
++      l = 0;
++    }
++  }
++
++DEBG("dyn4 ");
++
++  /* free decoding table for trees */
++  huft_free(tl);
++
++DEBG("dyn5 ");
++
++  /* restore the global bit buffer */
++  bb = b;
++  bk = k;
++
++DEBG("dyn5a ");
++
++  /* build the decoding tables for literal/length and distance codes */
++  bl = lbits;
++  if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0)
++  {
++DEBG("dyn5b ");
++    if (i == 1) {
++      error("incomplete literal tree");
++      huft_free(tl);
++    }
++    ret = i;                   /* incomplete code set */
++    goto out;
++  }
++DEBG("dyn5c ");
++  bd = dbits;
++  if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0)
++  {
++DEBG("dyn5d ");
++    if (i == 1) {
++      error("incomplete distance tree");
++#ifdef PKZIP_BUG_WORKAROUND
++      i = 0;
++    }
++#else
++      huft_free(td);
++    }
++    huft_free(tl);
++    ret = i;                   /* incomplete code set */
++    goto out;
++#endif
++  }
++
++DEBG("dyn6 ");
++
++  /* decompress until an end-of-block code */
++  if (inflate_codes(tl, td, bl, bd)) {
++    ret = 1;
++    goto out;
++  }
++
++DEBG("dyn7 ");
++
++  /* free the decoding tables, return */
++  huft_free(tl);
++  huft_free(td);
++
++  DEBG(">");
++  ret = 0;
++out:
++  free(ll);
++  return ret;
++
++underrun:
++  ret = 4;			/* Input underrun */
++  goto out;
++}
++
++
++
++STATIC int INIT inflate_block(
++	int *e                  /* last block flag */
++	)
++/* decompress an inflated block */
++{
++  unsigned t;           /* block type */
++  register ulg b;       /* bit buffer */
++  register unsigned k;  /* number of bits in bit buffer */
++
++  DEBG("<blk");
++
++  /* make local bit buffer */
++  b = bb;
++  k = bk;
++
++
++  /* read in last block bit */
++  NEEDBITS(1)
++  *e = (int)b & 1;
++  DUMPBITS(1)
++
++
++  /* read in block type */
++  NEEDBITS(2)
++  t = (unsigned)b & 3;
++  DUMPBITS(2)
++
++
++  /* restore the global bit buffer */
++  bb = b;
++  bk = k;
++
++  /* inflate that block type */
++  if (t == 2)
++    return inflate_dynamic();
++  if (t == 0)
++    return inflate_stored();
++  if (t == 1)
++    return inflate_fixed();
++
++  DEBG(">");
++
++  /* bad block type */
++  return 2;
++
++ underrun:
++  return 4;			/* Input underrun */
++}
++
++
++
++STATIC int INIT inflate(void)
++/* decompress an inflated entry */
++{
++  int e;                /* last block flag */
++  int r;                /* result code */
++  unsigned h;           /* maximum struct huft's malloc'ed */
++
++  /* initialize window, bit buffer */
++  wp = 0;
++  bk = 0;
++  bb = 0;
++
++
++  /* decompress until the last block */
++  h = 0;
++  do {
++    hufts = 0;
++#ifdef ARCH_HAS_DECOMP_WDOG
++    arch_decomp_wdog();
++#endif
++    r = inflate_block(&e);
++    if (r)
++	    return r;
++    if (hufts > h)
++      h = hufts;
++  } while (!e);
++
++  /* Undo too much lookahead. The next read will be byte aligned so we
++   * can discard unused bits in the last meaningful byte.
++   */
++  while (bk >= 8) {
++    bk -= 8;
++    inptr--;
++  }
++
++  /* flush out slide */
++  flush_output(wp);
++
++
++  /* return success */
++#ifdef DEBUG
++  fprintf(stderr, "<%u> ", h);
++#endif /* DEBUG */
++  return 0;
++}
++
++/**********************************************************************
++ *
++ * The following are support routines for inflate.c
++ *
++ **********************************************************************/
++
++static ulg crc_32_tab[256];
++static ulg crc;		/* initialized in makecrc() so it'll reside in bss */
++#define CRC_VALUE (crc ^ 0xffffffffUL)
++
++/*
++ * Code to compute the CRC-32 table. Borrowed from 
++ * gzip-1.0.3/makecrc.c.
++ */
++
++static void INIT
++makecrc(void)
++{
++/* Not copyrighted 1990 Mark Adler	*/
++
++  unsigned long c;      /* crc shift register */
++  unsigned long e;      /* polynomial exclusive-or pattern */
++  int i;                /* counter for all possible eight bit values */
++  int k;                /* byte being shifted into crc apparatus */
++
++  /* terms of polynomial defining this crc (except x^32): */
++  static const int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
++
++  /* Make exclusive-or pattern from polynomial */
++  e = 0;
++  for (i = 0; i < sizeof(p)/sizeof(int); i++)
++    e |= 1L << (31 - p[i]);
++
++  crc_32_tab[0] = 0;
++
++  for (i = 1; i < 256; i++)
++  {
++    c = 0;
++    for (k = i | 256; k != 1; k >>= 1)
++    {
++      c = c & 1 ? (c >> 1) ^ e : c >> 1;
++      if (k & 1)
++        c ^= e;
++    }
++    crc_32_tab[i] = c;
++  }
++
++  /* this is initialized here so this code could reside in ROM */
++  crc = (ulg)0xffffffffUL; /* shift register contents */
++}
++
++/* gzip flag byte */
++#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
++#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
++#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
++#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
++#define COMMENT      0x10 /* bit 4 set: file comment present */
++#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
++#define RESERVED     0xC0 /* bit 6,7:   reserved */
++
++/*
++ * Do the uncompression!
++ */
++static int INIT gunzip(void)
++{
++    uch flags;
++    unsigned char magic[2]; /* magic header */
++    char method;
++    ulg orig_crc = 0;       /* original crc */
++    ulg orig_len = 0;       /* original uncompressed length */
++    int res;
++
++    magic[0] = NEXTBYTE();
++    magic[1] = NEXTBYTE();
++    method   = NEXTBYTE();
++
++    if (magic[0] != 037 ||
++	((magic[1] != 0213) && (magic[1] != 0236))) {
++	    error("bad gzip magic numbers");
++	    return -1;
++    }
++
++    /* We only support method #8, DEFLATED */
++    if (method != 8)  {
++	    error("internal error, invalid method");
++	    return -1;
++    }
++
++    flags  = (uch)get_byte();
++    if ((flags & ENCRYPTED) != 0) {
++	    error("Input is encrypted");
++	    return -1;
++    }
++    if ((flags & CONTINUATION) != 0) {
++	    error("Multi part input");
++	    return -1;
++    }
++    if ((flags & RESERVED) != 0) {
++	    error("Input has invalid flags");
++	    return -1;
++    }
++    NEXTBYTE();	/* Get timestamp */
++    NEXTBYTE();
++    NEXTBYTE();
++    NEXTBYTE();
++
++    (void)NEXTBYTE();  /* Ignore extra flags for the moment */
++    (void)NEXTBYTE();  /* Ignore OS type for the moment */
++
++    if ((flags & EXTRA_FIELD) != 0) {
++	    unsigned len = (unsigned)NEXTBYTE();
++	    len |= ((unsigned)NEXTBYTE())<<8;
++	    while (len--) (void)NEXTBYTE();
++    }
++
++    /* Get original file name if it was truncated */
++    if ((flags & ORIG_NAME) != 0) {
++	    /* Discard the old name */
++	    while (NEXTBYTE() != 0) /* null */ ;
++    } 
++
++    /* Discard file comment if any */
++    if ((flags & COMMENT) != 0) {
++	    while (NEXTBYTE() != 0) /* null */ ;
++    }
++
++    /* Decompress */
++    if ((res = inflate())) {
++	    switch (res) {
++	    case 0:
++		    break;
++	    case 1:
++		    error("invalid compressed format (err=1)");
++		    break;
++	    case 2:
++		    error("invalid compressed format (err=2)");
++		    break;
++	    case 3:
++		    error("out of memory");
++		    break;
++	    case 4:
++		    error("out of input data");
++		    break;
++	    default:
++		    error("invalid compressed format (other)");
++	    }
++	    return -1;
++    }
++	    
++    /* Get the crc and original length */
++    /* crc32  (see algorithm.doc)
++     * uncompressed input size modulo 2^32
++     */
++    orig_crc = (ulg) NEXTBYTE();
++    orig_crc |= (ulg) NEXTBYTE() << 8;
++    orig_crc |= (ulg) NEXTBYTE() << 16;
++    orig_crc |= (ulg) NEXTBYTE() << 24;
++    
++    orig_len = (ulg) NEXTBYTE();
++    orig_len |= (ulg) NEXTBYTE() << 8;
++    orig_len |= (ulg) NEXTBYTE() << 16;
++    orig_len |= (ulg) NEXTBYTE() << 24;
++    
++    /* Validate decompression */
++    if (orig_crc != CRC_VALUE) {
++	    error("crc error");
++	    return -1;
++    }
++    if (orig_len != bytes_out) {
++	    error("length error");
++	    return -1;
++    }
++    return 0;
++
++ underrun:			/* NEXTBYTE() goto's here if needed */
++    error("out of input data");
++    return -1;
++}
++
++
+diff -rupN linux-2.6.35.11/lib/kobject.c linux-2.6.35.11-ts7500/lib/kobject.c
+--- linux-2.6.35.11/lib/kobject.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/lib/kobject.c	2011-03-14 11:18:24.000000000 -0400
+@@ -795,10 +795,15 @@ static struct kset *kset_create(const ch
+ 	struct kset *kset;
+ 	int retval;
+ 
++   //printk("kset_create(%s), calling kzalloc()\n", name);
++   
+ 	kset = kzalloc(sizeof(*kset), GFP_KERNEL);
++   //printk("Got kset = 0x%08lX\n", kset);
+ 	if (!kset)
+ 		return NULL;
++   //printk("kset_create(%s) calling kobject_set_name()\n", name);
+ 	retval = kobject_set_name(&kset->kobj, name);
++   //printk("Got retval = %d\n", retval);
+ 	if (retval) {
+ 		kfree(kset);
+ 		return NULL;
+@@ -838,14 +843,19 @@ struct kset *kset_create_and_add(const c
+ 	struct kset *kset;
+ 	int error;
+ 
++  // printk("kset_create_and_add(%s), calling kset_create()\n", name);
++   
+ 	kset = kset_create(name, uevent_ops, parent_kobj);
++   //printk("got kset = 0x%08lX\n", kset);
+ 	if (!kset)
+ 		return NULL;
+ 	error = kset_register(kset);
++  // printk("Got error = %d\n", error);
+ 	if (error) {
+ 		kfree(kset);
+ 		return NULL;
+ 	}
++   //printk("kset_create_and_add(%s) is done\n", name);
+ 	return kset;
+ }
+ EXPORT_SYMBOL_GPL(kset_create_and_add);
+diff -rupN linux-2.6.35.11/Makefile linux-2.6.35.11-ts7500/Makefile
+--- linux-2.6.35.11/Makefile	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/Makefile	2011-03-14 11:18:24.000000000 -0400
+@@ -532,7 +532,7 @@ all: vmlinux
+ ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
+ KBUILD_CFLAGS	+= -Os
+ else
+-KBUILD_CFLAGS	+= -O2
++KBUILD_CFLAGS	+= -O3
+ endif
+ 
+ include $(srctree)/arch/$(SRCARCH)/Makefile
+diff -rupN linux-2.6.35.11/Makefile.orig linux-2.6.35.11-ts7500/Makefile.orig
+--- linux-2.6.35.11/Makefile.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/Makefile.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,1503 @@
++VERSION = 2
++PATCHLEVEL = 6
++SUBLEVEL = 35
++EXTRAVERSION = .11
++NAME = Yokohama
++
++# *DOCUMENTATION*
++# To see a list of typical targets execute "make help"
++# More info can be located in ./README
++# Comments in this file are targeted only to the developer, do not
++# expect to learn how to build the kernel reading this file.
++
++# Do not:
++# o  use make's built-in rules and variables
++#    (this increases performance and avoids hard-to-debug behaviour);
++# o  print "Entering directory ...";
++MAKEFLAGS += -rR --no-print-directory
++
++# Avoid funny character set dependencies
++unexport LC_ALL
++LC_COLLATE=C
++LC_NUMERIC=C
++export LC_COLLATE LC_NUMERIC
++
++# We are using a recursive build, so we need to do a little thinking
++# to get the ordering right.
++#
++# Most importantly: sub-Makefiles should only ever modify files in
++# their own directory. If in some directory we have a dependency on
++# a file in another dir (which doesn't happen often, but it's often
++# unavoidable when linking the built-in.o targets which finally
++# turn into vmlinux), we will call a sub make in that other dir, and
++# after that we are sure that everything which is in that other dir
++# is now up to date.
++#
++# The only cases where we need to modify files which have global
++# effects are thus separated out and done before the recursive
++# descending is started. They are now explicitly listed as the
++# prepare rule.
++
++# To put more focus on warnings, be less verbose as default
++# Use 'make V=1' to see the full commands
++
++ifeq ("$(origin V)", "command line")
++  KBUILD_VERBOSE = $(V)
++endif
++ifndef KBUILD_VERBOSE
++  KBUILD_VERBOSE = 0
++endif
++
++# Call a source code checker (by default, "sparse") as part of the
++# C compilation.
++#
++# Use 'make C=1' to enable checking of only re-compiled files.
++# Use 'make C=2' to enable checking of *all* source files, regardless
++# of whether they are re-compiled or not.
++#
++# See the file "Documentation/sparse.txt" for more details, including
++# where to get the "sparse" utility.
++
++ifeq ("$(origin C)", "command line")
++  KBUILD_CHECKSRC = $(C)
++endif
++ifndef KBUILD_CHECKSRC
++  KBUILD_CHECKSRC = 0
++endif
++
++# Use make M=dir to specify directory of external module to build
++# Old syntax make ... SUBDIRS=$PWD is still supported
++# Setting the environment variable KBUILD_EXTMOD take precedence
++ifdef SUBDIRS
++  KBUILD_EXTMOD ?= $(SUBDIRS)
++endif
++
++ifeq ("$(origin M)", "command line")
++  KBUILD_EXTMOD := $(M)
++endif
++
++# kbuild supports saving output files in a separate directory.
++# To locate output files in a separate directory two syntaxes are supported.
++# In both cases the working directory must be the root of the kernel src.
++# 1) O=
++# Use "make O=dir/to/store/output/files/"
++#
++# 2) Set KBUILD_OUTPUT
++# Set the environment variable KBUILD_OUTPUT to point to the directory
++# where the output files shall be placed.
++# export KBUILD_OUTPUT=dir/to/store/output/files/
++# make
++#
++# The O= assignment takes precedence over the KBUILD_OUTPUT environment
++# variable.
++
++
++# KBUILD_SRC is set on invocation of make in OBJ directory
++# KBUILD_SRC is not intended to be used by the regular user (for now)
++ifeq ($(KBUILD_SRC),)
++
++# OK, Make called in directory where kernel src resides
++# Do we want to locate output files in a separate directory?
++ifeq ("$(origin O)", "command line")
++  KBUILD_OUTPUT := $(O)
++endif
++
++# That's our default target when none is given on the command line
++PHONY := _all
++_all:
++
++# Cancel implicit rules on top Makefile
++$(CURDIR)/Makefile Makefile: ;
++
++ifneq ($(KBUILD_OUTPUT),)
++# Invoke a second make in the output directory, passing relevant variables
++# check that the output directory actually exists
++saved-output := $(KBUILD_OUTPUT)
++KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)
++$(if $(KBUILD_OUTPUT),, \
++     $(error output directory "$(saved-output)" does not exist))
++
++PHONY += $(MAKECMDGOALS) sub-make
++
++$(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make
++	$(Q)@:
++
++sub-make: FORCE
++	$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
++	KBUILD_SRC=$(CURDIR) \
++	KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile \
++	$(filter-out _all sub-make,$(MAKECMDGOALS))
++
++# Leave processing to above invocation of make
++skip-makefile := 1
++endif # ifneq ($(KBUILD_OUTPUT),)
++endif # ifeq ($(KBUILD_SRC),)
++
++# We process the rest of the Makefile if this is the final invocation of make
++ifeq ($(skip-makefile),)
++
++# If building an external module we do not care about the all: rule
++# but instead _all depend on modules
++PHONY += all
++ifeq ($(KBUILD_EXTMOD),)
++_all: all
++else
++_all: modules
++endif
++
++srctree		:= $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
++objtree		:= $(CURDIR)
++src		:= $(srctree)
++obj		:= $(objtree)
++
++VPATH		:= $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
++
++export srctree objtree VPATH
++
++
++# SUBARCH tells the usermode build what the underlying arch is.  That is set
++# first, and if a usermode build is happening, the "ARCH=um" on the command
++# line overrides the setting of ARCH below.  If a native build is happening,
++# then ARCH is assigned, getting whatever value it gets normally, and 
++# SUBARCH is subsequently ignored.
++
++SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
++				  -e s/arm.*/arm/ -e s/sa110/arm/ \
++				  -e s/s390x/s390/ -e s/parisc64/parisc/ \
++				  -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
++				  -e s/sh[234].*/sh/ )
++
++# Cross compiling and selecting different set of gcc/bin-utils
++# ---------------------------------------------------------------------------
++#
++# When performing cross compilation for other architectures ARCH shall be set
++# to the target architecture. (See arch/* for the possibilities).
++# ARCH can be set during invocation of make:
++# make ARCH=ia64
++# Another way is to have ARCH set in the environment.
++# The default ARCH is the host where make is executed.
++
++# CROSS_COMPILE specify the prefix used for all executables used
++# during compilation. Only gcc and related bin-utils executables
++# are prefixed with $(CROSS_COMPILE).
++# CROSS_COMPILE can be set on the command line
++# make CROSS_COMPILE=ia64-linux-
++# Alternatively CROSS_COMPILE can be set in the environment.
++# A third alternative is to store a setting in .config so that plain
++# "make" in the configured kernel build directory always uses that.
++# Default value for CROSS_COMPILE is not to prefix executables
++# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
++export KBUILD_BUILDHOST := $(SUBARCH)
++ARCH		?= $(SUBARCH)
++CROSS_COMPILE	?=
++CROSS_COMPILE	?= $(CONFIG_CROSS_COMPILE:"%"=%)
++
++# Architecture as present in compile.h
++UTS_MACHINE 	:= $(ARCH)
++SRCARCH 	:= $(ARCH)
++
++# Additional ARCH settings for x86
++ifeq ($(ARCH),i386)
++        SRCARCH := x86
++endif
++ifeq ($(ARCH),x86_64)
++        SRCARCH := x86
++endif
++
++# Additional ARCH settings for sparc
++ifeq ($(ARCH),sparc64)
++       SRCARCH := sparc
++endif
++
++# Additional ARCH settings for sh
++ifeq ($(ARCH),sh64)
++       SRCARCH := sh
++endif
++
++# Where to locate arch specific headers
++hdr-arch  := $(SRCARCH)
++
++ifeq ($(ARCH),m68knommu)
++       hdr-arch  := m68k
++endif
++
++KCONFIG_CONFIG	?= .config
++
++# SHELL used by kbuild
++CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
++	  else if [ -x /bin/bash ]; then echo /bin/bash; \
++	  else echo sh; fi ; fi)
++
++HOSTCC       = gcc
++HOSTCXX      = g++
++HOSTCFLAGS   = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
++HOSTCXXFLAGS = -O2
++
++# Decide whether to build built-in, modular, or both.
++# Normally, just do built-in.
++
++KBUILD_MODULES :=
++KBUILD_BUILTIN := 1
++
++#	If we have only "make modules", don't compile built-in objects.
++#	When we're building modules with modversions, we need to consider
++#	the built-in objects during the descend as well, in order to
++#	make sure the checksums are up to date before we record them.
++
++ifeq ($(MAKECMDGOALS),modules)
++  KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
++endif
++
++#	If we have "make <whatever> modules", compile modules
++#	in addition to whatever we do anyway.
++#	Just "make" or "make all" shall build modules as well
++
++ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)
++  KBUILD_MODULES := 1
++endif
++
++ifeq ($(MAKECMDGOALS),)
++  KBUILD_MODULES := 1
++endif
++
++export KBUILD_MODULES KBUILD_BUILTIN
++export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
++
++# Beautify output
++# ---------------------------------------------------------------------------
++#
++# Normally, we echo the whole command before executing it. By making
++# that echo $($(quiet)$(cmd)), we now have the possibility to set
++# $(quiet) to choose other forms of output instead, e.g.
++#
++#         quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
++#         cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
++#
++# If $(quiet) is empty, the whole command will be printed.
++# If it is set to "quiet_", only the short version will be printed. 
++# If it is set to "silent_", nothing will be printed at all, since
++# the variable $(silent_cmd_cc_o_c) doesn't exist.
++#
++# A simple variant is to prefix commands with $(Q) - that's useful
++# for commands that shall be hidden in non-verbose mode.
++#
++#	$(Q)ln $@ :<
++#
++# If KBUILD_VERBOSE equals 0 then the above command will be hidden.
++# If KBUILD_VERBOSE equals 1 then the above command is displayed.
++
++ifeq ($(KBUILD_VERBOSE),1)
++  quiet =
++  Q =
++else
++  quiet=quiet_
++  Q = @
++endif
++
++# If the user is running make -s (silent mode), suppress echoing of
++# commands
++
++ifneq ($(findstring s,$(MAKEFLAGS)),)
++  quiet=silent_
++endif
++
++export quiet Q KBUILD_VERBOSE
++
++
++# Look for make include files relative to root of kernel src
++MAKEFLAGS += --include-dir=$(srctree)
++
++# We need some generic definitions (do not try to remake the file).
++$(srctree)/scripts/Kbuild.include: ;
++include $(srctree)/scripts/Kbuild.include
++
++# Make variables (CC, etc...)
++
++AS		= $(CROSS_COMPILE)as
++LD		= $(CROSS_COMPILE)ld
++CC		= $(CROSS_COMPILE)gcc
++CPP		= $(CC) -E
++AR		= $(CROSS_COMPILE)ar
++NM		= $(CROSS_COMPILE)nm
++STRIP		= $(CROSS_COMPILE)strip
++OBJCOPY		= $(CROSS_COMPILE)objcopy
++OBJDUMP		= $(CROSS_COMPILE)objdump
++AWK		= awk
++GENKSYMS	= scripts/genksyms/genksyms
++INSTALLKERNEL  := installkernel
++DEPMOD		= /sbin/depmod
++KALLSYMS	= scripts/kallsyms
++PERL		= perl
++CHECK		= sparse
++
++CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
++		  -Wbitwise -Wno-return-void $(CF)
++MODFLAGS	= -DMODULE
++CFLAGS_MODULE   = $(MODFLAGS)
++AFLAGS_MODULE   = $(MODFLAGS)
++LDFLAGS_MODULE  = -T $(srctree)/scripts/module-common.lds
++CFLAGS_KERNEL	=
++AFLAGS_KERNEL	=
++CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage
++
++
++# Use LINUXINCLUDE when you must reference the include/ directory.
++# Needed to be compatible with the O= option
++LINUXINCLUDE    := -I$(srctree)/arch/$(hdr-arch)/include -Iinclude \
++                   $(if $(KBUILD_SRC), -I$(srctree)/include) \
++                   -include include/generated/autoconf.h
++
++KBUILD_CPPFLAGS := -D__KERNEL__
++
++KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
++		   -fno-strict-aliasing -fno-common \
++		   -Werror-implicit-function-declaration \
++		   -Wno-format-security \
++		   -fno-delete-null-pointer-checks
++KBUILD_AFLAGS   := -D__ASSEMBLY__
++
++# Read KERNELRELEASE from include/config/kernel.release (if it exists)
++KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
++KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
++
++export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
++export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
++export CPP AR NM STRIP OBJCOPY OBJDUMP
++export MAKE AWK GENKSYMS INSTALLKERNEL PERL UTS_MACHINE
++export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
++
++export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
++export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
++export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
++
++# When compiling out-of-tree modules, put MODVERDIR in the module
++# tree rather than in the kernel tree. The kernel tree might
++# even be read-only.
++export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions
++
++# Files to ignore in find ... statements
++
++RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o
++export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg --exclude .git
++
++# ===========================================================================
++# Rules shared between *config targets and build targets
++
++# Basic helpers built in scripts/
++PHONY += scripts_basic
++scripts_basic:
++	$(Q)$(MAKE) $(build)=scripts/basic
++	$(Q)rm -f .tmp_quiet_recordmcount
++
++# To avoid any implicit rule to kick in, define an empty command.
++scripts/basic/%: scripts_basic ;
++
++PHONY += outputmakefile
++# outputmakefile generates a Makefile in the output directory, if using a
++# separate output directory. This allows convenient use of make in the
++# output directory.
++outputmakefile:
++ifneq ($(KBUILD_SRC),)
++	$(Q)ln -fsn $(srctree) source
++	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
++	    $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
++endif
++
++# To make sure we do not include .config for any of the *config targets
++# catch them early, and hand them over to scripts/kconfig/Makefile
++# It is allowed to specify more targets when calling make, including
++# mixing *config targets and build targets.
++# For example 'make oldconfig all'.
++# Detect when mixed targets is specified, and make a second invocation
++# of make so .config is not included in this case either (for *config).
++
++no-dot-config-targets := clean mrproper distclean \
++			 cscope TAGS tags help %docs check% \
++			 include/linux/version.h headers_% \
++			 kernelrelease kernelversion
++
++config-targets := 0
++mixed-targets  := 0
++dot-config     := 1
++
++ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
++	ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
++		dot-config := 0
++	endif
++endif
++
++ifeq ($(KBUILD_EXTMOD),)
++        ifneq ($(filter config %config,$(MAKECMDGOALS)),)
++                config-targets := 1
++                ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
++                        mixed-targets := 1
++                endif
++        endif
++endif
++
++ifeq ($(mixed-targets),1)
++# ===========================================================================
++# We're called with mixed targets (*config and build targets).
++# Handle them one by one.
++
++%:: FORCE
++	$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@
++
++else
++ifeq ($(config-targets),1)
++# ===========================================================================
++# *config targets only - make sure prerequisites are updated, and descend
++# in scripts/kconfig to make the *config target
++
++# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
++# KBUILD_DEFCONFIG may point out an alternative default configuration
++# used for 'make defconfig'
++include $(srctree)/arch/$(SRCARCH)/Makefile
++export KBUILD_DEFCONFIG KBUILD_KCONFIG
++
++config: scripts_basic outputmakefile FORCE
++	$(Q)mkdir -p include/linux include/config
++	$(Q)$(MAKE) $(build)=scripts/kconfig $@
++
++%config: scripts_basic outputmakefile FORCE
++	$(Q)mkdir -p include/linux include/config
++	$(Q)$(MAKE) $(build)=scripts/kconfig $@
++
++else
++# ===========================================================================
++# Build targets only - this includes vmlinux, arch specific targets, clean
++# targets and others. In general all targets except *config targets.
++
++ifeq ($(KBUILD_EXTMOD),)
++# Additional helpers built in scripts/
++# Carefully list dependencies so we do not try to build scripts twice
++# in parallel
++PHONY += scripts
++scripts: scripts_basic include/config/auto.conf include/config/tristate.conf
++	$(Q)$(MAKE) $(build)=$(@)
++
++# Objects we will link into vmlinux / subdirs we need to visit
++init-y		:= init/
++drivers-y	:= drivers/ sound/ firmware/
++net-y		:= net/
++libs-y		:= lib/
++core-y		:= usr/
++endif # KBUILD_EXTMOD
++
++ifeq ($(dot-config),1)
++# Read in config
++-include include/config/auto.conf
++
++ifeq ($(KBUILD_EXTMOD),)
++# Read in dependencies to all Kconfig* files, make sure to run
++# oldconfig if changes are detected.
++-include include/config/auto.conf.cmd
++
++# To avoid any implicit rule to kick in, define an empty command
++$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
++
++# If .config is newer than include/config/auto.conf, someone tinkered
++# with it and forgot to run make oldconfig.
++# if auto.conf.cmd is missing then we are probably in a cleaned tree so
++# we execute the config step to be sure to catch updated Kconfig files
++include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
++	$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
++else
++# external modules needs include/generated/autoconf.h and include/config/auto.conf
++# but do not care if they are up-to-date. Use auto.conf to trigger the test
++PHONY += include/config/auto.conf
++
++include/config/auto.conf:
++	$(Q)test -e include/generated/autoconf.h -a -e $@ || (		\
++	echo;								\
++	echo "  ERROR: Kernel configuration is invalid.";		\
++	echo "         include/generated/autoconf.h or $@ are missing.";\
++	echo "         Run 'make oldconfig && make prepare' on kernel src to fix it.";	\
++	echo;								\
++	/bin/false)
++
++endif # KBUILD_EXTMOD
++
++else
++# Dummy target needed, because used as prerequisite
++include/config/auto.conf: ;
++endif # $(dot-config)
++
++# The all: target is the default when no target is given on the
++# command line.
++# This allow a user to issue only 'make' to build a kernel including modules
++# Defaults vmlinux but it is usually overridden in the arch makefile
++all: vmlinux
++
++ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
++KBUILD_CFLAGS	+= -Os
++else
++KBUILD_CFLAGS	+= -O2
++endif
++
++include $(srctree)/arch/$(SRCARCH)/Makefile
++
++ifneq ($(CONFIG_FRAME_WARN),0)
++KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN})
++endif
++
++# Force gcc to behave correct even for buggy distributions
++ifndef CONFIG_CC_STACKPROTECTOR
++KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
++endif
++
++ifdef CONFIG_FRAME_POINTER
++KBUILD_CFLAGS	+= -fno-omit-frame-pointer -fno-optimize-sibling-calls
++else
++KBUILD_CFLAGS	+= -fomit-frame-pointer
++endif
++
++ifdef CONFIG_DEBUG_INFO
++KBUILD_CFLAGS	+= -g
++KBUILD_AFLAGS	+= -gdwarf-2
++endif
++
++ifdef CONFIG_FUNCTION_TRACER
++KBUILD_CFLAGS	+= -pg
++endif
++
++# We trigger additional mismatches with less inlining
++ifdef CONFIG_DEBUG_SECTION_MISMATCH
++KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
++endif
++
++# arch Makefile may override CC so keep this after arch Makefile is included
++NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
++CHECKFLAGS     += $(NOSTDINC_FLAGS)
++
++# warn about C99 declaration after statement
++KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
++
++# disable pointer signed / unsigned warnings in gcc 4.0
++KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
++
++# disable invalid "can't wrap" optimizations for signed / pointers
++KBUILD_CFLAGS	+= $(call cc-option,-fno-strict-overflow)
++
++# conserve stack if available
++KBUILD_CFLAGS   += $(call cc-option,-fconserve-stack)
++
++# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
++# But warn user when we do so
++warn-assign = \
++$(warning "WARNING: Appending $$K$(1) ($(K$(1))) from $(origin K$(1)) to kernel $$$(1)")
++
++ifneq ($(KCPPFLAGS),)
++        $(call warn-assign,CPPFLAGS)
++        KBUILD_CPPFLAGS += $(KCPPFLAGS)
++endif
++ifneq ($(KAFLAGS),)
++        $(call warn-assign,AFLAGS)
++        KBUILD_AFLAGS += $(KAFLAGS)
++endif
++ifneq ($(KCFLAGS),)
++        $(call warn-assign,CFLAGS)
++        KBUILD_CFLAGS += $(KCFLAGS)
++endif
++
++# Use --build-id when available.
++LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
++			      $(call cc-ldoption, -Wl$(comma)--build-id,))
++LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID)
++LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID)
++
++ifeq ($(CONFIG_STRIP_ASM_SYMS),y)
++LDFLAGS_vmlinux	+= $(call ld-option, -X,)
++endif
++
++# Default kernel image to build when no specific target is given.
++# KBUILD_IMAGE may be overruled on the command line or
++# set in the environment
++# Also any assignments in arch/$(ARCH)/Makefile take precedence over
++# this default value
++export KBUILD_IMAGE ?= vmlinux
++
++#
++# INSTALL_PATH specifies where to place the updated kernel and system map
++# images. Default is /boot, but you can set it to other values
++export	INSTALL_PATH ?= /boot
++
++#
++# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
++# relocations required by build roots.  This is not defined in the
++# makefile but the argument can be passed to make if needed.
++#
++
++MODLIB	= $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
++export MODLIB
++
++#
++#  INSTALL_MOD_STRIP, if defined, will cause modules to be
++#  stripped after they are installed.  If INSTALL_MOD_STRIP is '1', then
++#  the default option --strip-debug will be used.  Otherwise,
++#  INSTALL_MOD_STRIP will used as the options to the strip command.
++
++ifdef INSTALL_MOD_STRIP
++ifeq ($(INSTALL_MOD_STRIP),1)
++mod_strip_cmd = $(STRIP) --strip-debug
++else
++mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)
++endif # INSTALL_MOD_STRIP=1
++else
++mod_strip_cmd = true
++endif # INSTALL_MOD_STRIP
++export mod_strip_cmd
++
++
++ifeq ($(KBUILD_EXTMOD),)
++core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/
++
++vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
++		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
++		     $(net-y) $(net-m) $(libs-y) $(libs-m)))
++
++vmlinux-alldirs	:= $(sort $(vmlinux-dirs) $(patsubst %/,%,$(filter %/, \
++		     $(init-n) $(init-) \
++		     $(core-n) $(core-) $(drivers-n) $(drivers-) \
++		     $(net-n)  $(net-)  $(libs-n)    $(libs-))))
++
++init-y		:= $(patsubst %/, %/built-in.o, $(init-y))
++core-y		:= $(patsubst %/, %/built-in.o, $(core-y))
++drivers-y	:= $(patsubst %/, %/built-in.o, $(drivers-y))
++net-y		:= $(patsubst %/, %/built-in.o, $(net-y))
++libs-y1		:= $(patsubst %/, %/lib.a, $(libs-y))
++libs-y2		:= $(patsubst %/, %/built-in.o, $(libs-y))
++libs-y		:= $(libs-y1) $(libs-y2)
++
++# Build vmlinux
++# ---------------------------------------------------------------------------
++# vmlinux is built from the objects selected by $(vmlinux-init) and
++# $(vmlinux-main). Most are built-in.o files from top-level directories
++# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
++# Ordering when linking is important, and $(vmlinux-init) must be first.
++#
++# vmlinux
++#   ^
++#   |
++#   +-< $(vmlinux-init)
++#   |   +--< init/version.o + more
++#   |
++#   +--< $(vmlinux-main)
++#   |    +--< driver/built-in.o mm/built-in.o + more
++#   |
++#   +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
++#
++# vmlinux version (uname -v) cannot be updated during normal
++# descending-into-subdirs phase since we do not yet know if we need to
++# update vmlinux.
++# Therefore this step is delayed until just before final link of vmlinux -
++# except in the kallsyms case where it is done just before adding the
++# symbols to the kernel.
++#
++# System.map is generated to document addresses of all kernel symbols
++
++vmlinux-init := $(head-y) $(init-y)
++vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
++vmlinux-all  := $(vmlinux-init) $(vmlinux-main)
++vmlinux-lds  := arch/$(SRCARCH)/kernel/vmlinux.lds
++export KBUILD_VMLINUX_OBJS := $(vmlinux-all)
++
++# Rule to link vmlinux - also used during CONFIG_KALLSYMS
++# May be overridden by arch/$(ARCH)/Makefile
++quiet_cmd_vmlinux__ ?= LD      $@
++      cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \
++      -T $(vmlinux-lds) $(vmlinux-init)                          \
++      --start-group $(vmlinux-main) --end-group                  \
++      $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o FORCE ,$^)
++
++# Generate new vmlinux version
++quiet_cmd_vmlinux_version = GEN     .version
++      cmd_vmlinux_version = set -e;                     \
++	if [ ! -r .version ]; then			\
++	  rm -f .version;				\
++	  echo 1 >.version;				\
++	else						\
++	  mv .version .old_version;			\
++	  expr 0$$(cat .old_version) + 1 >.version;	\
++	fi;						\
++	$(MAKE) $(build)=init
++
++# Generate System.map
++quiet_cmd_sysmap = SYSMAP
++      cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
++
++# Link of vmlinux
++# If CONFIG_KALLSYMS is set .version is already updated
++# Generate System.map and verify that the content is consistent
++# Use + in front of the vmlinux_version rule to silent warning with make -j2
++# First command is ':' to allow us to use + in front of the rule
++define rule_vmlinux__
++	:
++	$(if $(CONFIG_KALLSYMS),,+$(call cmd,vmlinux_version))
++
++	$(call cmd,vmlinux__)
++	$(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
++
++	$(Q)$(if $($(quiet)cmd_sysmap),                                      \
++	  echo '  $($(quiet)cmd_sysmap)  System.map' &&)                     \
++	$(cmd_sysmap) $@ System.map;                                         \
++	if [ $$? -ne 0 ]; then                                               \
++		rm -f $@;                                                    \
++		/bin/false;                                                  \
++	fi;
++	$(verify_kallsyms)
++endef
++
++
++ifdef CONFIG_KALLSYMS
++# Generate section listing all symbols and add it into vmlinux $(kallsyms.o)
++# It's a three stage process:
++# o .tmp_vmlinux1 has all symbols and sections, but __kallsyms is
++#   empty
++#   Running kallsyms on that gives us .tmp_kallsyms1.o with
++#   the right size - vmlinux version (uname -v) is updated during this step
++# o .tmp_vmlinux2 now has a __kallsyms section of the right size,
++#   but due to the added section, some addresses have shifted.
++#   From here, we generate a correct .tmp_kallsyms2.o
++# o The correct .tmp_kallsyms2.o is linked into the final vmlinux.
++# o Verify that the System.map from vmlinux matches the map from
++#   .tmp_vmlinux2, just in case we did not generate kallsyms correctly.
++# o If CONFIG_KALLSYMS_EXTRA_PASS is set, do an extra pass using
++#   .tmp_vmlinux3 and .tmp_kallsyms3.o.  This is only meant as a
++#   temporary bypass to allow the kernel to be built while the
++#   maintainers work out what went wrong with kallsyms.
++
++ifdef CONFIG_KALLSYMS_EXTRA_PASS
++last_kallsyms := 3
++else
++last_kallsyms := 2
++endif
++
++kallsyms.o := .tmp_kallsyms$(last_kallsyms).o
++
++define verify_kallsyms
++	$(Q)$(if $($(quiet)cmd_sysmap),                                      \
++	  echo '  $($(quiet)cmd_sysmap)  .tmp_System.map' &&)                \
++	  $(cmd_sysmap) .tmp_vmlinux$(last_kallsyms) .tmp_System.map
++	$(Q)cmp -s System.map .tmp_System.map ||                             \
++		(echo Inconsistent kallsyms data;                            \
++		 echo Try setting CONFIG_KALLSYMS_EXTRA_PASS;                \
++		 rm .tmp_kallsyms* ; /bin/false )
++endef
++
++# Update vmlinux version before link
++# Use + in front of this rule to silent warning about make -j1
++# First command is ':' to allow us to use + in front of this rule
++cmd_ksym_ld = $(cmd_vmlinux__)
++define rule_ksym_ld
++	: 
++	+$(call cmd,vmlinux_version)
++	$(call cmd,vmlinux__)
++	$(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
++endef
++
++# Generate .S file with all kernel symbols
++quiet_cmd_kallsyms = KSYM    $@
++      cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
++                     $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
++
++.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
++	$(call if_changed_dep,as_o_S)
++
++.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS)
++	$(call cmd,kallsyms)
++
++# .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version
++.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE
++	$(call if_changed_rule,ksym_ld)
++
++.tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE
++	$(call if_changed,vmlinux__)
++
++.tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE
++	$(call if_changed,vmlinux__)
++
++# Needs to visit scripts/ before $(KALLSYMS) can be used.
++$(KALLSYMS): scripts ;
++
++# Generate some data for debugging strange kallsyms problems
++debug_kallsyms: .tmp_map$(last_kallsyms)
++
++.tmp_map%: .tmp_vmlinux% FORCE
++	($(OBJDUMP) -h $< | $(AWK) '/^ +[0-9]/{print $$4 " 0 " $$2}'; $(NM) $<) | sort > $@
++
++.tmp_map3: .tmp_map2
++
++.tmp_map2: .tmp_map1
++
++endif # ifdef CONFIG_KALLSYMS
++
++# Do modpost on a prelinked vmlinux. The finally linked vmlinux has
++# relevant sections renamed as per the linker script.
++quiet_cmd_vmlinux-modpost = LD      $@
++      cmd_vmlinux-modpost = $(LD) $(LDFLAGS) -r -o $@                          \
++	 $(vmlinux-init) --start-group $(vmlinux-main) --end-group             \
++	 $(filter-out $(vmlinux-init) $(vmlinux-main) FORCE ,$^)
++define rule_vmlinux-modpost
++	:
++	+$(call cmd,vmlinux-modpost)
++	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
++	$(Q)echo 'cmd_$@ := $(cmd_vmlinux-modpost)' > $(dot-target).cmd
++endef
++
++# vmlinux image - including updated kernel symbols
++vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE
++ifdef CONFIG_HEADERS_CHECK
++	$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
++endif
++ifdef CONFIG_SAMPLES
++	$(Q)$(MAKE) $(build)=samples
++endif
++ifdef CONFIG_BUILD_DOCSRC
++	$(Q)$(MAKE) $(build)=Documentation
++endif
++	$(call vmlinux-modpost)
++	$(call if_changed_rule,vmlinux__)
++	$(Q)rm -f .old_version
++
++# build vmlinux.o first to catch section mismatch errors early
++ifdef CONFIG_KALLSYMS
++.tmp_vmlinux1: vmlinux.o
++endif
++
++modpost-init := $(filter-out init/built-in.o, $(vmlinux-init))
++vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE
++	$(call if_changed_rule,vmlinux-modpost)
++
++# The actual objects are generated when descending, 
++# make sure no implicit rule kicks in
++$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
++
++# Handle descending into subdirectories listed in $(vmlinux-dirs)
++# Preset locale variables to speed up the build process. Limit locale
++# tweaks to this spot to avoid wrong language settings when running
++# make menuconfig etc.
++# Error messages still appears in the original language
++
++PHONY += $(vmlinux-dirs)
++$(vmlinux-dirs): prepare scripts
++	$(Q)$(MAKE) $(build)=$@
++
++# Store (new) KERNELRELASE string in include/config/kernel.release
++include/config/kernel.release: include/config/auto.conf FORCE
++	$(Q)rm -f $@
++	$(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" > $@
++
++
++# Things we need to do before we recursively start building the kernel
++# or the modules are listed in "prepare".
++# A multi level approach is used. prepareN is processed before prepareN-1.
++# archprepare is used in arch Makefiles and when processed asm symlink,
++# version.h and scripts_basic is processed / created.
++
++# Listed in dependency order
++PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3
++
++# prepare3 is used to check if we are building in a separate output directory,
++# and if so do:
++# 1) Check that make has not been executed in the kernel src $(srctree)
++prepare3: include/config/kernel.release
++ifneq ($(KBUILD_SRC),)
++	@$(kecho) '  Using $(srctree) as source for kernel'
++	$(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \
++		echo "  $(srctree) is not clean, please run 'make mrproper'";\
++		echo "  in the '$(srctree)' directory.";\
++		/bin/false; \
++	fi;
++endif
++
++# prepare2 creates a makefile if using a separate output directory
++prepare2: prepare3 outputmakefile
++
++prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \
++                   include/config/auto.conf
++	$(cmd_crmodverdir)
++
++archprepare: prepare1 scripts_basic
++
++prepare0: archprepare FORCE
++	$(Q)$(MAKE) $(build)=.
++	$(Q)$(MAKE) $(build)=. missing-syscalls
++
++# All the preparing..
++prepare: prepare0
++
++# Generate some files
++# ---------------------------------------------------------------------------
++
++# KERNELRELEASE can change from a few different places, meaning version.h
++# needs to be updated, so this check is forced on all builds
++
++uts_len := 64
++define filechk_utsrelease.h
++	if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then \
++	  echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2;    \
++	  exit 1;                                                         \
++	fi;                                                               \
++	(echo \#define UTS_RELEASE \"$(KERNELRELEASE)\";)
++endef
++
++define filechk_version.h
++	(echo \#define LINUX_VERSION_CODE $(shell                             \
++	expr $(VERSION) \* 65536 + $(PATCHLEVEL) \* 256 + $(SUBLEVEL));     \
++	echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
++endef
++
++include/linux/version.h: $(srctree)/Makefile FORCE
++	$(call filechk,version.h)
++
++include/generated/utsrelease.h: include/config/kernel.release FORCE
++	$(call filechk,utsrelease.h)
++
++PHONY += headerdep
++headerdep:
++	$(Q)find include/ -name '*.h' | xargs --max-args 1 scripts/headerdep.pl
++
++# ---------------------------------------------------------------------------
++
++PHONY += depend dep
++depend dep:
++	@echo '*** Warning: make $@ is unnecessary now.'
++
++# ---------------------------------------------------------------------------
++# Firmware install
++INSTALL_FW_PATH=$(INSTALL_MOD_PATH)/lib/firmware
++export INSTALL_FW_PATH
++
++PHONY += firmware_install
++firmware_install: FORCE
++	@mkdir -p $(objtree)/firmware
++	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_install
++
++# ---------------------------------------------------------------------------
++# Kernel headers
++
++#Default location for installed headers
++export INSTALL_HDR_PATH = $(objtree)/usr
++
++hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj
++
++# If we do an all arch process set dst to asm-$(hdr-arch)
++hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm)
++
++PHONY += __headers
++__headers: include/linux/version.h scripts_basic FORCE
++	$(Q)$(MAKE) $(build)=scripts scripts/unifdef
++
++PHONY += headers_install_all
++headers_install_all:
++	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/headers.sh install
++
++PHONY += headers_install
++headers_install: __headers
++	$(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild),, \
++	$(error Headers not exportable for the $(SRCARCH) architecture))
++	$(Q)$(MAKE) $(hdr-inst)=include
++	$(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst)
++
++PHONY += headers_check_all
++headers_check_all: headers_install_all
++	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/headers.sh check
++
++PHONY += headers_check
++headers_check: headers_install
++	$(Q)$(MAKE) $(hdr-inst)=include HDRCHECK=1
++	$(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst) HDRCHECK=1
++
++# ---------------------------------------------------------------------------
++# Modules
++
++ifdef CONFIG_MODULES
++
++# By default, build modules as well
++
++all: modules
++
++#	Build modules
++#
++#	A module can be listed more than once in obj-m resulting in
++#	duplicate lines in modules.order files.  Those are removed
++#	using awk while concatenating to the final file.
++
++PHONY += modules
++modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
++	$(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
++	@$(kecho) '  Building modules, stage 2.';
++	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
++	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild
++
++modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
++	$(Q)$(AWK) '!x[$$0]++' $^ > $(objtree)/modules.builtin
++
++%/modules.builtin: include/config/auto.conf
++	$(Q)$(MAKE) $(modbuiltin)=$*
++
++
++# Target to prepare building external modules
++PHONY += modules_prepare
++modules_prepare: prepare scripts
++
++# Target to install modules
++PHONY += modules_install
++modules_install: _modinst_ _modinst_post
++
++PHONY += _modinst_
++_modinst_:
++	@if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \
++		echo "Warning: you may need to install module-init-tools"; \
++		echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\
++		sleep 1; \
++	fi
++	@rm -rf $(MODLIB)/kernel
++	@rm -f $(MODLIB)/source
++	@mkdir -p $(MODLIB)/kernel
++	@ln -s $(srctree) $(MODLIB)/source
++	@if [ ! $(objtree) -ef  $(MODLIB)/build ]; then \
++		rm -f $(MODLIB)/build ; \
++		ln -s $(objtree) $(MODLIB)/build ; \
++	fi
++	@cp -f $(objtree)/modules.order $(MODLIB)/
++	@cp -f $(objtree)/modules.builtin $(MODLIB)/
++	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
++
++# This depmod is only for convenience to give the initial
++# boot a modules.dep even before / is mounted read-write.  However the
++# boot script depmod is the master version.
++PHONY += _modinst_post
++_modinst_post: _modinst_
++	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modinst
++	$(call cmd,depmod)
++
++else # CONFIG_MODULES
++
++# Modules not configured
++# ---------------------------------------------------------------------------
++
++modules modules_install: FORCE
++	@echo
++	@echo "The present kernel configuration has modules disabled."
++	@echo "Type 'make config' and enable loadable module support."
++	@echo "Then build a kernel with module support enabled."
++	@echo
++	@exit 1
++
++endif # CONFIG_MODULES
++
++###
++# Cleaning is done on three levels.
++# make clean     Delete most generated files
++#                Leave enough to build external modules
++# make mrproper  Delete the current configuration, and all generated files
++# make distclean Remove editor backup files, patch leftover files and the like
++
++# Directories & files removed with 'make clean'
++CLEAN_DIRS  += $(MODVERDIR)
++CLEAN_FILES +=	vmlinux System.map \
++                .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map
++
++# Directories & files removed with 'make mrproper'
++MRPROPER_DIRS  += include/config usr/include include/generated
++MRPROPER_FILES += .config .config.old .version .old_version             \
++                  include/linux/version.h                               \
++		  Module.symvers tags TAGS cscope*
++
++# clean - Delete most, but leave enough to build external modules
++#
++clean: rm-dirs  := $(CLEAN_DIRS)
++clean: rm-files := $(CLEAN_FILES)
++clean-dirs      := $(addprefix _clean_,$(srctree) $(vmlinux-alldirs) Documentation)
++
++PHONY += $(clean-dirs) clean archclean
++$(clean-dirs):
++	$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
++
++clean: archclean $(clean-dirs)
++	$(call cmd,rmdirs)
++	$(call cmd,rmfiles)
++	@find . $(RCS_FIND_IGNORE) \
++		\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
++		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
++		-o -name '*.symtypes' -o -name 'modules.order' \
++		-o -name modules.builtin -o -name '.tmp_*.o.*' \
++		-o -name '*.gcno' \) -type f -print | xargs rm -f
++
++# mrproper - Delete all generated files, including .config
++#
++mrproper: rm-dirs  := $(wildcard $(MRPROPER_DIRS))
++mrproper: rm-files := $(wildcard $(MRPROPER_FILES))
++mrproper-dirs      := $(addprefix _mrproper_,Documentation/DocBook scripts)
++
++PHONY += $(mrproper-dirs) mrproper archmrproper
++$(mrproper-dirs):
++	$(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
++
++mrproper: clean archmrproper $(mrproper-dirs)
++	$(call cmd,rmdirs)
++	$(call cmd,rmfiles)
++
++# distclean
++#
++PHONY += distclean
++
++distclean: mrproper
++	@find $(srctree) $(RCS_FIND_IGNORE) \
++		\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
++		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
++		-o -name '.*.rej' -o -size 0 \
++		-o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \
++		-type f -print | xargs rm -f
++
++
++# Packaging of the kernel to various formats
++# ---------------------------------------------------------------------------
++# rpm target kept for backward compatibility
++package-dir	:= $(srctree)/scripts/package
++
++%pkg: include/config/kernel.release FORCE
++	$(Q)$(MAKE) $(build)=$(package-dir) $@
++rpm: include/config/kernel.release FORCE
++	$(Q)$(MAKE) $(build)=$(package-dir) $@
++
++
++# Brief documentation of the typical targets used
++# ---------------------------------------------------------------------------
++
++boards := $(wildcard $(srctree)/arch/$(SRCARCH)/configs/*_defconfig)
++boards := $(notdir $(boards))
++board-dirs := $(dir $(wildcard $(srctree)/arch/$(SRCARCH)/configs/*/*_defconfig))
++board-dirs := $(sort $(notdir $(board-dirs:/=)))
++
++help:
++	@echo  'Cleaning targets:'
++	@echo  '  clean		  - Remove most generated files but keep the config and'
++	@echo  '                    enough build support to build external modules'
++	@echo  '  mrproper	  - Remove all generated files + config + various backup files'
++	@echo  '  distclean	  - mrproper + remove editor backup and patch files'
++	@echo  ''
++	@echo  'Configuration targets:'
++	@$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help
++	@echo  ''
++	@echo  'Other generic targets:'
++	@echo  '  all		  - Build all targets marked with [*]'
++	@echo  '* vmlinux	  - Build the bare kernel'
++	@echo  '* modules	  - Build all modules'
++	@echo  '  modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
++	@echo  '  firmware_install- Install all firmware to INSTALL_FW_PATH'
++	@echo  '                    (default: $$(INSTALL_MOD_PATH)/lib/firmware)'
++	@echo  '  dir/            - Build all files in dir and below'
++	@echo  '  dir/file.[oisS] - Build specified target only'
++	@echo  '  dir/file.lst    - Build specified mixed source/assembly target only'
++	@echo  '                    (requires a recent binutils and recent build (System.map))'
++	@echo  '  dir/file.ko     - Build module including final link'
++	@echo  '  modules_prepare - Set up for building external modules'
++	@echo  '  tags/TAGS	  - Generate tags file for editors'
++	@echo  '  cscope	  - Generate cscope index'
++	@echo  '  kernelrelease	  - Output the release version string'
++	@echo  '  kernelversion	  - Output the version stored in Makefile'
++	@echo  '  headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \
++	 echo  '                    (default: $(INSTALL_HDR_PATH))'; \
++	 echo  ''
++	@echo  'Static analysers'
++	@echo  '  checkstack      - Generate a list of stack hogs'
++	@echo  '  namespacecheck  - Name space analysis on compiled kernel'
++	@echo  '  versioncheck    - Sanity check on version.h usage'
++	@echo  '  includecheck    - Check for duplicate included header files'
++	@echo  '  export_report   - List the usages of all exported symbols'
++	@echo  '  headers_check   - Sanity check on exported headers'
++	@echo  '  headerdep       - Detect inclusion cycles in headers'; \
++	 echo  ''
++	@echo  'Kernel packaging:'
++	@$(MAKE) $(build)=$(package-dir) help
++	@echo  ''
++	@echo  'Documentation targets:'
++	@$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp
++	@echo  ''
++	@echo  'Architecture specific targets ($(SRCARCH)):'
++	@$(if $(archhelp),$(archhelp),\
++		echo '  No architecture specific help defined for $(SRCARCH)')
++	@echo  ''
++	@$(if $(boards), \
++		$(foreach b, $(boards), \
++		printf "  %-24s - Build for %s\\n" $(b) $(subst _defconfig,,$(b));) \
++		echo '')
++	@$(if $(board-dirs), \
++		$(foreach b, $(board-dirs), \
++		printf "  %-16s - Show %s-specific targets\\n" help-$(b) $(b);) \
++		printf "  %-16s - Show all of the above\\n" help-boards; \
++		echo '')
++
++	@echo  '  make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
++	@echo  '  make V=2   [targets] 2 => give reason for rebuild of target'
++	@echo  '  make O=dir [targets] Locate all output files in "dir", including .config'
++	@echo  '  make C=1   [targets] Check all c source with $$CHECK (sparse by default)'
++	@echo  '  make C=2   [targets] Force check of all c source with $$CHECK'
++	@echo  ''
++	@echo  'Execute "make" or "make all" to build all targets marked with [*] '
++	@echo  'For further info see the ./README file'
++
++
++help-board-dirs := $(addprefix help-,$(board-dirs))
++
++help-boards: $(help-board-dirs)
++
++boards-per-dir = $(notdir $(wildcard $(srctree)/arch/$(SRCARCH)/configs/$*/*_defconfig))
++
++$(help-board-dirs): help-%:
++	@echo  'Architecture specific targets ($(SRCARCH) $*):'
++	@$(if $(boards-per-dir), \
++		$(foreach b, $(boards-per-dir), \
++		printf "  %-24s - Build for %s\\n" $*/$(b) $(subst _defconfig,,$(b));) \
++		echo '')
++
++
++# Documentation targets
++# ---------------------------------------------------------------------------
++%docs: scripts_basic FORCE
++	$(Q)$(MAKE) $(build)=Documentation/DocBook $@
++
++else # KBUILD_EXTMOD
++
++###
++# External module support.
++# When building external modules the kernel used as basis is considered
++# read-only, and no consistency checks are made and the make
++# system is not used on the basis kernel. If updates are required
++# in the basis kernel ordinary make commands (without M=...) must
++# be used.
++#
++# The following are the only valid targets when building external
++# modules.
++# make M=dir clean     Delete all automatically generated files
++# make M=dir modules   Make all modules in specified dir
++# make M=dir	       Same as 'make M=dir modules'
++# make M=dir modules_install
++#                      Install the modules built in the module directory
++#                      Assumes install directory is already created
++
++# We are always building modules
++KBUILD_MODULES := 1
++PHONY += crmodverdir
++crmodverdir:
++	$(cmd_crmodverdir)
++
++PHONY += $(objtree)/Module.symvers
++$(objtree)/Module.symvers:
++	@test -e $(objtree)/Module.symvers || ( \
++	echo; \
++	echo "  WARNING: Symbol version dump $(objtree)/Module.symvers"; \
++	echo "           is missing; modules will have no dependencies and modversions."; \
++	echo )
++
++module-dirs := $(addprefix _module_,$(KBUILD_EXTMOD))
++PHONY += $(module-dirs) modules
++$(module-dirs): crmodverdir $(objtree)/Module.symvers
++	$(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@)
++
++modules: $(module-dirs)
++	@$(kecho) '  Building modules, stage 2.';
++	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
++
++PHONY += modules_install
++modules_install: _emodinst_ _emodinst_post
++
++install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra)
++PHONY += _emodinst_
++_emodinst_:
++	$(Q)mkdir -p $(MODLIB)/$(install-dir)
++	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
++
++PHONY += _emodinst_post
++_emodinst_post: _emodinst_
++	$(call cmd,depmod)
++
++clean-dirs := $(addprefix _clean_,$(KBUILD_EXTMOD))
++
++PHONY += $(clean-dirs) clean
++$(clean-dirs):
++	$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
++
++clean:	rm-dirs := $(MODVERDIR)
++clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers \
++                   $(KBUILD_EXTMOD)/modules.order \
++                   $(KBUILD_EXTMOD)/modules.builtin
++clean: $(clean-dirs)
++	$(call cmd,rmdirs)
++	$(call cmd,rmfiles)
++	@find $(KBUILD_EXTMOD) $(RCS_FIND_IGNORE) \
++		\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
++		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
++		-o -name '*.gcno' \) -type f -print | xargs rm -f
++
++help:
++	@echo  '  Building external modules.'
++	@echo  '  Syntax: make -C path/to/kernel/src M=$$PWD target'
++	@echo  ''
++	@echo  '  modules         - default target, build the module(s)'
++	@echo  '  modules_install - install the module'
++	@echo  '  clean           - remove generated files in module directory only'
++	@echo  ''
++
++# Dummies...
++PHONY += prepare scripts
++prepare: ;
++scripts: ;
++endif # KBUILD_EXTMOD
++
++# Generate tags for editors
++# ---------------------------------------------------------------------------
++quiet_cmd_tags = GEN     $@
++      cmd_tags = $(CONFIG_SHELL) $(srctree)/scripts/tags.sh $@
++
++tags TAGS cscope: FORCE
++	$(call cmd,tags)
++
++# Scripts to check various things for consistency
++# ---------------------------------------------------------------------------
++
++includecheck:
++	find * $(RCS_FIND_IGNORE) \
++		-name '*.[hcS]' -type f -print | sort \
++		| xargs $(PERL) -w $(srctree)/scripts/checkincludes.pl
++
++versioncheck:
++	find * $(RCS_FIND_IGNORE) \
++		-name '*.[hcS]' -type f -print | sort \
++		| xargs $(PERL) -w $(srctree)/scripts/checkversion.pl
++
++namespacecheck:
++	$(PERL) $(srctree)/scripts/namespace.pl
++
++export_report:
++	$(PERL) $(srctree)/scripts/export_report.pl
++
++endif #ifeq ($(config-targets),1)
++endif #ifeq ($(mixed-targets),1)
++
++PHONY += checkstack kernelrelease kernelversion
++
++# UML needs a little special treatment here.  It wants to use the host
++# toolchain, so needs $(SUBARCH) passed to checkstack.pl.  Everyone
++# else wants $(ARCH), including people doing cross-builds, which means
++# that $(SUBARCH) doesn't work here.
++ifeq ($(ARCH), um)
++CHECKSTACK_ARCH := $(SUBARCH)
++else
++CHECKSTACK_ARCH := $(ARCH)
++endif
++checkstack:
++	$(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \
++	$(PERL) $(src)/scripts/checkstack.pl $(CHECKSTACK_ARCH)
++
++kernelrelease:
++	$(if $(wildcard include/config/kernel.release), $(Q)echo $(KERNELRELEASE), \
++	$(error kernelrelease not valid - run 'make prepare' to update it))
++kernelversion:
++	@echo $(KERNELVERSION)
++
++# Single targets
++# ---------------------------------------------------------------------------
++# Single targets are compatible with:
++# - build with mixed source and output
++# - build with separate output dir 'make O=...'
++# - external modules
++#
++#  target-dir => where to store outputfile
++#  build-dir  => directory in kernel source tree to use
++
++ifeq ($(KBUILD_EXTMOD),)
++        build-dir  = $(patsubst %/,%,$(dir $@))
++        target-dir = $(dir $@)
++else
++        zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@)))
++        build-dir  = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash))
++        target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@))
++endif
++
++%.s: %.c prepare scripts FORCE
++	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
++%.i: %.c prepare scripts FORCE
++	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
++%.o: %.c prepare scripts FORCE
++	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
++%.lst: %.c prepare scripts FORCE
++	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
++%.s: %.S prepare scripts FORCE
++	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
++%.o: %.S prepare scripts FORCE
++	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
++%.symtypes: %.c prepare scripts FORCE
++	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
++
++# Modules
++/: prepare scripts FORCE
++	$(cmd_crmodverdir)
++	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
++	$(build)=$(build-dir)
++%/: prepare scripts FORCE
++	$(cmd_crmodverdir)
++	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
++	$(build)=$(build-dir)
++%.ko: prepare scripts FORCE
++	$(cmd_crmodverdir)
++	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1)   \
++	$(build)=$(build-dir) $(@:.ko=.o)
++	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
++
++# FIXME Should go into a make.lib or something 
++# ===========================================================================
++
++quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN   $(wildcard $(rm-dirs)))
++      cmd_rmdirs = rm -rf $(rm-dirs)
++
++quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN   $(wildcard $(rm-files)))
++      cmd_rmfiles = rm -f $(rm-files)
++
++# Run depmod only if we have System.map and depmod is executable
++quiet_cmd_depmod = DEPMOD  $(KERNELRELEASE)
++      cmd_depmod = \
++	if [ -r System.map -a -x $(DEPMOD) ]; then                              \
++		$(DEPMOD) -ae -F System.map                                     \
++		$(if $(strip $(INSTALL_MOD_PATH)), -b $(INSTALL_MOD_PATH) )     \
++		$(KERNELRELEASE);                                               \
++	fi
++
++# Create temporary dir for module support files
++# clean it up only when building all modules
++cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \
++                  $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*)
++
++a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \
++	  $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CPPFLAGS) \
++	  $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o)
++
++quiet_cmd_as_o_S = AS      $@
++cmd_as_o_S       = $(CC) $(a_flags) -c -o $@ $<
++
++# read all saved command lines
++
++targets := $(wildcard $(sort $(targets)))
++cmd_files := $(wildcard .*.cmd $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
++
++ifneq ($(cmd_files),)
++  $(cmd_files): ;	# Do not try to update included dependency files
++  include $(cmd_files)
++endif
++
++# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
++# Usage:
++# $(Q)$(MAKE) $(clean)=dir
++clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
++
++endif	# skip-makefile
++
++PHONY += FORCE
++FORCE:
++
++# Declare the contents of the .PHONY variable as phony.  We keep that
++# information in a variable so we can use it in if_changed and friends.
++.PHONY: $(PHONY)
+diff -rupN linux-2.6.35.11/mm/backing-dev.c linux-2.6.35.11-ts7500/mm/backing-dev.c
+--- linux-2.6.35.11/mm/backing-dev.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/mm/backing-dev.c	2011-03-14 11:18:24.000000000 -0400
+@@ -661,6 +661,7 @@ int bdi_init(struct backing_dev_info *bd
+ {
+ 	int i, err;
+ 
++//printk("bdi_init(), Calling spin_lock_init()\n");
+ 	bdi->dev = NULL;
+ 
+ 	bdi->min_ratio = 0;
+@@ -672,6 +673,7 @@ int bdi_init(struct backing_dev_info *bd
+ 	INIT_LIST_HEAD(&bdi->wb_list);
+ 	INIT_LIST_HEAD(&bdi->work_list);
+ 
++//printk("Calling bdi_wb_init()\n");
+ 	bdi_wb_init(&bdi->wb, bdi);
+ 
+ 	for (i = 0; i < NR_BDI_STAT_ITEMS; i++) {
+@@ -680,6 +682,7 @@ int bdi_init(struct backing_dev_info *bd
+ 			goto err;
+ 	}
+ 
++//printk("Calling prop_local_init_percpu()\n");
+ 	bdi->dirty_exceeded = 0;
+ 	err = prop_local_init_percpu(&bdi->completions);
+ 
+diff -rupN linux-2.6.35.11/mm/backing-dev.c.orig linux-2.6.35.11-ts7500/mm/backing-dev.c.orig
+--- linux-2.6.35.11/mm/backing-dev.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/mm/backing-dev.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,798 @@
++
++#include <linux/wait.h>
++#include <linux/backing-dev.h>
++#include <linux/kthread.h>
++#include <linux/freezer.h>
++#include <linux/fs.h>
++#include <linux/pagemap.h>
++#include <linux/mm.h>
++#include <linux/sched.h>
++#include <linux/module.h>
++#include <linux/writeback.h>
++#include <linux/device.h>
++
++static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
++
++void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
++{
++}
++EXPORT_SYMBOL(default_unplug_io_fn);
++
++struct backing_dev_info default_backing_dev_info = {
++	.name		= "default",
++	.ra_pages	= VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE,
++	.state		= 0,
++	.capabilities	= BDI_CAP_MAP_COPY,
++	.unplug_io_fn	= default_unplug_io_fn,
++};
++EXPORT_SYMBOL_GPL(default_backing_dev_info);
++
++struct backing_dev_info noop_backing_dev_info = {
++	.name		= "noop",
++	.capabilities	= BDI_CAP_NO_ACCT_AND_WRITEBACK,
++};
++EXPORT_SYMBOL_GPL(noop_backing_dev_info);
++
++static struct class *bdi_class;
++
++/*
++ * bdi_lock protects updates to bdi_list and bdi_pending_list, as well as
++ * reader side protection for bdi_pending_list. bdi_list has RCU reader side
++ * locking.
++ */
++DEFINE_SPINLOCK(bdi_lock);
++LIST_HEAD(bdi_list);
++LIST_HEAD(bdi_pending_list);
++
++static struct task_struct *sync_supers_tsk;
++static struct timer_list sync_supers_timer;
++
++static int bdi_sync_supers(void *);
++static void sync_supers_timer_fn(unsigned long);
++
++static void bdi_add_default_flusher_task(struct backing_dev_info *bdi);
++
++#ifdef CONFIG_DEBUG_FS
++#include <linux/debugfs.h>
++#include <linux/seq_file.h>
++
++static struct dentry *bdi_debug_root;
++
++static void bdi_debug_init(void)
++{
++	bdi_debug_root = debugfs_create_dir("bdi", NULL);
++}
++
++static int bdi_debug_stats_show(struct seq_file *m, void *v)
++{
++	struct backing_dev_info *bdi = m->private;
++	struct bdi_writeback *wb;
++	unsigned long background_thresh;
++	unsigned long dirty_thresh;
++	unsigned long bdi_thresh;
++	unsigned long nr_dirty, nr_io, nr_more_io, nr_wb;
++	struct inode *inode;
++
++	/*
++	 * inode lock is enough here, the bdi->wb_list is protected by
++	 * RCU on the reader side
++	 */
++	nr_wb = nr_dirty = nr_io = nr_more_io = 0;
++	spin_lock(&inode_lock);
++	list_for_each_entry(wb, &bdi->wb_list, list) {
++		nr_wb++;
++		list_for_each_entry(inode, &wb->b_dirty, i_list)
++			nr_dirty++;
++		list_for_each_entry(inode, &wb->b_io, i_list)
++			nr_io++;
++		list_for_each_entry(inode, &wb->b_more_io, i_list)
++			nr_more_io++;
++	}
++	spin_unlock(&inode_lock);
++
++	get_dirty_limits(&background_thresh, &dirty_thresh, &bdi_thresh, bdi);
++
++#define K(x) ((x) << (PAGE_SHIFT - 10))
++	seq_printf(m,
++		   "BdiWriteback:     %8lu kB\n"
++		   "BdiReclaimable:   %8lu kB\n"
++		   "BdiDirtyThresh:   %8lu kB\n"
++		   "DirtyThresh:      %8lu kB\n"
++		   "BackgroundThresh: %8lu kB\n"
++		   "WritebackThreads: %8lu\n"
++		   "b_dirty:          %8lu\n"
++		   "b_io:             %8lu\n"
++		   "b_more_io:        %8lu\n"
++		   "bdi_list:         %8u\n"
++		   "state:            %8lx\n"
++		   "wb_list:          %8u\n",
++		   (unsigned long) K(bdi_stat(bdi, BDI_WRITEBACK)),
++		   (unsigned long) K(bdi_stat(bdi, BDI_RECLAIMABLE)),
++		   K(bdi_thresh), K(dirty_thresh),
++		   K(background_thresh), nr_wb, nr_dirty, nr_io, nr_more_io,
++		   !list_empty(&bdi->bdi_list), bdi->state,
++		   !list_empty(&bdi->wb_list));
++#undef K
++
++	return 0;
++}
++
++static int bdi_debug_stats_open(struct inode *inode, struct file *file)
++{
++	return single_open(file, bdi_debug_stats_show, inode->i_private);
++}
++
++static const struct file_operations bdi_debug_stats_fops = {
++	.open		= bdi_debug_stats_open,
++	.read		= seq_read,
++	.llseek		= seq_lseek,
++	.release	= single_release,
++};
++
++static void bdi_debug_register(struct backing_dev_info *bdi, const char *name)
++{
++	bdi->debug_dir = debugfs_create_dir(name, bdi_debug_root);
++	bdi->debug_stats = debugfs_create_file("stats", 0444, bdi->debug_dir,
++					       bdi, &bdi_debug_stats_fops);
++}
++
++static void bdi_debug_unregister(struct backing_dev_info *bdi)
++{
++	debugfs_remove(bdi->debug_stats);
++	debugfs_remove(bdi->debug_dir);
++}
++#else
++static inline void bdi_debug_init(void)
++{
++}
++static inline void bdi_debug_register(struct backing_dev_info *bdi,
++				      const char *name)
++{
++}
++static inline void bdi_debug_unregister(struct backing_dev_info *bdi)
++{
++}
++#endif
++
++static ssize_t read_ahead_kb_store(struct device *dev,
++				  struct device_attribute *attr,
++				  const char *buf, size_t count)
++{
++	struct backing_dev_info *bdi = dev_get_drvdata(dev);
++	char *end;
++	unsigned long read_ahead_kb;
++	ssize_t ret = -EINVAL;
++
++	read_ahead_kb = simple_strtoul(buf, &end, 10);
++	if (*buf && (end[0] == '\0' || (end[0] == '\n' && end[1] == '\0'))) {
++		bdi->ra_pages = read_ahead_kb >> (PAGE_SHIFT - 10);
++		ret = count;
++	}
++	return ret;
++}
++
++#define K(pages) ((pages) << (PAGE_SHIFT - 10))
++
++#define BDI_SHOW(name, expr)						\
++static ssize_t name##_show(struct device *dev,				\
++			   struct device_attribute *attr, char *page)	\
++{									\
++	struct backing_dev_info *bdi = dev_get_drvdata(dev);		\
++									\
++	return snprintf(page, PAGE_SIZE-1, "%lld\n", (long long)expr);	\
++}
++
++BDI_SHOW(read_ahead_kb, K(bdi->ra_pages))
++
++static ssize_t min_ratio_store(struct device *dev,
++		struct device_attribute *attr, const char *buf, size_t count)
++{
++	struct backing_dev_info *bdi = dev_get_drvdata(dev);
++	char *end;
++	unsigned int ratio;
++	ssize_t ret = -EINVAL;
++
++	ratio = simple_strtoul(buf, &end, 10);
++	if (*buf && (end[0] == '\0' || (end[0] == '\n' && end[1] == '\0'))) {
++		ret = bdi_set_min_ratio(bdi, ratio);
++		if (!ret)
++			ret = count;
++	}
++	return ret;
++}
++BDI_SHOW(min_ratio, bdi->min_ratio)
++
++static ssize_t max_ratio_store(struct device *dev,
++		struct device_attribute *attr, const char *buf, size_t count)
++{
++	struct backing_dev_info *bdi = dev_get_drvdata(dev);
++	char *end;
++	unsigned int ratio;
++	ssize_t ret = -EINVAL;
++
++	ratio = simple_strtoul(buf, &end, 10);
++	if (*buf && (end[0] == '\0' || (end[0] == '\n' && end[1] == '\0'))) {
++		ret = bdi_set_max_ratio(bdi, ratio);
++		if (!ret)
++			ret = count;
++	}
++	return ret;
++}
++BDI_SHOW(max_ratio, bdi->max_ratio)
++
++#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store)
++
++static struct device_attribute bdi_dev_attrs[] = {
++	__ATTR_RW(read_ahead_kb),
++	__ATTR_RW(min_ratio),
++	__ATTR_RW(max_ratio),
++	__ATTR_NULL,
++};
++
++static __init int bdi_class_init(void)
++{
++	bdi_class = class_create(THIS_MODULE, "bdi");
++	if (IS_ERR(bdi_class))
++		return PTR_ERR(bdi_class);
++
++	bdi_class->dev_attrs = bdi_dev_attrs;
++	bdi_debug_init();
++	return 0;
++}
++postcore_initcall(bdi_class_init);
++
++static int __init default_bdi_init(void)
++{
++	int err;
++
++	sync_supers_tsk = kthread_run(bdi_sync_supers, NULL, "sync_supers");
++	BUG_ON(IS_ERR(sync_supers_tsk));
++
++	init_timer(&sync_supers_timer);
++	setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0);
++	bdi_arm_supers_timer();
++
++	err = bdi_init(&default_backing_dev_info);
++	if (!err)
++		bdi_register(&default_backing_dev_info, NULL, "default");
++	err = bdi_init(&noop_backing_dev_info);
++
++	return err;
++}
++subsys_initcall(default_bdi_init);
++
++static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi)
++{
++	memset(wb, 0, sizeof(*wb));
++
++	wb->bdi = bdi;
++	wb->last_old_flush = jiffies;
++	INIT_LIST_HEAD(&wb->b_dirty);
++	INIT_LIST_HEAD(&wb->b_io);
++	INIT_LIST_HEAD(&wb->b_more_io);
++}
++
++static void bdi_task_init(struct backing_dev_info *bdi,
++			  struct bdi_writeback *wb)
++{
++	struct task_struct *tsk = current;
++
++	spin_lock(&bdi->wb_lock);
++	list_add_tail_rcu(&wb->list, &bdi->wb_list);
++	spin_unlock(&bdi->wb_lock);
++
++	tsk->flags |= PF_FLUSHER | PF_SWAPWRITE;
++	set_freezable();
++
++	/*
++	 * Our parent may run at a different priority, just set us to normal
++	 */
++	set_user_nice(tsk, 0);
++}
++
++static int bdi_start_fn(void *ptr)
++{
++	struct bdi_writeback *wb = ptr;
++	struct backing_dev_info *bdi = wb->bdi;
++	int ret;
++
++	/*
++	 * Add us to the active bdi_list
++	 */
++	spin_lock_bh(&bdi_lock);
++	list_add_rcu(&bdi->bdi_list, &bdi_list);
++	spin_unlock_bh(&bdi_lock);
++
++	bdi_task_init(bdi, wb);
++
++	/*
++	 * Clear pending bit and wakeup anybody waiting to tear us down
++	 */
++	clear_bit(BDI_pending, &bdi->state);
++	smp_mb__after_clear_bit();
++	wake_up_bit(&bdi->state, BDI_pending);
++
++	ret = bdi_writeback_task(wb);
++
++	/*
++	 * Remove us from the list
++	 */
++	spin_lock(&bdi->wb_lock);
++	list_del_rcu(&wb->list);
++	spin_unlock(&bdi->wb_lock);
++
++	/*
++	 * Flush any work that raced with us exiting. No new work
++	 * will be added, since this bdi isn't discoverable anymore.
++	 */
++	if (!list_empty(&bdi->work_list))
++		wb_do_writeback(wb, 1);
++
++	wb->task = NULL;
++	return ret;
++}
++
++int bdi_has_dirty_io(struct backing_dev_info *bdi)
++{
++	return wb_has_dirty_io(&bdi->wb);
++}
++
++static void bdi_flush_io(struct backing_dev_info *bdi)
++{
++	struct writeback_control wbc = {
++		.sync_mode		= WB_SYNC_NONE,
++		.older_than_this	= NULL,
++		.range_cyclic		= 1,
++		.nr_to_write		= 1024,
++	};
++
++	writeback_inodes_wb(&bdi->wb, &wbc);
++}
++
++/*
++ * kupdated() used to do this. We cannot do it from the bdi_forker_task()
++ * or we risk deadlocking on ->s_umount. The longer term solution would be
++ * to implement sync_supers_bdi() or similar and simply do it from the
++ * bdi writeback tasks individually.
++ */
++static int bdi_sync_supers(void *unused)
++{
++	set_user_nice(current, 0);
++
++	while (!kthread_should_stop()) {
++		set_current_state(TASK_INTERRUPTIBLE);
++		schedule();
++
++		/*
++		 * Do this periodically, like kupdated() did before.
++		 */
++		sync_supers();
++	}
++
++	return 0;
++}
++
++void bdi_arm_supers_timer(void)
++{
++	unsigned long next;
++
++	if (!dirty_writeback_interval)
++		return;
++
++	next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies;
++	mod_timer(&sync_supers_timer, round_jiffies_up(next));
++}
++
++static void sync_supers_timer_fn(unsigned long unused)
++{
++	wake_up_process(sync_supers_tsk);
++	bdi_arm_supers_timer();
++}
++
++static int bdi_forker_task(void *ptr)
++{
++	struct bdi_writeback *me = ptr;
++
++	bdi_task_init(me->bdi, me);
++
++	for (;;) {
++		struct backing_dev_info *bdi, *tmp;
++		struct bdi_writeback *wb;
++
++		/*
++		 * Temporary measure, we want to make sure we don't see
++		 * dirty data on the default backing_dev_info
++		 */
++		if (wb_has_dirty_io(me) || !list_empty(&me->bdi->work_list))
++			wb_do_writeback(me, 0);
++
++		spin_lock_bh(&bdi_lock);
++
++		/*
++		 * Check if any existing bdi's have dirty data without
++		 * a thread registered. If so, set that up.
++		 */
++		list_for_each_entry_safe(bdi, tmp, &bdi_list, bdi_list) {
++			if (bdi->wb.task)
++				continue;
++			if (list_empty(&bdi->work_list) &&
++			    !bdi_has_dirty_io(bdi))
++				continue;
++
++			bdi_add_default_flusher_task(bdi);
++		}
++
++		set_current_state(TASK_INTERRUPTIBLE);
++
++		if (list_empty(&bdi_pending_list)) {
++			unsigned long wait;
++
++			spin_unlock_bh(&bdi_lock);
++			wait = msecs_to_jiffies(dirty_writeback_interval * 10);
++			if (wait)
++				schedule_timeout(wait);
++			else
++				schedule();
++			try_to_freeze();
++			continue;
++		}
++
++		__set_current_state(TASK_RUNNING);
++
++		/*
++		 * This is our real job - check for pending entries in
++		 * bdi_pending_list, and create the tasks that got added
++		 */
++		bdi = list_entry(bdi_pending_list.next, struct backing_dev_info,
++				 bdi_list);
++		list_del_init(&bdi->bdi_list);
++		spin_unlock_bh(&bdi_lock);
++
++		wb = &bdi->wb;
++		wb->task = kthread_run(bdi_start_fn, wb, "flush-%s",
++					dev_name(bdi->dev));
++		/*
++		 * If task creation fails, then readd the bdi to
++		 * the pending list and force writeout of the bdi
++		 * from this forker thread. That will free some memory
++		 * and we can try again.
++		 */
++		if (IS_ERR(wb->task)) {
++			wb->task = NULL;
++
++			/*
++			 * Add this 'bdi' to the back, so we get
++			 * a chance to flush other bdi's to free
++			 * memory.
++			 */
++			spin_lock_bh(&bdi_lock);
++			list_add_tail(&bdi->bdi_list, &bdi_pending_list);
++			spin_unlock_bh(&bdi_lock);
++
++			bdi_flush_io(bdi);
++		}
++	}
++
++	return 0;
++}
++
++static void bdi_add_to_pending(struct rcu_head *head)
++{
++	struct backing_dev_info *bdi;
++
++	bdi = container_of(head, struct backing_dev_info, rcu_head);
++	INIT_LIST_HEAD(&bdi->bdi_list);
++
++	spin_lock(&bdi_lock);
++	list_add_tail(&bdi->bdi_list, &bdi_pending_list);
++	spin_unlock(&bdi_lock);
++
++	/*
++	 * We are now on the pending list, wake up bdi_forker_task()
++	 * to finish the job and add us back to the active bdi_list
++	 */
++	wake_up_process(default_backing_dev_info.wb.task);
++}
++
++/*
++ * Add the default flusher task that gets created for any bdi
++ * that has dirty data pending writeout
++ */
++void static bdi_add_default_flusher_task(struct backing_dev_info *bdi)
++{
++	if (!bdi_cap_writeback_dirty(bdi))
++		return;
++
++	if (WARN_ON(!test_bit(BDI_registered, &bdi->state))) {
++		printk(KERN_ERR "bdi %p/%s is not registered!\n",
++							bdi, bdi->name);
++		return;
++	}
++
++	/*
++	 * Check with the helper whether to proceed adding a task. Will only
++	 * abort if we two or more simultanous calls to
++	 * bdi_add_default_flusher_task() occured, further additions will block
++	 * waiting for previous additions to finish.
++	 */
++	if (!test_and_set_bit(BDI_pending, &bdi->state)) {
++		list_del_rcu(&bdi->bdi_list);
++
++		/*
++		 * We must wait for the current RCU period to end before
++		 * moving to the pending list. So schedule that operation
++		 * from an RCU callback.
++		 */
++		call_rcu(&bdi->rcu_head, bdi_add_to_pending);
++	}
++}
++
++/*
++ * Remove bdi from bdi_list, and ensure that it is no longer visible
++ */
++static void bdi_remove_from_list(struct backing_dev_info *bdi)
++{
++	spin_lock_bh(&bdi_lock);
++	list_del_rcu(&bdi->bdi_list);
++	spin_unlock_bh(&bdi_lock);
++
++	synchronize_rcu();
++}
++
++int bdi_register(struct backing_dev_info *bdi, struct device *parent,
++		const char *fmt, ...)
++{
++	va_list args;
++	int ret = 0;
++	struct device *dev;
++
++	if (bdi->dev)	/* The driver needs to use separate queues per device */
++		goto exit;
++
++	va_start(args, fmt);
++	dev = device_create_vargs(bdi_class, parent, MKDEV(0, 0), bdi, fmt, args);
++	va_end(args);
++	if (IS_ERR(dev)) {
++		ret = PTR_ERR(dev);
++		goto exit;
++	}
++
++	spin_lock_bh(&bdi_lock);
++	list_add_tail_rcu(&bdi->bdi_list, &bdi_list);
++	spin_unlock_bh(&bdi_lock);
++
++	bdi->dev = dev;
++
++	/*
++	 * Just start the forker thread for our default backing_dev_info,
++	 * and add other bdi's to the list. They will get a thread created
++	 * on-demand when they need it.
++	 */
++	if (bdi_cap_flush_forker(bdi)) {
++		struct bdi_writeback *wb = &bdi->wb;
++
++		wb->task = kthread_run(bdi_forker_task, wb, "bdi-%s",
++						dev_name(dev));
++		if (IS_ERR(wb->task)) {
++			wb->task = NULL;
++			ret = -ENOMEM;
++
++			bdi_remove_from_list(bdi);
++			goto exit;
++		}
++	}
++
++	bdi_debug_register(bdi, dev_name(dev));
++	set_bit(BDI_registered, &bdi->state);
++exit:
++	return ret;
++}
++EXPORT_SYMBOL(bdi_register);
++
++int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev)
++{
++	return bdi_register(bdi, NULL, "%u:%u", MAJOR(dev), MINOR(dev));
++}
++EXPORT_SYMBOL(bdi_register_dev);
++
++/*
++ * Remove bdi from the global list and shutdown any threads we have running
++ */
++static void bdi_wb_shutdown(struct backing_dev_info *bdi)
++{
++	struct bdi_writeback *wb;
++
++	if (!bdi_cap_writeback_dirty(bdi))
++		return;
++
++	/*
++	 * If setup is pending, wait for that to complete first
++	 */
++	wait_on_bit(&bdi->state, BDI_pending, bdi_sched_wait,
++			TASK_UNINTERRUPTIBLE);
++
++	/*
++	 * Make sure nobody finds us on the bdi_list anymore
++	 */
++	bdi_remove_from_list(bdi);
++
++	/*
++	 * Finally, kill the kernel threads. We don't need to be RCU
++	 * safe anymore, since the bdi is gone from visibility. Force
++	 * unfreeze of the thread before calling kthread_stop(), otherwise
++	 * it would never exet if it is currently stuck in the refrigerator.
++	 */
++	list_for_each_entry(wb, &bdi->wb_list, list) {
++		thaw_process(wb->task);
++		kthread_stop(wb->task);
++	}
++}
++
++/*
++ * This bdi is going away now, make sure that no super_blocks point to it
++ */
++static void bdi_prune_sb(struct backing_dev_info *bdi)
++{
++	struct super_block *sb;
++
++	spin_lock(&sb_lock);
++	list_for_each_entry(sb, &super_blocks, s_list) {
++		if (sb->s_bdi == bdi)
++			sb->s_bdi = NULL;
++	}
++	spin_unlock(&sb_lock);
++}
++
++void bdi_unregister(struct backing_dev_info *bdi)
++{
++	if (bdi->dev) {
++		bdi_prune_sb(bdi);
++
++		if (!bdi_cap_flush_forker(bdi))
++			bdi_wb_shutdown(bdi);
++		bdi_debug_unregister(bdi);
++		device_unregister(bdi->dev);
++		bdi->dev = NULL;
++	}
++}
++EXPORT_SYMBOL(bdi_unregister);
++
++int bdi_init(struct backing_dev_info *bdi)
++{
++	int i, err;
++
++	bdi->dev = NULL;
++
++	bdi->min_ratio = 0;
++	bdi->max_ratio = 100;
++	bdi->max_prop_frac = PROP_FRAC_BASE;
++	spin_lock_init(&bdi->wb_lock);
++	INIT_RCU_HEAD(&bdi->rcu_head);
++	INIT_LIST_HEAD(&bdi->bdi_list);
++	INIT_LIST_HEAD(&bdi->wb_list);
++	INIT_LIST_HEAD(&bdi->work_list);
++
++	bdi_wb_init(&bdi->wb, bdi);
++
++	for (i = 0; i < NR_BDI_STAT_ITEMS; i++) {
++		err = percpu_counter_init(&bdi->bdi_stat[i], 0);
++		if (err)
++			goto err;
++	}
++
++	bdi->dirty_exceeded = 0;
++	err = prop_local_init_percpu(&bdi->completions);
++
++	if (err) {
++err:
++		while (i--)
++			percpu_counter_destroy(&bdi->bdi_stat[i]);
++	}
++
++	return err;
++}
++EXPORT_SYMBOL(bdi_init);
++
++void bdi_destroy(struct backing_dev_info *bdi)
++{
++	int i;
++
++	/*
++	 * Splice our entries to the default_backing_dev_info, if this
++	 * bdi disappears
++	 */
++	if (bdi_has_dirty_io(bdi)) {
++		struct bdi_writeback *dst = &default_backing_dev_info.wb;
++
++		spin_lock(&inode_lock);
++		list_splice(&bdi->wb.b_dirty, &dst->b_dirty);
++		list_splice(&bdi->wb.b_io, &dst->b_io);
++		list_splice(&bdi->wb.b_more_io, &dst->b_more_io);
++		spin_unlock(&inode_lock);
++	}
++
++	bdi_unregister(bdi);
++
++	for (i = 0; i < NR_BDI_STAT_ITEMS; i++)
++		percpu_counter_destroy(&bdi->bdi_stat[i]);
++
++	prop_local_destroy_percpu(&bdi->completions);
++}
++EXPORT_SYMBOL(bdi_destroy);
++
++/*
++ * For use from filesystems to quickly init and register a bdi associated
++ * with dirty writeback
++ */
++int bdi_setup_and_register(struct backing_dev_info *bdi, char *name,
++			   unsigned int cap)
++{
++	char tmp[32];
++	int err;
++
++	bdi->name = name;
++	bdi->capabilities = cap;
++	err = bdi_init(bdi);
++	if (err)
++		return err;
++
++	sprintf(tmp, "%.28s%s", name, "-%d");
++	err = bdi_register(bdi, NULL, tmp, atomic_long_inc_return(&bdi_seq));
++	if (err) {
++		bdi_destroy(bdi);
++		return err;
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL(bdi_setup_and_register);
++
++static wait_queue_head_t congestion_wqh[2] = {
++		__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
++		__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
++	};
++
++void clear_bdi_congested(struct backing_dev_info *bdi, int sync)
++{
++	enum bdi_state bit;
++	wait_queue_head_t *wqh = &congestion_wqh[sync];
++
++	bit = sync ? BDI_sync_congested : BDI_async_congested;
++	clear_bit(bit, &bdi->state);
++	smp_mb__after_clear_bit();
++	if (waitqueue_active(wqh))
++		wake_up(wqh);
++}
++EXPORT_SYMBOL(clear_bdi_congested);
++
++void set_bdi_congested(struct backing_dev_info *bdi, int sync)
++{
++	enum bdi_state bit;
++
++	bit = sync ? BDI_sync_congested : BDI_async_congested;
++	set_bit(bit, &bdi->state);
++}
++EXPORT_SYMBOL(set_bdi_congested);
++
++/**
++ * congestion_wait - wait for a backing_dev to become uncongested
++ * @sync: SYNC or ASYNC IO
++ * @timeout: timeout in jiffies
++ *
++ * Waits for up to @timeout jiffies for a backing_dev (any backing_dev) to exit
++ * write congestion.  If no backing_devs are congested then just wait for the
++ * next write to be completed.
++ */
++long congestion_wait(int sync, long timeout)
++{
++	long ret;
++	DEFINE_WAIT(wait);
++	wait_queue_head_t *wqh = &congestion_wqh[sync];
++
++	prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
++	ret = io_schedule_timeout(timeout);
++	finish_wait(wqh, &wait);
++	return ret;
++}
++EXPORT_SYMBOL(congestion_wait);
++
+diff -rupN linux-2.6.35.11/mm/shmem.c linux-2.6.35.11-ts7500/mm/shmem.c
+--- linux-2.6.35.11/mm/shmem.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/mm/shmem.c	2011-03-14 11:18:24.000000000 -0400
+@@ -2526,21 +2526,27 @@ static struct file_system_type tmpfs_fs_
+ int __init init_tmpfs(void)
+ {
+ 	int error;
++//printk("Calling bdi_init()\n");
++
+ 
+ 	error = bdi_init(&shmem_backing_dev_info);
+ 	if (error)
+ 		goto out4;
+ 
++//printk("Calling init_inodecache()\n");   
+ 	error = init_inodecache();
+ 	if (error)
+ 		goto out3;
+ 
++//printk("Calling register_filesystem()\n");
+ 	error = register_filesystem(&tmpfs_fs_type);
+ 	if (error) {
+ 		printk(KERN_ERR "Could not register tmpfs\n");
+ 		goto out2;
+ 	}
+ 
++//printk("Calling vfs_kern_mount()\n");
++
+ 	shm_mnt = vfs_kern_mount(&tmpfs_fs_type, MS_NOUSER,
+ 				tmpfs_fs_type.name, NULL);
+ 	if (IS_ERR(shm_mnt)) {
+@@ -2548,6 +2554,9 @@ int __init init_tmpfs(void)
+ 		printk(KERN_ERR "Could not kern_mount tmpfs\n");
+ 		goto out1;
+ 	}
++   //printf("init_tmpfs() done OK\n");
++   printk("init_tmpfs() done OK\n");
++   
+ 	return 0;
+ 
+ out1:
+@@ -2559,6 +2568,9 @@ out3:
+ out4:
+ 	shm_mnt = ERR_PTR(error);
+ 	return error;
++   
++
++
+ }
+ 
+ #ifdef CONFIG_CGROUP_MEM_RES_CTLR
+@@ -2621,8 +2633,11 @@ static struct file_system_type tmpfs_fs_
+ 
+ int __init init_tmpfs(void)
+ {
++//printk("Calling register_filesystem()\n");
++
+ 	BUG_ON(register_filesystem(&tmpfs_fs_type) != 0);
+ 
++//printk("Calling kern_mount()\n");
+ 	shm_mnt = kern_mount(&tmpfs_fs_type);
+ 	BUG_ON(IS_ERR(shm_mnt));
+ 
+diff -rupN linux-2.6.35.11/mm/shmem.c.orig linux-2.6.35.11-ts7500/mm/shmem.c.orig
+--- linux-2.6.35.11/mm/shmem.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.11-ts7500/mm/shmem.c.orig	2011-02-06 14:04:07.000000000 -0500
+@@ -0,0 +1,2760 @@
++/*
++ * Resizable virtual memory filesystem for Linux.
++ *
++ * Copyright (C) 2000 Linus Torvalds.
++ *		 2000 Transmeta Corp.
++ *		 2000-2001 Christoph Rohland
++ *		 2000-2001 SAP AG
++ *		 2002 Red Hat Inc.
++ * Copyright (C) 2002-2005 Hugh Dickins.
++ * Copyright (C) 2002-2005 VERITAS Software Corporation.
++ * Copyright (C) 2004 Andi Kleen, SuSE Labs
++ *
++ * Extended attribute support for tmpfs:
++ * Copyright (c) 2004, Luke Kenneth Casson Leighton <lkcl@lkcl.net>
++ * Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
++ *
++ * tiny-shmem:
++ * Copyright (c) 2004, 2008 Matt Mackall <mpm@selenic.com>
++ *
++ * This file is released under the GPL.
++ */
++
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/vfs.h>
++#include <linux/mount.h>
++#include <linux/pagemap.h>
++#include <linux/file.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/swap.h>
++
++static struct vfsmount *shm_mnt;
++
++#ifdef CONFIG_SHMEM
++/*
++ * This virtual memory filesystem is heavily based on the ramfs. It
++ * extends ramfs by the ability to use swap and honor resource limits
++ * which makes it a completely usable filesystem.
++ */
++
++#include <linux/xattr.h>
++#include <linux/exportfs.h>
++#include <linux/posix_acl.h>
++#include <linux/generic_acl.h>
++#include <linux/mman.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/backing-dev.h>
++#include <linux/shmem_fs.h>
++#include <linux/writeback.h>
++#include <linux/blkdev.h>
++#include <linux/security.h>
++#include <linux/swapops.h>
++#include <linux/mempolicy.h>
++#include <linux/namei.h>
++#include <linux/ctype.h>
++#include <linux/migrate.h>
++#include <linux/highmem.h>
++#include <linux/seq_file.h>
++#include <linux/magic.h>
++
++#include <asm/uaccess.h>
++#include <asm/div64.h>
++#include <asm/pgtable.h>
++
++/*
++ * The maximum size of a shmem/tmpfs file is limited by the maximum size of
++ * its triple-indirect swap vector - see illustration at shmem_swp_entry().
++ *
++ * With 4kB page size, maximum file size is just over 2TB on a 32-bit kernel,
++ * but one eighth of that on a 64-bit kernel.  With 8kB page size, maximum
++ * file size is just over 4TB on a 64-bit kernel, but 16TB on a 32-bit kernel,
++ * MAX_LFS_FILESIZE being then more restrictive than swap vector layout.
++ *
++ * We use / and * instead of shifts in the definitions below, so that the swap
++ * vector can be tested with small even values (e.g. 20) for ENTRIES_PER_PAGE.
++ */
++#define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
++#define ENTRIES_PER_PAGEPAGE ((unsigned long long)ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
++
++#define SHMSWP_MAX_INDEX (SHMEM_NR_DIRECT + (ENTRIES_PER_PAGEPAGE/2) * (ENTRIES_PER_PAGE+1))
++#define SHMSWP_MAX_BYTES (SHMSWP_MAX_INDEX << PAGE_CACHE_SHIFT)
++
++#define SHMEM_MAX_BYTES  min_t(unsigned long long, SHMSWP_MAX_BYTES, MAX_LFS_FILESIZE)
++#define SHMEM_MAX_INDEX  ((unsigned long)((SHMEM_MAX_BYTES+1) >> PAGE_CACHE_SHIFT))
++
++#define BLOCKS_PER_PAGE  (PAGE_CACHE_SIZE/512)
++#define VM_ACCT(size)    (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT)
++
++/* info->flags needs VM_flags to handle pagein/truncate races efficiently */
++#define SHMEM_PAGEIN	 VM_READ
++#define SHMEM_TRUNCATE	 VM_WRITE
++
++/* Definition to limit shmem_truncate's steps between cond_rescheds */
++#define LATENCY_LIMIT	 64
++
++/* Pretend that each entry is of this size in directory's i_size */
++#define BOGO_DIRENT_SIZE 20
++
++/* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */
++enum sgp_type {
++	SGP_READ,	/* don't exceed i_size, don't allocate page */
++	SGP_CACHE,	/* don't exceed i_size, may allocate page */
++	SGP_DIRTY,	/* like SGP_CACHE, but set new page dirty */
++	SGP_WRITE,	/* may exceed i_size, may allocate page */
++};
++
++#ifdef CONFIG_TMPFS
++static unsigned long shmem_default_max_blocks(void)
++{
++	return totalram_pages / 2;
++}
++
++static unsigned long shmem_default_max_inodes(void)
++{
++	return min(totalram_pages - totalhigh_pages, totalram_pages / 2);
++}
++#endif
++
++static int shmem_getpage(struct inode *inode, unsigned long idx,
++			 struct page **pagep, enum sgp_type sgp, int *type);
++
++static inline struct page *shmem_dir_alloc(gfp_t gfp_mask)
++{
++	/*
++	 * The above definition of ENTRIES_PER_PAGE, and the use of
++	 * BLOCKS_PER_PAGE on indirect pages, assume PAGE_CACHE_SIZE:
++	 * might be reconsidered if it ever diverges from PAGE_SIZE.
++	 *
++	 * Mobility flags are masked out as swap vectors cannot move
++	 */
++	return alloc_pages((gfp_mask & ~GFP_MOVABLE_MASK) | __GFP_ZERO,
++				PAGE_CACHE_SHIFT-PAGE_SHIFT);
++}
++
++static inline void shmem_dir_free(struct page *page)
++{
++	__free_pages(page, PAGE_CACHE_SHIFT-PAGE_SHIFT);
++}
++
++static struct page **shmem_dir_map(struct page *page)
++{
++	return (struct page **)kmap_atomic(page, KM_USER0);
++}
++
++static inline void shmem_dir_unmap(struct page **dir)
++{
++	kunmap_atomic(dir, KM_USER0);
++}
++
++static swp_entry_t *shmem_swp_map(struct page *page)
++{
++	return (swp_entry_t *)kmap_atomic(page, KM_USER1);
++}
++
++static inline void shmem_swp_balance_unmap(void)
++{
++	/*
++	 * When passing a pointer to an i_direct entry, to code which
++	 * also handles indirect entries and so will shmem_swp_unmap,
++	 * we must arrange for the preempt count to remain in balance.
++	 * What kmap_atomic of a lowmem page does depends on config
++	 * and architecture, so pretend to kmap_atomic some lowmem page.
++	 */
++	(void) kmap_atomic(ZERO_PAGE(0), KM_USER1);
++}
++
++static inline void shmem_swp_unmap(swp_entry_t *entry)
++{
++	kunmap_atomic(entry, KM_USER1);
++}
++
++static inline struct shmem_sb_info *SHMEM_SB(struct super_block *sb)
++{
++	return sb->s_fs_info;
++}
++
++/*
++ * shmem_file_setup pre-accounts the whole fixed size of a VM object,
++ * for shared memory and for shared anonymous (/dev/zero) mappings
++ * (unless MAP_NORESERVE and sysctl_overcommit_memory <= 1),
++ * consistent with the pre-accounting of private mappings ...
++ */
++static inline int shmem_acct_size(unsigned long flags, loff_t size)
++{
++	return (flags & VM_NORESERVE) ?
++		0 : security_vm_enough_memory_kern(VM_ACCT(size));
++}
++
++static inline void shmem_unacct_size(unsigned long flags, loff_t size)
++{
++	if (!(flags & VM_NORESERVE))
++		vm_unacct_memory(VM_ACCT(size));
++}
++
++/*
++ * ... whereas tmpfs objects are accounted incrementally as
++ * pages are allocated, in order to allow huge sparse files.
++ * shmem_getpage reports shmem_acct_block failure as -ENOSPC not -ENOMEM,
++ * so that a failure on a sparse tmpfs mapping will give SIGBUS not OOM.
++ */
++static inline int shmem_acct_block(unsigned long flags)
++{
++	return (flags & VM_NORESERVE) ?
++		security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)) : 0;
++}
++
++static inline void shmem_unacct_blocks(unsigned long flags, long pages)
++{
++	if (flags & VM_NORESERVE)
++		vm_unacct_memory(pages * VM_ACCT(PAGE_CACHE_SIZE));
++}
++
++static const struct super_operations shmem_ops;
++static const struct address_space_operations shmem_aops;
++static const struct file_operations shmem_file_operations;
++static const struct inode_operations shmem_inode_operations;
++static const struct inode_operations shmem_dir_inode_operations;
++static const struct inode_operations shmem_special_inode_operations;
++static const struct vm_operations_struct shmem_vm_ops;
++
++static struct backing_dev_info shmem_backing_dev_info  __read_mostly = {
++	.ra_pages	= 0,	/* No readahead */
++	.capabilities	= BDI_CAP_NO_ACCT_AND_WRITEBACK | BDI_CAP_SWAP_BACKED,
++	.unplug_io_fn	= default_unplug_io_fn,
++};
++
++static LIST_HEAD(shmem_swaplist);
++static DEFINE_MUTEX(shmem_swaplist_mutex);
++
++static void shmem_free_blocks(struct inode *inode, long pages)
++{
++	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
++	if (sbinfo->max_blocks) {
++		spin_lock(&sbinfo->stat_lock);
++		sbinfo->free_blocks += pages;
++		inode->i_blocks -= pages*BLOCKS_PER_PAGE;
++		spin_unlock(&sbinfo->stat_lock);
++	}
++}
++
++static int shmem_reserve_inode(struct super_block *sb)
++{
++	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
++	if (sbinfo->max_inodes) {
++		spin_lock(&sbinfo->stat_lock);
++		if (!sbinfo->free_inodes) {
++			spin_unlock(&sbinfo->stat_lock);
++			return -ENOSPC;
++		}
++		sbinfo->free_inodes--;
++		spin_unlock(&sbinfo->stat_lock);
++	}
++	return 0;
++}
++
++static void shmem_free_inode(struct super_block *sb)
++{
++	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
++	if (sbinfo->max_inodes) {
++		spin_lock(&sbinfo->stat_lock);
++		sbinfo->free_inodes++;
++		spin_unlock(&sbinfo->stat_lock);
++	}
++}
++
++/**
++ * shmem_recalc_inode - recalculate the size of an inode
++ * @inode: inode to recalc
++ *
++ * We have to calculate the free blocks since the mm can drop
++ * undirtied hole pages behind our back.
++ *
++ * But normally   info->alloced == inode->i_mapping->nrpages + info->swapped
++ * So mm freed is info->alloced - (inode->i_mapping->nrpages + info->swapped)
++ *
++ * It has to be called with the spinlock held.
++ */
++static void shmem_recalc_inode(struct inode *inode)
++{
++	struct shmem_inode_info *info = SHMEM_I(inode);
++	long freed;
++
++	freed = info->alloced - info->swapped - inode->i_mapping->nrpages;
++	if (freed > 0) {
++		info->alloced -= freed;
++		shmem_unacct_blocks(info->flags, freed);
++		shmem_free_blocks(inode, freed);
++	}
++}
++
++/**
++ * shmem_swp_entry - find the swap vector position in the info structure
++ * @info:  info structure for the inode
++ * @index: index of the page to find
++ * @page:  optional page to add to the structure. Has to be preset to
++ *         all zeros
++ *
++ * If there is no space allocated yet it will return NULL when
++ * page is NULL, else it will use the page for the needed block,
++ * setting it to NULL on return to indicate that it has been used.
++ *
++ * The swap vector is organized the following way:
++ *
++ * There are SHMEM_NR_DIRECT entries directly stored in the
++ * shmem_inode_info structure. So small files do not need an addional
++ * allocation.
++ *
++ * For pages with index > SHMEM_NR_DIRECT there is the pointer
++ * i_indirect which points to a page which holds in the first half
++ * doubly indirect blocks, in the second half triple indirect blocks:
++ *
++ * For an artificial ENTRIES_PER_PAGE = 4 this would lead to the
++ * following layout (for SHMEM_NR_DIRECT == 16):
++ *
++ * i_indirect -> dir --> 16-19
++ * 	      |	     +-> 20-23
++ * 	      |
++ * 	      +-->dir2 --> 24-27
++ * 	      |	       +-> 28-31
++ * 	      |	       +-> 32-35
++ * 	      |	       +-> 36-39
++ * 	      |
++ * 	      +-->dir3 --> 40-43
++ * 	       	       +-> 44-47
++ * 	      	       +-> 48-51
++ * 	      	       +-> 52-55
++ */
++static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, struct page **page)
++{
++	unsigned long offset;
++	struct page **dir;
++	struct page *subdir;
++
++	if (index < SHMEM_NR_DIRECT) {
++		shmem_swp_balance_unmap();
++		return info->i_direct+index;
++	}
++	if (!info->i_indirect) {
++		if (page) {
++			info->i_indirect = *page;
++			*page = NULL;
++		}
++		return NULL;			/* need another page */
++	}
++
++	index -= SHMEM_NR_DIRECT;
++	offset = index % ENTRIES_PER_PAGE;
++	index /= ENTRIES_PER_PAGE;
++	dir = shmem_dir_map(info->i_indirect);
++
++	if (index >= ENTRIES_PER_PAGE/2) {
++		index -= ENTRIES_PER_PAGE/2;
++		dir += ENTRIES_PER_PAGE/2 + index/ENTRIES_PER_PAGE;
++		index %= ENTRIES_PER_PAGE;
++		subdir = *dir;
++		if (!subdir) {
++			if (page) {
++				*dir = *page;
++				*page = NULL;
++			}
++			shmem_dir_unmap(dir);
++			return NULL;		/* need another page */
++		}
++		shmem_dir_unmap(dir);
++		dir = shmem_dir_map(subdir);
++	}
++
++	dir += index;
++	subdir = *dir;
++	if (!subdir) {
++		if (!page || !(subdir = *page)) {
++			shmem_dir_unmap(dir);
++			return NULL;		/* need a page */
++		}
++		*dir = subdir;
++		*page = NULL;
++	}
++	shmem_dir_unmap(dir);
++	return shmem_swp_map(subdir) + offset;
++}
++
++static void shmem_swp_set(struct shmem_inode_info *info, swp_entry_t *entry, unsigned long value)
++{
++	long incdec = value? 1: -1;
++
++	entry->val = value;
++	info->swapped += incdec;
++	if ((unsigned long)(entry - info->i_direct) >= SHMEM_NR_DIRECT) {
++		struct page *page = kmap_atomic_to_page(entry);
++		set_page_private(page, page_private(page) + incdec);
++	}
++}
++
++/**
++ * shmem_swp_alloc - get the position of the swap entry for the page.
++ * @info:	info structure for the inode
++ * @index:	index of the page to find
++ * @sgp:	check and recheck i_size? skip allocation?
++ *
++ * If the entry does not exist, allocate it.
++ */
++static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long index, enum sgp_type sgp)
++{
++	struct inode *inode = &info->vfs_inode;
++	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
++	struct page *page = NULL;
++	swp_entry_t *entry;
++
++	if (sgp != SGP_WRITE &&
++	    ((loff_t) index << PAGE_CACHE_SHIFT) >= i_size_read(inode))
++		return ERR_PTR(-EINVAL);
++
++	while (!(entry = shmem_swp_entry(info, index, &page))) {
++		if (sgp == SGP_READ)
++			return shmem_swp_map(ZERO_PAGE(0));
++		/*
++		 * Test free_blocks against 1 not 0, since we have 1 data
++		 * page (and perhaps indirect index pages) yet to allocate:
++		 * a waste to allocate index if we cannot allocate data.
++		 */
++		if (sbinfo->max_blocks) {
++			spin_lock(&sbinfo->stat_lock);
++			if (sbinfo->free_blocks <= 1) {
++				spin_unlock(&sbinfo->stat_lock);
++				return ERR_PTR(-ENOSPC);
++			}
++			sbinfo->free_blocks--;
++			inode->i_blocks += BLOCKS_PER_PAGE;
++			spin_unlock(&sbinfo->stat_lock);
++		}
++
++		spin_unlock(&info->lock);
++		page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping));
++		spin_lock(&info->lock);
++
++		if (!page) {
++			shmem_free_blocks(inode, 1);
++			return ERR_PTR(-ENOMEM);
++		}
++		if (sgp != SGP_WRITE &&
++		    ((loff_t) index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) {
++			entry = ERR_PTR(-EINVAL);
++			break;
++		}
++		if (info->next_index <= index)
++			info->next_index = index + 1;
++	}
++	if (page) {
++		/* another task gave its page, or truncated the file */
++		shmem_free_blocks(inode, 1);
++		shmem_dir_free(page);
++	}
++	if (info->next_index <= index && !IS_ERR(entry))
++		info->next_index = index + 1;
++	return entry;
++}
++
++/**
++ * shmem_free_swp - free some swap entries in a directory
++ * @dir:        pointer to the directory
++ * @edir:       pointer after last entry of the directory
++ * @punch_lock: pointer to spinlock when needed for the holepunch case
++ */
++static int shmem_free_swp(swp_entry_t *dir, swp_entry_t *edir,
++						spinlock_t *punch_lock)
++{
++	spinlock_t *punch_unlock = NULL;
++	swp_entry_t *ptr;
++	int freed = 0;
++
++	for (ptr = dir; ptr < edir; ptr++) {
++		if (ptr->val) {
++			if (unlikely(punch_lock)) {
++				punch_unlock = punch_lock;
++				punch_lock = NULL;
++				spin_lock(punch_unlock);
++				if (!ptr->val)
++					continue;
++			}
++			free_swap_and_cache(*ptr);
++			*ptr = (swp_entry_t){0};
++			freed++;
++		}
++	}
++	if (punch_unlock)
++		spin_unlock(punch_unlock);
++	return freed;
++}
++
++static int shmem_map_and_free_swp(struct page *subdir, int offset,
++		int limit, struct page ***dir, spinlock_t *punch_lock)
++{
++	swp_entry_t *ptr;
++	int freed = 0;
++
++	ptr = shmem_swp_map(subdir);
++	for (; offset < limit; offset += LATENCY_LIMIT) {
++		int size = limit - offset;
++		if (size > LATENCY_LIMIT)
++			size = LATENCY_LIMIT;
++		freed += shmem_free_swp(ptr+offset, ptr+offset+size,
++							punch_lock);
++		if (need_resched()) {
++			shmem_swp_unmap(ptr);
++			if (*dir) {
++				shmem_dir_unmap(*dir);
++				*dir = NULL;
++			}
++			cond_resched();
++			ptr = shmem_swp_map(subdir);
++		}
++	}
++	shmem_swp_unmap(ptr);
++	return freed;
++}
++
++static void shmem_free_pages(struct list_head *next)
++{
++	struct page *page;
++	int freed = 0;
++
++	do {
++		page = container_of(next, struct page, lru);
++		next = next->next;
++		shmem_dir_free(page);
++		freed++;
++		if (freed >= LATENCY_LIMIT) {
++			cond_resched();
++			freed = 0;
++		}
++	} while (next);
++}
++
++static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
++{
++	struct shmem_inode_info *info = SHMEM_I(inode);
++	unsigned long idx;
++	unsigned long size;
++	unsigned long limit;
++	unsigned long stage;
++	unsigned long diroff;
++	struct page **dir;
++	struct page *topdir;
++	struct page *middir;
++	struct page *subdir;
++	swp_entry_t *ptr;
++	LIST_HEAD(pages_to_free);
++	long nr_pages_to_free = 0;
++	long nr_swaps_freed = 0;
++	int offset;
++	int freed;
++	int punch_hole;
++	spinlock_t *needs_lock;
++	spinlock_t *punch_lock;
++	unsigned long upper_limit;
++
++	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
++	idx = (start + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
++	if (idx >= info->next_index)
++		return;
++
++	spin_lock(&info->lock);
++	info->flags |= SHMEM_TRUNCATE;
++	if (likely(end == (loff_t) -1)) {
++		limit = info->next_index;
++		upper_limit = SHMEM_MAX_INDEX;
++		info->next_index = idx;
++		needs_lock = NULL;
++		punch_hole = 0;
++	} else {
++		if (end + 1 >= inode->i_size) {	/* we may free a little more */
++			limit = (inode->i_size + PAGE_CACHE_SIZE - 1) >>
++							PAGE_CACHE_SHIFT;
++			upper_limit = SHMEM_MAX_INDEX;
++		} else {
++			limit = (end + 1) >> PAGE_CACHE_SHIFT;
++			upper_limit = limit;
++		}
++		needs_lock = &info->lock;
++		punch_hole = 1;
++	}
++
++	topdir = info->i_indirect;
++	if (topdir && idx <= SHMEM_NR_DIRECT && !punch_hole) {
++		info->i_indirect = NULL;
++		nr_pages_to_free++;
++		list_add(&topdir->lru, &pages_to_free);
++	}
++	spin_unlock(&info->lock);
++
++	if (info->swapped && idx < SHMEM_NR_DIRECT) {
++		ptr = info->i_direct;
++		size = limit;
++		if (size > SHMEM_NR_DIRECT)
++			size = SHMEM_NR_DIRECT;
++		nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size, needs_lock);
++	}
++
++	/*
++	 * If there are no indirect blocks or we are punching a hole
++	 * below indirect blocks, nothing to be done.
++	 */
++	if (!topdir || limit <= SHMEM_NR_DIRECT)
++		goto done2;
++
++	/*
++	 * The truncation case has already dropped info->lock, and we're safe
++	 * because i_size and next_index have already been lowered, preventing
++	 * access beyond.  But in the punch_hole case, we still need to take
++	 * the lock when updating the swap directory, because there might be
++	 * racing accesses by shmem_getpage(SGP_CACHE), shmem_unuse_inode or
++	 * shmem_writepage.  However, whenever we find we can remove a whole
++	 * directory page (not at the misaligned start or end of the range),
++	 * we first NULLify its pointer in the level above, and then have no
++	 * need to take the lock when updating its contents: needs_lock and
++	 * punch_lock (either pointing to info->lock or NULL) manage this.
++	 */
++
++	upper_limit -= SHMEM_NR_DIRECT;
++	limit -= SHMEM_NR_DIRECT;
++	idx = (idx > SHMEM_NR_DIRECT)? (idx - SHMEM_NR_DIRECT): 0;
++	offset = idx % ENTRIES_PER_PAGE;
++	idx -= offset;
++
++	dir = shmem_dir_map(topdir);
++	stage = ENTRIES_PER_PAGEPAGE/2;
++	if (idx < ENTRIES_PER_PAGEPAGE/2) {
++		middir = topdir;
++		diroff = idx/ENTRIES_PER_PAGE;
++	} else {
++		dir += ENTRIES_PER_PAGE/2;
++		dir += (idx - ENTRIES_PER_PAGEPAGE/2)/ENTRIES_PER_PAGEPAGE;
++		while (stage <= idx)
++			stage += ENTRIES_PER_PAGEPAGE;
++		middir = *dir;
++		if (*dir) {
++			diroff = ((idx - ENTRIES_PER_PAGEPAGE/2) %
++				ENTRIES_PER_PAGEPAGE) / ENTRIES_PER_PAGE;
++			if (!diroff && !offset && upper_limit >= stage) {
++				if (needs_lock) {
++					spin_lock(needs_lock);
++					*dir = NULL;
++					spin_unlock(needs_lock);
++					needs_lock = NULL;
++				} else
++					*dir = NULL;
++				nr_pages_to_free++;
++				list_add(&middir->lru, &pages_to_free);
++			}
++			shmem_dir_unmap(dir);
++			dir = shmem_dir_map(middir);
++		} else {
++			diroff = 0;
++			offset = 0;
++			idx = stage;
++		}
++	}
++
++	for (; idx < limit; idx += ENTRIES_PER_PAGE, diroff++) {
++		if (unlikely(idx == stage)) {
++			shmem_dir_unmap(dir);
++			dir = shmem_dir_map(topdir) +
++			    ENTRIES_PER_PAGE/2 + idx/ENTRIES_PER_PAGEPAGE;
++			while (!*dir) {
++				dir++;
++				idx += ENTRIES_PER_PAGEPAGE;
++				if (idx >= limit)
++					goto done1;
++			}
++			stage = idx + ENTRIES_PER_PAGEPAGE;
++			middir = *dir;
++			if (punch_hole)
++				needs_lock = &info->lock;
++			if (upper_limit >= stage) {
++				if (needs_lock) {
++					spin_lock(needs_lock);
++					*dir = NULL;
++					spin_unlock(needs_lock);
++					needs_lock = NULL;
++				} else
++					*dir = NULL;
++				nr_pages_to_free++;
++				list_add(&middir->lru, &pages_to_free);
++			}
++			shmem_dir_unmap(dir);
++			cond_resched();
++			dir = shmem_dir_map(middir);
++			diroff = 0;
++		}
++		punch_lock = needs_lock;
++		subdir = dir[diroff];
++		if (subdir && !offset && upper_limit-idx >= ENTRIES_PER_PAGE) {
++			if (needs_lock) {
++				spin_lock(needs_lock);
++				dir[diroff] = NULL;
++				spin_unlock(needs_lock);
++				punch_lock = NULL;
++			} else
++				dir[diroff] = NULL;
++			nr_pages_to_free++;
++			list_add(&subdir->lru, &pages_to_free);
++		}
++		if (subdir && page_private(subdir) /* has swap entries */) {
++			size = limit - idx;
++			if (size > ENTRIES_PER_PAGE)
++				size = ENTRIES_PER_PAGE;
++			freed = shmem_map_and_free_swp(subdir,
++					offset, size, &dir, punch_lock);
++			if (!dir)
++				dir = shmem_dir_map(middir);
++			nr_swaps_freed += freed;
++			if (offset || punch_lock) {
++				spin_lock(&info->lock);
++				set_page_private(subdir,
++					page_private(subdir) - freed);
++				spin_unlock(&info->lock);
++			} else
++				BUG_ON(page_private(subdir) != freed);
++		}
++		offset = 0;
++	}
++done1:
++	shmem_dir_unmap(dir);
++done2:
++	if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) {
++		/*
++		 * Call truncate_inode_pages again: racing shmem_unuse_inode
++		 * may have swizzled a page in from swap since
++		 * truncate_pagecache or generic_delete_inode did it, before we
++		 * lowered next_index.  Also, though shmem_getpage checks
++		 * i_size before adding to cache, no recheck after: so fix the
++		 * narrow window there too.
++		 *
++		 * Recalling truncate_inode_pages_range and unmap_mapping_range
++		 * every time for punch_hole (which never got a chance to clear
++		 * SHMEM_PAGEIN at the start of vmtruncate_range) is expensive,
++		 * yet hardly ever necessary: try to optimize them out later.
++		 */
++		truncate_inode_pages_range(inode->i_mapping, start, end);
++		if (punch_hole)
++			unmap_mapping_range(inode->i_mapping, start,
++							end - start, 1);
++	}
++
++	spin_lock(&info->lock);
++	info->flags &= ~SHMEM_TRUNCATE;
++	info->swapped -= nr_swaps_freed;
++	if (nr_pages_to_free)
++		shmem_free_blocks(inode, nr_pages_to_free);
++	shmem_recalc_inode(inode);
++	spin_unlock(&info->lock);
++
++	/*
++	 * Empty swap vector directory pages to be freed?
++	 */
++	if (!list_empty(&pages_to_free)) {
++		pages_to_free.prev->next = NULL;
++		shmem_free_pages(pages_to_free.next);
++	}
++}
++
++static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
++{
++	struct inode *inode = dentry->d_inode;
++	loff_t newsize = attr->ia_size;
++	int error;
++
++	if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)
++					&& newsize != inode->i_size) {
++		struct page *page = NULL;
++
++		if (newsize < inode->i_size) {
++			/*
++			 * If truncating down to a partial page, then
++			 * if that page is already allocated, hold it
++			 * in memory until the truncation is over, so
++			 * truncate_partial_page cannnot miss it were
++			 * it assigned to swap.
++			 */
++			if (newsize & (PAGE_CACHE_SIZE-1)) {
++				(void) shmem_getpage(inode,
++					newsize >> PAGE_CACHE_SHIFT,
++						&page, SGP_READ, NULL);
++				if (page)
++					unlock_page(page);
++			}
++			/*
++			 * Reset SHMEM_PAGEIN flag so that shmem_truncate can
++			 * detect if any pages might have been added to cache
++			 * after truncate_inode_pages.  But we needn't bother
++			 * if it's being fully truncated to zero-length: the
++			 * nrpages check is efficient enough in that case.
++			 */
++			if (newsize) {
++				struct shmem_inode_info *info = SHMEM_I(inode);
++				spin_lock(&info->lock);
++				info->flags &= ~SHMEM_PAGEIN;
++				spin_unlock(&info->lock);
++			}
++		}
++
++		error = simple_setsize(inode, newsize);
++		if (page)
++			page_cache_release(page);
++		if (error)
++			return error;
++		shmem_truncate_range(inode, newsize, (loff_t)-1);
++	}
++
++	error = inode_change_ok(inode, attr);
++	if (!error)
++		generic_setattr(inode, attr);
++#ifdef CONFIG_TMPFS_POSIX_ACL
++	if (!error && (attr->ia_valid & ATTR_MODE))
++		error = generic_acl_chmod(inode);
++#endif
++	return error;
++}
++
++static void shmem_delete_inode(struct inode *inode)
++{
++	struct shmem_inode_info *info = SHMEM_I(inode);
++
++	if (inode->i_mapping->a_ops == &shmem_aops) {
++		truncate_inode_pages(inode->i_mapping, 0);
++		shmem_unacct_size(info->flags, inode->i_size);
++		inode->i_size = 0;
++		shmem_truncate_range(inode, 0, (loff_t)-1);
++		if (!list_empty(&info->swaplist)) {
++			mutex_lock(&shmem_swaplist_mutex);
++			list_del_init(&info->swaplist);
++			mutex_unlock(&shmem_swaplist_mutex);
++		}
++	}
++	BUG_ON(inode->i_blocks);
++	shmem_free_inode(inode->i_sb);
++	clear_inode(inode);
++}
++
++static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *dir, swp_entry_t *edir)
++{
++	swp_entry_t *ptr;
++
++	for (ptr = dir; ptr < edir; ptr++) {
++		if (ptr->val == entry.val)
++			return ptr - dir;
++	}
++	return -1;
++}
++
++static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, struct page *page)
++{
++	struct inode *inode;
++	unsigned long idx;
++	unsigned long size;
++	unsigned long limit;
++	unsigned long stage;
++	struct page **dir;
++	struct page *subdir;
++	swp_entry_t *ptr;
++	int offset;
++	int error;
++
++	idx = 0;
++	ptr = info->i_direct;
++	spin_lock(&info->lock);
++	if (!info->swapped) {
++		list_del_init(&info->swaplist);
++		goto lost2;
++	}
++	limit = info->next_index;
++	size = limit;
++	if (size > SHMEM_NR_DIRECT)
++		size = SHMEM_NR_DIRECT;
++	offset = shmem_find_swp(entry, ptr, ptr+size);
++	if (offset >= 0)
++		goto found;
++	if (!info->i_indirect)
++		goto lost2;
++
++	dir = shmem_dir_map(info->i_indirect);
++	stage = SHMEM_NR_DIRECT + ENTRIES_PER_PAGEPAGE/2;
++
++	for (idx = SHMEM_NR_DIRECT; idx < limit; idx += ENTRIES_PER_PAGE, dir++) {
++		if (unlikely(idx == stage)) {
++			shmem_dir_unmap(dir-1);
++			if (cond_resched_lock(&info->lock)) {
++				/* check it has not been truncated */
++				if (limit > info->next_index) {
++					limit = info->next_index;
++					if (idx >= limit)
++						goto lost2;
++				}
++			}
++			dir = shmem_dir_map(info->i_indirect) +
++			    ENTRIES_PER_PAGE/2 + idx/ENTRIES_PER_PAGEPAGE;
++			while (!*dir) {
++				dir++;
++				idx += ENTRIES_PER_PAGEPAGE;
++				if (idx >= limit)
++					goto lost1;
++			}
++			stage = idx + ENTRIES_PER_PAGEPAGE;
++			subdir = *dir;
++			shmem_dir_unmap(dir);
++			dir = shmem_dir_map(subdir);
++		}
++		subdir = *dir;
++		if (subdir && page_private(subdir)) {
++			ptr = shmem_swp_map(subdir);
++			size = limit - idx;
++			if (size > ENTRIES_PER_PAGE)
++				size = ENTRIES_PER_PAGE;
++			offset = shmem_find_swp(entry, ptr, ptr+size);
++			shmem_swp_unmap(ptr);
++			if (offset >= 0) {
++				shmem_dir_unmap(dir);
++				goto found;
++			}
++		}
++	}
++lost1:
++	shmem_dir_unmap(dir-1);
++lost2:
++	spin_unlock(&info->lock);
++	return 0;
++found:
++	idx += offset;
++	inode = igrab(&info->vfs_inode);
++	spin_unlock(&info->lock);
++
++	/*
++	 * Move _head_ to start search for next from here.
++	 * But be careful: shmem_delete_inode checks list_empty without taking
++	 * mutex, and there's an instant in list_move_tail when info->swaplist
++	 * would appear empty, if it were the only one on shmem_swaplist.  We
++	 * could avoid doing it if inode NULL; or use this minor optimization.
++	 */
++	if (shmem_swaplist.next != &info->swaplist)
++		list_move_tail(&shmem_swaplist, &info->swaplist);
++	mutex_unlock(&shmem_swaplist_mutex);
++
++	error = 1;
++	if (!inode)
++		goto out;
++	/*
++	 * Charge page using GFP_KERNEL while we can wait.
++	 * Charged back to the user(not to caller) when swap account is used.
++	 * add_to_page_cache() will be called with GFP_NOWAIT.
++	 */
++	error = mem_cgroup_cache_charge(page, current->mm, GFP_KERNEL);
++	if (error)
++		goto out;
++	error = radix_tree_preload(GFP_KERNEL);
++	if (error) {
++		mem_cgroup_uncharge_cache_page(page);
++		goto out;
++	}
++	error = 1;
++
++	spin_lock(&info->lock);
++	ptr = shmem_swp_entry(info, idx, NULL);
++	if (ptr && ptr->val == entry.val) {
++		error = add_to_page_cache_locked(page, inode->i_mapping,
++						idx, GFP_NOWAIT);
++		/* does mem_cgroup_uncharge_cache_page on error */
++	} else	/* we must compensate for our precharge above */
++		mem_cgroup_uncharge_cache_page(page);
++
++	if (error == -EEXIST) {
++		struct page *filepage = find_get_page(inode->i_mapping, idx);
++		error = 1;
++		if (filepage) {
++			/*
++			 * There might be a more uptodate page coming down
++			 * from a stacked writepage: forget our swappage if so.
++			 */
++			if (PageUptodate(filepage))
++				error = 0;
++			page_cache_release(filepage);
++		}
++	}
++	if (!error) {
++		delete_from_swap_cache(page);
++		set_page_dirty(page);
++		info->flags |= SHMEM_PAGEIN;
++		shmem_swp_set(info, ptr, 0);
++		swap_free(entry);
++		error = 1;	/* not an error, but entry was found */
++	}
++	if (ptr)
++		shmem_swp_unmap(ptr);
++	spin_unlock(&info->lock);
++	radix_tree_preload_end();
++out:
++	unlock_page(page);
++	page_cache_release(page);
++	iput(inode);		/* allows for NULL */
++	return error;
++}
++
++/*
++ * shmem_unuse() search for an eventually swapped out shmem page.
++ */
++int shmem_unuse(swp_entry_t entry, struct page *page)
++{
++	struct list_head *p, *next;
++	struct shmem_inode_info *info;
++	int found = 0;
++
++	mutex_lock(&shmem_swaplist_mutex);
++	list_for_each_safe(p, next, &shmem_swaplist) {
++		info = list_entry(p, struct shmem_inode_info, swaplist);
++		found = shmem_unuse_inode(info, entry, page);
++		cond_resched();
++		if (found)
++			goto out;
++	}
++	mutex_unlock(&shmem_swaplist_mutex);
++	/*
++	 * Can some race bring us here?  We've been holding page lock,
++	 * so I think not; but would rather try again later than BUG()
++	 */
++	unlock_page(page);
++	page_cache_release(page);
++out:
++	return (found < 0) ? found : 0;
++}
++
++/*
++ * Move the page from the page cache to the swap cache.
++ */
++static int shmem_writepage(struct page *page, struct writeback_control *wbc)
++{
++	struct shmem_inode_info *info;
++	swp_entry_t *entry, swap;
++	struct address_space *mapping;
++	unsigned long index;
++	struct inode *inode;
++
++	BUG_ON(!PageLocked(page));
++	mapping = page->mapping;
++	index = page->index;
++	inode = mapping->host;
++	info = SHMEM_I(inode);
++	if (info->flags & VM_LOCKED)
++		goto redirty;
++	if (!total_swap_pages)
++		goto redirty;
++
++	/*
++	 * shmem_backing_dev_info's capabilities prevent regular writeback or
++	 * sync from ever calling shmem_writepage; but a stacking filesystem
++	 * may use the ->writepage of its underlying filesystem, in which case
++	 * tmpfs should write out to swap only in response to memory pressure,
++	 * and not for the writeback threads or sync.  However, in those cases,
++	 * we do still want to check if there's a redundant swappage to be
++	 * discarded.
++	 */
++	if (wbc->for_reclaim)
++		swap = get_swap_page();
++	else
++		swap.val = 0;
++
++	spin_lock(&info->lock);
++	if (index >= info->next_index) {
++		BUG_ON(!(info->flags & SHMEM_TRUNCATE));
++		goto unlock;
++	}
++	entry = shmem_swp_entry(info, index, NULL);
++	if (entry->val) {
++		/*
++		 * The more uptodate page coming down from a stacked
++		 * writepage should replace our old swappage.
++		 */
++		free_swap_and_cache(*entry);
++		shmem_swp_set(info, entry, 0);
++	}
++	shmem_recalc_inode(inode);
++
++	if (swap.val && add_to_swap_cache(page, swap, GFP_ATOMIC) == 0) {
++		remove_from_page_cache(page);
++		shmem_swp_set(info, entry, swap.val);
++		shmem_swp_unmap(entry);
++		if (list_empty(&info->swaplist))
++			inode = igrab(inode);
++		else
++			inode = NULL;
++		spin_unlock(&info->lock);
++		swap_shmem_alloc(swap);
++		BUG_ON(page_mapped(page));
++		page_cache_release(page);	/* pagecache ref */
++		swap_writepage(page, wbc);
++		if (inode) {
++			mutex_lock(&shmem_swaplist_mutex);
++			/* move instead of add in case we're racing */
++			list_move_tail(&info->swaplist, &shmem_swaplist);
++			mutex_unlock(&shmem_swaplist_mutex);
++			iput(inode);
++		}
++		return 0;
++	}
++
++	shmem_swp_unmap(entry);
++unlock:
++	spin_unlock(&info->lock);
++	/*
++	 * add_to_swap_cache() doesn't return -EEXIST, so we can safely
++	 * clear SWAP_HAS_CACHE flag.
++	 */
++	swapcache_free(swap, NULL);
++redirty:
++	set_page_dirty(page);
++	if (wbc->for_reclaim)
++		return AOP_WRITEPAGE_ACTIVATE;	/* Return with page locked */
++	unlock_page(page);
++	return 0;
++}
++
++#ifdef CONFIG_NUMA
++#ifdef CONFIG_TMPFS
++static void shmem_show_mpol(struct seq_file *seq, struct mempolicy *mpol)
++{
++	char buffer[64];
++
++	if (!mpol || mpol->mode == MPOL_DEFAULT)
++		return;		/* show nothing */
++
++	mpol_to_str(buffer, sizeof(buffer), mpol, 1);
++
++	seq_printf(seq, ",mpol=%s", buffer);
++}
++
++static struct mempolicy *shmem_get_sbmpol(struct shmem_sb_info *sbinfo)
++{
++	struct mempolicy *mpol = NULL;
++	if (sbinfo->mpol) {
++		spin_lock(&sbinfo->stat_lock);	/* prevent replace/use races */
++		mpol = sbinfo->mpol;
++		mpol_get(mpol);
++		spin_unlock(&sbinfo->stat_lock);
++	}
++	return mpol;
++}
++#endif /* CONFIG_TMPFS */
++
++static struct page *shmem_swapin(swp_entry_t entry, gfp_t gfp,
++			struct shmem_inode_info *info, unsigned long idx)
++{
++	struct mempolicy mpol, *spol;
++	struct vm_area_struct pvma;
++	struct page *page;
++
++	spol = mpol_cond_copy(&mpol,
++				mpol_shared_policy_lookup(&info->policy, idx));
++
++	/* Create a pseudo vma that just contains the policy */
++	pvma.vm_start = 0;
++	pvma.vm_pgoff = idx;
++	pvma.vm_ops = NULL;
++	pvma.vm_policy = spol;
++	page = swapin_readahead(entry, gfp, &pvma, 0);
++	return page;
++}
++
++static struct page *shmem_alloc_page(gfp_t gfp,
++			struct shmem_inode_info *info, unsigned long idx)
++{
++	struct vm_area_struct pvma;
++
++	/* Create a pseudo vma that just contains the policy */
++	pvma.vm_start = 0;
++	pvma.vm_pgoff = idx;
++	pvma.vm_ops = NULL;
++	pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx);
++
++	/*
++	 * alloc_page_vma() will drop the shared policy reference
++	 */
++	return alloc_page_vma(gfp, &pvma, 0);
++}
++#else /* !CONFIG_NUMA */
++#ifdef CONFIG_TMPFS
++static inline void shmem_show_mpol(struct seq_file *seq, struct mempolicy *p)
++{
++}
++#endif /* CONFIG_TMPFS */
++
++static inline struct page *shmem_swapin(swp_entry_t entry, gfp_t gfp,
++			struct shmem_inode_info *info, unsigned long idx)
++{
++	return swapin_readahead(entry, gfp, NULL, 0);
++}
++
++static inline struct page *shmem_alloc_page(gfp_t gfp,
++			struct shmem_inode_info *info, unsigned long idx)
++{
++	return alloc_page(gfp);
++}
++#endif /* CONFIG_NUMA */
++
++#if !defined(CONFIG_NUMA) || !defined(CONFIG_TMPFS)
++static inline struct mempolicy *shmem_get_sbmpol(struct shmem_sb_info *sbinfo)
++{
++	return NULL;
++}
++#endif
++
++/*
++ * shmem_getpage - either get the page from swap or allocate a new one
++ *
++ * If we allocate a new one we do not mark it dirty. That's up to the
++ * vm. If we swap it in we mark it dirty since we also free the swap
++ * entry since a page cannot live in both the swap and page cache
++ */
++static int shmem_getpage(struct inode *inode, unsigned long idx,
++			struct page **pagep, enum sgp_type sgp, int *type)
++{
++	struct address_space *mapping = inode->i_mapping;
++	struct shmem_inode_info *info = SHMEM_I(inode);
++	struct shmem_sb_info *sbinfo;
++	struct page *filepage = *pagep;
++	struct page *swappage;
++	swp_entry_t *entry;
++	swp_entry_t swap;
++	gfp_t gfp;
++	int error;
++
++	if (idx >= SHMEM_MAX_INDEX)
++		return -EFBIG;
++
++	if (type)
++		*type = 0;
++
++	/*
++	 * Normally, filepage is NULL on entry, and either found
++	 * uptodate immediately, or allocated and zeroed, or read
++	 * in under swappage, which is then assigned to filepage.
++	 * But shmem_readpage (required for splice) passes in a locked
++	 * filepage, which may be found not uptodate by other callers
++	 * too, and may need to be copied from the swappage read in.
++	 */
++repeat:
++	if (!filepage)
++		filepage = find_lock_page(mapping, idx);
++	if (filepage && PageUptodate(filepage))
++		goto done;
++	error = 0;
++	gfp = mapping_gfp_mask(mapping);
++	if (!filepage) {
++		/*
++		 * Try to preload while we can wait, to not make a habit of
++		 * draining atomic reserves; but don't latch on to this cpu.
++		 */
++		error = radix_tree_preload(gfp & ~__GFP_HIGHMEM);
++		if (error)
++			goto failed;
++		radix_tree_preload_end();
++	}
++
++	spin_lock(&info->lock);
++	shmem_recalc_inode(inode);
++	entry = shmem_swp_alloc(info, idx, sgp);
++	if (IS_ERR(entry)) {
++		spin_unlock(&info->lock);
++		error = PTR_ERR(entry);
++		goto failed;
++	}
++	swap = *entry;
++
++	if (swap.val) {
++		/* Look it up and read it in.. */
++		swappage = lookup_swap_cache(swap);
++		if (!swappage) {
++			shmem_swp_unmap(entry);
++			/* here we actually do the io */
++			if (type && !(*type & VM_FAULT_MAJOR)) {
++				__count_vm_event(PGMAJFAULT);
++				*type |= VM_FAULT_MAJOR;
++			}
++			spin_unlock(&info->lock);
++			swappage = shmem_swapin(swap, gfp, info, idx);
++			if (!swappage) {
++				spin_lock(&info->lock);
++				entry = shmem_swp_alloc(info, idx, sgp);
++				if (IS_ERR(entry))
++					error = PTR_ERR(entry);
++				else {
++					if (entry->val == swap.val)
++						error = -ENOMEM;
++					shmem_swp_unmap(entry);
++				}
++				spin_unlock(&info->lock);
++				if (error)
++					goto failed;
++				goto repeat;
++			}
++			wait_on_page_locked(swappage);
++			page_cache_release(swappage);
++			goto repeat;
++		}
++
++		/* We have to do this with page locked to prevent races */
++		if (!trylock_page(swappage)) {
++			shmem_swp_unmap(entry);
++			spin_unlock(&info->lock);
++			wait_on_page_locked(swappage);
++			page_cache_release(swappage);
++			goto repeat;
++		}
++		if (PageWriteback(swappage)) {
++			shmem_swp_unmap(entry);
++			spin_unlock(&info->lock);
++			wait_on_page_writeback(swappage);
++			unlock_page(swappage);
++			page_cache_release(swappage);
++			goto repeat;
++		}
++		if (!PageUptodate(swappage)) {
++			shmem_swp_unmap(entry);
++			spin_unlock(&info->lock);
++			unlock_page(swappage);
++			page_cache_release(swappage);
++			error = -EIO;
++			goto failed;
++		}
++
++		if (filepage) {
++			shmem_swp_set(info, entry, 0);
++			shmem_swp_unmap(entry);
++			delete_from_swap_cache(swappage);
++			spin_unlock(&info->lock);
++			copy_highpage(filepage, swappage);
++			unlock_page(swappage);
++			page_cache_release(swappage);
++			flush_dcache_page(filepage);
++			SetPageUptodate(filepage);
++			set_page_dirty(filepage);
++			swap_free(swap);
++		} else if (!(error = add_to_page_cache_locked(swappage, mapping,
++					idx, GFP_NOWAIT))) {
++			info->flags |= SHMEM_PAGEIN;
++			shmem_swp_set(info, entry, 0);
++			shmem_swp_unmap(entry);
++			delete_from_swap_cache(swappage);
++			spin_unlock(&info->lock);
++			filepage = swappage;
++			set_page_dirty(filepage);
++			swap_free(swap);
++		} else {
++			shmem_swp_unmap(entry);
++			spin_unlock(&info->lock);
++			if (error == -ENOMEM) {
++				/*
++				 * reclaim from proper memory cgroup and
++				 * call memcg's OOM if needed.
++				 */
++				error = mem_cgroup_shmem_charge_fallback(
++								swappage,
++								current->mm,
++								gfp);
++				if (error) {
++					unlock_page(swappage);
++					page_cache_release(swappage);
++					goto failed;
++				}
++			}
++			unlock_page(swappage);
++			page_cache_release(swappage);
++			goto repeat;
++		}
++	} else if (sgp == SGP_READ && !filepage) {
++		shmem_swp_unmap(entry);
++		filepage = find_get_page(mapping, idx);
++		if (filepage &&
++		    (!PageUptodate(filepage) || !trylock_page(filepage))) {
++			spin_unlock(&info->lock);
++			wait_on_page_locked(filepage);
++			page_cache_release(filepage);
++			filepage = NULL;
++			goto repeat;
++		}
++		spin_unlock(&info->lock);
++	} else {
++		shmem_swp_unmap(entry);
++		sbinfo = SHMEM_SB(inode->i_sb);
++		if (sbinfo->max_blocks) {
++			spin_lock(&sbinfo->stat_lock);
++			if (sbinfo->free_blocks == 0 ||
++			    shmem_acct_block(info->flags)) {
++				spin_unlock(&sbinfo->stat_lock);
++				spin_unlock(&info->lock);
++				error = -ENOSPC;
++				goto failed;
++			}
++			sbinfo->free_blocks--;
++			inode->i_blocks += BLOCKS_PER_PAGE;
++			spin_unlock(&sbinfo->stat_lock);
++		} else if (shmem_acct_block(info->flags)) {
++			spin_unlock(&info->lock);
++			error = -ENOSPC;
++			goto failed;
++		}
++
++		if (!filepage) {
++			int ret;
++
++			spin_unlock(&info->lock);
++			filepage = shmem_alloc_page(gfp, info, idx);
++			if (!filepage) {
++				shmem_unacct_blocks(info->flags, 1);
++				shmem_free_blocks(inode, 1);
++				error = -ENOMEM;
++				goto failed;
++			}
++			SetPageSwapBacked(filepage);
++
++			/* Precharge page while we can wait, compensate after */
++			error = mem_cgroup_cache_charge(filepage, current->mm,
++					GFP_KERNEL);
++			if (error) {
++				page_cache_release(filepage);
++				shmem_unacct_blocks(info->flags, 1);
++				shmem_free_blocks(inode, 1);
++				filepage = NULL;
++				goto failed;
++			}
++
++			spin_lock(&info->lock);
++			entry = shmem_swp_alloc(info, idx, sgp);
++			if (IS_ERR(entry))
++				error = PTR_ERR(entry);
++			else {
++				swap = *entry;
++				shmem_swp_unmap(entry);
++			}
++			ret = error || swap.val;
++			if (ret)
++				mem_cgroup_uncharge_cache_page(filepage);
++			else
++				ret = add_to_page_cache_lru(filepage, mapping,
++						idx, GFP_NOWAIT);
++			/*
++			 * At add_to_page_cache_lru() failure, uncharge will
++			 * be done automatically.
++			 */
++			if (ret) {
++				spin_unlock(&info->lock);
++				page_cache_release(filepage);
++				shmem_unacct_blocks(info->flags, 1);
++				shmem_free_blocks(inode, 1);
++				filepage = NULL;
++				if (error)
++					goto failed;
++				goto repeat;
++			}
++			info->flags |= SHMEM_PAGEIN;
++		}
++
++		info->alloced++;
++		spin_unlock(&info->lock);
++		clear_highpage(filepage);
++		flush_dcache_page(filepage);
++		SetPageUptodate(filepage);
++		if (sgp == SGP_DIRTY)
++			set_page_dirty(filepage);
++	}
++done:
++	*pagep = filepage;
++	return 0;
++
++failed:
++	if (*pagep != filepage) {
++		unlock_page(filepage);
++		page_cache_release(filepage);
++	}
++	return error;
++}
++
++static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
++{
++	struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
++	int error;
++	int ret;
++
++	if (((loff_t)vmf->pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode))
++		return VM_FAULT_SIGBUS;
++
++	error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, &ret);
++	if (error)
++		return ((error == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS);
++
++	return ret | VM_FAULT_LOCKED;
++}
++
++#ifdef CONFIG_NUMA
++static int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
++{
++	struct inode *i = vma->vm_file->f_path.dentry->d_inode;
++	return mpol_set_shared_policy(&SHMEM_I(i)->policy, vma, new);
++}
++
++static struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
++					  unsigned long addr)
++{
++	struct inode *i = vma->vm_file->f_path.dentry->d_inode;
++	unsigned long idx;
++
++	idx = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
++	return mpol_shared_policy_lookup(&SHMEM_I(i)->policy, idx);
++}
++#endif
++
++int shmem_lock(struct file *file, int lock, struct user_struct *user)
++{
++	struct inode *inode = file->f_path.dentry->d_inode;
++	struct shmem_inode_info *info = SHMEM_I(inode);
++	int retval = -ENOMEM;
++
++	spin_lock(&info->lock);
++	if (lock && !(info->flags & VM_LOCKED)) {
++		if (!user_shm_lock(inode->i_size, user))
++			goto out_nomem;
++		info->flags |= VM_LOCKED;
++		mapping_set_unevictable(file->f_mapping);
++	}
++	if (!lock && (info->flags & VM_LOCKED) && user) {
++		user_shm_unlock(inode->i_size, user);
++		info->flags &= ~VM_LOCKED;
++		mapping_clear_unevictable(file->f_mapping);
++		scan_mapping_unevictable_pages(file->f_mapping);
++	}
++	retval = 0;
++
++out_nomem:
++	spin_unlock(&info->lock);
++	return retval;
++}
++
++static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
++{
++	file_accessed(file);
++	vma->vm_ops = &shmem_vm_ops;
++	vma->vm_flags |= VM_CAN_NONLINEAR;
++	return 0;
++}
++
++static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir,
++				     int mode, dev_t dev, unsigned long flags)
++{
++	struct inode *inode;
++	struct shmem_inode_info *info;
++	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
++
++	if (shmem_reserve_inode(sb))
++		return NULL;
++
++	inode = new_inode(sb);
++	if (inode) {
++		inode_init_owner(inode, dir, mode);
++		inode->i_blocks = 0;
++		inode->i_mapping->backing_dev_info = &shmem_backing_dev_info;
++		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
++		inode->i_generation = get_seconds();
++		info = SHMEM_I(inode);
++		memset(info, 0, (char *)inode - (char *)info);
++		spin_lock_init(&info->lock);
++		info->flags = flags & VM_NORESERVE;
++		INIT_LIST_HEAD(&info->swaplist);
++		cache_no_acl(inode);
++
++		switch (mode & S_IFMT) {
++		default:
++			inode->i_op = &shmem_special_inode_operations;
++			init_special_inode(inode, mode, dev);
++			break;
++		case S_IFREG:
++			inode->i_mapping->a_ops = &shmem_aops;
++			inode->i_op = &shmem_inode_operations;
++			inode->i_fop = &shmem_file_operations;
++			mpol_shared_policy_init(&info->policy,
++						 shmem_get_sbmpol(sbinfo));
++			break;
++		case S_IFDIR:
++			inc_nlink(inode);
++			/* Some things misbehave if size == 0 on a directory */
++			inode->i_size = 2 * BOGO_DIRENT_SIZE;
++			inode->i_op = &shmem_dir_inode_operations;
++			inode->i_fop = &simple_dir_operations;
++			break;
++		case S_IFLNK:
++			/*
++			 * Must not load anything in the rbtree,
++			 * mpol_free_shared_policy will not be called.
++			 */
++			mpol_shared_policy_init(&info->policy, NULL);
++			break;
++		}
++	} else
++		shmem_free_inode(sb);
++	return inode;
++}
++
++#ifdef CONFIG_TMPFS
++static const struct inode_operations shmem_symlink_inode_operations;
++static const struct inode_operations shmem_symlink_inline_operations;
++
++/*
++ * Normally tmpfs avoids the use of shmem_readpage and shmem_write_begin;
++ * but providing them allows a tmpfs file to be used for splice, sendfile, and
++ * below the loop driver, in the generic fashion that many filesystems support.
++ */
++static int shmem_readpage(struct file *file, struct page *page)
++{
++	struct inode *inode = page->mapping->host;
++	int error = shmem_getpage(inode, page->index, &page, SGP_CACHE, NULL);
++	unlock_page(page);
++	return error;
++}
++
++static int
++shmem_write_begin(struct file *file, struct address_space *mapping,
++			loff_t pos, unsigned len, unsigned flags,
++			struct page **pagep, void **fsdata)
++{
++	struct inode *inode = mapping->host;
++	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
++	*pagep = NULL;
++	return shmem_getpage(inode, index, pagep, SGP_WRITE, NULL);
++}
++
++static int
++shmem_write_end(struct file *file, struct address_space *mapping,
++			loff_t pos, unsigned len, unsigned copied,
++			struct page *page, void *fsdata)
++{
++	struct inode *inode = mapping->host;
++
++	if (pos + copied > inode->i_size)
++		i_size_write(inode, pos + copied);
++
++	set_page_dirty(page);
++	unlock_page(page);
++	page_cache_release(page);
++
++	return copied;
++}
++
++static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_t *desc, read_actor_t actor)
++{
++	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct address_space *mapping = inode->i_mapping;
++	unsigned long index, offset;
++	enum sgp_type sgp = SGP_READ;
++
++	/*
++	 * Might this read be for a stacking filesystem?  Then when reading
++	 * holes of a sparse file, we actually need to allocate those pages,
++	 * and even mark them dirty, so it cannot exceed the max_blocks limit.
++	 */
++	if (segment_eq(get_fs(), KERNEL_DS))
++		sgp = SGP_DIRTY;
++
++	index = *ppos >> PAGE_CACHE_SHIFT;
++	offset = *ppos & ~PAGE_CACHE_MASK;
++
++	for (;;) {
++		struct page *page = NULL;
++		unsigned long end_index, nr, ret;
++		loff_t i_size = i_size_read(inode);
++
++		end_index = i_size >> PAGE_CACHE_SHIFT;
++		if (index > end_index)
++			break;
++		if (index == end_index) {
++			nr = i_size & ~PAGE_CACHE_MASK;
++			if (nr <= offset)
++				break;
++		}
++
++		desc->error = shmem_getpage(inode, index, &page, sgp, NULL);
++		if (desc->error) {
++			if (desc->error == -EINVAL)
++				desc->error = 0;
++			break;
++		}
++		if (page)
++			unlock_page(page);
++
++		/*
++		 * We must evaluate after, since reads (unlike writes)
++		 * are called without i_mutex protection against truncate
++		 */
++		nr = PAGE_CACHE_SIZE;
++		i_size = i_size_read(inode);
++		end_index = i_size >> PAGE_CACHE_SHIFT;
++		if (index == end_index) {
++			nr = i_size & ~PAGE_CACHE_MASK;
++			if (nr <= offset) {
++				if (page)
++					page_cache_release(page);
++				break;
++			}
++		}
++		nr -= offset;
++
++		if (page) {
++			/*
++			 * If users can be writing to this page using arbitrary
++			 * virtual addresses, take care about potential aliasing
++			 * before reading the page on the kernel side.
++			 */
++			if (mapping_writably_mapped(mapping))
++				flush_dcache_page(page);
++			/*
++			 * Mark the page accessed if we read the beginning.
++			 */
++			if (!offset)
++				mark_page_accessed(page);
++		} else {
++			page = ZERO_PAGE(0);
++			page_cache_get(page);
++		}
++
++		/*
++		 * Ok, we have the page, and it's up-to-date, so
++		 * now we can copy it to user space...
++		 *
++		 * The actor routine returns how many bytes were actually used..
++		 * NOTE! This may not be the same as how much of a user buffer
++		 * we filled up (we may be padding etc), so we can only update
++		 * "pos" here (the actor routine has to update the user buffer
++		 * pointers and the remaining count).
++		 */
++		ret = actor(desc, page, offset, nr);
++		offset += ret;
++		index += offset >> PAGE_CACHE_SHIFT;
++		offset &= ~PAGE_CACHE_MASK;
++
++		page_cache_release(page);
++		if (ret != nr || !desc->count)
++			break;
++
++		cond_resched();
++	}
++
++	*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
++	file_accessed(filp);
++}
++
++static ssize_t shmem_file_aio_read(struct kiocb *iocb,
++		const struct iovec *iov, unsigned long nr_segs, loff_t pos)
++{
++	struct file *filp = iocb->ki_filp;
++	ssize_t retval;
++	unsigned long seg;
++	size_t count;
++	loff_t *ppos = &iocb->ki_pos;
++
++	retval = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE);
++	if (retval)
++		return retval;
++
++	for (seg = 0; seg < nr_segs; seg++) {
++		read_descriptor_t desc;
++
++		desc.written = 0;
++		desc.arg.buf = iov[seg].iov_base;
++		desc.count = iov[seg].iov_len;
++		if (desc.count == 0)
++			continue;
++		desc.error = 0;
++		do_shmem_file_read(filp, ppos, &desc, file_read_actor);
++		retval += desc.written;
++		if (desc.error) {
++			retval = retval ?: desc.error;
++			break;
++		}
++		if (desc.count > 0)
++			break;
++	}
++	return retval;
++}
++
++static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf)
++{
++	struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
++
++	buf->f_type = TMPFS_MAGIC;
++	buf->f_bsize = PAGE_CACHE_SIZE;
++	buf->f_namelen = NAME_MAX;
++	spin_lock(&sbinfo->stat_lock);
++	if (sbinfo->max_blocks) {
++		buf->f_blocks = sbinfo->max_blocks;
++		buf->f_bavail = buf->f_bfree = sbinfo->free_blocks;
++	}
++	if (sbinfo->max_inodes) {
++		buf->f_files = sbinfo->max_inodes;
++		buf->f_ffree = sbinfo->free_inodes;
++	}
++	/* else leave those fields 0 like simple_statfs */
++	spin_unlock(&sbinfo->stat_lock);
++	return 0;
++}
++
++/*
++ * File creation. Allocate an inode, and we're done..
++ */
++static int
++shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
++{
++	struct inode *inode;
++	int error = -ENOSPC;
++
++	inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
++	if (inode) {
++		error = security_inode_init_security(inode, dir, NULL, NULL,
++						     NULL);
++		if (error) {
++			if (error != -EOPNOTSUPP) {
++				iput(inode);
++				return error;
++			}
++		}
++#ifdef CONFIG_TMPFS_POSIX_ACL
++		error = generic_acl_init(inode, dir);
++		if (error) {
++			iput(inode);
++			return error;
++		}
++#else
++		error = 0;
++#endif
++		dir->i_size += BOGO_DIRENT_SIZE;
++		dir->i_ctime = dir->i_mtime = CURRENT_TIME;
++		d_instantiate(dentry, inode);
++		dget(dentry); /* Extra count - pin the dentry in core */
++	}
++	return error;
++}
++
++static int shmem_mkdir(struct inode *dir, struct dentry *dentry, int mode)
++{
++	int error;
++
++	if ((error = shmem_mknod(dir, dentry, mode | S_IFDIR, 0)))
++		return error;
++	inc_nlink(dir);
++	return 0;
++}
++
++static int shmem_create(struct inode *dir, struct dentry *dentry, int mode,
++		struct nameidata *nd)
++{
++	return shmem_mknod(dir, dentry, mode | S_IFREG, 0);
++}
++
++/*
++ * Link a file..
++ */
++static int shmem_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
++{
++	struct inode *inode = old_dentry->d_inode;
++	int ret;
++
++	/*
++	 * No ordinary (disk based) filesystem counts links as inodes;
++	 * but each new link needs a new dentry, pinning lowmem, and
++	 * tmpfs dentries cannot be pruned until they are unlinked.
++	 */
++	ret = shmem_reserve_inode(inode->i_sb);
++	if (ret)
++		goto out;
++
++	dir->i_size += BOGO_DIRENT_SIZE;
++	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
++	inc_nlink(inode);
++	atomic_inc(&inode->i_count);	/* New dentry reference */
++	dget(dentry);		/* Extra pinning count for the created dentry */
++	d_instantiate(dentry, inode);
++out:
++	return ret;
++}
++
++static int shmem_unlink(struct inode *dir, struct dentry *dentry)
++{
++	struct inode *inode = dentry->d_inode;
++
++	if (inode->i_nlink > 1 && !S_ISDIR(inode->i_mode))
++		shmem_free_inode(inode->i_sb);
++
++	dir->i_size -= BOGO_DIRENT_SIZE;
++	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
++	drop_nlink(inode);
++	dput(dentry);	/* Undo the count from "create" - this does all the work */
++	return 0;
++}
++
++static int shmem_rmdir(struct inode *dir, struct dentry *dentry)
++{
++	if (!simple_empty(dentry))
++		return -ENOTEMPTY;
++
++	drop_nlink(dentry->d_inode);
++	drop_nlink(dir);
++	return shmem_unlink(dir, dentry);
++}
++
++/*
++ * The VFS layer already does all the dentry stuff for rename,
++ * we just have to decrement the usage count for the target if
++ * it exists so that the VFS layer correctly free's it when it
++ * gets overwritten.
++ */
++static int shmem_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
++{
++	struct inode *inode = old_dentry->d_inode;
++	int they_are_dirs = S_ISDIR(inode->i_mode);
++
++	if (!simple_empty(new_dentry))
++		return -ENOTEMPTY;
++
++	if (new_dentry->d_inode) {
++		(void) shmem_unlink(new_dir, new_dentry);
++		if (they_are_dirs)
++			drop_nlink(old_dir);
++	} else if (they_are_dirs) {
++		drop_nlink(old_dir);
++		inc_nlink(new_dir);
++	}
++
++	old_dir->i_size -= BOGO_DIRENT_SIZE;
++	new_dir->i_size += BOGO_DIRENT_SIZE;
++	old_dir->i_ctime = old_dir->i_mtime =
++	new_dir->i_ctime = new_dir->i_mtime =
++	inode->i_ctime = CURRENT_TIME;
++	return 0;
++}
++
++static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
++{
++	int error;
++	int len;
++	struct inode *inode;
++	struct page *page = NULL;
++	char *kaddr;
++	struct shmem_inode_info *info;
++
++	len = strlen(symname) + 1;
++	if (len > PAGE_CACHE_SIZE)
++		return -ENAMETOOLONG;
++
++	inode = shmem_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE);
++	if (!inode)
++		return -ENOSPC;
++
++	error = security_inode_init_security(inode, dir, NULL, NULL,
++					     NULL);
++	if (error) {
++		if (error != -EOPNOTSUPP) {
++			iput(inode);
++			return error;
++		}
++		error = 0;
++	}
++
++	info = SHMEM_I(inode);
++	inode->i_size = len-1;
++	if (len <= (char *)inode - (char *)info) {
++		/* do it inline */
++		memcpy(info, symname, len);
++		inode->i_op = &shmem_symlink_inline_operations;
++	} else {
++		error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL);
++		if (error) {
++			iput(inode);
++			return error;
++		}
++		inode->i_mapping->a_ops = &shmem_aops;
++		inode->i_op = &shmem_symlink_inode_operations;
++		kaddr = kmap_atomic(page, KM_USER0);
++		memcpy(kaddr, symname, len);
++		kunmap_atomic(kaddr, KM_USER0);
++		set_page_dirty(page);
++		unlock_page(page);
++		page_cache_release(page);
++	}
++	dir->i_size += BOGO_DIRENT_SIZE;
++	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
++	d_instantiate(dentry, inode);
++	dget(dentry);
++	return 0;
++}
++
++static void *shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
++{
++	nd_set_link(nd, (char *)SHMEM_I(dentry->d_inode));
++	return NULL;
++}
++
++static void *shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
++{
++	struct page *page = NULL;
++	int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL);
++	nd_set_link(nd, res ? ERR_PTR(res) : kmap(page));
++	if (page)
++		unlock_page(page);
++	return page;
++}
++
++static void shmem_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
++{
++	if (!IS_ERR(nd_get_link(nd))) {
++		struct page *page = cookie;
++		kunmap(page);
++		mark_page_accessed(page);
++		page_cache_release(page);
++	}
++}
++
++static const struct inode_operations shmem_symlink_inline_operations = {
++	.readlink	= generic_readlink,
++	.follow_link	= shmem_follow_link_inline,
++};
++
++static const struct inode_operations shmem_symlink_inode_operations = {
++	.readlink	= generic_readlink,
++	.follow_link	= shmem_follow_link,
++	.put_link	= shmem_put_link,
++};
++
++#ifdef CONFIG_TMPFS_POSIX_ACL
++/*
++ * Superblocks without xattr inode operations will get security.* xattr
++ * support from the VFS "for free". As soon as we have any other xattrs
++ * like ACLs, we also need to implement the security.* handlers at
++ * filesystem level, though.
++ */
++
++static size_t shmem_xattr_security_list(struct dentry *dentry, char *list,
++					size_t list_len, const char *name,
++					size_t name_len, int handler_flags)
++{
++	return security_inode_listsecurity(dentry->d_inode, list, list_len);
++}
++
++static int shmem_xattr_security_get(struct dentry *dentry, const char *name,
++		void *buffer, size_t size, int handler_flags)
++{
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	return xattr_getsecurity(dentry->d_inode, name, buffer, size);
++}
++
++static int shmem_xattr_security_set(struct dentry *dentry, const char *name,
++		const void *value, size_t size, int flags, int handler_flags)
++{
++	if (strcmp(name, "") == 0)
++		return -EINVAL;
++	return security_inode_setsecurity(dentry->d_inode, name, value,
++					  size, flags);
++}
++
++static const struct xattr_handler shmem_xattr_security_handler = {
++	.prefix = XATTR_SECURITY_PREFIX,
++	.list   = shmem_xattr_security_list,
++	.get    = shmem_xattr_security_get,
++	.set    = shmem_xattr_security_set,
++};
++
++static const struct xattr_handler *shmem_xattr_handlers[] = {
++	&generic_acl_access_handler,
++	&generic_acl_default_handler,
++	&shmem_xattr_security_handler,
++	NULL
++};
++#endif
++
++static struct dentry *shmem_get_parent(struct dentry *child)
++{
++	return ERR_PTR(-ESTALE);
++}
++
++static int shmem_match(struct inode *ino, void *vfh)
++{
++	__u32 *fh = vfh;
++	__u64 inum = fh[2];
++	inum = (inum << 32) | fh[1];
++	return ino->i_ino == inum && fh[0] == ino->i_generation;
++}
++
++static struct dentry *shmem_fh_to_dentry(struct super_block *sb,
++		struct fid *fid, int fh_len, int fh_type)
++{
++	struct inode *inode;
++	struct dentry *dentry = NULL;
++	u64 inum = fid->raw[2];
++	inum = (inum << 32) | fid->raw[1];
++
++	if (fh_len < 3)
++		return NULL;
++
++	inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]),
++			shmem_match, fid->raw);
++	if (inode) {
++		dentry = d_find_alias(inode);
++		iput(inode);
++	}
++
++	return dentry;
++}
++
++static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
++				int connectable)
++{
++	struct inode *inode = dentry->d_inode;
++
++	if (*len < 3)
++		return 255;
++
++	if (hlist_unhashed(&inode->i_hash)) {
++		/* Unfortunately insert_inode_hash is not idempotent,
++		 * so as we hash inodes here rather than at creation
++		 * time, we need a lock to ensure we only try
++		 * to do it once
++		 */
++		static DEFINE_SPINLOCK(lock);
++		spin_lock(&lock);
++		if (hlist_unhashed(&inode->i_hash))
++			__insert_inode_hash(inode,
++					    inode->i_ino + inode->i_generation);
++		spin_unlock(&lock);
++	}
++
++	fh[0] = inode->i_generation;
++	fh[1] = inode->i_ino;
++	fh[2] = ((__u64)inode->i_ino) >> 32;
++
++	*len = 3;
++	return 1;
++}
++
++static const struct export_operations shmem_export_ops = {
++	.get_parent     = shmem_get_parent,
++	.encode_fh      = shmem_encode_fh,
++	.fh_to_dentry	= shmem_fh_to_dentry,
++};
++
++static int shmem_parse_options(char *options, struct shmem_sb_info *sbinfo,
++			       bool remount)
++{
++	char *this_char, *value, *rest;
++
++	while (options != NULL) {
++		this_char = options;
++		for (;;) {
++			/*
++			 * NUL-terminate this option: unfortunately,
++			 * mount options form a comma-separated list,
++			 * but mpol's nodelist may also contain commas.
++			 */
++			options = strchr(options, ',');
++			if (options == NULL)
++				break;
++			options++;
++			if (!isdigit(*options)) {
++				options[-1] = '\0';
++				break;
++			}
++		}
++		if (!*this_char)
++			continue;
++		if ((value = strchr(this_char,'=')) != NULL) {
++			*value++ = 0;
++		} else {
++			printk(KERN_ERR
++			    "tmpfs: No value for mount option '%s'\n",
++			    this_char);
++			return 1;
++		}
++
++		if (!strcmp(this_char,"size")) {
++			unsigned long long size;
++			size = memparse(value,&rest);
++			if (*rest == '%') {
++				size <<= PAGE_SHIFT;
++				size *= totalram_pages;
++				do_div(size, 100);
++				rest++;
++			}
++			if (*rest)
++				goto bad_val;
++			sbinfo->max_blocks =
++				DIV_ROUND_UP(size, PAGE_CACHE_SIZE);
++		} else if (!strcmp(this_char,"nr_blocks")) {
++			sbinfo->max_blocks = memparse(value, &rest);
++			if (*rest)
++				goto bad_val;
++		} else if (!strcmp(this_char,"nr_inodes")) {
++			sbinfo->max_inodes = memparse(value, &rest);
++			if (*rest)
++				goto bad_val;
++		} else if (!strcmp(this_char,"mode")) {
++			if (remount)
++				continue;
++			sbinfo->mode = simple_strtoul(value, &rest, 8) & 07777;
++			if (*rest)
++				goto bad_val;
++		} else if (!strcmp(this_char,"uid")) {
++			if (remount)
++				continue;
++			sbinfo->uid = simple_strtoul(value, &rest, 0);
++			if (*rest)
++				goto bad_val;
++		} else if (!strcmp(this_char,"gid")) {
++			if (remount)
++				continue;
++			sbinfo->gid = simple_strtoul(value, &rest, 0);
++			if (*rest)
++				goto bad_val;
++		} else if (!strcmp(this_char,"mpol")) {
++			if (mpol_parse_str(value, &sbinfo->mpol, 1))
++				goto bad_val;
++		} else {
++			printk(KERN_ERR "tmpfs: Bad mount option %s\n",
++			       this_char);
++			return 1;
++		}
++	}
++	return 0;
++
++bad_val:
++	printk(KERN_ERR "tmpfs: Bad value '%s' for mount option '%s'\n",
++	       value, this_char);
++	return 1;
++
++}
++
++static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
++{
++	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
++	struct shmem_sb_info config = *sbinfo;
++	unsigned long blocks;
++	unsigned long inodes;
++	int error = -EINVAL;
++
++	if (shmem_parse_options(data, &config, true))
++		return error;
++
++	spin_lock(&sbinfo->stat_lock);
++	blocks = sbinfo->max_blocks - sbinfo->free_blocks;
++	inodes = sbinfo->max_inodes - sbinfo->free_inodes;
++	if (config.max_blocks < blocks)
++		goto out;
++	if (config.max_inodes < inodes)
++		goto out;
++	/*
++	 * Those tests also disallow limited->unlimited while any are in
++	 * use, so i_blocks will always be zero when max_blocks is zero;
++	 * but we must separately disallow unlimited->limited, because
++	 * in that case we have no record of how much is already in use.
++	 */
++	if (config.max_blocks && !sbinfo->max_blocks)
++		goto out;
++	if (config.max_inodes && !sbinfo->max_inodes)
++		goto out;
++
++	error = 0;
++	sbinfo->max_blocks  = config.max_blocks;
++	sbinfo->free_blocks = config.max_blocks - blocks;
++	sbinfo->max_inodes  = config.max_inodes;
++	sbinfo->free_inodes = config.max_inodes - inodes;
++
++	mpol_put(sbinfo->mpol);
++	sbinfo->mpol        = config.mpol;	/* transfers initial ref */
++out:
++	spin_unlock(&sbinfo->stat_lock);
++	return error;
++}
++
++static int shmem_show_options(struct seq_file *seq, struct vfsmount *vfs)
++{
++	struct shmem_sb_info *sbinfo = SHMEM_SB(vfs->mnt_sb);
++
++	if (sbinfo->max_blocks != shmem_default_max_blocks())
++		seq_printf(seq, ",size=%luk",
++			sbinfo->max_blocks << (PAGE_CACHE_SHIFT - 10));
++	if (sbinfo->max_inodes != shmem_default_max_inodes())
++		seq_printf(seq, ",nr_inodes=%lu", sbinfo->max_inodes);
++	if (sbinfo->mode != (S_IRWXUGO | S_ISVTX))
++		seq_printf(seq, ",mode=%03o", sbinfo->mode);
++	if (sbinfo->uid != 0)
++		seq_printf(seq, ",uid=%u", sbinfo->uid);
++	if (sbinfo->gid != 0)
++		seq_printf(seq, ",gid=%u", sbinfo->gid);
++	shmem_show_mpol(seq, sbinfo->mpol);
++	return 0;
++}
++#endif /* CONFIG_TMPFS */
++
++static void shmem_put_super(struct super_block *sb)
++{
++	kfree(sb->s_fs_info);
++	sb->s_fs_info = NULL;
++}
++
++int shmem_fill_super(struct super_block *sb, void *data, int silent)
++{
++	struct inode *inode;
++	struct dentry *root;
++	struct shmem_sb_info *sbinfo;
++	int err = -ENOMEM;
++
++	/* Round up to L1_CACHE_BYTES to resist false sharing */
++	sbinfo = kzalloc(max((int)sizeof(struct shmem_sb_info),
++				L1_CACHE_BYTES), GFP_KERNEL);
++	if (!sbinfo)
++		return -ENOMEM;
++
++	sbinfo->mode = S_IRWXUGO | S_ISVTX;
++	sbinfo->uid = current_fsuid();
++	sbinfo->gid = current_fsgid();
++	sb->s_fs_info = sbinfo;
++
++#ifdef CONFIG_TMPFS
++	/*
++	 * Per default we only allow half of the physical ram per
++	 * tmpfs instance, limiting inodes to one per page of lowmem;
++	 * but the internal instance is left unlimited.
++	 */
++	if (!(sb->s_flags & MS_NOUSER)) {
++		sbinfo->max_blocks = shmem_default_max_blocks();
++		sbinfo->max_inodes = shmem_default_max_inodes();
++		if (shmem_parse_options(data, sbinfo, false)) {
++			err = -EINVAL;
++			goto failed;
++		}
++	}
++	sb->s_export_op = &shmem_export_ops;
++#else
++	sb->s_flags |= MS_NOUSER;
++#endif
++
++	spin_lock_init(&sbinfo->stat_lock);
++	sbinfo->free_blocks = sbinfo->max_blocks;
++	sbinfo->free_inodes = sbinfo->max_inodes;
++
++	sb->s_maxbytes = SHMEM_MAX_BYTES;
++	sb->s_blocksize = PAGE_CACHE_SIZE;
++	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
++	sb->s_magic = TMPFS_MAGIC;
++	sb->s_op = &shmem_ops;
++	sb->s_time_gran = 1;
++#ifdef CONFIG_TMPFS_POSIX_ACL
++	sb->s_xattr = shmem_xattr_handlers;
++	sb->s_flags |= MS_POSIXACL;
++#endif
++
++	inode = shmem_get_inode(sb, NULL, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE);
++	if (!inode)
++		goto failed;
++	inode->i_uid = sbinfo->uid;
++	inode->i_gid = sbinfo->gid;
++	root = d_alloc_root(inode);
++	if (!root)
++		goto failed_iput;
++	sb->s_root = root;
++	return 0;
++
++failed_iput:
++	iput(inode);
++failed:
++	shmem_put_super(sb);
++	return err;
++}
++
++static struct kmem_cache *shmem_inode_cachep;
++
++static struct inode *shmem_alloc_inode(struct super_block *sb)
++{
++	struct shmem_inode_info *p;
++	p = (struct shmem_inode_info *)kmem_cache_alloc(shmem_inode_cachep, GFP_KERNEL);
++	if (!p)
++		return NULL;
++	return &p->vfs_inode;
++}
++
++static void shmem_destroy_inode(struct inode *inode)
++{
++	if ((inode->i_mode & S_IFMT) == S_IFREG) {
++		/* only struct inode is valid if it's an inline symlink */
++		mpol_free_shared_policy(&SHMEM_I(inode)->policy);
++	}
++	kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
++}
++
++static void init_once(void *foo)
++{
++	struct shmem_inode_info *p = (struct shmem_inode_info *) foo;
++
++	inode_init_once(&p->vfs_inode);
++}
++
++static int init_inodecache(void)
++{
++	shmem_inode_cachep = kmem_cache_create("shmem_inode_cache",
++				sizeof(struct shmem_inode_info),
++				0, SLAB_PANIC, init_once);
++	return 0;
++}
++
++static void destroy_inodecache(void)
++{
++	kmem_cache_destroy(shmem_inode_cachep);
++}
++
++static const struct address_space_operations shmem_aops = {
++	.writepage	= shmem_writepage,
++	.set_page_dirty	= __set_page_dirty_no_writeback,
++#ifdef CONFIG_TMPFS
++	.readpage	= shmem_readpage,
++	.write_begin	= shmem_write_begin,
++	.write_end	= shmem_write_end,
++#endif
++	.migratepage	= migrate_page,
++	.error_remove_page = generic_error_remove_page,
++};
++
++static const struct file_operations shmem_file_operations = {
++	.mmap		= shmem_mmap,
++#ifdef CONFIG_TMPFS
++	.llseek		= generic_file_llseek,
++	.read		= do_sync_read,
++	.write		= do_sync_write,
++	.aio_read	= shmem_file_aio_read,
++	.aio_write	= generic_file_aio_write,
++	.fsync		= noop_fsync,
++	.splice_read	= generic_file_splice_read,
++	.splice_write	= generic_file_splice_write,
++#endif
++};
++
++static const struct inode_operations shmem_inode_operations = {
++	.setattr	= shmem_notify_change,
++	.truncate_range	= shmem_truncate_range,
++#ifdef CONFIG_TMPFS_POSIX_ACL
++	.setxattr	= generic_setxattr,
++	.getxattr	= generic_getxattr,
++	.listxattr	= generic_listxattr,
++	.removexattr	= generic_removexattr,
++	.check_acl	= generic_check_acl,
++#endif
++
++};
++
++static const struct inode_operations shmem_dir_inode_operations = {
++#ifdef CONFIG_TMPFS
++	.create		= shmem_create,
++	.lookup		= simple_lookup,
++	.link		= shmem_link,
++	.unlink		= shmem_unlink,
++	.symlink	= shmem_symlink,
++	.mkdir		= shmem_mkdir,
++	.rmdir		= shmem_rmdir,
++	.mknod		= shmem_mknod,
++	.rename		= shmem_rename,
++#endif
++#ifdef CONFIG_TMPFS_POSIX_ACL
++	.setattr	= shmem_notify_change,
++	.setxattr	= generic_setxattr,
++	.getxattr	= generic_getxattr,
++	.listxattr	= generic_listxattr,
++	.removexattr	= generic_removexattr,
++	.check_acl	= generic_check_acl,
++#endif
++};
++
++static const struct inode_operations shmem_special_inode_operations = {
++#ifdef CONFIG_TMPFS_POSIX_ACL
++	.setattr	= shmem_notify_change,
++	.setxattr	= generic_setxattr,
++	.getxattr	= generic_getxattr,
++	.listxattr	= generic_listxattr,
++	.removexattr	= generic_removexattr,
++	.check_acl	= generic_check_acl,
++#endif
++};
++
++static const struct super_operations shmem_ops = {
++	.alloc_inode	= shmem_alloc_inode,
++	.destroy_inode	= shmem_destroy_inode,
++#ifdef CONFIG_TMPFS
++	.statfs		= shmem_statfs,
++	.remount_fs	= shmem_remount_fs,
++	.show_options	= shmem_show_options,
++#endif
++	.delete_inode	= shmem_delete_inode,
++	.drop_inode	= generic_delete_inode,
++	.put_super	= shmem_put_super,
++};
++
++static const struct vm_operations_struct shmem_vm_ops = {
++	.fault		= shmem_fault,
++#ifdef CONFIG_NUMA
++	.set_policy     = shmem_set_policy,
++	.get_policy     = shmem_get_policy,
++#endif
++};
++
++
++static int shmem_get_sb(struct file_system_type *fs_type,
++	int flags, const char *dev_name, void *data, struct vfsmount *mnt)
++{
++	return get_sb_nodev(fs_type, flags, data, shmem_fill_super, mnt);
++}
++
++static struct file_system_type tmpfs_fs_type = {
++	.owner		= THIS_MODULE,
++	.name		= "tmpfs",
++	.get_sb		= shmem_get_sb,
++	.kill_sb	= kill_litter_super,
++};
++
++int __init init_tmpfs(void)
++{
++	int error;
++
++	error = bdi_init(&shmem_backing_dev_info);
++	if (error)
++		goto out4;
++
++	error = init_inodecache();
++	if (error)
++		goto out3;
++
++	error = register_filesystem(&tmpfs_fs_type);
++	if (error) {
++		printk(KERN_ERR "Could not register tmpfs\n");
++		goto out2;
++	}
++
++	shm_mnt = vfs_kern_mount(&tmpfs_fs_type, MS_NOUSER,
++				tmpfs_fs_type.name, NULL);
++	if (IS_ERR(shm_mnt)) {
++		error = PTR_ERR(shm_mnt);
++		printk(KERN_ERR "Could not kern_mount tmpfs\n");
++		goto out1;
++	}
++	return 0;
++
++out1:
++	unregister_filesystem(&tmpfs_fs_type);
++out2:
++	destroy_inodecache();
++out3:
++	bdi_destroy(&shmem_backing_dev_info);
++out4:
++	shm_mnt = ERR_PTR(error);
++	return error;
++}
++
++#ifdef CONFIG_CGROUP_MEM_RES_CTLR
++/**
++ * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file
++ * @inode: the inode to be searched
++ * @pgoff: the offset to be searched
++ * @pagep: the pointer for the found page to be stored
++ * @ent: the pointer for the found swap entry to be stored
++ *
++ * If a page is found, refcount of it is incremented. Callers should handle
++ * these refcount.
++ */
++void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff,
++					struct page **pagep, swp_entry_t *ent)
++{
++	swp_entry_t entry = { .val = 0 }, *ptr;
++	struct page *page = NULL;
++	struct shmem_inode_info *info = SHMEM_I(inode);
++
++	if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode))
++		goto out;
++
++	spin_lock(&info->lock);
++	ptr = shmem_swp_entry(info, pgoff, NULL);
++#ifdef CONFIG_SWAP
++	if (ptr && ptr->val) {
++		entry.val = ptr->val;
++		page = find_get_page(&swapper_space, entry.val);
++	} else
++#endif
++		page = find_get_page(inode->i_mapping, pgoff);
++	if (ptr)
++		shmem_swp_unmap(ptr);
++	spin_unlock(&info->lock);
++out:
++	*pagep = page;
++	*ent = entry;
++}
++#endif
++
++#else /* !CONFIG_SHMEM */
++
++/*
++ * tiny-shmem: simple shmemfs and tmpfs using ramfs code
++ *
++ * This is intended for small system where the benefits of the full
++ * shmem code (swap-backed and resource-limited) are outweighed by
++ * their complexity. On systems without swap this code should be
++ * effectively equivalent, but much lighter weight.
++ */
++
++#include <linux/ramfs.h>
++
++static struct file_system_type tmpfs_fs_type = {
++	.name		= "tmpfs",
++	.get_sb		= ramfs_get_sb,
++	.kill_sb	= kill_litter_super,
++};
++
++int __init init_tmpfs(void)
++{
++	BUG_ON(register_filesystem(&tmpfs_fs_type) != 0);
++
++	shm_mnt = kern_mount(&tmpfs_fs_type);
++	BUG_ON(IS_ERR(shm_mnt));
++
++	return 0;
++}
++
++int shmem_unuse(swp_entry_t entry, struct page *page)
++{
++	return 0;
++}
++
++int shmem_lock(struct file *file, int lock, struct user_struct *user)
++{
++	return 0;
++}
++
++#ifdef CONFIG_CGROUP_MEM_RES_CTLR
++/**
++ * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file
++ * @inode: the inode to be searched
++ * @pgoff: the offset to be searched
++ * @pagep: the pointer for the found page to be stored
++ * @ent: the pointer for the found swap entry to be stored
++ *
++ * If a page is found, refcount of it is incremented. Callers should handle
++ * these refcount.
++ */
++void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff,
++					struct page **pagep, swp_entry_t *ent)
++{
++	struct page *page = NULL;
++
++	if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode))
++		goto out;
++	page = find_get_page(inode->i_mapping, pgoff);
++out:
++	*pagep = page;
++	*ent = (swp_entry_t){ .val = 0 };
++}
++#endif
++
++#define shmem_vm_ops				generic_file_vm_ops
++#define shmem_file_operations			ramfs_file_operations
++#define shmem_get_inode(sb, dir, mode, dev, flags)	ramfs_get_inode(sb, dir, mode, dev)
++#define shmem_acct_size(flags, size)		0
++#define shmem_unacct_size(flags, size)		do {} while (0)
++#define SHMEM_MAX_BYTES				MAX_LFS_FILESIZE
++
++#endif /* CONFIG_SHMEM */
++
++/* common code */
++
++/**
++ * shmem_file_setup - get an unlinked file living in tmpfs
++ * @name: name for dentry (to be seen in /proc/<pid>/maps
++ * @size: size to be set for the file
++ * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size
++ */
++struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
++{
++	int error;
++	struct file *file;
++	struct inode *inode;
++	struct path path;
++	struct dentry *root;
++	struct qstr this;
++
++	if (IS_ERR(shm_mnt))
++		return (void *)shm_mnt;
++
++	if (size < 0 || size > SHMEM_MAX_BYTES)
++		return ERR_PTR(-EINVAL);
++
++	if (shmem_acct_size(flags, size))
++		return ERR_PTR(-ENOMEM);
++
++	error = -ENOMEM;
++	this.name = name;
++	this.len = strlen(name);
++	this.hash = 0; /* will go */
++	root = shm_mnt->mnt_root;
++	path.dentry = d_alloc(root, &this);
++	if (!path.dentry)
++		goto put_memory;
++	path.mnt = mntget(shm_mnt);
++
++	error = -ENOSPC;
++	inode = shmem_get_inode(root->d_sb, NULL, S_IFREG | S_IRWXUGO, 0, flags);
++	if (!inode)
++		goto put_dentry;
++
++	d_instantiate(path.dentry, inode);
++	inode->i_size = size;
++	inode->i_nlink = 0;	/* It is unlinked */
++#ifndef CONFIG_MMU
++	error = ramfs_nommu_expand_for_mapping(inode, size);
++	if (error)
++		goto put_dentry;
++#endif
++
++	error = -ENFILE;
++	file = alloc_file(&path, FMODE_WRITE | FMODE_READ,
++		  &shmem_file_operations);
++	if (!file)
++		goto put_dentry;
++
++	return file;
++
++put_dentry:
++	path_put(&path);
++put_memory:
++	shmem_unacct_size(flags, size);
++	return ERR_PTR(error);
++}
++EXPORT_SYMBOL_GPL(shmem_file_setup);
++
++/**
++ * shmem_zero_setup - setup a shared anonymous mapping
++ * @vma: the vma to be mmapped is prepared by do_mmap_pgoff
++ */
++int shmem_zero_setup(struct vm_area_struct *vma)
++{
++	struct file *file;
++	loff_t size = vma->vm_end - vma->vm_start;
++
++	file = shmem_file_setup("dev/zero", size, vma->vm_flags);
++	if (IS_ERR(file))
++		return PTR_ERR(file);
++
++	if (vma->vm_file)
++		fput(vma->vm_file);
++	vma->vm_file = file;
++	vma->vm_ops = &shmem_vm_ops;
++	return 0;
++}
+diff -rupN linux-2.6.35.11/mm/swap.c linux-2.6.35.11-ts7500/mm/swap.c
+--- linux-2.6.35.11/mm/swap.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/mm/swap.c	2011-03-14 11:18:24.000000000 -0400
+@@ -500,6 +500,8 @@ void __init swap_setup(void)
+ {
+ 	unsigned long megs = totalram_pages >> (20 - PAGE_SHIFT);
+ 
++   //printk("swap_setup(), calling bdi_init()\n");
++   
+ #ifdef CONFIG_SWAP
+ 	bdi_init(swapper_space.backing_dev_info);
+ #endif
+diff -rupN linux-2.6.35.11/net/bridge/Kconfig linux-2.6.35.11-ts7500/net/bridge/Kconfig
+--- linux-2.6.35.11/net/bridge/Kconfig	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/net/bridge/Kconfig	2011-03-14 11:18:24.000000000 -0400
+@@ -32,6 +32,17 @@ config BRIDGE
+ 
+ 	  If unsure, say N.
+ 
++if BRIDGE
++config BRIDGE_ID_POLICY_MINIMUM
++	bool "Bridge ID select policy - minimum"
++	default n
++	help
++	  The policy to choose bridge ID. If you say Y, the bridge would choose 
++	  the minimum bridge port ID as it's ID. This feature will affect PCI 
++	  fastpath function of Star's STR9100 series.
++	  
++endif     
++     
+ config BRIDGE_IGMP_SNOOPING
+ 	bool "IGMP/MLD snooping"
+ 	depends on BRIDGE
+diff -rupN linux-2.6.35.11/net/core/net_namespace.c linux-2.6.35.11-ts7500/net/core/net_namespace.c
+--- linux-2.6.35.11/net/core/net_namespace.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/net/core/net_namespace.c	2011-03-14 11:18:24.000000000 -0400
+@@ -346,6 +346,7 @@ static int __init net_ns_init(void)
+ 	struct net_generic *ng;
+ 
+ #ifdef CONFIG_NET_NS
++  	printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net));
+ 	net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
+ 					SMP_CACHE_BYTES,
+ 					SLAB_PANIC, NULL);
+diff -rupN linux-2.6.35.11/security/min_addr.c linux-2.6.35.11-ts7500/security/min_addr.c
+--- linux-2.6.35.11/security/min_addr.c	2011-02-06 14:04:07.000000000 -0500
++++ linux-2.6.35.11-ts7500/security/min_addr.c	2011-03-14 11:18:24.000000000 -0400
+@@ -14,6 +14,7 @@ unsigned long dac_mmap_min_addr = CONFIG
+  */
+ static void update_mmap_min_addr(void)
+ {
++   
+ #ifdef CONFIG_LSM_MMAP_MIN_ADDR
+ 	if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR)
+ 		mmap_min_addr = dac_mmap_min_addr;
+@@ -22,6 +23,7 @@ static void update_mmap_min_addr(void)
+ #else
+ 	mmap_min_addr = dac_mmap_min_addr;
+ #endif
++
+ }
+ 
+ /*
+@@ -45,8 +47,9 @@ int mmap_min_addr_handler(struct ctl_tab
+ 
+ static int __init init_mmap_min_addr(void)
+ {
++         
+ 	update_mmap_min_addr();
+-
++	
+ 	return 0;
+ }
+ pure_initcall(init_mmap_min_addr);
diff --git a/recipes/linux/linux-ts75xx-2.6.35/ts75xx/unionfs-2.5.8_for_2.6.35.11.patch b/recipes/linux/linux-ts75xx-2.6.35/ts75xx/unionfs-2.5.8_for_2.6.35.11.patch
new file mode 100644
index 0000000..4ea03ac
--- /dev/null
+++ b/recipes/linux/linux-ts75xx-2.6.35/ts75xx/unionfs-2.5.8_for_2.6.35.11.patch
@@ -0,0 +1,11286 @@
+diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
+index 4303614..5ade4a8 100644
+--- a/Documentation/filesystems/00-INDEX
++++ b/Documentation/filesystems/00-INDEX
+@@ -112,6 +112,8 @@ udf.txt
+ 	- info and mount options for the UDF filesystem.
+ ufs.txt
+ 	- info on the ufs filesystem.
++unionfs/
++	- info on the unionfs filesystem
+ vfat.txt
+ 	- info on using the VFAT filesystem used in Windows NT and Windows 95
+ vfs.txt
+diff --git a/Documentation/filesystems/unionfs/00-INDEX b/Documentation/filesystems/unionfs/00-INDEX
+new file mode 100644
+index 0000000..96fdf67
+--- /dev/null
++++ b/Documentation/filesystems/unionfs/00-INDEX
+@@ -0,0 +1,10 @@
++00-INDEX
++	- this file.
++concepts.txt
++	- A brief introduction of concepts.
++issues.txt
++	- A summary of known issues with unionfs.
++rename.txt
++	- Information regarding rename operations.
++usage.txt
++	- Usage information and examples.
+diff --git a/Documentation/filesystems/unionfs/concepts.txt b/Documentation/filesystems/unionfs/concepts.txt
+new file mode 100644
+index 0000000..b853788
+--- /dev/null
++++ b/Documentation/filesystems/unionfs/concepts.txt
+@@ -0,0 +1,287 @@
++Unionfs 2.x CONCEPTS:
++=====================
++
++This file describes the concepts needed by a namespace unification file
++system.
++
++
++Branch Priority:
++================
++
++Each branch is assigned a unique priority - starting from 0 (highest
++priority).  No two branches can have the same priority.
++
++
++Branch Mode:
++============
++
++Each branch is assigned a mode - read-write or read-only. This allows
++directories on media mounted read-write to be used in a read-only manner.
++
++
++Whiteouts:
++==========
++
++A whiteout removes a file name from the namespace. Whiteouts are needed when
++one attempts to remove a file on a read-only branch.
++
++Suppose we have a two-branch union, where branch 0 is read-write and branch
++1 is read-only. And a file 'foo' on branch 1:
++
++./b0/
++./b1/
++./b1/foo
++
++The unified view would simply be:
++
++./union/
++./union/foo
++
++Since 'foo' is stored on a read-only branch, it cannot be removed. A
++whiteout is used to remove the name 'foo' from the unified namespace. Again,
++since branch 1 is read-only, the whiteout cannot be created there. So, we
++try on a higher priority (lower numerically) branch and create the whiteout
++there.
++
++./b0/
++./b0/.wh.foo
++./b1/
++./b1/foo
++
++Later, when Unionfs traverses branches (due to lookup or readdir), it
++eliminate 'foo' from the namespace (as well as the whiteout itself.)
++
++
++Opaque Directories:
++===================
++
++Assume we have a unionfs mount comprising of two branches.  Branch 0 is
++empty; branch 1 has the directory /a and file /a/f.  Let's say we mount a
++union of branch 0 as read-write and branch 1 as read-only.  Now, let's say
++we try to perform the following operation in the union:
++
++	rm -fr a
++
++Because branch 1 is not writable, we cannot physically remove the file /a/f
++or the directory /a.  So instead, we will create a whiteout in branch 0
++named /.wh.a, masking out the name "a" from branch 1.  Next, let's say we
++try to create a directory named "a" as follows:
++
++	mkdir a
++
++Because we have a whiteout for "a" already, Unionfs behaves as if "a"
++doesn't exist, and thus will delete the whiteout and replace it with an
++actual directory named "a".
++
++The problem now is that if you try to "ls" in the union, Unionfs will
++perform is normal directory name unification, for *all* directories named
++"a" in all branches.  This will cause the file /a/f from branch 1 to
++re-appear in the union's namespace, which violates Unix semantics.
++
++To avoid this problem, we have a different form of whiteouts for
++directories, called "opaque directories" (same as BSD Union Mount does).
++Whenever we replace a whiteout with a directory, that directory is marked as
++opaque.  In Unionfs 2.x, it means that we create a file named
++/a/.wh.__dir_opaque in branch 0, after having created directory /a there.
++When unionfs notices that a directory is opaque, it stops all namespace
++operations (including merging readdir contents) at that opaque directory.
++This prevents re-exposing names from masked out directories.
++
++
++Duplicate Elimination:
++======================
++
++It is possible for files on different branches to have the same name.
++Unionfs then has to select which instance of the file to show to the user.
++Given the fact that each branch has a priority associated with it, the
++simplest solution is to take the instance from the highest priority
++(numerically lowest value) and "hide" the others.
++
++
++Unlinking:
++=========
++
++Unlink operation on non-directory instances is optimized to remove the
++maximum possible objects in case multiple underlying branches have the same
++file name.  The unlink operation will first try to delete file instances
++from highest priority branch and then move further to delete from remaining
++branches in order of their decreasing priority.  Consider a case (F..D..F),
++where F is a file and D is a directory of the same name; here, some
++intermediate branch could have an empty directory instance with the same
++name, so this operation also tries to delete this directory instance and
++proceed further to delete from next possible lower priority branch.  The
++unionfs unlink operation will smoothly delete the files with same name from
++all possible underlying branches.  In case if some error occurs, it creates
++whiteout in highest priority branch that will hide file instance in rest of
++the branches.  An error could occur either if an unlink operations in any of
++the underlying branch failed or if a branch has no write permission.
++
++This unlinking policy is known as "delete all" and it has the benefit of
++overall reducing the number of inodes used by duplicate files, and further
++reducing the total number of inodes consumed by whiteouts.  The cost is of
++extra processing, but testing shows this extra processing is well worth the
++savings.
++
++
++Copyup:
++=======
++
++When a change is made to the contents of a file's data or meta-data, they
++have to be stored somewhere.  The best way is to create a copy of the
++original file on a branch that is writable, and then redirect the write
++though to this copy.  The copy must be made on a higher priority branch so
++that lookup and readdir return this newer "version" of the file rather than
++the original (see duplicate elimination).
++
++An entire unionfs mount can be read-only or read-write.  If it's read-only,
++then none of the branches will be written to, even if some of the branches
++are physically writeable.  If the unionfs mount is read-write, then the
++leftmost (highest priority) branch must be writeable (for copyup to take
++place); the remaining branches can be any mix of read-write and read-only.
++
++In a writeable mount, unionfs will create new files/dir in the leftmost
++branch.  If one tries to modify a file in a read-only branch/media, unionfs
++will copyup the file to the leftmost branch and modify it there.  If you try
++to modify a file from a writeable branch which is not the leftmost branch,
++then unionfs will modify it in that branch; this is useful if you, say,
++unify differnet packages (e.g., apache, sendmail, ftpd, etc.) and you want
++changes to specific package files to remain logically in the directory where
++they came from.
++
++Cache Coherency:
++================
++
++Unionfs users often want to be able to modify files and directories directly
++on the lower branches, and have those changes be visible at the Unionfs
++level.  This means that data (e.g., pages) and meta-data (dentries, inodes,
++open files, etc.) have to be synchronized between the upper and lower
++layers.  In other words, the newest changes from a layer below have to be
++propagated to the Unionfs layer above.  If the two layers are not in sync, a
++cache incoherency ensues, which could lead to application failures and even
++oopses.  The Linux kernel, however, has a rather limited set of mechanisms
++to ensure this inter-layer cache coherency---so Unionfs has to do most of
++the hard work on its own.
++
++Maintaining Invariants:
++
++The way Unionfs ensures cache coherency is as follows.  At each entry point
++to a Unionfs file system method, we call a utility function to validate the
++primary objects of this method.  Generally, we call unionfs_file_revalidate
++on open files, and __unionfs_d_revalidate_chain on dentries (which also
++validates inodes).  These utility functions check to see whether the upper
++Unionfs object is in sync with any of the lower objects that it represents.
++The checks we perform include whether the Unionfs superblock has a newer
++generation number, or if any of the lower objects mtime's or ctime's are
++newer.  (Note: generation numbers change when branch-management commands are
++issued, so in a way, maintaining cache coherency is also very important for
++branch-management.)  If indeed we determine that any Unionfs object is no
++longer in sync with its lower counterparts, then we rebuild that object
++similarly to how we do so for branch-management.
++
++While rebuilding Unionfs's objects, we also purge any page mappings and
++truncate inode pages (see fs/unionfs/dentry.c:purge_inode_data).  This is to
++ensure that Unionfs will re-get the newer data from the lower branches.  We
++perform this purging only if the Unionfs operation in question is a reading
++operation; if Unionfs is performing a data writing operation (e.g., ->write,
++->commit_write, etc.) then we do NOT flush the lower mappings/pages: this is
++because (1) a self-deadlock could occur and (2) the upper Unionfs pages are
++considered more authoritative anyway, as they are newer and will overwrite
++any lower pages.
++
++Unionfs maintains the following important invariant regarding mtime's,
++ctime's, and atime's: the upper inode object's times are the max() of all of
++the lower ones.  For non-directory objects, there's only one object below,
++so the mapping is simple; for directory objects, there could me multiple
++lower objects and we have to sync up with the newest one of all the lower
++ones.  This invariant is important to maintain, especially for directories
++(besides, we need this to be POSIX compliant).  A union could comprise
++multiple writable branches, each of which could change.  If we don't reflect
++the newest possible mtime/ctime, some applications could fail.  For example,
++NFSv2/v3 exports check for newer directory mtimes on the server to determine
++if the client-side attribute cache should be purged.
++
++To maintain these important invariants, of course, Unionfs carefully
++synchronizes upper and lower times in various places.  For example, if we
++copy-up a file to a top-level branch, the parent directory where the file
++was copied up to will now have a new mtime: so after a successful copy-up,
++we sync up with the new top-level branch's parent directory mtime.
++
++Implementation:
++
++This cache-coherency implementation is efficient because it defers any
++synchronizing between the upper and lower layers until absolutely needed.
++Consider the example a common situation where users perform a lot of lower
++changes, such as untarring a whole package.  While these take place,
++typically the user doesn't access the files via Unionfs; only after the
++lower changes are done, does the user try to access the lower files.  With
++our cache-coherency implementation, the entirety of the changes to the lower
++branches will not result in a single CPU cycle spent at the Unionfs level
++until the user invokes a system call that goes through Unionfs.
++
++We have considered two alternate cache-coherency designs.  (1) Using the
++dentry/inode notify functionality to register interest in finding out about
++any lower changes.  This is a somewhat limited and also a heavy-handed
++approach which could result in many notifications to the Unionfs layer upon
++each small change at the lower layer (imagine a file being modified multiple
++times in rapid succession).  (2) Rewriting the VFS to support explicit
++callbacks from lower objects to upper objects.  We began exploring such an
++implementation, but found it to be very complicated--it would have resulted
++in massive VFS/MM changes which are unlikely to be accepted by the LKML
++community.  We therefore believe that our current cache-coherency design and
++implementation represent the best approach at this time.
++
++Limitations:
++
++Our implementation works in that as long as a user process will have caused
++Unionfs to be called, directly or indirectly, even to just do
++->d_revalidate; then we will have purged the current Unionfs data and the
++process will see the new data.  For example, a process that continually
++re-reads the same file's data will see the NEW data as soon as the lower
++file had changed, upon the next read(2) syscall (even if the file is still
++open!)  However, this doesn't work when the process re-reads the open file's
++data via mmap(2) (unless the user unmaps/closes the file and remaps/reopens
++it).  Once we respond to ->readpage(s), then the kernel maps the page into
++the process's address space and there doesn't appear to be a way to force
++the kernel to invalidate those pages/mappings, and force the process to
++re-issue ->readpage.  If there's a way to invalidate active mappings and
++force a ->readpage, let us know please (invalidate_inode_pages2 doesn't do
++the trick).
++
++Our current Unionfs code has to perform many file-revalidation calls.  It
++would be really nice if the VFS would export an optional file system hook
++->file_revalidate (similarly to dentry->d_revalidate) that will be called
++before each VFS op that has a "struct file" in it.
++
++Certain file systems have micro-second granularity (or better) for inode
++times, and asynchronous actions could cause those times to change with some
++small delay.  In such cases, Unionfs may see a changed inode time that only
++differs by a tiny fraction of a second: such a change may be a false
++positive indication that the lower object has changed, whereas if unionfs
++waits a little longer, that false indication will not be seen.  (These false
++positives are harmless, because they would at most cause unionfs to
++re-validate an object that may need no revalidation, and print a debugging
++message that clutters the console/logs.)  Therefore, to minimize the chances
++of these situations, we delay the detection of changed times by a small
++factor of a few seconds, called UNIONFS_MIN_CC_TIME (which defaults to 3
++seconds, as does NFS).  This means that we will detect the change, only a
++couple of seconds later, if indeed the time change persists in the lower
++file object.  This delayed detection has an added performance benefit: we
++reduce the number of times that unionfs has to revalidate objects, in case
++there's a lot of concurrent activity on both the upper and lower objects,
++for the same file(s).  Lastly, this delayed time attribute detection is
++similar to how NFS clients operate (e.g., acregmin).
++
++Finally, there is no way currently in Linux to prevent lower directories
++from being moved around (i.e., topology changes); there's no way to prevent
++modifications to directory sub-trees of whole file systems which are mounted
++read-write.  It is therefore possible for in-flight operations in unionfs to
++take place, while a lower directory is being moved around.  Therefore, if
++you try to, say, create a new file in a directory through unionfs, while the
++directory is being moved around directly, then the new file may get created
++in the new location where that directory was moved to.  This is a somewhat
++similar behaviour in NFS: an NFS client could be creating a new file while
++th NFS server is moving th directory around; the file will get successfully
++created in the new location.  (The one exception in unionfs is that if the
++branch is marked read-only by unionfs, then a copyup will take place.)
++
++For more information, see <http://unionfs.filesystems.org/>.
+diff --git a/Documentation/filesystems/unionfs/issues.txt b/Documentation/filesystems/unionfs/issues.txt
+new file mode 100644
+index 0000000..f4b7e7e
+--- /dev/null
++++ b/Documentation/filesystems/unionfs/issues.txt
+@@ -0,0 +1,28 @@
++KNOWN Unionfs 2.x ISSUES:
++=========================
++
++1. Unionfs should not use lookup_one_len() on the underlying f/s as it
++   confuses NFSv4.  Currently, unionfs_lookup() passes lookup intents to the
++   lower file-system, this eliminates part of the problem.  The remaining
++   calls to lookup_one_len may need to be changed to pass an intent.  We are
++   currently introducing VFS changes to fs/namei.c's do_path_lookup() to
++   allow proper file lookup and opening in stackable file systems.
++
++2. Lockdep (a debugging feature) isn't aware of stacking, and so it
++   incorrectly complains about locking problems.  The problem boils down to
++   this: Lockdep considers all objects of a certain type to be in the same
++   class, for example, all inodes.  Lockdep doesn't like to see a lock held
++   on two inodes within the same task, and warns that it could lead to a
++   deadlock.  However, stackable file systems do precisely that: they lock
++   an upper object, and then a lower object, in a strict order to avoid
++   locking problems; in addition, Unionfs, as a fan-out file system, may
++   have to lock several lower inodes.  We are currently looking into Lockdep
++   to see how to make it aware of stackable file systems.  For now, we
++   temporarily disable lockdep when calling vfs methods on lower objects,
++   but only for those places where lockdep complained.  While this solution
++   may seem unclean, it is not without precedent: other places in the kernel
++   also do similar temporary disabling, of course after carefully having
++   checked that it is the right thing to do.  Anyway, you get any warnings
++   from Lockdep, please report them to the Unionfs maintainers.
++
++For more information, see <http://unionfs.filesystems.org/>.
+diff --git a/Documentation/filesystems/unionfs/rename.txt b/Documentation/filesystems/unionfs/rename.txt
+new file mode 100644
+index 0000000..e20bb82
+--- /dev/null
++++ b/Documentation/filesystems/unionfs/rename.txt
+@@ -0,0 +1,31 @@
++Rename is a complex beast. The following table shows which rename(2) operations
++should succeed and which should fail.
++
++o: success
++E: error (either unionfs or vfs)
++X: EXDEV
++
++none = file does not exist
++file = file is a file
++dir  = file is a empty directory
++child= file is a non-empty directory
++wh   = file is a directory containing only whiteouts; this makes it logically
++		empty
++
++                      none    file    dir     child   wh
++file                  o       o       E       E       E
++dir                   o       E       o       E       o
++child                 X       E       X       E       X
++wh                    o       E       o       E       o
++
++
++Renaming directories:
++=====================
++
++Whenever a empty (either physically or logically) directory is being renamed,
++the following sequence of events should take place:
++
++1) Remove whiteouts from both source and destination directory
++2) Rename source to destination
++3) Make destination opaque to prevent anything under it from showing up
++
+diff --git a/Documentation/filesystems/unionfs/usage.txt b/Documentation/filesystems/unionfs/usage.txt
+new file mode 100644
+index 0000000..1adde69
+--- /dev/null
++++ b/Documentation/filesystems/unionfs/usage.txt
+@@ -0,0 +1,134 @@
++Unionfs is a stackable unification file system, which can appear to merge
++the contents of several directories (branches), while keeping their physical
++content separate.  Unionfs is useful for unified source tree management,
++merged contents of split CD-ROM, merged separate software package
++directories, data grids, and more.  Unionfs allows any mix of read-only and
++read-write branches, as well as insertion and deletion of branches anywhere
++in the fan-out.  To maintain Unix semantics, Unionfs handles elimination of
++duplicates, partial-error conditions, and more.
++
++GENERAL SYNTAX
++==============
++
++# mount -t unionfs -o <OPTIONS>,<BRANCH-OPTIONS> none MOUNTPOINT
++
++OPTIONS can be any legal combination of:
++
++- ro		# mount file system read-only
++- rw		# mount file system read-write
++- remount	# remount the file system (see Branch Management below)
++- incgen	# increment generation no. (see Cache Consistency below)
++
++BRANCH-OPTIONS can be either (1) a list of branches given to the "dirs="
++option, or (2) a list of individual branch manipulation commands, combined
++with the "remount" option, and is further described in the "Branch
++Management" section below.
++
++The syntax for the "dirs=" mount option is:
++
++	dirs=branch[=ro|=rw][:...]
++
++The "dirs=" option takes a colon-delimited list of directories to compose
++the union, with an optional branch mode for each of those directories.
++Directories that come earlier (specified first, on the left) in the list
++have a higher precedence than those which come later.  Additionally,
++read-only or read-write permissions of the branch can be specified by
++appending =ro or =rw (default) to each directory.  See the Copyup section in
++concepts.txt, for a description of Unionfs's behavior when mixing read-only
++and read-write branches and mounts.
++
++Syntax:
++
++	dirs=/branch1[=ro|=rw]:/branch2[=ro|=rw]:...:/branchN[=ro|=rw]
++
++Example:
++
++	dirs=/writable_branch=rw:/read-only_branch=ro
++
++
++BRANCH MANAGEMENT
++=================
++
++Once you mount your union for the first time, using the "dirs=" option, you
++can then change the union's overall mode or reconfigure the branches, using
++the remount option, as follows.
++
++To downgrade a union from read-write to read-only:
++
++# mount -t unionfs -o remount,ro none MOUNTPOINT
++
++To upgrade a union from read-only to read-write:
++
++# mount -t unionfs -o remount,rw none MOUNTPOINT
++
++To delete a branch /foo, regardless where it is in the current union:
++
++# mount -t unionfs -o remount,del=/foo none MOUNTPOINT
++
++To insert (add) a branch /foo before /bar:
++
++# mount -t unionfs -o remount,add=/bar:/foo none MOUNTPOINT
++
++To insert (add) a branch /foo (with the "rw" mode flag) before /bar:
++
++# mount -t unionfs -o remount,add=/bar:/foo=rw none MOUNTPOINT
++
++To insert (add) a branch /foo (in "rw" mode) at the very beginning (i.e., a
++new highest-priority branch), you can use the above syntax, or use a short
++hand version as follows:
++
++# mount -t unionfs -o remount,add=/foo none MOUNTPOINT
++
++To append a branch to the very end (new lowest-priority branch):
++
++# mount -t unionfs -o remount,add=:/foo none MOUNTPOINT
++
++To append a branch to the very end (new lowest-priority branch), in
++read-only mode:
++
++# mount -t unionfs -o remount,add=:/foo=ro none MOUNTPOINT
++
++Finally, to change the mode of one existing branch, say /foo, from read-only
++to read-write, and change /bar from read-write to read-only:
++
++# mount -t unionfs -o remount,mode=/foo=rw,mode=/bar=ro none MOUNTPOINT
++
++Note: in Unionfs 2.x, you cannot set the leftmost branch to readonly because
++then Unionfs won't have any writable place for copyups to take place.
++Moreover, the VFS can get confused when it tries to modify something in a
++file system mounted read-write, but isn't permitted to write to it.
++Instead, you should set the whole union as readonly, as described above.
++If, however, you must set the leftmost branch as readonly, perhaps so you
++can get a snapshot of it at a point in time, then you should insert a new
++writable top-level branch, and mark the one you want as readonly.  This can
++be accomplished as follows, assuming that /foo is your current leftmost
++branch:
++
++# mount -t tmpfs -o size=NNN /new
++# mount -t unionfs -o remount,add=/new,mode=/foo=ro none MOUNTPOINT
++<do what you want safely in /foo>
++# mount -t unionfs -o remount,del=/new,mode=/foo=rw none MOUNTPOINT
++<check if there's anything in /new you want to preserve>
++# umount /new
++
++CACHE CONSISTENCY
++=================
++
++If you modify any file on any of the lower branches directly, while there is
++a Unionfs 2.x mounted above any of those branches, you should tell Unionfs
++to purge its caches and re-get the objects.  To do that, you have to
++increment the generation number of the superblock using the following
++command:
++
++# mount -t unionfs -o remount,incgen none MOUNTPOINT
++
++Note that the older way of incrementing the generation number using an
++ioctl, is no longer supported in Unionfs 2.0 and newer.  Ioctls in general
++are not encouraged.  Plus, an ioctl is per-file concept, whereas the
++generation number is a per-file-system concept.  Worse, such an ioctl
++requires an open file, which then has to be invalidated by the very nature
++of the generation number increase (read: the old generation increase ioctl
++was pretty racy).
++
++
++For more information, see <http://unionfs.filesystems.org/>.
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 02f75fc..8c5efe7 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -5766,6 +5766,14 @@ F:	Documentation/cdrom/
+ F:	drivers/cdrom/cdrom.c
+ F:	include/linux/cdrom.h
+ 
++UNIONFS
++P:	Erez Zadok
++M:	ezk@cs.sunysb.edu
++L:	unionfs@filesystems.org
++W:	http://unionfs.filesystems.org/
++T:	git git.kernel.org/pub/scm/linux/kernel/git/ezk/unionfs.git
++S:	Maintained
++
+ UNSORTED BLOCK IMAGES (UBI)
+ M:	Artem Bityutskiy <dedekind1@gmail.com>
+ W:	http://www.linux-mtd.infradead.org/
+diff --git a/fs/Kconfig b/fs/Kconfig
+index 5f85b59..7b4501b 100644
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -169,6 +169,7 @@ if MISC_FILESYSTEMS
+ source "fs/adfs/Kconfig"
+ source "fs/affs/Kconfig"
+ source "fs/ecryptfs/Kconfig"
++source "fs/unionfs/Kconfig"
+ source "fs/hfs/Kconfig"
+ source "fs/hfsplus/Kconfig"
+ source "fs/befs/Kconfig"
+diff --git a/fs/Makefile b/fs/Makefile
+index e6ec1d3..787332e 100644
+--- a/fs/Makefile
++++ b/fs/Makefile
+@@ -84,6 +84,7 @@ obj-$(CONFIG_ISO9660_FS)	+= isofs/
+ obj-$(CONFIG_HFSPLUS_FS)	+= hfsplus/ # Before hfs to find wrapped HFS+
+ obj-$(CONFIG_HFS_FS)		+= hfs/
+ obj-$(CONFIG_ECRYPT_FS)		+= ecryptfs/
++obj-$(CONFIG_UNION_FS)		+= unionfs/
+ obj-$(CONFIG_VXFS_FS)		+= freevxfs/
+ obj-$(CONFIG_NFS_FS)		+= nfs/
+ obj-$(CONFIG_EXPORTFS)		+= exportfs/
+diff --git a/fs/namei.c b/fs/namei.c
+index 868d0cb..b5e09e1 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -386,6 +386,7 @@ void release_open_intent(struct nameidata *nd)
+ 	else
+ 		fput(nd->intent.open.file);
+ }
++EXPORT_SYMBOL_GPL(release_open_intent);
+ 
+ static inline struct dentry *
+ do_revalidate(struct dentry *dentry, struct nameidata *nd)
+diff --git a/fs/splice.c b/fs/splice.c
+index efdbfec..1ff6bca 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -1104,8 +1104,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+ /*
+  * Attempt to initiate a splice from pipe to file.
+  */
+-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+-			   loff_t *ppos, size_t len, unsigned int flags)
++long vfs_splice_from(struct pipe_inode_info *pipe, struct file *out,
++		     loff_t *ppos, size_t len, unsigned int flags)
+ {
+ 	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
+ 				loff_t *, size_t, unsigned int);
+@@ -1128,13 +1128,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+ 
+ 	return splice_write(pipe, out, ppos, len, flags);
+ }
++EXPORT_SYMBOL_GPL(vfs_splice_from);
+ 
+ /*
+  * Attempt to initiate a splice from a file to a pipe.
+  */
+-static long do_splice_to(struct file *in, loff_t *ppos,
+-			 struct pipe_inode_info *pipe, size_t len,
+-			 unsigned int flags)
++long vfs_splice_to(struct file *in, loff_t *ppos,
++		   struct pipe_inode_info *pipe, size_t len,
++		   unsigned int flags)
+ {
+ 	ssize_t (*splice_read)(struct file *, loff_t *,
+ 			       struct pipe_inode_info *, size_t, unsigned int);
+@@ -1154,6 +1155,7 @@ static long do_splice_to(struct file *in, loff_t *ppos,
+ 
+ 	return splice_read(in, ppos, pipe, len, flags);
+ }
++EXPORT_SYMBOL_GPL(vfs_splice_to);
+ 
+ /**
+  * splice_direct_to_actor - splices data directly between two non-pipes
+@@ -1223,7 +1225,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
+ 		size_t read_len;
+ 		loff_t pos = sd->pos, prev_pos = pos;
+ 
+-		ret = do_splice_to(in, &pos, pipe, len, flags);
++		ret = vfs_splice_to(in, &pos, pipe, len, flags);
+ 		if (unlikely(ret <= 0))
+ 			goto out_release;
+ 
+@@ -1282,8 +1284,8 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
+ {
+ 	struct file *file = sd->u.file;
+ 
+-	return do_splice_from(pipe, file, &file->f_pos, sd->total_len,
+-			      sd->flags);
++	return vfs_splice_from(pipe, file, &file->f_pos, sd->total_len,
++			       sd->flags);
+ }
+ 
+ /**
+@@ -1380,7 +1382,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
+ 		} else
+ 			off = &out->f_pos;
+ 
+-		ret = do_splice_from(ipipe, out, off, len, flags);
++		ret = vfs_splice_from(ipipe, out, off, len, flags);
+ 
+ 		if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
+ 			ret = -EFAULT;
+@@ -1400,7 +1402,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
+ 		} else
+ 			off = &in->f_pos;
+ 
+-		ret = do_splice_to(in, off, opipe, len, flags);
++		ret = vfs_splice_to(in, off, opipe, len, flags);
+ 
+ 		if (off_in && copy_to_user(off_in, off, sizeof(loff_t)))
+ 			ret = -EFAULT;
+diff --git a/fs/stack.c b/fs/stack.c
+index 4a6f7f4..7eeef12 100644
+--- a/fs/stack.c
++++ b/fs/stack.c
+@@ -1,8 +1,20 @@
++/*
++ * Copyright (c) 2006-2009 Erez Zadok
++ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2006-2009 Stony Brook University
++ * Copyright (c) 2006-2009 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
+ #include <linux/module.h>
+ #include <linux/fs.h>
+ #include <linux/fs_stack.h>
+ 
+-/* does _NOT_ require i_mutex to be held.
++/*
++ * does _NOT_ require i_mutex to be held.
+  *
+  * This function cannot be inlined since i_size_{read,write} is rather
+  * heavy-weight on 32-bit systems
+diff --git a/fs/unionfs/Kconfig b/fs/unionfs/Kconfig
+new file mode 100644
+index 0000000..f3c1ac4
+--- /dev/null
++++ b/fs/unionfs/Kconfig
+@@ -0,0 +1,24 @@
++config UNION_FS
++	tristate "Union file system (EXPERIMENTAL)"
++	depends on EXPERIMENTAL
++	help
++	  Unionfs is a stackable unification file system, which appears to
++	  merge the contents of several directories (branches), while keeping
++	  their physical content separate.
++
++	  See <http://unionfs.filesystems.org> for details
++
++config UNION_FS_XATTR
++	bool "Unionfs extended attributes"
++	depends on UNION_FS
++	help
++	  Extended attributes are name:value pairs associated with inodes by
++	  the kernel or by users (see the attr(5) manual page).
++
++	  If unsure, say N.
++
++config UNION_FS_DEBUG
++	bool "Debug Unionfs"
++	depends on UNION_FS
++	help
++	  If you say Y here, you can turn on debugging output from Unionfs.
+diff --git a/fs/unionfs/Makefile b/fs/unionfs/Makefile
+new file mode 100644
+index 0000000..7f8c980
+--- /dev/null
++++ b/fs/unionfs/Makefile
+@@ -0,0 +1,17 @@
++UNIONFS_VERSION="2.5.8 (for 2.6.35.9)"
++
++EXTRA_CFLAGS += -DUNIONFS_VERSION=\"$(UNIONFS_VERSION)\"
++
++obj-$(CONFIG_UNION_FS) += unionfs.o
++
++unionfs-y := subr.o dentry.o file.o inode.o main.o super.o \
++	rdstate.o copyup.o dirhelper.o rename.o unlink.o \
++	lookup.o commonfops.o dirfops.o sioq.o mmap.o whiteout.o
++
++unionfs-$(CONFIG_UNION_FS_XATTR) += xattr.o
++
++unionfs-$(CONFIG_UNION_FS_DEBUG) += debug.o
++
++ifeq ($(CONFIG_UNION_FS_DEBUG),y)
++EXTRA_CFLAGS += -DDEBUG
++endif
+diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
+new file mode 100644
+index 0000000..740c4ad
+--- /dev/null
++++ b/fs/unionfs/commonfops.c
+@@ -0,0 +1,896 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/*
++ * 1) Copyup the file
++ * 2) Rename the file to '.unionfs<original inode#><counter>' - obviously
++ * stolen from NFS's silly rename
++ */
++static int copyup_deleted_file(struct file *file, struct dentry *dentry,
++			       struct dentry *parent, int bstart, int bindex)
++{
++	static unsigned int counter;
++	const int i_inosize = sizeof(dentry->d_inode->i_ino) * 2;
++	const int countersize = sizeof(counter) * 2;
++	const int nlen = sizeof(".unionfs") + i_inosize + countersize - 1;
++	char name[nlen + 1];
++	int err;
++	struct dentry *tmp_dentry = NULL;
++	struct dentry *lower_dentry;
++	struct dentry *lower_dir_dentry = NULL;
++
++	lower_dentry = unionfs_lower_dentry_idx(dentry, bstart);
++
++	sprintf(name, ".unionfs%*.*lx",
++		i_inosize, i_inosize, lower_dentry->d_inode->i_ino);
++
++	/*
++	 * Loop, looking for an unused temp name to copyup to.
++	 *
++	 * It's somewhat silly that we look for a free temp tmp name in the
++	 * source branch (bstart) instead of the dest branch (bindex), where
++	 * the final name will be created.  We _will_ catch it if somehow
++	 * the name exists in the dest branch, but it'd be nice to catch it
++	 * sooner than later.
++	 */
++retry:
++	tmp_dentry = NULL;
++	do {
++		char *suffix = name + nlen - countersize;
++
++		dput(tmp_dentry);
++		counter++;
++		sprintf(suffix, "%*.*x", countersize, countersize, counter);
++
++		pr_debug("unionfs: trying to rename %s to %s\n",
++			 dentry->d_name.name, name);
++
++		tmp_dentry = lookup_lck_len(name, lower_dentry->d_parent,
++					    nlen);
++		if (IS_ERR(tmp_dentry)) {
++			err = PTR_ERR(tmp_dentry);
++			goto out;
++		}
++	} while (tmp_dentry->d_inode != NULL);	/* need negative dentry */
++	dput(tmp_dentry);
++
++	err = copyup_named_file(parent->d_inode, file, name, bstart, bindex,
++				i_size_read(file->f_path.dentry->d_inode));
++	if (err) {
++		if (unlikely(err == -EEXIST))
++			goto retry;
++		goto out;
++	}
++
++	/* bring it to the same state as an unlinked file */
++	lower_dentry = unionfs_lower_dentry_idx(dentry, dbstart(dentry));
++	if (!unionfs_lower_inode_idx(dentry->d_inode, bindex)) {
++		atomic_inc(&lower_dentry->d_inode->i_count);
++		unionfs_set_lower_inode_idx(dentry->d_inode, bindex,
++					    lower_dentry->d_inode);
++	}
++	lower_dir_dentry = lock_parent(lower_dentry);
++	err = vfs_unlink(lower_dir_dentry->d_inode, lower_dentry);
++	unlock_dir(lower_dir_dentry);
++
++out:
++	if (!err)
++		unionfs_check_dentry(dentry);
++	return err;
++}
++
++/*
++ * put all references held by upper struct file and free lower file pointer
++ * array
++ */
++static void cleanup_file(struct file *file)
++{
++	int bindex, bstart, bend;
++	struct file **lower_files;
++	struct file *lower_file;
++	struct super_block *sb = file->f_path.dentry->d_sb;
++
++	lower_files = UNIONFS_F(file)->lower_files;
++	bstart = fbstart(file);
++	bend = fbend(file);
++
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		int i;	/* holds (possibly) updated branch index */
++		int old_bid;
++
++		lower_file = unionfs_lower_file_idx(file, bindex);
++		if (!lower_file)
++			continue;
++
++		/*
++		 * Find new index of matching branch with an open
++		 * file, since branches could have been added or
++		 * deleted causing the one with open files to shift.
++		 */
++		old_bid = UNIONFS_F(file)->saved_branch_ids[bindex];
++		i = branch_id_to_idx(sb, old_bid);
++		if (unlikely(i < 0)) {
++			printk(KERN_ERR "unionfs: no superblock for "
++			       "file %p\n", file);
++			continue;
++		}
++
++		/* decrement count of open files */
++		branchput(sb, i);
++		/*
++		 * fput will perform an mntput for us on the correct branch.
++		 * Although we're using the file's old branch configuration,
++		 * bindex, which is the old index, correctly points to the
++		 * right branch in the file's branch list.  In other words,
++		 * we're going to mntput the correct branch even if branches
++		 * have been added/removed.
++		 */
++		fput(lower_file);
++		UNIONFS_F(file)->lower_files[bindex] = NULL;
++		UNIONFS_F(file)->saved_branch_ids[bindex] = -1;
++	}
++
++	UNIONFS_F(file)->lower_files = NULL;
++	kfree(lower_files);
++	kfree(UNIONFS_F(file)->saved_branch_ids);
++	/* set to NULL because caller needs to know if to kfree on error */
++	UNIONFS_F(file)->saved_branch_ids = NULL;
++}
++
++/* open all lower files for a given file */
++static int open_all_files(struct file *file)
++{
++	int bindex, bstart, bend, err = 0;
++	struct file *lower_file;
++	struct dentry *lower_dentry;
++	struct dentry *dentry = file->f_path.dentry;
++	struct super_block *sb = dentry->d_sb;
++
++	bstart = dbstart(dentry);
++	bend = dbend(dentry);
++
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (!lower_dentry)
++			continue;
++
++		dget(lower_dentry);
++		unionfs_mntget(dentry, bindex);
++		branchget(sb, bindex);
++
++		lower_file =
++			dentry_open(lower_dentry,
++				    unionfs_lower_mnt_idx(dentry, bindex),
++				    file->f_flags, current_cred());
++		if (IS_ERR(lower_file)) {
++			branchput(sb, bindex);
++			err = PTR_ERR(lower_file);
++			goto out;
++		} else {
++			unionfs_set_lower_file_idx(file, bindex, lower_file);
++		}
++	}
++out:
++	return err;
++}
++
++/* open the highest priority file for a given upper file */
++static int open_highest_file(struct file *file, bool willwrite)
++{
++	int bindex, bstart, bend, err = 0;
++	struct file *lower_file;
++	struct dentry *lower_dentry;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent = dget_parent(dentry);
++	struct inode *parent_inode = parent->d_inode;
++	struct super_block *sb = dentry->d_sb;
++
++	bstart = dbstart(dentry);
++	bend = dbend(dentry);
++
++	lower_dentry = unionfs_lower_dentry(dentry);
++	if (willwrite && IS_WRITE_FLAG(file->f_flags) && is_robranch(dentry)) {
++		for (bindex = bstart - 1; bindex >= 0; bindex--) {
++			err = copyup_file(parent_inode, file, bstart, bindex,
++					  i_size_read(dentry->d_inode));
++			if (!err)
++				break;
++		}
++		atomic_set(&UNIONFS_F(file)->generation,
++			   atomic_read(&UNIONFS_I(dentry->d_inode)->
++				       generation));
++		goto out;
++	}
++
++	dget(lower_dentry);
++	unionfs_mntget(dentry, bstart);
++	lower_file = dentry_open(lower_dentry,
++				 unionfs_lower_mnt_idx(dentry, bstart),
++				 file->f_flags, current_cred());
++	if (IS_ERR(lower_file)) {
++		err = PTR_ERR(lower_file);
++		goto out;
++	}
++	branchget(sb, bstart);
++	unionfs_set_lower_file(file, lower_file);
++	/* Fix up the position. */
++	lower_file->f_pos = file->f_pos;
++
++	memcpy(&lower_file->f_ra, &file->f_ra, sizeof(struct file_ra_state));
++out:
++	dput(parent);
++	return err;
++}
++
++/* perform a delayed copyup of a read-write file on a read-only branch */
++static int do_delayed_copyup(struct file *file, struct dentry *parent)
++{
++	int bindex, bstart, bend, err = 0;
++	struct dentry *dentry = file->f_path.dentry;
++	struct inode *parent_inode = parent->d_inode;
++
++	bstart = fbstart(file);
++	bend = fbend(file);
++
++	BUG_ON(!S_ISREG(dentry->d_inode->i_mode));
++
++	unionfs_check_file(file);
++	for (bindex = bstart - 1; bindex >= 0; bindex--) {
++		if (!d_deleted(dentry))
++			err = copyup_file(parent_inode, file, bstart,
++					  bindex,
++					  i_size_read(dentry->d_inode));
++		else
++			err = copyup_deleted_file(file, dentry, parent,
++						  bstart, bindex);
++		/* if succeeded, set lower open-file flags and break */
++		if (!err) {
++			struct file *lower_file;
++			lower_file = unionfs_lower_file_idx(file, bindex);
++			lower_file->f_flags = file->f_flags;
++			break;
++		}
++	}
++	if (err || (bstart <= fbstart(file)))
++		goto out;
++	bend = fbend(file);
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		if (unionfs_lower_file_idx(file, bindex)) {
++			branchput(dentry->d_sb, bindex);
++			fput(unionfs_lower_file_idx(file, bindex));
++			unionfs_set_lower_file_idx(file, bindex, NULL);
++		}
++	}
++	path_put_lowers(dentry, bstart, bend, false);
++	iput_lowers(dentry->d_inode, bstart, bend, false);
++	/* for reg file, we only open it "once" */
++	fbend(file) = fbstart(file);
++	dbend(dentry) = dbstart(dentry);
++	ibend(dentry->d_inode) = ibstart(dentry->d_inode);
++
++out:
++	unionfs_check_file(file);
++	return err;
++}
++
++/*
++ * Helper function for unionfs_file_revalidate/locked.
++ * Expects dentry/parent to be locked already, and revalidated.
++ */
++static int __unionfs_file_revalidate(struct file *file, struct dentry *dentry,
++				     struct dentry *parent,
++				     struct super_block *sb, int sbgen,
++				     int dgen, bool willwrite)
++{
++	int fgen;
++	int bstart, bend, orig_brid;
++	int size;
++	int err = 0;
++
++	fgen = atomic_read(&UNIONFS_F(file)->generation);
++
++	/*
++	 * There are two cases we are interested in.  The first is if the
++	 * generation is lower than the super-block.  The second is if
++	 * someone has copied up this file from underneath us, we also need
++	 * to refresh things.
++	 */
++	if (d_deleted(dentry) ||
++	    (sbgen <= fgen &&
++	     dbstart(dentry) == fbstart(file) &&
++	     unionfs_lower_file(file)))
++		goto out_may_copyup;
++
++	/* save orig branch ID */
++	orig_brid = UNIONFS_F(file)->saved_branch_ids[fbstart(file)];
++
++	/* First we throw out the existing files. */
++	cleanup_file(file);
++
++	/* Now we reopen the file(s) as in unionfs_open. */
++	bstart = fbstart(file) = dbstart(dentry);
++	bend = fbend(file) = dbend(dentry);
++
++	size = sizeof(struct file *) * sbmax(sb);
++	UNIONFS_F(file)->lower_files = kzalloc(size, GFP_KERNEL);
++	if (unlikely(!UNIONFS_F(file)->lower_files)) {
++		err = -ENOMEM;
++		goto out;
++	}
++	size = sizeof(int) * sbmax(sb);
++	UNIONFS_F(file)->saved_branch_ids = kzalloc(size, GFP_KERNEL);
++	if (unlikely(!UNIONFS_F(file)->saved_branch_ids)) {
++		err = -ENOMEM;
++		goto out;
++	}
++
++	if (S_ISDIR(dentry->d_inode->i_mode)) {
++		/* We need to open all the files. */
++		err = open_all_files(file);
++		if (err)
++			goto out;
++	} else {
++		int new_brid;
++		/* We only open the highest priority branch. */
++		err = open_highest_file(file, willwrite);
++		if (err)
++			goto out;
++		new_brid = UNIONFS_F(file)->saved_branch_ids[fbstart(file)];
++		if (unlikely(new_brid != orig_brid && sbgen > fgen)) {
++			/*
++			 * If we re-opened the file on a different branch
++			 * than the original one, and this was due to a new
++			 * branch inserted, then update the mnt counts of
++			 * the old and new branches accordingly.
++			 */
++			unionfs_mntget(dentry, bstart);
++			unionfs_mntput(sb->s_root,
++				       branch_id_to_idx(sb, orig_brid));
++		}
++		/* regular files have only one open lower file */
++		fbend(file) = fbstart(file);
++	}
++	atomic_set(&UNIONFS_F(file)->generation,
++		   atomic_read(&UNIONFS_I(dentry->d_inode)->generation));
++
++out_may_copyup:
++	/* Copyup on the first write to a file on a readonly branch. */
++	if (willwrite && IS_WRITE_FLAG(file->f_flags) &&
++	    !IS_WRITE_FLAG(unionfs_lower_file(file)->f_flags) &&
++	    is_robranch(dentry)) {
++		pr_debug("unionfs: do delay copyup of \"%s\"\n",
++			 dentry->d_name.name);
++		err = do_delayed_copyup(file, parent);
++		/* regular files have only one open lower file */
++		if (!err && !S_ISDIR(dentry->d_inode->i_mode))
++			fbend(file) = fbstart(file);
++	}
++
++out:
++	if (err) {
++		kfree(UNIONFS_F(file)->lower_files);
++		kfree(UNIONFS_F(file)->saved_branch_ids);
++	}
++	return err;
++}
++
++/*
++ * Revalidate the struct file
++ * @file: file to revalidate
++ * @parent: parent dentry (locked by caller)
++ * @willwrite: true if caller may cause changes to the file; false otherwise.
++ * Caller must lock/unlock dentry's branch configuration.
++ */
++int unionfs_file_revalidate(struct file *file, struct dentry *parent,
++			    bool willwrite)
++{
++	struct super_block *sb;
++	struct dentry *dentry;
++	int sbgen, dgen;
++	int err = 0;
++
++	dentry = file->f_path.dentry;
++	sb = dentry->d_sb;
++	verify_locked(dentry);
++	verify_locked(parent);
++
++	/*
++	 * First revalidate the dentry inside struct file,
++	 * but not unhashed dentries.
++	 */
++	if (!d_deleted(dentry) &&
++	    !__unionfs_d_revalidate(dentry, parent, willwrite)) {
++		err = -ESTALE;
++		goto out;
++	}
++
++	sbgen = atomic_read(&UNIONFS_SB(sb)->generation);
++	dgen = atomic_read(&UNIONFS_D(dentry)->generation);
++
++	if (unlikely(sbgen > dgen)) { /* XXX: should never happen */
++		pr_debug("unionfs: failed to revalidate dentry (%s)\n",
++			 dentry->d_name.name);
++		err = -ESTALE;
++		goto out;
++	}
++
++	err = __unionfs_file_revalidate(file, dentry, parent, sb,
++					sbgen, dgen, willwrite);
++out:
++	return err;
++}
++
++/* unionfs_open helper function: open a directory */
++static int __open_dir(struct inode *inode, struct file *file)
++{
++	struct dentry *lower_dentry;
++	struct file *lower_file;
++	int bindex, bstart, bend;
++	struct vfsmount *mnt;
++
++	bstart = fbstart(file) = dbstart(file->f_path.dentry);
++	bend = fbend(file) = dbend(file->f_path.dentry);
++
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_dentry =
++			unionfs_lower_dentry_idx(file->f_path.dentry, bindex);
++		if (!lower_dentry)
++			continue;
++
++		dget(lower_dentry);
++		unionfs_mntget(file->f_path.dentry, bindex);
++		mnt = unionfs_lower_mnt_idx(file->f_path.dentry, bindex);
++		lower_file = dentry_open(lower_dentry, mnt, file->f_flags,
++					 current_cred());
++		if (IS_ERR(lower_file))
++			return PTR_ERR(lower_file);
++
++		unionfs_set_lower_file_idx(file, bindex, lower_file);
++
++		/*
++		 * The branchget goes after the open, because otherwise
++		 * we would miss the reference on release.
++		 */
++		branchget(inode->i_sb, bindex);
++	}
++
++	return 0;
++}
++
++/* unionfs_open helper function: open a file */
++static int __open_file(struct inode *inode, struct file *file,
++		       struct dentry *parent)
++{
++	struct dentry *lower_dentry;
++	struct file *lower_file;
++	int lower_flags;
++	int bindex, bstart, bend;
++
++	lower_dentry = unionfs_lower_dentry(file->f_path.dentry);
++	lower_flags = file->f_flags;
++
++	bstart = fbstart(file) = dbstart(file->f_path.dentry);
++	bend = fbend(file) = dbend(file->f_path.dentry);
++
++	/*
++	 * check for the permission for lower file.  If the error is
++	 * COPYUP_ERR, copyup the file.
++	 */
++	if (lower_dentry->d_inode && is_robranch(file->f_path.dentry)) {
++		/*
++		 * if the open will change the file, copy it up otherwise
++		 * defer it.
++		 */
++		if (lower_flags & O_TRUNC) {
++			int size = 0;
++			int err = -EROFS;
++
++			/* copyup the file */
++			for (bindex = bstart - 1; bindex >= 0; bindex--) {
++				err = copyup_file(parent->d_inode, file,
++						  bstart, bindex, size);
++				if (!err)
++					break;
++			}
++			return err;
++		} else {
++			/*
++			 * turn off writeable flags, to force delayed copyup
++			 * by caller.
++			 */
++			lower_flags &= ~(OPEN_WRITE_FLAGS);
++		}
++	}
++
++	dget(lower_dentry);
++
++	/*
++	 * dentry_open will decrement mnt refcnt if err.
++	 * otherwise fput() will do an mntput() for us upon file close.
++	 */
++	unionfs_mntget(file->f_path.dentry, bstart);
++	lower_file =
++		dentry_open(lower_dentry,
++			    unionfs_lower_mnt_idx(file->f_path.dentry, bstart),
++			    lower_flags, current_cred());
++	if (IS_ERR(lower_file))
++		return PTR_ERR(lower_file);
++
++	unionfs_set_lower_file(file, lower_file);
++	branchget(inode->i_sb, bstart);
++
++	return 0;
++}
++
++int unionfs_open(struct inode *inode, struct file *file)
++{
++	int err = 0;
++	struct file *lower_file = NULL;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++	int bindex = 0, bstart = 0, bend = 0;
++	int size;
++	int valid = 0;
++
++	unionfs_read_lock(inode->i_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	/* don't open unhashed/deleted files */
++	if (d_deleted(dentry)) {
++		err = -ENOENT;
++		goto out_nofree;
++	}
++
++	/* XXX: should I change 'false' below to the 'willwrite' flag? */
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;
++		goto out_nofree;
++	}
++
++	file->private_data =
++		kzalloc(sizeof(struct unionfs_file_info), GFP_KERNEL);
++	if (unlikely(!UNIONFS_F(file))) {
++		err = -ENOMEM;
++		goto out_nofree;
++	}
++	fbstart(file) = -1;
++	fbend(file) = -1;
++	atomic_set(&UNIONFS_F(file)->generation,
++		   atomic_read(&UNIONFS_I(inode)->generation));
++
++	size = sizeof(struct file *) * sbmax(inode->i_sb);
++	UNIONFS_F(file)->lower_files = kzalloc(size, GFP_KERNEL);
++	if (unlikely(!UNIONFS_F(file)->lower_files)) {
++		err = -ENOMEM;
++		goto out;
++	}
++	size = sizeof(int) * sbmax(inode->i_sb);
++	UNIONFS_F(file)->saved_branch_ids = kzalloc(size, GFP_KERNEL);
++	if (unlikely(!UNIONFS_F(file)->saved_branch_ids)) {
++		err = -ENOMEM;
++		goto out;
++	}
++
++	bstart = fbstart(file) = dbstart(dentry);
++	bend = fbend(file) = dbend(dentry);
++
++	/*
++	 * open all directories and make the unionfs file struct point to
++	 * these lower file structs
++	 */
++	if (S_ISDIR(inode->i_mode))
++		err = __open_dir(inode, file);	/* open a dir */
++	else
++		err = __open_file(inode, file, parent);	/* open a file */
++
++	/* freeing the allocated resources, and fput the opened files */
++	if (err) {
++		for (bindex = bstart; bindex <= bend; bindex++) {
++			lower_file = unionfs_lower_file_idx(file, bindex);
++			if (!lower_file)
++				continue;
++
++			branchput(dentry->d_sb, bindex);
++			/* fput calls dput for lower_dentry */
++			fput(lower_file);
++		}
++	}
++
++out:
++	if (err) {
++		kfree(UNIONFS_F(file)->lower_files);
++		kfree(UNIONFS_F(file)->saved_branch_ids);
++		kfree(UNIONFS_F(file));
++	}
++out_nofree:
++	if (!err) {
++		unionfs_postcopyup_setmnt(dentry);
++		unionfs_copy_attr_times(inode);
++		unionfs_check_file(file);
++		unionfs_check_inode(inode);
++	}
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(inode->i_sb);
++	return err;
++}
++
++/*
++ * release all lower object references & free the file info structure
++ *
++ * No need to grab sb info's rwsem.
++ */
++int unionfs_file_release(struct inode *inode, struct file *file)
++{
++	struct file *lower_file = NULL;
++	struct unionfs_file_info *fileinfo;
++	struct unionfs_inode_info *inodeinfo;
++	struct super_block *sb = inode->i_sb;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++	int bindex, bstart, bend;
++	int fgen, err = 0;
++
++	/*
++	 * Since mm/memory.c:might_fault() (under PROVE_LOCKING) was
++	 * modified in 2.6.29-rc1 to call might_lock_read on mmap_sem, this
++	 * has been causing false positives in file system stacking layers.
++	 * In particular, our ->mmap is called after sys_mmap2 already holds
++	 * mmap_sem, then we lock our own mutexes; but earlier, it's
++	 * possible for lockdep to have locked our mutexes first, and then
++	 * we call a lower ->readdir which could call might_fault.  The
++	 * different ordering of the locks is what lockdep complains about
++	 * -- unnecessarily.  Therefore, we have no choice but to tell
++	 * lockdep to temporarily turn off lockdep here.  Note: the comments
++	 * inside might_sleep also suggest that it would have been
++	 * nicer to only annotate paths that needs that might_lock_read.
++	 */
++	lockdep_off();
++	unionfs_read_lock(sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	/*
++	 * We try to revalidate, but the VFS ignores return return values
++	 * from file->release, so we must always try to succeed here,
++	 * including to do the kfree and dput below.  So if revalidation
++	 * failed, all we can do is print some message and keep going.
++	 */
++	err = unionfs_file_revalidate(file, parent,
++				      UNIONFS_F(file)->wrote_to_file);
++	if (!err)
++		unionfs_check_file(file);
++	fileinfo = UNIONFS_F(file);
++	BUG_ON(file->f_path.dentry->d_inode != inode);
++	inodeinfo = UNIONFS_I(inode);
++
++	/* fput all the lower files */
++	fgen = atomic_read(&fileinfo->generation);
++	bstart = fbstart(file);
++	bend = fbend(file);
++
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_file = unionfs_lower_file_idx(file, bindex);
++
++		if (lower_file) {
++			unionfs_set_lower_file_idx(file, bindex, NULL);
++			fput(lower_file);
++			branchput(sb, bindex);
++		}
++
++		/* if there are no more refs to the dentry, dput it */
++		if (d_deleted(dentry)) {
++			dput(unionfs_lower_dentry_idx(dentry, bindex));
++			unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
++		}
++	}
++
++	kfree(fileinfo->lower_files);
++	kfree(fileinfo->saved_branch_ids);
++
++	if (fileinfo->rdstate) {
++		fileinfo->rdstate->access = jiffies;
++		spin_lock(&inodeinfo->rdlock);
++		inodeinfo->rdcount++;
++		list_add_tail(&fileinfo->rdstate->cache,
++			      &inodeinfo->readdircache);
++		mark_inode_dirty(inode);
++		spin_unlock(&inodeinfo->rdlock);
++		fileinfo->rdstate = NULL;
++	}
++	kfree(fileinfo);
++
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(sb);
++	lockdep_on();
++	return err;
++}
++
++/* pass the ioctl to the lower fs */
++static long do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++	struct file *lower_file;
++	int err;
++
++	lower_file = unionfs_lower_file(file);
++
++	err = -ENOTTY;
++	if (!lower_file || !lower_file->f_op)
++		goto out;
++	if (lower_file->f_op->unlocked_ioctl) {
++		err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
++	} else if (lower_file->f_op->ioctl) {
++		lock_kernel();
++		err = lower_file->f_op->ioctl(
++			lower_file->f_path.dentry->d_inode,
++			lower_file, cmd, arg);
++		unlock_kernel();
++	}
++
++out:
++	return err;
++}
++
++/*
++ * return to user-space the branch indices containing the file in question
++ *
++ * We use fd_set and therefore we are limited to the number of the branches
++ * to FD_SETSIZE, which is currently 1024 - plenty for most people
++ */
++static int unionfs_ioctl_queryfile(struct file *file, struct dentry *parent,
++				   unsigned int cmd, unsigned long arg)
++{
++	int err = 0;
++	fd_set branchlist;
++	int bstart = 0, bend = 0, bindex = 0;
++	int orig_bstart, orig_bend;
++	struct dentry *dentry, *lower_dentry;
++	struct vfsmount *mnt;
++
++	dentry = file->f_path.dentry;
++	orig_bstart = dbstart(dentry);
++	orig_bend = dbend(dentry);
++	err = unionfs_partial_lookup(dentry, parent);
++	if (err)
++		goto out;
++	bstart = dbstart(dentry);
++	bend = dbend(dentry);
++
++	FD_ZERO(&branchlist);
++
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (!lower_dentry)
++			continue;
++		if (likely(lower_dentry->d_inode))
++			FD_SET(bindex, &branchlist);
++		/* purge any lower objects after partial_lookup */
++		if (bindex < orig_bstart || bindex > orig_bend) {
++			dput(lower_dentry);
++			unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
++			iput(unionfs_lower_inode_idx(dentry->d_inode, bindex));
++			unionfs_set_lower_inode_idx(dentry->d_inode, bindex,
++						    NULL);
++			mnt = unionfs_lower_mnt_idx(dentry, bindex);
++			if (!mnt)
++				continue;
++			unionfs_mntput(dentry, bindex);
++			unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
++		}
++	}
++	/* restore original dentry's offsets */
++	dbstart(dentry) = orig_bstart;
++	dbend(dentry) = orig_bend;
++	ibstart(dentry->d_inode) = orig_bstart;
++	ibend(dentry->d_inode) = orig_bend;
++
++	err = copy_to_user((void __user *)arg, &branchlist, sizeof(fd_set));
++	if (unlikely(err))
++		err = -EFAULT;
++
++out:
++	return err < 0 ? err : bend;
++}
++
++long unionfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++	long err;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	err = unionfs_file_revalidate(file, parent, true);
++	if (unlikely(err))
++		goto out;
++
++	/* check if asked for local commands */
++	switch (cmd) {
++	case UNIONFS_IOCTL_INCGEN:
++		/* Increment the superblock generation count */
++		pr_info("unionfs: incgen ioctl deprecated; "
++			"use \"-o remount,incgen\"\n");
++		err = -ENOSYS;
++		break;
++
++	case UNIONFS_IOCTL_QUERYFILE:
++		/* Return list of branches containing the given file */
++		err = unionfs_ioctl_queryfile(file, parent, cmd, arg);
++		break;
++
++	default:
++		/* pass the ioctl down */
++		err = do_ioctl(file, cmd, arg);
++		break;
++	}
++
++out:
++	unionfs_check_file(file);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++int unionfs_flush(struct file *file, fl_owner_t id)
++{
++	int err = 0;
++	struct file *lower_file = NULL;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++	int bindex, bstart, bend;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	err = unionfs_file_revalidate(file, parent,
++				      UNIONFS_F(file)->wrote_to_file);
++	if (unlikely(err))
++		goto out;
++	unionfs_check_file(file);
++
++	bstart = fbstart(file);
++	bend = fbend(file);
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_file = unionfs_lower_file_idx(file, bindex);
++
++		if (lower_file && lower_file->f_op &&
++		    lower_file->f_op->flush) {
++			err = lower_file->f_op->flush(lower_file, id);
++			if (err)
++				goto out;
++		}
++
++	}
++
++out:
++	if (!err)
++		unionfs_check_file(file);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
+diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c
+new file mode 100644
+index 0000000..bba3a75
+--- /dev/null
++++ b/fs/unionfs/copyup.c
+@@ -0,0 +1,896 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/*
++ * For detailed explanation of copyup see:
++ * Documentation/filesystems/unionfs/concepts.txt
++ */
++
++#ifdef CONFIG_UNION_FS_XATTR
++/* copyup all extended attrs for a given dentry */
++static int copyup_xattrs(struct dentry *old_lower_dentry,
++			 struct dentry *new_lower_dentry)
++{
++	int err = 0;
++	ssize_t list_size = -1;
++	char *name_list = NULL;
++	char *attr_value = NULL;
++	char *name_list_buf = NULL;
++
++	/* query the actual size of the xattr list */
++	list_size = vfs_listxattr(old_lower_dentry, NULL, 0);
++	if (list_size <= 0) {
++		err = list_size;
++		goto out;
++	}
++
++	/* allocate space for the actual list */
++	name_list = unionfs_xattr_alloc(list_size + 1, XATTR_LIST_MAX);
++	if (unlikely(!name_list || IS_ERR(name_list))) {
++		err = PTR_ERR(name_list);
++		goto out;
++	}
++
++	name_list_buf = name_list; /* save for kfree at end */
++
++	/* now get the actual xattr list of the source file */
++	list_size = vfs_listxattr(old_lower_dentry, name_list, list_size);
++	if (list_size <= 0) {
++		err = list_size;
++		goto out;
++	}
++
++	/* allocate space to hold each xattr's value */
++	attr_value = unionfs_xattr_alloc(XATTR_SIZE_MAX, XATTR_SIZE_MAX);
++	if (unlikely(!attr_value || IS_ERR(attr_value))) {
++		err = PTR_ERR(name_list);
++		goto out;
++	}
++
++	/* in a loop, get and set each xattr from src to dst file */
++	while (*name_list) {
++		ssize_t size;
++
++		/* Lock here since vfs_getxattr doesn't lock for us */
++		mutex_lock(&old_lower_dentry->d_inode->i_mutex);
++		size = vfs_getxattr(old_lower_dentry, name_list,
++				    attr_value, XATTR_SIZE_MAX);
++		mutex_unlock(&old_lower_dentry->d_inode->i_mutex);
++		if (size < 0) {
++			err = size;
++			goto out;
++		}
++		if (size > XATTR_SIZE_MAX) {
++			err = -E2BIG;
++			goto out;
++		}
++		/* Don't lock here since vfs_setxattr does it for us. */
++		err = vfs_setxattr(new_lower_dentry, name_list, attr_value,
++				   size, 0);
++		/*
++		 * Selinux depends on "security.*" xattrs, so to maintain
++		 * the security of copied-up files, if Selinux is active,
++		 * then we must copy these xattrs as well.  So we need to
++		 * temporarily get FOWNER privileges.
++		 * XXX: move entire copyup code to SIOQ.
++		 */
++		if (err == -EPERM && !capable(CAP_FOWNER)) {
++			const struct cred *old_creds;
++			struct cred *new_creds;
++
++			new_creds = prepare_creds();
++			if (unlikely(!new_creds)) {
++				err = -ENOMEM;
++				goto out;
++			}
++			cap_raise(new_creds->cap_effective, CAP_FOWNER);
++			old_creds = override_creds(new_creds);
++			err = vfs_setxattr(new_lower_dentry, name_list,
++					   attr_value, size, 0);
++			revert_creds(old_creds);
++		}
++		if (err < 0)
++			goto out;
++		name_list += strlen(name_list) + 1;
++	}
++out:
++	unionfs_xattr_kfree(name_list_buf);
++	unionfs_xattr_kfree(attr_value);
++	/* Ignore if xattr isn't supported */
++	if (err == -ENOTSUPP || err == -EOPNOTSUPP)
++		err = 0;
++	return err;
++}
++#endif /* CONFIG_UNION_FS_XATTR */
++
++/*
++ * Determine the mode based on the copyup flags, and the existing dentry.
++ *
++ * Handle file systems which may not support certain options.  For example
++ * jffs2 doesn't allow one to chmod a symlink.  So we ignore such harmless
++ * errors, rather than propagating them up, which results in copyup errors
++ * and errors returned back to users.
++ */
++static int copyup_permissions(struct super_block *sb,
++			      struct dentry *old_lower_dentry,
++			      struct dentry *new_lower_dentry)
++{
++	struct inode *i = old_lower_dentry->d_inode;
++	struct iattr newattrs;
++	int err;
++
++	newattrs.ia_atime = i->i_atime;
++	newattrs.ia_mtime = i->i_mtime;
++	newattrs.ia_ctime = i->i_ctime;
++	newattrs.ia_gid = i->i_gid;
++	newattrs.ia_uid = i->i_uid;
++	newattrs.ia_valid = ATTR_CTIME | ATTR_ATIME | ATTR_MTIME |
++		ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_FORCE |
++		ATTR_GID | ATTR_UID;
++	mutex_lock(&new_lower_dentry->d_inode->i_mutex);
++	err = notify_change(new_lower_dentry, &newattrs);
++	if (err)
++		goto out;
++
++	/* now try to change the mode and ignore EOPNOTSUPP on symlinks */
++	newattrs.ia_mode = i->i_mode;
++	newattrs.ia_valid = ATTR_MODE | ATTR_FORCE;
++	err = notify_change(new_lower_dentry, &newattrs);
++	if (err == -EOPNOTSUPP &&
++	    S_ISLNK(new_lower_dentry->d_inode->i_mode)) {
++		printk(KERN_WARNING
++		       "unionfs: changing \"%s\" symlink mode unsupported\n",
++		       new_lower_dentry->d_name.name);
++		err = 0;
++	}
++
++out:
++	mutex_unlock(&new_lower_dentry->d_inode->i_mutex);
++	return err;
++}
++
++/*
++ * create the new device/file/directory - use copyup_permission to copyup
++ * times, and mode
++ *
++ * if the object being copied up is a regular file, the file is only created,
++ * the contents have to be copied up separately
++ */
++static int __copyup_ndentry(struct dentry *old_lower_dentry,
++			    struct dentry *new_lower_dentry,
++			    struct dentry *new_lower_parent_dentry,
++			    char *symbuf)
++{
++	int err = 0;
++	umode_t old_mode = old_lower_dentry->d_inode->i_mode;
++	struct sioq_args args;
++
++	if (S_ISDIR(old_mode)) {
++		args.mkdir.parent = new_lower_parent_dentry->d_inode;
++		args.mkdir.dentry = new_lower_dentry;
++		args.mkdir.mode = old_mode;
++
++		run_sioq(__unionfs_mkdir, &args);
++		err = args.err;
++	} else if (S_ISLNK(old_mode)) {
++		args.symlink.parent = new_lower_parent_dentry->d_inode;
++		args.symlink.dentry = new_lower_dentry;
++		args.symlink.symbuf = symbuf;
++
++		run_sioq(__unionfs_symlink, &args);
++		err = args.err;
++	} else if (S_ISBLK(old_mode) || S_ISCHR(old_mode) ||
++		   S_ISFIFO(old_mode) || S_ISSOCK(old_mode)) {
++		args.mknod.parent = new_lower_parent_dentry->d_inode;
++		args.mknod.dentry = new_lower_dentry;
++		args.mknod.mode = old_mode;
++		args.mknod.dev = old_lower_dentry->d_inode->i_rdev;
++
++		run_sioq(__unionfs_mknod, &args);
++		err = args.err;
++	} else if (S_ISREG(old_mode)) {
++		struct nameidata nd;
++		err = init_lower_nd(&nd, LOOKUP_CREATE);
++		if (unlikely(err < 0))
++			goto out;
++		args.create.nd = &nd;
++		args.create.parent = new_lower_parent_dentry->d_inode;
++		args.create.dentry = new_lower_dentry;
++		args.create.mode = old_mode;
++
++		run_sioq(__unionfs_create, &args);
++		err = args.err;
++		release_lower_nd(&nd, err);
++	} else {
++		printk(KERN_CRIT "unionfs: unknown inode type %d\n",
++		       old_mode);
++		BUG();
++	}
++
++out:
++	return err;
++}
++
++static int __copyup_reg_data(struct dentry *dentry,
++			     struct dentry *new_lower_dentry, int new_bindex,
++			     struct dentry *old_lower_dentry, int old_bindex,
++			     struct file **copyup_file, loff_t len)
++{
++	struct super_block *sb = dentry->d_sb;
++	struct file *input_file;
++	struct file *output_file;
++	struct vfsmount *output_mnt;
++	mm_segment_t old_fs;
++	char *buf = NULL;
++	ssize_t read_bytes, write_bytes;
++	loff_t size;
++	int err = 0;
++
++	/* open old file */
++	unionfs_mntget(dentry, old_bindex);
++	branchget(sb, old_bindex);
++	/* dentry_open calls dput and mntput if it returns an error */
++	input_file = dentry_open(old_lower_dentry,
++				 unionfs_lower_mnt_idx(dentry, old_bindex),
++				 O_RDONLY | O_LARGEFILE, current_cred());
++	if (IS_ERR(input_file)) {
++		dput(old_lower_dentry);
++		err = PTR_ERR(input_file);
++		goto out;
++	}
++	if (unlikely(!input_file->f_op || !input_file->f_op->read)) {
++		err = -EINVAL;
++		goto out_close_in;
++	}
++
++	/* open new file */
++	dget(new_lower_dentry);
++	output_mnt = unionfs_mntget(sb->s_root, new_bindex);
++	branchget(sb, new_bindex);
++	output_file = dentry_open(new_lower_dentry, output_mnt,
++				  O_RDWR | O_LARGEFILE, current_cred());
++	if (IS_ERR(output_file)) {
++		err = PTR_ERR(output_file);
++		goto out_close_in2;
++	}
++	if (unlikely(!output_file->f_op || !output_file->f_op->write)) {
++		err = -EINVAL;
++		goto out_close_out;
++	}
++
++	/* allocating a buffer */
++	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
++	if (unlikely(!buf)) {
++		err = -ENOMEM;
++		goto out_close_out;
++	}
++
++	input_file->f_pos = 0;
++	output_file->f_pos = 0;
++
++	old_fs = get_fs();
++	set_fs(KERNEL_DS);
++
++	size = len;
++	err = 0;
++	do {
++		if (len >= PAGE_SIZE)
++			size = PAGE_SIZE;
++		else if ((len < PAGE_SIZE) && (len > 0))
++			size = len;
++
++		len -= PAGE_SIZE;
++
++		read_bytes =
++			input_file->f_op->read(input_file,
++					       (char __user *)buf, size,
++					       &input_file->f_pos);
++		if (read_bytes <= 0) {
++			err = read_bytes;
++			break;
++		}
++
++		/* see Documentation/filesystems/unionfs/issues.txt */
++		lockdep_off();
++		write_bytes =
++			output_file->f_op->write(output_file,
++						 (char __user *)buf,
++						 read_bytes,
++						 &output_file->f_pos);
++		lockdep_on();
++		if ((write_bytes < 0) || (write_bytes < read_bytes)) {
++			err = write_bytes;
++			break;
++		}
++	} while ((read_bytes > 0) && (len > 0));
++
++	set_fs(old_fs);
++
++	kfree(buf);
++
++	if (!err)
++		err = output_file->f_op->fsync(output_file, 0);
++
++	if (err)
++		goto out_close_out;
++
++	if (copyup_file) {
++		*copyup_file = output_file;
++		goto out_close_in;
++	}
++
++out_close_out:
++	fput(output_file);
++
++out_close_in2:
++	branchput(sb, new_bindex);
++
++out_close_in:
++	fput(input_file);
++
++out:
++	branchput(sb, old_bindex);
++
++	return err;
++}
++
++/*
++ * dput the lower references for old and new dentry & clear a lower dentry
++ * pointer
++ */
++static void __clear(struct dentry *dentry, struct dentry *old_lower_dentry,
++		    int old_bstart, int old_bend,
++		    struct dentry *new_lower_dentry, int new_bindex)
++{
++	/* get rid of the lower dentry and all its traces */
++	unionfs_set_lower_dentry_idx(dentry, new_bindex, NULL);
++	dbstart(dentry) = old_bstart;
++	dbend(dentry) = old_bend;
++
++	dput(new_lower_dentry);
++	dput(old_lower_dentry);
++}
++
++/*
++ * Copy up a dentry to a file of specified name.
++ *
++ * @dir: used to pull the ->i_sb to access other branches
++ * @dentry: the non-negative dentry whose lower_inode we should copy
++ * @bstart: the branch of the lower_inode to copy from
++ * @new_bindex: the branch to create the new file in
++ * @name: the name of the file to create
++ * @namelen: length of @name
++ * @copyup_file: the "struct file" to return (optional)
++ * @len: how many bytes to copy-up?
++ */
++int copyup_dentry(struct inode *dir, struct dentry *dentry, int bstart,
++		  int new_bindex, const char *name, int namelen,
++		  struct file **copyup_file, loff_t len)
++{
++	struct dentry *new_lower_dentry;
++	struct dentry *old_lower_dentry = NULL;
++	struct super_block *sb;
++	int err = 0;
++	int old_bindex;
++	int old_bstart;
++	int old_bend;
++	struct dentry *new_lower_parent_dentry = NULL;
++	mm_segment_t oldfs;
++	char *symbuf = NULL;
++
++	verify_locked(dentry);
++
++	old_bindex = bstart;
++	old_bstart = dbstart(dentry);
++	old_bend = dbend(dentry);
++
++	BUG_ON(new_bindex < 0);
++	BUG_ON(new_bindex >= old_bindex);
++
++	sb = dir->i_sb;
++
++	err = is_robranch_super(sb, new_bindex);
++	if (err)
++		goto out;
++
++	/* Create the directory structure above this dentry. */
++	new_lower_dentry = create_parents(dir, dentry, name, new_bindex);
++	if (IS_ERR(new_lower_dentry)) {
++		err = PTR_ERR(new_lower_dentry);
++		goto out;
++	}
++
++	old_lower_dentry = unionfs_lower_dentry_idx(dentry, old_bindex);
++	/* we conditionally dput this old_lower_dentry at end of function */
++	dget(old_lower_dentry);
++
++	/* For symlinks, we must read the link before we lock the directory. */
++	if (S_ISLNK(old_lower_dentry->d_inode->i_mode)) {
++
++		symbuf = kmalloc(PATH_MAX, GFP_KERNEL);
++		if (unlikely(!symbuf)) {
++			__clear(dentry, old_lower_dentry,
++				old_bstart, old_bend,
++				new_lower_dentry, new_bindex);
++			err = -ENOMEM;
++			goto out_free;
++		}
++
++		oldfs = get_fs();
++		set_fs(KERNEL_DS);
++		err = old_lower_dentry->d_inode->i_op->readlink(
++			old_lower_dentry,
++			(char __user *)symbuf,
++			PATH_MAX);
++		set_fs(oldfs);
++		if (err < 0) {
++			__clear(dentry, old_lower_dentry,
++				old_bstart, old_bend,
++				new_lower_dentry, new_bindex);
++			goto out_free;
++		}
++		symbuf[err] = '\0';
++	}
++
++	/* Now we lock the parent, and create the object in the new branch. */
++	new_lower_parent_dentry = lock_parent(new_lower_dentry);
++
++	/* create the new inode */
++	err = __copyup_ndentry(old_lower_dentry, new_lower_dentry,
++			       new_lower_parent_dentry, symbuf);
++
++	if (err) {
++		__clear(dentry, old_lower_dentry,
++			old_bstart, old_bend,
++			new_lower_dentry, new_bindex);
++		goto out_unlock;
++	}
++
++	/* We actually copyup the file here. */
++	if (S_ISREG(old_lower_dentry->d_inode->i_mode))
++		err = __copyup_reg_data(dentry, new_lower_dentry, new_bindex,
++					old_lower_dentry, old_bindex,
++					copyup_file, len);
++	if (err)
++		goto out_unlink;
++
++	/* Set permissions. */
++	err = copyup_permissions(sb, old_lower_dentry, new_lower_dentry);
++	if (err)
++		goto out_unlink;
++
++#ifdef CONFIG_UNION_FS_XATTR
++	/* Selinux uses extended attributes for permissions. */
++	err = copyup_xattrs(old_lower_dentry, new_lower_dentry);
++	if (err)
++		goto out_unlink;
++#endif /* CONFIG_UNION_FS_XATTR */
++
++	/* do not allow files getting deleted to be re-interposed */
++	if (!d_deleted(dentry))
++		unionfs_reinterpose(dentry);
++
++	goto out_unlock;
++
++out_unlink:
++	/*
++	 * copyup failed, because we possibly ran out of space or
++	 * quota, or something else happened so let's unlink; we don't
++	 * really care about the return value of vfs_unlink
++	 */
++	vfs_unlink(new_lower_parent_dentry->d_inode, new_lower_dentry);
++
++	if (copyup_file) {
++		/* need to close the file */
++
++		fput(*copyup_file);
++		branchput(sb, new_bindex);
++	}
++
++	/*
++	 * TODO: should we reset the error to something like -EIO?
++	 *
++	 * If we don't reset, the user may get some nonsensical errors, but
++	 * on the other hand, if we reset to EIO, we guarantee that the user
++	 * will get a "confusing" error message.
++	 */
++
++out_unlock:
++	unlock_dir(new_lower_parent_dentry);
++
++out_free:
++	/*
++	 * If old_lower_dentry was not a file, then we need to dput it.  If
++	 * it was a file, then it was already dput indirectly by other
++	 * functions we call above which operate on regular files.
++	 */
++	if (old_lower_dentry && old_lower_dentry->d_inode &&
++	    !S_ISREG(old_lower_dentry->d_inode->i_mode))
++		dput(old_lower_dentry);
++	kfree(symbuf);
++
++	if (err) {
++		/*
++		 * if directory creation succeeded, but inode copyup failed,
++		 * then purge new dentries.
++		 */
++		if (dbstart(dentry) < old_bstart &&
++		    ibstart(dentry->d_inode) > dbstart(dentry))
++			__clear(dentry, NULL, old_bstart, old_bend,
++				unionfs_lower_dentry(dentry), dbstart(dentry));
++		goto out;
++	}
++	if (!S_ISDIR(dentry->d_inode->i_mode)) {
++		unionfs_postcopyup_release(dentry);
++		if (!unionfs_lower_inode(dentry->d_inode)) {
++			/*
++			 * If we got here, then we copied up to an
++			 * unlinked-open file, whose name is .unionfsXXXXX.
++			 */
++			struct inode *inode = new_lower_dentry->d_inode;
++			atomic_inc(&inode->i_count);
++			unionfs_set_lower_inode_idx(dentry->d_inode,
++						    ibstart(dentry->d_inode),
++						    inode);
++		}
++	}
++	unionfs_postcopyup_setmnt(dentry);
++	/* sync inode times from copied-up inode to our inode */
++	unionfs_copy_attr_times(dentry->d_inode);
++	unionfs_check_inode(dir);
++	unionfs_check_dentry(dentry);
++out:
++	return err;
++}
++
++/*
++ * This function creates a copy of a file represented by 'file' which
++ * currently resides in branch 'bstart' to branch 'new_bindex.'  The copy
++ * will be named "name".
++ */
++int copyup_named_file(struct inode *dir, struct file *file, char *name,
++		      int bstart, int new_bindex, loff_t len)
++{
++	int err = 0;
++	struct file *output_file = NULL;
++
++	err = copyup_dentry(dir, file->f_path.dentry, bstart, new_bindex,
++			    name, strlen(name), &output_file, len);
++	if (!err) {
++		fbstart(file) = new_bindex;
++		unionfs_set_lower_file_idx(file, new_bindex, output_file);
++	}
++
++	return err;
++}
++
++/*
++ * This function creates a copy of a file represented by 'file' which
++ * currently resides in branch 'bstart' to branch 'new_bindex'.
++ */
++int copyup_file(struct inode *dir, struct file *file, int bstart,
++		int new_bindex, loff_t len)
++{
++	int err = 0;
++	struct file *output_file = NULL;
++	struct dentry *dentry = file->f_path.dentry;
++
++	err = copyup_dentry(dir, dentry, bstart, new_bindex,
++			    dentry->d_name.name, dentry->d_name.len,
++			    &output_file, len);
++	if (!err) {
++		fbstart(file) = new_bindex;
++		unionfs_set_lower_file_idx(file, new_bindex, output_file);
++	}
++
++	return err;
++}
++
++/* purge a dentry's lower-branch states (dput/mntput, etc.) */
++static void __cleanup_dentry(struct dentry *dentry, int bindex,
++			     int old_bstart, int old_bend)
++{
++	int loop_start;
++	int loop_end;
++	int new_bstart = -1;
++	int new_bend = -1;
++	int i;
++
++	loop_start = min(old_bstart, bindex);
++	loop_end = max(old_bend, bindex);
++
++	/*
++	 * This loop sets the bstart and bend for the new dentry by
++	 * traversing from left to right.  It also dputs all negative
++	 * dentries except bindex
++	 */
++	for (i = loop_start; i <= loop_end; i++) {
++		if (!unionfs_lower_dentry_idx(dentry, i))
++			continue;
++
++		if (i == bindex) {
++			new_bend = i;
++			if (new_bstart < 0)
++				new_bstart = i;
++			continue;
++		}
++
++		if (!unionfs_lower_dentry_idx(dentry, i)->d_inode) {
++			dput(unionfs_lower_dentry_idx(dentry, i));
++			unionfs_set_lower_dentry_idx(dentry, i, NULL);
++
++			unionfs_mntput(dentry, i);
++			unionfs_set_lower_mnt_idx(dentry, i, NULL);
++		} else {
++			if (new_bstart < 0)
++				new_bstart = i;
++			new_bend = i;
++		}
++	}
++
++	if (new_bstart < 0)
++		new_bstart = bindex;
++	if (new_bend < 0)
++		new_bend = bindex;
++	dbstart(dentry) = new_bstart;
++	dbend(dentry) = new_bend;
++
++}
++
++/* set lower inode ptr and update bstart & bend if necessary */
++static void __set_inode(struct dentry *upper, struct dentry *lower,
++			int bindex)
++{
++	unionfs_set_lower_inode_idx(upper->d_inode, bindex,
++				    igrab(lower->d_inode));
++	if (likely(ibstart(upper->d_inode) > bindex))
++		ibstart(upper->d_inode) = bindex;
++	if (likely(ibend(upper->d_inode) < bindex))
++		ibend(upper->d_inode) = bindex;
++
++}
++
++/* set lower dentry ptr and update bstart & bend if necessary */
++static void __set_dentry(struct dentry *upper, struct dentry *lower,
++			 int bindex)
++{
++	unionfs_set_lower_dentry_idx(upper, bindex, lower);
++	if (likely(dbstart(upper) > bindex))
++		dbstart(upper) = bindex;
++	if (likely(dbend(upper) < bindex))
++		dbend(upper) = bindex;
++}
++
++/*
++ * This function replicates the directory structure up-to given dentry
++ * in the bindex branch.
++ */
++struct dentry *create_parents(struct inode *dir, struct dentry *dentry,
++			      const char *name, int bindex)
++{
++	int err;
++	struct dentry *child_dentry;
++	struct dentry *parent_dentry;
++	struct dentry *lower_parent_dentry = NULL;
++	struct dentry *lower_dentry = NULL;
++	const char *childname;
++	unsigned int childnamelen;
++	int nr_dentry;
++	int count = 0;
++	int old_bstart;
++	int old_bend;
++	struct dentry **path = NULL;
++	struct super_block *sb;
++
++	verify_locked(dentry);
++
++	err = is_robranch_super(dir->i_sb, bindex);
++	if (err) {
++		lower_dentry = ERR_PTR(err);
++		goto out;
++	}
++
++	old_bstart = dbstart(dentry);
++	old_bend = dbend(dentry);
++
++	lower_dentry = ERR_PTR(-ENOMEM);
++
++	/* There is no sense allocating any less than the minimum. */
++	nr_dentry = 1;
++	path = kmalloc(nr_dentry * sizeof(struct dentry *), GFP_KERNEL);
++	if (unlikely(!path))
++		goto out;
++
++	/* assume the negative dentry of unionfs as the parent dentry */
++	parent_dentry = dentry;
++
++	/*
++	 * This loop finds the first parent that exists in the given branch.
++	 * We start building the directory structure from there.  At the end
++	 * of the loop, the following should hold:
++	 *  - child_dentry is the first nonexistent child
++	 *  - parent_dentry is the first existent parent
++	 *  - path[0] is the = deepest child
++	 *  - path[count] is the first child to create
++	 */
++	do {
++		child_dentry = parent_dentry;
++
++		/* find the parent directory dentry in unionfs */
++		parent_dentry = dget_parent(child_dentry);
++
++		/* find out the lower_parent_dentry in the given branch */
++		lower_parent_dentry =
++			unionfs_lower_dentry_idx(parent_dentry, bindex);
++
++		/* grow path table */
++		if (count == nr_dentry) {
++			void *p;
++
++			nr_dentry *= 2;
++			p = krealloc(path, nr_dentry * sizeof(struct dentry *),
++				     GFP_KERNEL);
++			if (unlikely(!p)) {
++				lower_dentry = ERR_PTR(-ENOMEM);
++				goto out;
++			}
++			path = p;
++		}
++
++		/* store the child dentry */
++		path[count++] = child_dentry;
++	} while (!lower_parent_dentry);
++	count--;
++
++	sb = dentry->d_sb;
++
++	/*
++	 * This code goes between the begin/end labels and basically
++	 * emulates a while(child_dentry != dentry), only cleaner and
++	 * shorter than what would be a much longer while loop.
++	 */
++begin:
++	/* get lower parent dir in the current branch */
++	lower_parent_dentry = unionfs_lower_dentry_idx(parent_dentry, bindex);
++	dput(parent_dentry);
++
++	/* init the values to lookup */
++	childname = child_dentry->d_name.name;
++	childnamelen = child_dentry->d_name.len;
++
++	if (child_dentry != dentry) {
++		/* lookup child in the underlying file system */
++		lower_dentry = lookup_lck_len(childname, lower_parent_dentry,
++					      childnamelen);
++		if (IS_ERR(lower_dentry))
++			goto out;
++	} else {
++		/*
++		 * Is the name a whiteout of the child name ?  lookup the
++		 * whiteout child in the underlying file system
++		 */
++		lower_dentry = lookup_lck_len(name, lower_parent_dentry,
++					      strlen(name));
++		if (IS_ERR(lower_dentry))
++			goto out;
++
++		/* Replace the current dentry (if any) with the new one */
++		dput(unionfs_lower_dentry_idx(dentry, bindex));
++		unionfs_set_lower_dentry_idx(dentry, bindex,
++					     lower_dentry);
++
++		__cleanup_dentry(dentry, bindex, old_bstart, old_bend);
++		goto out;
++	}
++
++	if (lower_dentry->d_inode) {
++		/*
++		 * since this already exists we dput to avoid
++		 * multiple references on the same dentry
++		 */
++		dput(lower_dentry);
++	} else {
++		struct sioq_args args;
++
++		/* it's a negative dentry, create a new dir */
++		lower_parent_dentry = lock_parent(lower_dentry);
++
++		args.mkdir.parent = lower_parent_dentry->d_inode;
++		args.mkdir.dentry = lower_dentry;
++		args.mkdir.mode = child_dentry->d_inode->i_mode;
++
++		run_sioq(__unionfs_mkdir, &args);
++		err = args.err;
++
++		if (!err)
++			err = copyup_permissions(dir->i_sb, child_dentry,
++						 lower_dentry);
++		unlock_dir(lower_parent_dentry);
++		if (err) {
++			dput(lower_dentry);
++			lower_dentry = ERR_PTR(err);
++			goto out;
++		}
++
++	}
++
++	__set_inode(child_dentry, lower_dentry, bindex);
++	__set_dentry(child_dentry, lower_dentry, bindex);
++	/*
++	 * update times of this dentry, but also the parent, because if
++	 * we changed, the parent may have changed too.
++	 */
++	fsstack_copy_attr_times(parent_dentry->d_inode,
++				lower_parent_dentry->d_inode);
++	unionfs_copy_attr_times(child_dentry->d_inode);
++
++	parent_dentry = child_dentry;
++	child_dentry = path[--count];
++	goto begin;
++out:
++	/* cleanup any leftover locks from the do/while loop above */
++	if (IS_ERR(lower_dentry))
++		while (count)
++			dput(path[count--]);
++	kfree(path);
++	return lower_dentry;
++}
++
++/*
++ * Post-copyup helper to ensure we have valid mnts: set lower mnt of
++ * dentry+parents to the first parent node that has an mnt.
++ */
++void unionfs_postcopyup_setmnt(struct dentry *dentry)
++{
++	struct dentry *parent, *hasone;
++	int bindex = dbstart(dentry);
++
++	if (unionfs_lower_mnt_idx(dentry, bindex))
++		return;
++	hasone = dentry->d_parent;
++	/* this loop should stop at root dentry */
++	while (!unionfs_lower_mnt_idx(hasone, bindex))
++		hasone = hasone->d_parent;
++	parent = dentry;
++	while (!unionfs_lower_mnt_idx(parent, bindex)) {
++		unionfs_set_lower_mnt_idx(parent, bindex,
++					  unionfs_mntget(hasone, bindex));
++		parent = parent->d_parent;
++	}
++}
++
++/*
++ * Post-copyup helper to release all non-directory source objects of a
++ * copied-up file.  Regular files should have only one lower object.
++ */
++void unionfs_postcopyup_release(struct dentry *dentry)
++{
++	int bstart, bend;
++
++	BUG_ON(S_ISDIR(dentry->d_inode->i_mode));
++	bstart = dbstart(dentry);
++	bend = dbend(dentry);
++
++	path_put_lowers(dentry, bstart + 1, bend, false);
++	iput_lowers(dentry->d_inode, bstart + 1, bend, false);
++
++	dbend(dentry) = bstart;
++	ibend(dentry->d_inode) = ibstart(dentry->d_inode) = bstart;
++}
+diff --git a/fs/unionfs/debug.c b/fs/unionfs/debug.c
+new file mode 100644
+index 0000000..100d2c6
+--- /dev/null
++++ b/fs/unionfs/debug.c
+@@ -0,0 +1,532 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/*
++ * Helper debugging functions for maintainers (and for users to report back
++ * useful information back to maintainers)
++ */
++
++/* it's always useful to know what part of the code called us */
++#define PRINT_CALLER(fname, fxn, line)					\
++	do {								\
++		if (!printed_caller) {					\
++			pr_debug("PC:%s:%s:%d\n", (fname), (fxn), (line)); \
++			printed_caller = 1;				\
++		}							\
++	} while (0)
++
++/*
++ * __unionfs_check_{inode,dentry,file} perform exhaustive sanity checking on
++ * the fan-out of various Unionfs objects.  We check that no lower objects
++ * exist  outside the start/end branch range; that all objects within are
++ * non-NULL (with some allowed exceptions); that for every lower file
++ * there's a lower dentry+inode; that the start/end ranges match for all
++ * corresponding lower objects; that open files/symlinks have only one lower
++ * objects, but directories can have several; and more.
++ */
++void __unionfs_check_inode(const struct inode *inode,
++			   const char *fname, const char *fxn, int line)
++{
++	int bindex;
++	int istart, iend;
++	struct inode *lower_inode;
++	struct super_block *sb;
++	int printed_caller = 0;
++	void *poison_ptr;
++
++	/* for inodes now */
++	BUG_ON(!inode);
++	sb = inode->i_sb;
++	istart = ibstart(inode);
++	iend = ibend(inode);
++	/* don't check inode if no lower branches */
++	if (istart < 0 && iend < 0)
++		return;
++	if (unlikely(istart > iend)) {
++		PRINT_CALLER(fname, fxn, line);
++		pr_debug(" Ci0: inode=%p istart/end=%d:%d\n",
++			 inode, istart, iend);
++	}
++	if (unlikely((istart == -1 && iend != -1) ||
++		     (istart != -1 && iend == -1))) {
++		PRINT_CALLER(fname, fxn, line);
++		pr_debug(" Ci1: inode=%p istart/end=%d:%d\n",
++			 inode, istart, iend);
++	}
++	if (!S_ISDIR(inode->i_mode)) {
++		if (unlikely(iend != istart)) {
++			PRINT_CALLER(fname, fxn, line);
++			pr_debug(" Ci2: inode=%p istart=%d iend=%d\n",
++				 inode, istart, iend);
++		}
++	}
++
++	for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
++		if (unlikely(!UNIONFS_I(inode))) {
++			PRINT_CALLER(fname, fxn, line);
++			pr_debug(" Ci3: no inode_info %p\n", inode);
++			return;
++		}
++		if (unlikely(!UNIONFS_I(inode)->lower_inodes)) {
++			PRINT_CALLER(fname, fxn, line);
++			pr_debug(" Ci4: no lower_inodes %p\n", inode);
++			return;
++		}
++		lower_inode = unionfs_lower_inode_idx(inode, bindex);
++		if (lower_inode) {
++			memset(&poison_ptr, POISON_INUSE, sizeof(void *));
++			if (unlikely(bindex < istart || bindex > iend)) {
++				PRINT_CALLER(fname, fxn, line);
++				pr_debug(" Ci5: inode/linode=%p:%p bindex=%d "
++					 "istart/end=%d:%d\n", inode,
++					 lower_inode, bindex, istart, iend);
++			} else if (unlikely(lower_inode == poison_ptr)) {
++				/* freed inode! */
++				PRINT_CALLER(fname, fxn, line);
++				pr_debug(" Ci6: inode/linode=%p:%p bindex=%d "
++					 "istart/end=%d:%d\n", inode,
++					 lower_inode, bindex, istart, iend);
++			}
++			continue;
++		}
++		/* if we get here, then lower_inode == NULL */
++		if (bindex < istart || bindex > iend)
++			continue;
++		/*
++		 * directories can have NULL lower inodes in b/t start/end,
++		 * but NOT if at the start/end range.
++		 */
++		if (unlikely(S_ISDIR(inode->i_mode) &&
++			     bindex > istart && bindex < iend))
++			continue;
++		PRINT_CALLER(fname, fxn, line);
++		pr_debug(" Ci7: inode/linode=%p:%p "
++			 "bindex=%d istart/end=%d:%d\n",
++			 inode, lower_inode, bindex, istart, iend);
++	}
++}
++
++void __unionfs_check_dentry(const struct dentry *dentry,
++			    const char *fname, const char *fxn, int line)
++{
++	int bindex;
++	int dstart, dend, istart, iend;
++	struct dentry *lower_dentry;
++	struct inode *inode, *lower_inode;
++	struct super_block *sb;
++	struct vfsmount *lower_mnt;
++	int printed_caller = 0;
++	void *poison_ptr;
++
++	BUG_ON(!dentry);
++	sb = dentry->d_sb;
++	inode = dentry->d_inode;
++	dstart = dbstart(dentry);
++	dend = dbend(dentry);
++	/* don't check dentry/mnt if no lower branches */
++	if (dstart < 0 && dend < 0)
++		goto check_inode;
++	BUG_ON(dstart > dend);
++
++	if (unlikely((dstart == -1 && dend != -1) ||
++		     (dstart != -1 && dend == -1))) {
++		PRINT_CALLER(fname, fxn, line);
++		pr_debug(" CD0: dentry=%p dstart/end=%d:%d\n",
++			 dentry, dstart, dend);
++	}
++	/*
++	 * check for NULL dentries inside the start/end range, or
++	 * non-NULL dentries outside the start/end range.
++	 */
++	for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (lower_dentry) {
++			if (unlikely(bindex < dstart || bindex > dend)) {
++				PRINT_CALLER(fname, fxn, line);
++				pr_debug(" CD1: dentry/lower=%p:%p(%p) "
++					 "bindex=%d dstart/end=%d:%d\n",
++					 dentry, lower_dentry,
++					 (lower_dentry ? lower_dentry->d_inode :
++					  (void *) -1L),
++					 bindex, dstart, dend);
++			}
++		} else {	/* lower_dentry == NULL */
++			if (bindex < dstart || bindex > dend)
++				continue;
++			/*
++			 * Directories can have NULL lower inodes in b/t
++			 * start/end, but NOT if at the start/end range.
++			 * Ignore this rule, however, if this is a NULL
++			 * dentry or a deleted dentry.
++			 */
++			if (unlikely(!d_deleted((struct dentry *) dentry) &&
++				     inode &&
++				     !(inode && S_ISDIR(inode->i_mode) &&
++				       bindex > dstart && bindex < dend))) {
++				PRINT_CALLER(fname, fxn, line);
++				pr_debug(" CD2: dentry/lower=%p:%p(%p) "
++					 "bindex=%d dstart/end=%d:%d\n",
++					 dentry, lower_dentry,
++					 (lower_dentry ?
++					  lower_dentry->d_inode :
++					  (void *) -1L),
++					 bindex, dstart, dend);
++			}
++		}
++	}
++
++	/* check for vfsmounts same as for dentries */
++	for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
++		lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
++		if (lower_mnt) {
++			if (unlikely(bindex < dstart || bindex > dend)) {
++				PRINT_CALLER(fname, fxn, line);
++				pr_debug(" CM0: dentry/lmnt=%p:%p bindex=%d "
++					 "dstart/end=%d:%d\n", dentry,
++					 lower_mnt, bindex, dstart, dend);
++			}
++		} else {	/* lower_mnt == NULL */
++			if (bindex < dstart || bindex > dend)
++				continue;
++			/*
++			 * Directories can have NULL lower inodes in b/t
++			 * start/end, but NOT if at the start/end range.
++			 * Ignore this rule, however, if this is a NULL
++			 * dentry.
++			 */
++			if (unlikely(inode &&
++				     !(inode && S_ISDIR(inode->i_mode) &&
++				       bindex > dstart && bindex < dend))) {
++				PRINT_CALLER(fname, fxn, line);
++				pr_debug(" CM1: dentry/lmnt=%p:%p "
++					 "bindex=%d dstart/end=%d:%d\n",
++					 dentry, lower_mnt, bindex,
++					 dstart, dend);
++			}
++		}
++	}
++
++check_inode:
++	/* for inodes now */
++	if (!inode)
++		return;
++	istart = ibstart(inode);
++	iend = ibend(inode);
++	/* don't check inode if no lower branches */
++	if (istart < 0 && iend < 0)
++		return;
++	BUG_ON(istart > iend);
++	if (unlikely((istart == -1 && iend != -1) ||
++		     (istart != -1 && iend == -1))) {
++		PRINT_CALLER(fname, fxn, line);
++		pr_debug(" CI0: dentry/inode=%p:%p istart/end=%d:%d\n",
++			 dentry, inode, istart, iend);
++	}
++	if (unlikely(istart != dstart)) {
++		PRINT_CALLER(fname, fxn, line);
++		pr_debug(" CI1: dentry/inode=%p:%p istart=%d dstart=%d\n",
++			 dentry, inode, istart, dstart);
++	}
++	if (unlikely(iend != dend)) {
++		PRINT_CALLER(fname, fxn, line);
++		pr_debug(" CI2: dentry/inode=%p:%p iend=%d dend=%d\n",
++			 dentry, inode, iend, dend);
++	}
++
++	if (!S_ISDIR(inode->i_mode)) {
++		if (unlikely(dend != dstart)) {
++			PRINT_CALLER(fname, fxn, line);
++			pr_debug(" CI3: dentry/inode=%p:%p dstart=%d dend=%d\n",
++				 dentry, inode, dstart, dend);
++		}
++		if (unlikely(iend != istart)) {
++			PRINT_CALLER(fname, fxn, line);
++			pr_debug(" CI4: dentry/inode=%p:%p istart=%d iend=%d\n",
++				 dentry, inode, istart, iend);
++		}
++	}
++
++	for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
++		lower_inode = unionfs_lower_inode_idx(inode, bindex);
++		if (lower_inode) {
++			memset(&poison_ptr, POISON_INUSE, sizeof(void *));
++			if (unlikely(bindex < istart || bindex > iend)) {
++				PRINT_CALLER(fname, fxn, line);
++				pr_debug(" CI5: dentry/linode=%p:%p bindex=%d "
++					 "istart/end=%d:%d\n", dentry,
++					 lower_inode, bindex, istart, iend);
++			} else if (unlikely(lower_inode == poison_ptr)) {
++				/* freed inode! */
++				PRINT_CALLER(fname, fxn, line);
++				pr_debug(" CI6: dentry/linode=%p:%p bindex=%d "
++					 "istart/end=%d:%d\n", dentry,
++					 lower_inode, bindex, istart, iend);
++			}
++			continue;
++		}
++		/* if we get here, then lower_inode == NULL */
++		if (bindex < istart || bindex > iend)
++			continue;
++		/*
++		 * directories can have NULL lower inodes in b/t start/end,
++		 * but NOT if at the start/end range.
++		 */
++		if (unlikely(S_ISDIR(inode->i_mode) &&
++			     bindex > istart && bindex < iend))
++			continue;
++		PRINT_CALLER(fname, fxn, line);
++		pr_debug(" CI7: dentry/linode=%p:%p "
++			 "bindex=%d istart/end=%d:%d\n",
++			 dentry, lower_inode, bindex, istart, iend);
++	}
++
++	/*
++	 * If it's a directory, then intermediate objects b/t start/end can
++	 * be NULL.  But, check that all three are NULL: lower dentry, mnt,
++	 * and inode.
++	 */
++	if (dstart >= 0 && dend >= 0 && S_ISDIR(inode->i_mode))
++		for (bindex = dstart+1; bindex < dend; bindex++) {
++			lower_inode = unionfs_lower_inode_idx(inode, bindex);
++			lower_dentry = unionfs_lower_dentry_idx(dentry,
++								bindex);
++			lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
++			if (unlikely(!((lower_inode && lower_dentry &&
++					lower_mnt) ||
++				       (!lower_inode &&
++					!lower_dentry && !lower_mnt)))) {
++				PRINT_CALLER(fname, fxn, line);
++				pr_debug(" Cx: lmnt/ldentry/linode=%p:%p:%p "
++					 "bindex=%d dstart/end=%d:%d\n",
++					 lower_mnt, lower_dentry, lower_inode,
++					 bindex, dstart, dend);
++			}
++		}
++	/* check if lower inode is newer than upper one (it shouldn't) */
++	if (unlikely(is_newer_lower(dentry) && !is_negative_lower(dentry))) {
++		PRINT_CALLER(fname, fxn, line);
++		for (bindex = ibstart(inode); bindex <= ibend(inode);
++		     bindex++) {
++			lower_inode = unionfs_lower_inode_idx(inode, bindex);
++			if (unlikely(!lower_inode))
++				continue;
++			pr_debug(" CI8: bindex=%d mtime/lmtime=%lu.%lu/%lu.%lu "
++				 "ctime/lctime=%lu.%lu/%lu.%lu\n",
++				 bindex,
++				 inode->i_mtime.tv_sec,
++				 inode->i_mtime.tv_nsec,
++				 lower_inode->i_mtime.tv_sec,
++				 lower_inode->i_mtime.tv_nsec,
++				 inode->i_ctime.tv_sec,
++				 inode->i_ctime.tv_nsec,
++				 lower_inode->i_ctime.tv_sec,
++				 lower_inode->i_ctime.tv_nsec);
++		}
++	}
++}
++
++void __unionfs_check_file(const struct file *file,
++			  const char *fname, const char *fxn, int line)
++{
++	int bindex;
++	int dstart, dend, fstart, fend;
++	struct dentry *dentry;
++	struct file *lower_file;
++	struct inode *inode;
++	struct super_block *sb;
++	int printed_caller = 0;
++
++	BUG_ON(!file);
++	dentry = file->f_path.dentry;
++	sb = dentry->d_sb;
++	dstart = dbstart(dentry);
++	dend = dbend(dentry);
++	BUG_ON(dstart > dend);
++	fstart = fbstart(file);
++	fend = fbend(file);
++	BUG_ON(fstart > fend);
++
++	if (unlikely((fstart == -1 && fend != -1) ||
++		     (fstart != -1 && fend == -1))) {
++		PRINT_CALLER(fname, fxn, line);
++		pr_debug(" CF0: file/dentry=%p:%p fstart/end=%d:%d\n",
++			 file, dentry, fstart, fend);
++	}
++	if (unlikely(fstart != dstart)) {
++		PRINT_CALLER(fname, fxn, line);
++		pr_debug(" CF1: file/dentry=%p:%p fstart=%d dstart=%d\n",
++			 file, dentry, fstart, dstart);
++	}
++	if (unlikely(fend != dend)) {
++		PRINT_CALLER(fname, fxn, line);
++		pr_debug(" CF2: file/dentry=%p:%p fend=%d dend=%d\n",
++			 file, dentry, fend, dend);
++	}
++	inode = dentry->d_inode;
++	if (!S_ISDIR(inode->i_mode)) {
++		if (unlikely(fend != fstart)) {
++			PRINT_CALLER(fname, fxn, line);
++			pr_debug(" CF3: file/inode=%p:%p fstart=%d fend=%d\n",
++				 file, inode, fstart, fend);
++		}
++		if (unlikely(dend != dstart)) {
++			PRINT_CALLER(fname, fxn, line);
++			pr_debug(" CF4: file/dentry=%p:%p dstart=%d dend=%d\n",
++				 file, dentry, dstart, dend);
++		}
++	}
++
++	/*
++	 * check for NULL dentries inside the start/end range, or
++	 * non-NULL dentries outside the start/end range.
++	 */
++	for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
++		lower_file = unionfs_lower_file_idx(file, bindex);
++		if (lower_file) {
++			if (unlikely(bindex < fstart || bindex > fend)) {
++				PRINT_CALLER(fname, fxn, line);
++				pr_debug(" CF5: file/lower=%p:%p bindex=%d "
++					 "fstart/end=%d:%d\n", file,
++					 lower_file, bindex, fstart, fend);
++			}
++		} else {	/* lower_file == NULL */
++			if (bindex >= fstart && bindex <= fend) {
++				/*
++				 * directories can have NULL lower inodes in
++				 * b/t start/end, but NOT if at the
++				 * start/end range.
++				 */
++				if (unlikely(!(S_ISDIR(inode->i_mode) &&
++					       bindex > fstart &&
++					       bindex < fend))) {
++					PRINT_CALLER(fname, fxn, line);
++					pr_debug(" CF6: file/lower=%p:%p "
++						 "bindex=%d fstart/end=%d:%d\n",
++						 file, lower_file, bindex,
++						 fstart, fend);
++				}
++			}
++		}
++	}
++
++	__unionfs_check_dentry(dentry, fname, fxn, line);
++}
++
++void __unionfs_check_nd(const struct nameidata *nd,
++			const char *fname, const char *fxn, int line)
++{
++	struct file *file;
++	int printed_caller = 0;
++
++	if (unlikely(!nd))
++		return;
++	if (nd->flags & LOOKUP_OPEN) {
++		file = nd->intent.open.file;
++		if (unlikely(file->f_path.dentry &&
++			     strcmp(file->f_path.dentry->d_sb->s_type->name,
++				    UNIONFS_NAME))) {
++			PRINT_CALLER(fname, fxn, line);
++			pr_debug(" CND1: lower_file of type %s\n",
++				 file->f_path.dentry->d_sb->s_type->name);
++		}
++	}
++}
++
++/* useful to track vfsmount leaks that could cause EBUSY on unmount */
++void __show_branch_counts(const struct super_block *sb,
++			  const char *file, const char *fxn, int line)
++{
++	int i;
++	struct vfsmount *mnt;
++
++	pr_debug("BC:");
++	for (i = 0; i < sbmax(sb); i++) {
++		if (likely(sb->s_root))
++			mnt = UNIONFS_D(sb->s_root)->lower_paths[i].mnt;
++		else
++			mnt = NULL;
++		printk(KERN_CONT "%d:",
++		       (mnt ? atomic_read(&mnt->mnt_count) : -99));
++	}
++	printk(KERN_CONT "%s:%s:%d\n", file, fxn, line);
++}
++
++void __show_inode_times(const struct inode *inode,
++			const char *file, const char *fxn, int line)
++{
++	struct inode *lower_inode;
++	int bindex;
++
++	for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
++		lower_inode = unionfs_lower_inode_idx(inode, bindex);
++		if (unlikely(!lower_inode))
++			continue;
++		pr_debug("IT(%lu:%d): %s:%s:%d "
++			 "um=%lu/%lu lm=%lu/%lu uc=%lu/%lu lc=%lu/%lu\n",
++			 inode->i_ino, bindex,
++			 file, fxn, line,
++			 inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
++			 lower_inode->i_mtime.tv_sec,
++			 lower_inode->i_mtime.tv_nsec,
++			 inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
++			 lower_inode->i_ctime.tv_sec,
++			 lower_inode->i_ctime.tv_nsec);
++	}
++}
++
++void __show_dinode_times(const struct dentry *dentry,
++			const char *file, const char *fxn, int line)
++{
++	struct inode *inode = dentry->d_inode;
++	struct inode *lower_inode;
++	int bindex;
++
++	for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
++		lower_inode = unionfs_lower_inode_idx(inode, bindex);
++		if (!lower_inode)
++			continue;
++		pr_debug("DT(%s:%lu:%d): %s:%s:%d "
++			 "um=%lu/%lu lm=%lu/%lu uc=%lu/%lu lc=%lu/%lu\n",
++			 dentry->d_name.name, inode->i_ino, bindex,
++			 file, fxn, line,
++			 inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
++			 lower_inode->i_mtime.tv_sec,
++			 lower_inode->i_mtime.tv_nsec,
++			 inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
++			 lower_inode->i_ctime.tv_sec,
++			 lower_inode->i_ctime.tv_nsec);
++	}
++}
++
++void __show_inode_counts(const struct inode *inode,
++			const char *file, const char *fxn, int line)
++{
++	struct inode *lower_inode;
++	int bindex;
++
++	if (unlikely(!inode)) {
++		pr_debug("SiC: Null inode\n");
++		return;
++	}
++	for (bindex = sbstart(inode->i_sb); bindex <= sbend(inode->i_sb);
++	     bindex++) {
++		lower_inode = unionfs_lower_inode_idx(inode, bindex);
++		if (unlikely(!lower_inode))
++			continue;
++		pr_debug("SIC(%lu:%d:%d): lc=%d %s:%s:%d\n",
++			 inode->i_ino, bindex,
++			 atomic_read(&(inode)->i_count),
++			 atomic_read(&(lower_inode)->i_count),
++			 file, fxn, line);
++	}
++}
+diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c
+new file mode 100644
+index 0000000..a0c3bba
+--- /dev/null
++++ b/fs/unionfs/dentry.c
+@@ -0,0 +1,397 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++bool is_negative_lower(const struct dentry *dentry)
++{
++	int bindex;
++	struct dentry *lower_dentry;
++
++	BUG_ON(!dentry);
++	/* cache coherency: check if file was deleted on lower branch */
++	if (dbstart(dentry) < 0)
++		return true;
++	for (bindex = dbstart(dentry); bindex <= dbend(dentry); bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		/* unhashed (i.e., unlinked) lower dentries don't count */
++		if (lower_dentry && lower_dentry->d_inode &&
++		    !d_deleted(lower_dentry) &&
++		    !(lower_dentry->d_flags & DCACHE_NFSFS_RENAMED))
++			return false;
++	}
++	return true;
++}
++
++static inline void __dput_lowers(struct dentry *dentry, int start, int end)
++{
++	struct dentry *lower_dentry;
++	int bindex;
++
++	if (start < 0)
++		return;
++	for (bindex = start; bindex <= end; bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (!lower_dentry)
++			continue;
++		unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
++		dput(lower_dentry);
++	}
++}
++
++/*
++ * Purge and invalidate as many data pages of a unionfs inode.  This is
++ * called when the lower inode has changed, and we want to force processes
++ * to re-get the new data.
++ */
++static inline void purge_inode_data(struct inode *inode)
++{
++	/* remove all non-private mappings */
++	unmap_mapping_range(inode->i_mapping, 0, 0, 0);
++	/* invalidate as many pages as possible */
++	invalidate_mapping_pages(inode->i_mapping, 0, -1);
++	/*
++	 * Don't try to truncate_inode_pages here, because this could lead
++	 * to a deadlock between some of address_space ops and dentry
++	 * revalidation: the address space op is invoked with a lock on our
++	 * own page, and truncate_inode_pages will block on locked pages.
++	 */
++}
++
++/*
++ * Revalidate a single file/symlink/special dentry.  Assume that info nodes
++ * of the @dentry and its @parent are locked.  Assume parent is valid,
++ * otherwise return false (and let's hope the VFS will try to re-lookup this
++ * dentry).  Returns true if valid, false otherwise.
++ */
++bool __unionfs_d_revalidate(struct dentry *dentry, struct dentry *parent,
++			    bool willwrite)
++{
++	bool valid = true;	/* default is valid */
++	struct dentry *lower_dentry;
++	struct dentry *result;
++	int bindex, bstart, bend;
++	int sbgen, dgen, pdgen;
++	int positive = 0;
++	int interpose_flag;
++
++	verify_locked(dentry);
++	verify_locked(parent);
++
++	/* if the dentry is unhashed, do NOT revalidate */
++	if (d_deleted(dentry))
++		goto out;
++
++	dgen = atomic_read(&UNIONFS_D(dentry)->generation);
++
++	if (is_newer_lower(dentry)) {
++		/* root dentry is always valid */
++		if (IS_ROOT(dentry)) {
++			unionfs_copy_attr_times(dentry->d_inode);
++		} else {
++			/*
++			 * reset generation number to zero, guaranteed to be
++			 * "old"
++			 */
++			dgen = 0;
++			atomic_set(&UNIONFS_D(dentry)->generation, dgen);
++		}
++		if (!willwrite)
++			purge_inode_data(dentry->d_inode);
++	}
++
++	sbgen = atomic_read(&UNIONFS_SB(dentry->d_sb)->generation);
++
++	BUG_ON(dbstart(dentry) == -1);
++	if (dentry->d_inode)
++		positive = 1;
++
++	/* if our dentry is valid, then validate all lower ones */
++	if (sbgen == dgen)
++		goto validate_lowers;
++
++	/* The root entry should always be valid */
++	BUG_ON(IS_ROOT(dentry));
++
++	/* We can't work correctly if our parent isn't valid. */
++	pdgen = atomic_read(&UNIONFS_D(parent)->generation);
++
++	/* Free the pointers for our inodes and this dentry. */
++	path_put_lowers_all(dentry, false);
++
++	interpose_flag = INTERPOSE_REVAL_NEG;
++	if (positive) {
++		interpose_flag = INTERPOSE_REVAL;
++		iput_lowers_all(dentry->d_inode, true);
++	}
++
++	if (realloc_dentry_private_data(dentry) != 0) {
++		valid = false;
++		goto out;
++	}
++
++	result = unionfs_lookup_full(dentry, parent, interpose_flag);
++	if (result) {
++		if (IS_ERR(result)) {
++			valid = false;
++			goto out;
++		}
++		/*
++		 * current unionfs_lookup_backend() doesn't return
++		 * a valid dentry
++		 */
++		dput(dentry);
++		dentry = result;
++	}
++
++	if (unlikely(positive && is_negative_lower(dentry))) {
++		/* call make_bad_inode here ? */
++		d_drop(dentry);
++		valid = false;
++		goto out;
++	}
++
++	/*
++	 * if we got here then we have revalidated our dentry and all lower
++	 * ones, so we can return safely.
++	 */
++	if (!valid)		/* lower dentry revalidation failed */
++		goto out;
++
++	/*
++	 * If the parent's gen no.  matches the superblock's gen no., then
++	 * we can update our denty's gen no.  If they didn't match, then it
++	 * was OK to revalidate this dentry with a stale parent, but we'll
++	 * purposely not update our dentry's gen no. (so it can be redone);
++	 * and, we'll mark our parent dentry as invalid so it'll force it
++	 * (and our dentry) to be revalidated.
++	 */
++	if (pdgen == sbgen)
++		atomic_set(&UNIONFS_D(dentry)->generation, sbgen);
++	goto out;
++
++validate_lowers:
++
++	/* The revalidation must occur across all branches */
++	bstart = dbstart(dentry);
++	bend = dbend(dentry);
++	BUG_ON(bstart == -1);
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (!lower_dentry || !lower_dentry->d_op
++		    || !lower_dentry->d_op->d_revalidate)
++			continue;
++		/*
++		 * Don't pass nameidata to lower file system, because we
++		 * don't want an arbitrary lower file being opened or
++		 * returned to us: it may be useless to us because of the
++		 * fanout nature of unionfs (cf. file/directory open-file
++		 * invariants).  We will open lower files as and when needed
++		 * later on.
++		 */
++		if (!lower_dentry->d_op->d_revalidate(lower_dentry, NULL))
++			valid = false;
++	}
++
++	if (!dentry->d_inode ||
++	    ibstart(dentry->d_inode) < 0 ||
++	    ibend(dentry->d_inode) < 0) {
++		valid = false;
++		goto out;
++	}
++
++	if (valid) {
++		/*
++		 * If we get here, and we copy the meta-data from the lower
++		 * inode to our inode, then it is vital that we have already
++		 * purged all unionfs-level file data.  We do that in the
++		 * caller (__unionfs_d_revalidate) by calling
++		 * purge_inode_data.
++		 */
++		unionfs_copy_attr_all(dentry->d_inode,
++				      unionfs_lower_inode(dentry->d_inode));
++		fsstack_copy_inode_size(dentry->d_inode,
++					unionfs_lower_inode(dentry->d_inode));
++	}
++
++out:
++	return valid;
++}
++
++/*
++ * Determine if the lower inode objects have changed from below the unionfs
++ * inode.  Return true if changed, false otherwise.
++ *
++ * We check if the mtime or ctime have changed.  However, the inode times
++ * can be changed by anyone without much protection, including
++ * asynchronously.  This can sometimes cause unionfs to find that the lower
++ * file system doesn't change its inode times quick enough, resulting in a
++ * false positive indication (which is harmless, it just makes unionfs do
++ * extra work in re-validating the objects).  To minimize the chances of
++ * these situations, we still consider such small time changes valid, but we
++ * don't print debugging messages unless the time changes are greater than
++ * UNIONFS_MIN_CC_TIME (which defaults to 3 seconds, as with NFS's acregmin)
++ * because significant changes are more likely due to users manually
++ * touching lower files.
++ */
++bool is_newer_lower(const struct dentry *dentry)
++{
++	int bindex;
++	struct inode *inode;
++	struct inode *lower_inode;
++
++	/* ignore if we're called on semi-initialized dentries/inodes */
++	if (!dentry || !UNIONFS_D(dentry))
++		return false;
++	inode = dentry->d_inode;
++	if (!inode || !UNIONFS_I(inode)->lower_inodes ||
++	    ibstart(inode) < 0 || ibend(inode) < 0)
++		return false;
++
++	for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
++		lower_inode = unionfs_lower_inode_idx(inode, bindex);
++		if (!lower_inode)
++			continue;
++
++		/* check if mtime/ctime have changed */
++		if (unlikely(timespec_compare(&inode->i_mtime,
++					      &lower_inode->i_mtime) < 0)) {
++			if ((lower_inode->i_mtime.tv_sec -
++			     inode->i_mtime.tv_sec) > UNIONFS_MIN_CC_TIME) {
++				pr_info("unionfs: new lower inode mtime "
++					"(bindex=%d, name=%s)\n", bindex,
++					dentry->d_name.name);
++				show_dinode_times(dentry);
++			}
++			return true;
++		}
++		if (unlikely(timespec_compare(&inode->i_ctime,
++					      &lower_inode->i_ctime) < 0)) {
++			if ((lower_inode->i_ctime.tv_sec -
++			     inode->i_ctime.tv_sec) > UNIONFS_MIN_CC_TIME) {
++				pr_info("unionfs: new lower inode ctime "
++					"(bindex=%d, name=%s)\n", bindex,
++					dentry->d_name.name);
++				show_dinode_times(dentry);
++			}
++			return true;
++		}
++	}
++
++	/*
++	 * Last check: if this is a positive dentry, but somehow all lower
++	 * dentries are negative or unhashed, then this dentry needs to be
++	 * revalidated, because someone probably deleted the objects from
++	 * the lower branches directly.
++	 */
++	if (is_negative_lower(dentry))
++		return true;
++
++	return false;		/* default: lower is not newer */
++}
++
++static int unionfs_d_revalidate(struct dentry *dentry,
++				struct nameidata *nd_unused)
++{
++	bool valid = true;
++	int err = 1;		/* 1 means valid for the VFS */
++	struct dentry *parent;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (valid) {
++		unionfs_postcopyup_setmnt(dentry);
++		unionfs_check_dentry(dentry);
++	} else {
++		d_drop(dentry);
++		err = valid;
++	}
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++
++	return err;
++}
++
++static void unionfs_d_release(struct dentry *dentry)
++{
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	if (unlikely(!UNIONFS_D(dentry)))
++		goto out;	/* skip if no lower branches */
++	/* must lock our branch configuration here */
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	unionfs_check_dentry(dentry);
++	/* this could be a negative dentry, so check first */
++	if (dbstart(dentry) < 0) {
++		unionfs_unlock_dentry(dentry);
++		goto out;	/* due to a (normal) failed lookup */
++	}
++
++	/* Release all the lower dentries */
++	path_put_lowers_all(dentry, true);
++
++	unionfs_unlock_dentry(dentry);
++
++out:
++	free_dentry_private_data(dentry);
++	unionfs_read_unlock(dentry->d_sb);
++	return;
++}
++
++/*
++ * Called when we're removing the last reference to our dentry.  So we
++ * should drop all lower references too.
++ */
++static void unionfs_d_iput(struct dentry *dentry, struct inode *inode)
++{
++	int rc;
++
++	BUG_ON(!dentry);
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	if (!UNIONFS_D(dentry) || dbstart(dentry) < 0)
++		goto drop_lower_inodes;
++	path_put_lowers_all(dentry, false);
++
++drop_lower_inodes:
++	rc = atomic_read(&inode->i_count);
++	if (rc == 1 && inode->i_nlink == 1 && ibstart(inode) >= 0) {
++		/* see Documentation/filesystems/unionfs/issues.txt */
++		lockdep_off();
++		iput(unionfs_lower_inode(inode));
++		lockdep_on();
++		unionfs_set_lower_inode(inode, NULL);
++		/* XXX: may need to set start/end to -1? */
++	}
++
++	iput(inode);
++
++	unionfs_unlock_dentry(dentry);
++	unionfs_read_unlock(dentry->d_sb);
++}
++
++struct dentry_operations unionfs_dops = {
++	.d_revalidate	= unionfs_d_revalidate,
++	.d_release	= unionfs_d_release,
++	.d_iput		= unionfs_d_iput,
++};
+diff --git a/fs/unionfs/dirfops.c b/fs/unionfs/dirfops.c
+new file mode 100644
+index 0000000..7da0ff0
+--- /dev/null
++++ b/fs/unionfs/dirfops.c
+@@ -0,0 +1,302 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/* Make sure our rdstate is playing by the rules. */
++static void verify_rdstate_offset(struct unionfs_dir_state *rdstate)
++{
++	BUG_ON(rdstate->offset >= DIREOF);
++	BUG_ON(rdstate->cookie >= MAXRDCOOKIE);
++}
++
++struct unionfs_getdents_callback {
++	struct unionfs_dir_state *rdstate;
++	void *dirent;
++	int entries_written;
++	int filldir_called;
++	int filldir_error;
++	filldir_t filldir;
++	struct super_block *sb;
++};
++
++/* based on generic filldir in fs/readir.c */
++static int unionfs_filldir(void *dirent, const char *oname, int namelen,
++			   loff_t offset, u64 ino, unsigned int d_type)
++{
++	struct unionfs_getdents_callback *buf = dirent;
++	struct filldir_node *found = NULL;
++	int err = 0;
++	int is_whiteout;
++	char *name = (char *) oname;
++
++	buf->filldir_called++;
++
++	is_whiteout = is_whiteout_name(&name, &namelen);
++
++	found = find_filldir_node(buf->rdstate, name, namelen, is_whiteout);
++
++	if (found) {
++		/*
++		 * If we had non-whiteout entry in dir cache, then mark it
++		 * as a whiteout and but leave it in the dir cache.
++		 */
++		if (is_whiteout && !found->whiteout)
++			found->whiteout = is_whiteout;
++		goto out;
++	}
++
++	/* if 'name' isn't a whiteout, filldir it. */
++	if (!is_whiteout) {
++		off_t pos = rdstate2offset(buf->rdstate);
++		u64 unionfs_ino = ino;
++
++		err = buf->filldir(buf->dirent, name, namelen, pos,
++				   unionfs_ino, d_type);
++		buf->rdstate->offset++;
++		verify_rdstate_offset(buf->rdstate);
++	}
++	/*
++	 * If we did fill it, stuff it in our hash, otherwise return an
++	 * error.
++	 */
++	if (err) {
++		buf->filldir_error = err;
++		goto out;
++	}
++	buf->entries_written++;
++	err = add_filldir_node(buf->rdstate, name, namelen,
++			       buf->rdstate->bindex, is_whiteout);
++	if (err)
++		buf->filldir_error = err;
++
++out:
++	return err;
++}
++
++static int unionfs_readdir(struct file *file, void *dirent, filldir_t filldir)
++{
++	int err = 0;
++	struct file *lower_file = NULL;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++	struct inode *inode = NULL;
++	struct unionfs_getdents_callback buf;
++	struct unionfs_dir_state *uds;
++	int bend;
++	loff_t offset;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	err = unionfs_file_revalidate(file, parent, false);
++	if (unlikely(err))
++		goto out;
++
++	inode = dentry->d_inode;
++
++	uds = UNIONFS_F(file)->rdstate;
++	if (!uds) {
++		if (file->f_pos == DIREOF) {
++			goto out;
++		} else if (file->f_pos > 0) {
++			uds = find_rdstate(inode, file->f_pos);
++			if (unlikely(!uds)) {
++				err = -ESTALE;
++				goto out;
++			}
++			UNIONFS_F(file)->rdstate = uds;
++		} else {
++			init_rdstate(file);
++			uds = UNIONFS_F(file)->rdstate;
++		}
++	}
++	bend = fbend(file);
++
++	while (uds->bindex <= bend) {
++		lower_file = unionfs_lower_file_idx(file, uds->bindex);
++		if (!lower_file) {
++			uds->bindex++;
++			uds->dirpos = 0;
++			continue;
++		}
++
++		/* prepare callback buffer */
++		buf.filldir_called = 0;
++		buf.filldir_error = 0;
++		buf.entries_written = 0;
++		buf.dirent = dirent;
++		buf.filldir = filldir;
++		buf.rdstate = uds;
++		buf.sb = inode->i_sb;
++
++		/* Read starting from where we last left off. */
++		offset = vfs_llseek(lower_file, uds->dirpos, SEEK_SET);
++		if (offset < 0) {
++			err = offset;
++			goto out;
++		}
++		err = vfs_readdir(lower_file, unionfs_filldir, &buf);
++
++		/* Save the position for when we continue. */
++		offset = vfs_llseek(lower_file, 0, SEEK_CUR);
++		if (offset < 0) {
++			err = offset;
++			goto out;
++		}
++		uds->dirpos = offset;
++
++		/* Copy the atime. */
++		fsstack_copy_attr_atime(inode,
++					lower_file->f_path.dentry->d_inode);
++
++		if (err < 0)
++			goto out;
++
++		if (buf.filldir_error)
++			break;
++
++		if (!buf.entries_written) {
++			uds->bindex++;
++			uds->dirpos = 0;
++		}
++	}
++
++	if (!buf.filldir_error && uds->bindex >= bend) {
++		/* Save the number of hash entries for next time. */
++		UNIONFS_I(inode)->hashsize = uds->hashentries;
++		free_rdstate(uds);
++		UNIONFS_F(file)->rdstate = NULL;
++		file->f_pos = DIREOF;
++	} else {
++		file->f_pos = rdstate2offset(uds);
++	}
++
++out:
++	if (!err)
++		unionfs_check_file(file);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++/*
++ * This is not meant to be a generic repositioning function.  If you do
++ * things that aren't supported, then we return EINVAL.
++ *
++ * What is allowed:
++ *  (1) seeking to the same position that you are currently at
++ *	This really has no effect, but returns where you are.
++ *  (2) seeking to the beginning of the file
++ *	This throws out all state, and lets you begin again.
++ */
++static loff_t unionfs_dir_llseek(struct file *file, loff_t offset, int origin)
++{
++	struct unionfs_dir_state *rdstate;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++	loff_t err;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	err = unionfs_file_revalidate(file, parent, false);
++	if (unlikely(err))
++		goto out;
++
++	rdstate = UNIONFS_F(file)->rdstate;
++
++	/*
++	 * we let users seek to their current position, but not anywhere
++	 * else.
++	 */
++	if (!offset) {
++		switch (origin) {
++		case SEEK_SET:
++			if (rdstate) {
++				free_rdstate(rdstate);
++				UNIONFS_F(file)->rdstate = NULL;
++			}
++			init_rdstate(file);
++			err = 0;
++			break;
++		case SEEK_CUR:
++			err = file->f_pos;
++			break;
++		case SEEK_END:
++			/* Unsupported, because we would break everything.  */
++			err = -EINVAL;
++			break;
++		}
++	} else {
++		switch (origin) {
++		case SEEK_SET:
++			if (rdstate) {
++				if (offset == rdstate2offset(rdstate))
++					err = offset;
++				else if (file->f_pos == DIREOF)
++					err = DIREOF;
++				else
++					err = -EINVAL;
++			} else {
++				struct inode *inode;
++				inode = dentry->d_inode;
++				rdstate = find_rdstate(inode, offset);
++				if (rdstate) {
++					UNIONFS_F(file)->rdstate = rdstate;
++					err = rdstate->offset;
++				} else {
++					err = -EINVAL;
++				}
++			}
++			break;
++		case SEEK_CUR:
++		case SEEK_END:
++			/* Unsupported, because we would break everything.  */
++			err = -EINVAL;
++			break;
++		}
++	}
++
++out:
++	if (!err)
++		unionfs_check_file(file);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++/*
++ * Trimmed directory options, we shouldn't pass everything down since
++ * we don't want to operate on partial directories.
++ */
++struct file_operations unionfs_dir_fops = {
++	.llseek		= unionfs_dir_llseek,
++	.read		= generic_read_dir,
++	.readdir	= unionfs_readdir,
++	.unlocked_ioctl	= unionfs_ioctl,
++	.open		= unionfs_open,
++	.release	= unionfs_file_release,
++	.flush		= unionfs_flush,
++	.fsync		= unionfs_fsync,
++	.fasync		= unionfs_fasync,
++};
+diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
+new file mode 100644
+index 0000000..033343b
+--- /dev/null
++++ b/fs/unionfs/dirhelper.c
+@@ -0,0 +1,158 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++#define RD_NONE 0
++#define RD_CHECK_EMPTY 1
++/* The callback structure for check_empty. */
++struct unionfs_rdutil_callback {
++	int err;
++	int filldir_called;
++	struct unionfs_dir_state *rdstate;
++	int mode;
++};
++
++/* This filldir function makes sure only whiteouts exist within a directory. */
++static int readdir_util_callback(void *dirent, const char *oname, int namelen,
++				 loff_t offset, u64 ino, unsigned int d_type)
++{
++	int err = 0;
++	struct unionfs_rdutil_callback *buf = dirent;
++	int is_whiteout;
++	struct filldir_node *found;
++	char *name = (char *) oname;
++
++	buf->filldir_called = 1;
++
++	if (name[0] == '.' && (namelen == 1 ||
++			       (name[1] == '.' && namelen == 2)))
++		goto out;
++
++	is_whiteout = is_whiteout_name(&name, &namelen);
++
++	found = find_filldir_node(buf->rdstate, name, namelen, is_whiteout);
++	/* If it was found in the table there was a previous whiteout. */
++	if (found)
++		goto out;
++
++	/*
++	 * if it wasn't found and isn't a whiteout, the directory isn't
++	 * empty.
++	 */
++	err = -ENOTEMPTY;
++	if ((buf->mode == RD_CHECK_EMPTY) && !is_whiteout)
++		goto out;
++
++	err = add_filldir_node(buf->rdstate, name, namelen,
++			       buf->rdstate->bindex, is_whiteout);
++
++out:
++	buf->err = err;
++	return err;
++}
++
++/* Is a directory logically empty? */
++int check_empty(struct dentry *dentry, struct dentry *parent,
++		struct unionfs_dir_state **namelist)
++{
++	int err = 0;
++	struct dentry *lower_dentry = NULL;
++	struct vfsmount *mnt;
++	struct super_block *sb;
++	struct file *lower_file;
++	struct unionfs_rdutil_callback *buf = NULL;
++	int bindex, bstart, bend, bopaque;
++
++	sb = dentry->d_sb;
++
++
++	BUG_ON(!S_ISDIR(dentry->d_inode->i_mode));
++
++	err = unionfs_partial_lookup(dentry, parent);
++	if (err)
++		goto out;
++
++	bstart = dbstart(dentry);
++	bend = dbend(dentry);
++	bopaque = dbopaque(dentry);
++	if (0 <= bopaque && bopaque < bend)
++		bend = bopaque;
++
++	buf = kmalloc(sizeof(struct unionfs_rdutil_callback), GFP_KERNEL);
++	if (unlikely(!buf)) {
++		err = -ENOMEM;
++		goto out;
++	}
++	buf->err = 0;
++	buf->mode = RD_CHECK_EMPTY;
++	buf->rdstate = alloc_rdstate(dentry->d_inode, bstart);
++	if (unlikely(!buf->rdstate)) {
++		err = -ENOMEM;
++		goto out;
++	}
++
++	/* Process the lower directories with rdutil_callback as a filldir. */
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (!lower_dentry)
++			continue;
++		if (!lower_dentry->d_inode)
++			continue;
++		if (!S_ISDIR(lower_dentry->d_inode->i_mode))
++			continue;
++
++		dget(lower_dentry);
++		mnt = unionfs_mntget(dentry, bindex);
++		branchget(sb, bindex);
++		lower_file = dentry_open(lower_dentry, mnt, O_RDONLY, current_cred());
++		if (IS_ERR(lower_file)) {
++			err = PTR_ERR(lower_file);
++			branchput(sb, bindex);
++			goto out;
++		}
++
++		do {
++			buf->filldir_called = 0;
++			buf->rdstate->bindex = bindex;
++			err = vfs_readdir(lower_file,
++					  readdir_util_callback, buf);
++			if (buf->err)
++				err = buf->err;
++		} while ((err >= 0) && buf->filldir_called);
++
++		/* fput calls dput for lower_dentry */
++		fput(lower_file);
++		branchput(sb, bindex);
++
++		if (err < 0)
++			goto out;
++	}
++
++out:
++	if (buf) {
++		if (namelist && !err)
++			*namelist = buf->rdstate;
++		else if (buf->rdstate)
++			free_rdstate(buf->rdstate);
++		kfree(buf);
++	}
++
++
++	return err;
++}
+diff --git a/fs/unionfs/fanout.h b/fs/unionfs/fanout.h
+new file mode 100644
+index 0000000..5b77eac
+--- /dev/null
++++ b/fs/unionfs/fanout.h
+@@ -0,0 +1,407 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef _FANOUT_H_
++#define _FANOUT_H_
++
++/*
++ * Inode to private data
++ *
++ * Since we use containers and the struct inode is _inside_ the
++ * unionfs_inode_info structure, UNIONFS_I will always (given a non-NULL
++ * inode pointer), return a valid non-NULL pointer.
++ */
++static inline struct unionfs_inode_info *UNIONFS_I(const struct inode *inode)
++{
++	return container_of(inode, struct unionfs_inode_info, vfs_inode);
++}
++
++#define ibstart(ino) (UNIONFS_I(ino)->bstart)
++#define ibend(ino) (UNIONFS_I(ino)->bend)
++
++/* Dentry to private data */
++#define UNIONFS_D(dent) ((struct unionfs_dentry_info *)(dent)->d_fsdata)
++#define dbstart(dent) (UNIONFS_D(dent)->bstart)
++#define dbend(dent) (UNIONFS_D(dent)->bend)
++#define dbopaque(dent) (UNIONFS_D(dent)->bopaque)
++
++/* Superblock to private data */
++#define UNIONFS_SB(super) ((struct unionfs_sb_info *)(super)->s_fs_info)
++#define sbstart(sb) 0
++#define sbend(sb) (UNIONFS_SB(sb)->bend)
++#define sbmax(sb) (UNIONFS_SB(sb)->bend + 1)
++#define sbhbid(sb) (UNIONFS_SB(sb)->high_branch_id)
++
++/* File to private Data */
++#define UNIONFS_F(file) ((struct unionfs_file_info *)((file)->private_data))
++#define fbstart(file) (UNIONFS_F(file)->bstart)
++#define fbend(file) (UNIONFS_F(file)->bend)
++
++/* macros to manipulate branch IDs in stored in our superblock */
++static inline int branch_id(struct super_block *sb, int index)
++{
++	BUG_ON(!sb || index < 0);
++	return UNIONFS_SB(sb)->data[index].branch_id;
++}
++
++static inline void set_branch_id(struct super_block *sb, int index, int val)
++{
++	BUG_ON(!sb || index < 0);
++	UNIONFS_SB(sb)->data[index].branch_id = val;
++}
++
++static inline void new_branch_id(struct super_block *sb, int index)
++{
++	BUG_ON(!sb || index < 0);
++	set_branch_id(sb, index, ++UNIONFS_SB(sb)->high_branch_id);
++}
++
++/*
++ * Find new index of matching branch with an existing superblock of a known
++ * (possibly old) id.  This is needed because branches could have been
++ * added/deleted causing the branches of any open files to shift.
++ *
++ * @sb: the new superblock which may have new/different branch IDs
++ * @id: the old/existing id we're looking for
++ * Returns index of newly found branch (0 or greater), -1 otherwise.
++ */
++static inline int branch_id_to_idx(struct super_block *sb, int id)
++{
++	int i;
++	for (i = 0; i < sbmax(sb); i++) {
++		if (branch_id(sb, i) == id)
++			return i;
++	}
++	/* in the non-ODF code, this should really never happen */
++	printk(KERN_WARNING "unionfs: cannot find branch with id %d\n", id);
++	return -1;
++}
++
++/* File to lower file. */
++static inline struct file *unionfs_lower_file(const struct file *f)
++{
++	BUG_ON(!f);
++	return UNIONFS_F(f)->lower_files[fbstart(f)];
++}
++
++static inline struct file *unionfs_lower_file_idx(const struct file *f,
++						  int index)
++{
++	BUG_ON(!f || index < 0);
++	return UNIONFS_F(f)->lower_files[index];
++}
++
++static inline void unionfs_set_lower_file_idx(struct file *f, int index,
++					      struct file *val)
++{
++	BUG_ON(!f || index < 0);
++	UNIONFS_F(f)->lower_files[index] = val;
++	/* save branch ID (may be redundant?) */
++	UNIONFS_F(f)->saved_branch_ids[index] =
++		branch_id((f)->f_path.dentry->d_sb, index);
++}
++
++static inline void unionfs_set_lower_file(struct file *f, struct file *val)
++{
++	BUG_ON(!f);
++	unionfs_set_lower_file_idx((f), fbstart(f), (val));
++}
++
++/* Inode to lower inode. */
++static inline struct inode *unionfs_lower_inode(const struct inode *i)
++{
++	BUG_ON(!i);
++	return UNIONFS_I(i)->lower_inodes[ibstart(i)];
++}
++
++static inline struct inode *unionfs_lower_inode_idx(const struct inode *i,
++						    int index)
++{
++	BUG_ON(!i || index < 0);
++	return UNIONFS_I(i)->lower_inodes[index];
++}
++
++static inline void unionfs_set_lower_inode_idx(struct inode *i, int index,
++					       struct inode *val)
++{
++	BUG_ON(!i || index < 0);
++	UNIONFS_I(i)->lower_inodes[index] = val;
++}
++
++static inline void unionfs_set_lower_inode(struct inode *i, struct inode *val)
++{
++	BUG_ON(!i);
++	UNIONFS_I(i)->lower_inodes[ibstart(i)] = val;
++}
++
++/* Superblock to lower superblock. */
++static inline struct super_block *unionfs_lower_super(
++					const struct super_block *sb)
++{
++	BUG_ON(!sb);
++	return UNIONFS_SB(sb)->data[sbstart(sb)].sb;
++}
++
++static inline struct super_block *unionfs_lower_super_idx(
++					const struct super_block *sb,
++					int index)
++{
++	BUG_ON(!sb || index < 0);
++	return UNIONFS_SB(sb)->data[index].sb;
++}
++
++static inline void unionfs_set_lower_super_idx(struct super_block *sb,
++					       int index,
++					       struct super_block *val)
++{
++	BUG_ON(!sb || index < 0);
++	UNIONFS_SB(sb)->data[index].sb = val;
++}
++
++static inline void unionfs_set_lower_super(struct super_block *sb,
++					   struct super_block *val)
++{
++	BUG_ON(!sb);
++	UNIONFS_SB(sb)->data[sbstart(sb)].sb = val;
++}
++
++/* Branch count macros. */
++static inline int branch_count(const struct super_block *sb, int index)
++{
++	BUG_ON(!sb || index < 0);
++	return atomic_read(&UNIONFS_SB(sb)->data[index].open_files);
++}
++
++static inline void set_branch_count(struct super_block *sb, int index, int val)
++{
++	BUG_ON(!sb || index < 0);
++	atomic_set(&UNIONFS_SB(sb)->data[index].open_files, val);
++}
++
++static inline void branchget(struct super_block *sb, int index)
++{
++	BUG_ON(!sb || index < 0);
++	atomic_inc(&UNIONFS_SB(sb)->data[index].open_files);
++}
++
++static inline void branchput(struct super_block *sb, int index)
++{
++	BUG_ON(!sb || index < 0);
++	atomic_dec(&UNIONFS_SB(sb)->data[index].open_files);
++}
++
++/* Dentry macros */
++static inline void unionfs_set_lower_dentry_idx(struct dentry *dent, int index,
++						struct dentry *val)
++{
++	BUG_ON(!dent || index < 0);
++	UNIONFS_D(dent)->lower_paths[index].dentry = val;
++}
++
++static inline struct dentry *unionfs_lower_dentry_idx(
++				const struct dentry *dent,
++				int index)
++{
++	BUG_ON(!dent || index < 0);
++	return UNIONFS_D(dent)->lower_paths[index].dentry;
++}
++
++static inline struct dentry *unionfs_lower_dentry(const struct dentry *dent)
++{
++	BUG_ON(!dent);
++	return unionfs_lower_dentry_idx(dent, dbstart(dent));
++}
++
++static inline void unionfs_set_lower_mnt_idx(struct dentry *dent, int index,
++					     struct vfsmount *mnt)
++{
++	BUG_ON(!dent || index < 0);
++	UNIONFS_D(dent)->lower_paths[index].mnt = mnt;
++}
++
++static inline struct vfsmount *unionfs_lower_mnt_idx(
++					const struct dentry *dent,
++					int index)
++{
++	BUG_ON(!dent || index < 0);
++	return UNIONFS_D(dent)->lower_paths[index].mnt;
++}
++
++static inline struct vfsmount *unionfs_lower_mnt(const struct dentry *dent)
++{
++	BUG_ON(!dent);
++	return unionfs_lower_mnt_idx(dent, dbstart(dent));
++}
++
++/* Macros for locking a dentry. */
++enum unionfs_dentry_lock_class {
++	UNIONFS_DMUTEX_NORMAL,
++	UNIONFS_DMUTEX_ROOT,
++	UNIONFS_DMUTEX_PARENT,
++	UNIONFS_DMUTEX_CHILD,
++	UNIONFS_DMUTEX_WHITEOUT,
++	UNIONFS_DMUTEX_REVAL_PARENT, /* for file/dentry revalidate */
++	UNIONFS_DMUTEX_REVAL_CHILD,   /* for file/dentry revalidate */
++};
++
++static inline void unionfs_lock_dentry(struct dentry *d,
++				       unsigned int subclass)
++{
++	BUG_ON(!d);
++	mutex_lock_nested(&UNIONFS_D(d)->lock, subclass);
++}
++
++static inline void unionfs_unlock_dentry(struct dentry *d)
++{
++	BUG_ON(!d);
++	mutex_unlock(&UNIONFS_D(d)->lock);
++}
++
++static inline struct dentry *unionfs_lock_parent(struct dentry *d,
++						 unsigned int subclass)
++{
++	struct dentry *p;
++
++	BUG_ON(!d);
++	p = dget_parent(d);
++	if (p != d)
++		mutex_lock_nested(&UNIONFS_D(p)->lock, subclass);
++	return p;
++}
++
++static inline void unionfs_unlock_parent(struct dentry *d, struct dentry *p)
++{
++	BUG_ON(!d);
++	BUG_ON(!p);
++	if (p != d) {
++		BUG_ON(!mutex_is_locked(&UNIONFS_D(p)->lock));
++		mutex_unlock(&UNIONFS_D(p)->lock);
++	}
++	dput(p);
++}
++
++static inline void verify_locked(struct dentry *d)
++{
++	BUG_ON(!d);
++	BUG_ON(!mutex_is_locked(&UNIONFS_D(d)->lock));
++}
++
++/* macros to put lower objects */
++
++/*
++ * iput lower inodes of an unionfs dentry, from bstart to bend.  If
++ * @free_lower is true, then also kfree the memory used to hold the lower
++ * object pointers.
++ */
++static inline void iput_lowers(struct inode *inode,
++			       int bstart, int bend, bool free_lower)
++{
++	struct inode *lower_inode;
++	int bindex;
++
++	BUG_ON(!inode);
++	BUG_ON(!UNIONFS_I(inode));
++	BUG_ON(bstart < 0);
++
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_inode = unionfs_lower_inode_idx(inode, bindex);
++		if (lower_inode) {
++			unionfs_set_lower_inode_idx(inode, bindex, NULL);
++			/* see Documentation/filesystems/unionfs/issues.txt */
++			lockdep_off();
++			iput(lower_inode);
++			lockdep_on();
++		}
++	}
++
++	if (free_lower) {
++		kfree(UNIONFS_I(inode)->lower_inodes);
++		UNIONFS_I(inode)->lower_inodes = NULL;
++	}
++}
++
++/* iput all lower inodes, and reset start/end branch indices to -1 */
++static inline void iput_lowers_all(struct inode *inode, bool free_lower)
++{
++	int bstart, bend;
++
++	BUG_ON(!inode);
++	BUG_ON(!UNIONFS_I(inode));
++	bstart = ibstart(inode);
++	bend = ibend(inode);
++	BUG_ON(bstart < 0);
++
++	iput_lowers(inode, bstart, bend, free_lower);
++	ibstart(inode) = ibend(inode) = -1;
++}
++
++/*
++ * dput/mntput all lower dentries and vfsmounts of an unionfs dentry, from
++ * bstart to bend.  If @free_lower is true, then also kfree the memory used
++ * to hold the lower object pointers.
++ *
++ * XXX: implement using path_put VFS macros
++ */
++static inline void path_put_lowers(struct dentry *dentry,
++				   int bstart, int bend, bool free_lower)
++{
++	struct dentry *lower_dentry;
++	struct vfsmount *lower_mnt;
++	int bindex;
++
++	BUG_ON(!dentry);
++	BUG_ON(!UNIONFS_D(dentry));
++	BUG_ON(bstart < 0);
++
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (lower_dentry) {
++			unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
++			dput(lower_dentry);
++		}
++		lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
++		if (lower_mnt) {
++			unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
++			mntput(lower_mnt);
++		}
++	}
++
++	if (free_lower) {
++		kfree(UNIONFS_D(dentry)->lower_paths);
++		UNIONFS_D(dentry)->lower_paths = NULL;
++	}
++}
++
++/*
++ * dput/mntput all lower dentries and vfsmounts, and reset start/end branch
++ * indices to -1.
++ */
++static inline void path_put_lowers_all(struct dentry *dentry, bool free_lower)
++{
++	int bstart, bend;
++
++	BUG_ON(!dentry);
++	BUG_ON(!UNIONFS_D(dentry));
++	bstart = dbstart(dentry);
++	bend = dbend(dentry);
++	BUG_ON(bstart < 0);
++
++	path_put_lowers(dentry, bstart, bend, free_lower);
++	dbstart(dentry) = dbend(dentry) = -1;
++}
++
++#endif	/* not _FANOUT_H */
+diff --git a/fs/unionfs/file.c b/fs/unionfs/file.c
+new file mode 100644
+index 0000000..5a8f4e0
+--- /dev/null
++++ b/fs/unionfs/file.c
+@@ -0,0 +1,379 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++static ssize_t unionfs_read(struct file *file, char __user *buf,
++			    size_t count, loff_t *ppos)
++{
++	int err;
++	struct file *lower_file;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	err = unionfs_file_revalidate(file, parent, false);
++	if (unlikely(err))
++		goto out;
++
++	lower_file = unionfs_lower_file(file);
++	err = vfs_read(lower_file, buf, count, ppos);
++	/* update our inode atime upon a successful lower read */
++	if (err >= 0) {
++		fsstack_copy_attr_atime(dentry->d_inode,
++					lower_file->f_path.dentry->d_inode);
++		unionfs_check_file(file);
++	}
++
++out:
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++static ssize_t unionfs_write(struct file *file, const char __user *buf,
++			     size_t count, loff_t *ppos)
++{
++	int err = 0;
++	struct file *lower_file;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	err = unionfs_file_revalidate(file, parent, true);
++	if (unlikely(err))
++		goto out;
++
++	lower_file = unionfs_lower_file(file);
++	err = vfs_write(lower_file, buf, count, ppos);
++	/* update our inode times+sizes upon a successful lower write */
++	if (err >= 0) {
++		fsstack_copy_inode_size(dentry->d_inode,
++					lower_file->f_path.dentry->d_inode);
++		fsstack_copy_attr_times(dentry->d_inode,
++					lower_file->f_path.dentry->d_inode);
++		UNIONFS_F(file)->wrote_to_file = true; /* for delayed copyup */
++		unionfs_check_file(file);
++	}
++
++out:
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++static int unionfs_file_readdir(struct file *file, void *dirent,
++				filldir_t filldir)
++{
++	return -ENOTDIR;
++}
++
++static int unionfs_mmap(struct file *file, struct vm_area_struct *vma)
++{
++	int err = 0;
++	bool willwrite;
++	struct file *lower_file;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++	const struct vm_operations_struct *saved_vm_ops = NULL;
++
++	/*
++	 * Since mm/memory.c:might_fault() (under PROVE_LOCKING) was
++	 * modified in 2.6.29-rc1 to call might_lock_read on mmap_sem, this
++	 * has been causing false positives in file system stacking layers.
++	 * In particular, our ->mmap is called after sys_mmap2 already holds
++	 * mmap_sem, then we lock our own mutexes; but earlier, it's
++	 * possible for lockdep to have locked our mutexes first, and then
++	 * we call a lower ->readdir which could call might_fault.  The
++	 * different ordering of the locks is what lockdep complains about
++	 * -- unnecessarily.  Therefore, we have no choice but to tell
++	 * lockdep to temporarily turn off lockdep here.  Note: the comments
++	 * inside might_sleep also suggest that it would have been
++	 * nicer to only annotate paths that needs that might_lock_read.
++	 */
++	lockdep_off();
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	/* This might be deferred to mmap's writepage */
++	willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags);
++	err = unionfs_file_revalidate(file, parent, willwrite);
++	if (unlikely(err))
++		goto out;
++	unionfs_check_file(file);
++
++	/*
++	 * File systems which do not implement ->writepage may use
++	 * generic_file_readonly_mmap as their ->mmap op.  If you call
++	 * generic_file_readonly_mmap with VM_WRITE, you'd get an -EINVAL.
++	 * But we cannot call the lower ->mmap op, so we can't tell that
++	 * writeable mappings won't work.  Therefore, our only choice is to
++	 * check if the lower file system supports the ->writepage, and if
++	 * not, return EINVAL (the same error that
++	 * generic_file_readonly_mmap returns in that case).
++	 */
++	lower_file = unionfs_lower_file(file);
++	if (willwrite && !lower_file->f_mapping->a_ops->writepage) {
++		err = -EINVAL;
++		printk(KERN_ERR "unionfs: branch %d file system does not "
++		       "support writeable mmap\n", fbstart(file));
++		goto out;
++	}
++
++	/*
++	 * find and save lower vm_ops.
++	 *
++	 * XXX: the VFS should have a cleaner way of finding the lower vm_ops
++	 */
++	if (!UNIONFS_F(file)->lower_vm_ops) {
++		err = lower_file->f_op->mmap(lower_file, vma);
++		if (err) {
++			printk(KERN_ERR "unionfs: lower mmap failed %d\n", err);
++			goto out;
++		}
++		saved_vm_ops = vma->vm_ops;
++		err = do_munmap(current->mm, vma->vm_start,
++				vma->vm_end - vma->vm_start);
++		if (err) {
++			printk(KERN_ERR "unionfs: do_munmap failed %d\n", err);
++			goto out;
++		}
++	}
++
++	file->f_mapping->a_ops = &unionfs_dummy_aops;
++	err = generic_file_mmap(file, vma);
++	file->f_mapping->a_ops = &unionfs_aops;
++	if (err) {
++		printk(KERN_ERR "unionfs: generic_file_mmap failed %d\n", err);
++		goto out;
++	}
++	vma->vm_ops = &unionfs_vm_ops;
++	if (!UNIONFS_F(file)->lower_vm_ops)
++		UNIONFS_F(file)->lower_vm_ops = saved_vm_ops;
++
++out:
++	if (!err) {
++		/* copyup could cause parent dir times to change */
++		unionfs_copy_attr_times(parent->d_inode);
++		unionfs_check_file(file);
++	}
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	lockdep_on();
++	return err;
++}
++
++int unionfs_fsync(struct file *file, int datasync)
++{
++	int bindex, bstart, bend;
++	struct file *lower_file;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *lower_dentry;
++	struct dentry *parent;
++	struct inode *lower_inode, *inode;
++	int err = -EINVAL;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	err = unionfs_file_revalidate(file, parent, true);
++	if (unlikely(err))
++		goto out;
++	unionfs_check_file(file);
++
++	bstart = fbstart(file);
++	bend = fbend(file);
++	if (bstart < 0 || bend < 0)
++		goto out;
++
++	inode = dentry->d_inode;
++	if (unlikely(!inode)) {
++		printk(KERN_ERR
++		       "unionfs: null lower inode in unionfs_fsync\n");
++		goto out;
++	}
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_inode = unionfs_lower_inode_idx(inode, bindex);
++		if (!lower_inode || !lower_inode->i_fop->fsync)
++			continue;
++		lower_file = unionfs_lower_file_idx(file, bindex);
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		mutex_lock(&lower_inode->i_mutex);
++		err = lower_inode->i_fop->fsync(lower_file, datasync);
++		if (!err && bindex == bstart)
++			fsstack_copy_attr_times(inode, lower_inode);
++		mutex_unlock(&lower_inode->i_mutex);
++		if (err)
++			goto out;
++	}
++
++out:
++	if (!err)
++		unionfs_check_file(file);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++int unionfs_fasync(int fd, struct file *file, int flag)
++{
++	int bindex, bstart, bend;
++	struct file *lower_file;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++	struct inode *lower_inode, *inode;
++	int err = 0;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	err = unionfs_file_revalidate(file, parent, true);
++	if (unlikely(err))
++		goto out;
++	unionfs_check_file(file);
++
++	bstart = fbstart(file);
++	bend = fbend(file);
++	if (bstart < 0 || bend < 0)
++		goto out;
++
++	inode = dentry->d_inode;
++	if (unlikely(!inode)) {
++		printk(KERN_ERR
++		       "unionfs: null lower inode in unionfs_fasync\n");
++		goto out;
++	}
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_inode = unionfs_lower_inode_idx(inode, bindex);
++		if (!lower_inode || !lower_inode->i_fop->fasync)
++			continue;
++		lower_file = unionfs_lower_file_idx(file, bindex);
++		mutex_lock(&lower_inode->i_mutex);
++		err = lower_inode->i_fop->fasync(fd, lower_file, flag);
++		if (!err && bindex == bstart)
++			fsstack_copy_attr_times(inode, lower_inode);
++		mutex_unlock(&lower_inode->i_mutex);
++		if (err)
++			goto out;
++	}
++
++out:
++	if (!err)
++		unionfs_check_file(file);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++static ssize_t unionfs_splice_read(struct file *file, loff_t *ppos,
++				   struct pipe_inode_info *pipe, size_t len,
++				   unsigned int flags)
++{
++	ssize_t err;
++	struct file *lower_file;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	err = unionfs_file_revalidate(file, parent, false);
++	if (unlikely(err))
++		goto out;
++
++	lower_file = unionfs_lower_file(file);
++	err = vfs_splice_to(lower_file, ppos, pipe, len, flags);
++	/* update our inode atime upon a successful lower splice-read */
++	if (err >= 0) {
++		fsstack_copy_attr_atime(dentry->d_inode,
++					lower_file->f_path.dentry->d_inode);
++		unionfs_check_file(file);
++	}
++
++out:
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++static ssize_t unionfs_splice_write(struct pipe_inode_info *pipe,
++				    struct file *file, loff_t *ppos,
++				    size_t len, unsigned int flags)
++{
++	ssize_t err = 0;
++	struct file *lower_file;
++	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *parent;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	err = unionfs_file_revalidate(file, parent, true);
++	if (unlikely(err))
++		goto out;
++
++	lower_file = unionfs_lower_file(file);
++	err = vfs_splice_from(pipe, lower_file, ppos, len, flags);
++	/* update our inode times+sizes upon a successful lower write */
++	if (err >= 0) {
++		fsstack_copy_inode_size(dentry->d_inode,
++					lower_file->f_path.dentry->d_inode);
++		fsstack_copy_attr_times(dentry->d_inode,
++					lower_file->f_path.dentry->d_inode);
++		unionfs_check_file(file);
++	}
++
++out:
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++struct file_operations unionfs_main_fops = {
++	.llseek		= generic_file_llseek,
++	.read		= unionfs_read,
++	.write		= unionfs_write,
++	.readdir	= unionfs_file_readdir,
++	.unlocked_ioctl	= unionfs_ioctl,
++	.mmap		= unionfs_mmap,
++	.open		= unionfs_open,
++	.flush		= unionfs_flush,
++	.release	= unionfs_file_release,
++	.fsync		= unionfs_fsync,
++	.fasync		= unionfs_fasync,
++	.splice_read	= unionfs_splice_read,
++	.splice_write	= unionfs_splice_write,
++};
+diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
+new file mode 100644
+index 0000000..cc994bd
+--- /dev/null
++++ b/fs/unionfs/inode.c
+@@ -0,0 +1,1074 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/*
++ * Find a writeable branch to create new object in.  Checks all writeble
++ * branches of the parent inode, from istart to iend order; if none are
++ * suitable, also tries branch 0 (which may require a copyup).
++ *
++ * Return a lower_dentry we can use to create object in, or ERR_PTR.
++ */
++static struct dentry *find_writeable_branch(struct inode *parent,
++					    struct dentry *dentry)
++{
++	int err = -EINVAL;
++	int bindex, istart, iend;
++	struct dentry *lower_dentry = NULL;
++
++	istart = ibstart(parent);
++	iend = ibend(parent);
++	if (istart < 0)
++		goto out;
++
++begin:
++	for (bindex = istart; bindex <= iend; bindex++) {
++		/* skip non-writeable branches */
++		err = is_robranch_super(dentry->d_sb, bindex);
++		if (err) {
++			err = -EROFS;
++			continue;
++		}
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (!lower_dentry)
++			continue;
++		/*
++		 * check for whiteouts in writeable branch, and remove them
++		 * if necessary.
++		 */
++		err = check_unlink_whiteout(dentry, lower_dentry, bindex);
++		if (err > 0)	/* ignore if whiteout found and removed */
++			err = 0;
++		if (err)
++			continue;
++		/* if get here, we can write to the branch */
++		break;
++	}
++	/*
++	 * If istart wasn't already branch 0, and we got any error, then try
++	 * branch 0 (which may require copyup)
++	 */
++	if (err && istart > 0) {
++		istart = iend = 0;
++		goto begin;
++	}
++
++	/*
++	 * If we tried even branch 0, and still got an error, abort.  But if
++	 * the error was an EROFS, then we should try to copyup.
++	 */
++	if (err && err != -EROFS)
++		goto out;
++
++	/*
++	 * If we get here, then check if copyup needed.  If lower_dentry is
++	 * NULL, create the entire dentry directory structure in branch 0.
++	 */
++	if (!lower_dentry) {
++		bindex = 0;
++		lower_dentry = create_parents(parent, dentry,
++					      dentry->d_name.name, bindex);
++		if (IS_ERR(lower_dentry)) {
++			err = PTR_ERR(lower_dentry);
++			goto out;
++		}
++	}
++	err = 0;		/* all's well */
++out:
++	if (err)
++		return ERR_PTR(err);
++	return lower_dentry;
++}
++
++static int unionfs_create(struct inode *dir, struct dentry *dentry,
++			  int mode, struct nameidata *nd_unused)
++{
++	int err = 0;
++	struct dentry *lower_dentry = NULL;
++	struct dentry *lower_parent_dentry = NULL;
++	struct dentry *parent;
++	int valid = 0;
++	struct nameidata lower_nd;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;	/* same as what real_lookup does */
++		goto out;
++	}
++
++	lower_dentry = find_writeable_branch(dir, dentry);
++	if (IS_ERR(lower_dentry)) {
++		err = PTR_ERR(lower_dentry);
++		goto out;
++	}
++
++	lower_parent_dentry = lock_parent(lower_dentry);
++	if (IS_ERR(lower_parent_dentry)) {
++		err = PTR_ERR(lower_parent_dentry);
++		goto out_unlock;
++	}
++
++	err = init_lower_nd(&lower_nd, LOOKUP_CREATE);
++	if (unlikely(err < 0))
++		goto out_unlock;
++	err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode,
++			 &lower_nd);
++	release_lower_nd(&lower_nd, err);
++
++	if (!err) {
++		err = PTR_ERR(unionfs_interpose(dentry, dir->i_sb, 0));
++		if (!err) {
++			unionfs_copy_attr_times(dir);
++			fsstack_copy_inode_size(dir,
++						lower_parent_dentry->d_inode);
++			/* update no. of links on parent directory */
++			dir->i_nlink = unionfs_get_nlinks(dir);
++		}
++	}
++
++out_unlock:
++	unlock_dir(lower_parent_dentry);
++out:
++	if (!err) {
++		unionfs_postcopyup_setmnt(dentry);
++		unionfs_check_inode(dir);
++		unionfs_check_dentry(dentry);
++	}
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++/*
++ * unionfs_lookup is the only special function which takes a dentry, yet we
++ * do NOT want to call __unionfs_d_revalidate_chain because by definition,
++ * we don't have a valid dentry here yet.
++ */
++static struct dentry *unionfs_lookup(struct inode *dir,
++				     struct dentry *dentry,
++				     struct nameidata *nd_unused)
++{
++	struct dentry *ret, *parent;
++	int err = 0;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++
++	/*
++	 * As long as we lock/dget the parent, then can skip validating the
++	 * parent now; we may have to rebuild this dentry on the next
++	 * ->d_revalidate, however.
++	 */
++
++	/* allocate dentry private data.  We free it in ->d_release */
++	err = new_dentry_private_data(dentry, UNIONFS_DMUTEX_CHILD);
++	if (unlikely(err)) {
++		ret = ERR_PTR(err);
++		goto out;
++	}
++
++	ret = unionfs_lookup_full(dentry, parent, INTERPOSE_LOOKUP);
++
++	if (!IS_ERR(ret)) {
++		if (ret)
++			dentry = ret;
++		/* lookup_full can return multiple positive dentries */
++		if (dentry->d_inode && !S_ISDIR(dentry->d_inode->i_mode)) {
++			BUG_ON(dbstart(dentry) < 0);
++			unionfs_postcopyup_release(dentry);
++		}
++		unionfs_copy_attr_times(dentry->d_inode);
++	}
++
++	unionfs_check_inode(dir);
++	if (!IS_ERR(ret))
++		unionfs_check_dentry(dentry);
++	unionfs_check_dentry(parent);
++	unionfs_unlock_dentry(dentry); /* locked in new_dentry_private data */
++
++out:
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++
++	return ret;
++}
++
++static int unionfs_link(struct dentry *old_dentry, struct inode *dir,
++			struct dentry *new_dentry)
++{
++	int err = 0;
++	struct dentry *lower_old_dentry = NULL;
++	struct dentry *lower_new_dentry = NULL;
++	struct dentry *lower_dir_dentry = NULL;
++	struct dentry *old_parent, *new_parent;
++	char *name = NULL;
++	bool valid;
++
++	unionfs_read_lock(old_dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	old_parent = dget_parent(old_dentry);
++	new_parent = dget_parent(new_dentry);
++	unionfs_double_lock_parents(old_parent, new_parent);
++	unionfs_double_lock_dentry(old_dentry, new_dentry);
++
++	valid = __unionfs_d_revalidate(old_dentry, old_parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;
++		goto out;
++	}
++	if (new_dentry->d_inode) {
++		valid = __unionfs_d_revalidate(new_dentry, new_parent, false);
++		if (unlikely(!valid)) {
++			err = -ESTALE;
++			goto out;
++		}
++	}
++
++	lower_new_dentry = unionfs_lower_dentry(new_dentry);
++
++	/* check for a whiteout in new dentry branch, and delete it */
++	err = check_unlink_whiteout(new_dentry, lower_new_dentry,
++				    dbstart(new_dentry));
++	if (err > 0) {	       /* whiteout found and removed successfully */
++		lower_dir_dentry = dget_parent(lower_new_dentry);
++		fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
++		dput(lower_dir_dentry);
++		dir->i_nlink = unionfs_get_nlinks(dir);
++		err = 0;
++	}
++	if (err)
++		goto out;
++
++	/* check if parent hierachy is needed, then link in same branch */
++	if (dbstart(old_dentry) != dbstart(new_dentry)) {
++		lower_new_dentry = create_parents(dir, new_dentry,
++						  new_dentry->d_name.name,
++						  dbstart(old_dentry));
++		err = PTR_ERR(lower_new_dentry);
++		if (IS_COPYUP_ERR(err))
++			goto docopyup;
++		if (!lower_new_dentry || IS_ERR(lower_new_dentry))
++			goto out;
++	}
++	lower_new_dentry = unionfs_lower_dentry(new_dentry);
++	lower_old_dentry = unionfs_lower_dentry(old_dentry);
++
++	BUG_ON(dbstart(old_dentry) != dbstart(new_dentry));
++	lower_dir_dentry = lock_parent(lower_new_dentry);
++	err = is_robranch(old_dentry);
++	if (!err) {
++		/* see Documentation/filesystems/unionfs/issues.txt */
++		lockdep_off();
++		err = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
++			       lower_new_dentry);
++		lockdep_on();
++	}
++	unlock_dir(lower_dir_dentry);
++
++docopyup:
++	if (IS_COPYUP_ERR(err)) {
++		int old_bstart = dbstart(old_dentry);
++		int bindex;
++
++		for (bindex = old_bstart - 1; bindex >= 0; bindex--) {
++			err = copyup_dentry(old_parent->d_inode,
++					    old_dentry, old_bstart,
++					    bindex, old_dentry->d_name.name,
++					    old_dentry->d_name.len, NULL,
++					    i_size_read(old_dentry->d_inode));
++			if (err)
++				continue;
++			lower_new_dentry =
++				create_parents(dir, new_dentry,
++					       new_dentry->d_name.name,
++					       bindex);
++			lower_old_dentry = unionfs_lower_dentry(old_dentry);
++			lower_dir_dentry = lock_parent(lower_new_dentry);
++			/* see Documentation/filesystems/unionfs/issues.txt */
++			lockdep_off();
++			/* do vfs_link */
++			err = vfs_link(lower_old_dentry,
++				       lower_dir_dentry->d_inode,
++				       lower_new_dentry);
++			lockdep_on();
++			unlock_dir(lower_dir_dentry);
++			goto check_link;
++		}
++		goto out;
++	}
++
++check_link:
++	if (err || !lower_new_dentry->d_inode)
++		goto out;
++
++	/* Its a hard link, so use the same inode */
++	new_dentry->d_inode = igrab(old_dentry->d_inode);
++	d_add(new_dentry, new_dentry->d_inode);
++	unionfs_copy_attr_all(dir, lower_new_dentry->d_parent->d_inode);
++	fsstack_copy_inode_size(dir, lower_new_dentry->d_parent->d_inode);
++
++	/* propagate number of hard-links */
++	old_dentry->d_inode->i_nlink = unionfs_get_nlinks(old_dentry->d_inode);
++	/* new dentry's ctime may have changed due to hard-link counts */
++	unionfs_copy_attr_times(new_dentry->d_inode);
++
++out:
++	if (!new_dentry->d_inode)
++		d_drop(new_dentry);
++
++	kfree(name);
++	if (!err)
++		unionfs_postcopyup_setmnt(new_dentry);
++
++	unionfs_check_inode(dir);
++	unionfs_check_dentry(new_dentry);
++	unionfs_check_dentry(old_dentry);
++
++	unionfs_double_unlock_dentry(old_dentry, new_dentry);
++	unionfs_double_unlock_parents(old_parent, new_parent);
++	dput(new_parent);
++	dput(old_parent);
++	unionfs_read_unlock(old_dentry->d_sb);
++
++	return err;
++}
++
++static int unionfs_symlink(struct inode *dir, struct dentry *dentry,
++			   const char *symname)
++{
++	int err = 0;
++	struct dentry *lower_dentry = NULL;
++	struct dentry *wh_dentry = NULL;
++	struct dentry *lower_parent_dentry = NULL;
++	struct dentry *parent;
++	char *name = NULL;
++	int valid = 0;
++	umode_t mode;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;
++		goto out;
++	}
++
++	/*
++	 * It's only a bug if this dentry was not negative and couldn't be
++	 * revalidated (shouldn't happen).
++	 */
++	BUG_ON(!valid && dentry->d_inode);
++
++	lower_dentry = find_writeable_branch(dir, dentry);
++	if (IS_ERR(lower_dentry)) {
++		err = PTR_ERR(lower_dentry);
++		goto out;
++	}
++
++	lower_parent_dentry = lock_parent(lower_dentry);
++	if (IS_ERR(lower_parent_dentry)) {
++		err = PTR_ERR(lower_parent_dentry);
++		goto out_unlock;
++	}
++
++	mode = S_IALLUGO;
++	err = vfs_symlink(lower_parent_dentry->d_inode, lower_dentry, symname);
++	if (!err) {
++		err = PTR_ERR(unionfs_interpose(dentry, dir->i_sb, 0));
++		if (!err) {
++			unionfs_copy_attr_times(dir);
++			fsstack_copy_inode_size(dir,
++						lower_parent_dentry->d_inode);
++			/* update no. of links on parent directory */
++			dir->i_nlink = unionfs_get_nlinks(dir);
++		}
++	}
++
++out_unlock:
++	unlock_dir(lower_parent_dentry);
++out:
++	dput(wh_dentry);
++	kfree(name);
++
++	if (!err) {
++		unionfs_postcopyup_setmnt(dentry);
++		unionfs_check_inode(dir);
++		unionfs_check_dentry(dentry);
++	}
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++static int unionfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
++{
++	int err = 0;
++	struct dentry *lower_dentry = NULL;
++	struct dentry *lower_parent_dentry = NULL;
++	struct dentry *parent;
++	int bindex = 0, bstart;
++	char *name = NULL;
++	int valid;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;	/* same as what real_lookup does */
++		goto out;
++	}
++
++	bstart = dbstart(dentry);
++
++	lower_dentry = unionfs_lower_dentry(dentry);
++
++	/* check for a whiteout in new dentry branch, and delete it */
++	err = check_unlink_whiteout(dentry, lower_dentry, bstart);
++	if (err > 0)	       /* whiteout found and removed successfully */
++		err = 0;
++	if (err) {
++		/* exit if the error returned was NOT -EROFS */
++		if (!IS_COPYUP_ERR(err))
++			goto out;
++		bstart--;
++	}
++
++	/* check if copyup's needed, and mkdir */
++	for (bindex = bstart; bindex >= 0; bindex--) {
++		int i;
++		int bend = dbend(dentry);
++
++		if (is_robranch_super(dentry->d_sb, bindex))
++			continue;
++
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (!lower_dentry) {
++			lower_dentry = create_parents(dir, dentry,
++						      dentry->d_name.name,
++						      bindex);
++			if (!lower_dentry || IS_ERR(lower_dentry)) {
++				printk(KERN_ERR "unionfs: lower dentry "
++				       " NULL for bindex = %d\n", bindex);
++				continue;
++			}
++		}
++
++		lower_parent_dentry = lock_parent(lower_dentry);
++
++		if (IS_ERR(lower_parent_dentry)) {
++			err = PTR_ERR(lower_parent_dentry);
++			goto out;
++		}
++
++		err = vfs_mkdir(lower_parent_dentry->d_inode, lower_dentry,
++				mode);
++
++		unlock_dir(lower_parent_dentry);
++
++		/* did the mkdir succeed? */
++		if (err)
++			break;
++
++		for (i = bindex + 1; i <= bend; i++) {
++			/* XXX: use path_put_lowers? */
++			if (unionfs_lower_dentry_idx(dentry, i)) {
++				dput(unionfs_lower_dentry_idx(dentry, i));
++				unionfs_set_lower_dentry_idx(dentry, i, NULL);
++			}
++		}
++		dbend(dentry) = bindex;
++
++		/*
++		 * Only INTERPOSE_LOOKUP can return a value other than 0 on
++		 * err.
++		 */
++		err = PTR_ERR(unionfs_interpose(dentry, dir->i_sb, 0));
++		if (!err) {
++			unionfs_copy_attr_times(dir);
++			fsstack_copy_inode_size(dir,
++						lower_parent_dentry->d_inode);
++
++			/* update number of links on parent directory */
++			dir->i_nlink = unionfs_get_nlinks(dir);
++		}
++
++		err = make_dir_opaque(dentry, dbstart(dentry));
++		if (err) {
++			printk(KERN_ERR "unionfs: mkdir: error creating "
++			       ".wh.__dir_opaque: %d\n", err);
++			goto out;
++		}
++
++		/* we are done! */
++		break;
++	}
++
++out:
++	if (!dentry->d_inode)
++		d_drop(dentry);
++
++	kfree(name);
++
++	if (!err) {
++		unionfs_copy_attr_times(dentry->d_inode);
++		unionfs_postcopyup_setmnt(dentry);
++	}
++	unionfs_check_inode(dir);
++	unionfs_check_dentry(dentry);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++
++	return err;
++}
++
++static int unionfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
++			 dev_t dev)
++{
++	int err = 0;
++	struct dentry *lower_dentry = NULL;
++	struct dentry *wh_dentry = NULL;
++	struct dentry *lower_parent_dentry = NULL;
++	struct dentry *parent;
++	char *name = NULL;
++	int valid = 0;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;
++		goto out;
++	}
++
++	/*
++	 * It's only a bug if this dentry was not negative and couldn't be
++	 * revalidated (shouldn't happen).
++	 */
++	BUG_ON(!valid && dentry->d_inode);
++
++	lower_dentry = find_writeable_branch(dir, dentry);
++	if (IS_ERR(lower_dentry)) {
++		err = PTR_ERR(lower_dentry);
++		goto out;
++	}
++
++	lower_parent_dentry = lock_parent(lower_dentry);
++	if (IS_ERR(lower_parent_dentry)) {
++		err = PTR_ERR(lower_parent_dentry);
++		goto out_unlock;
++	}
++
++	err = vfs_mknod(lower_parent_dentry->d_inode, lower_dentry, mode, dev);
++	if (!err) {
++		err = PTR_ERR(unionfs_interpose(dentry, dir->i_sb, 0));
++		if (!err) {
++			unionfs_copy_attr_times(dir);
++			fsstack_copy_inode_size(dir,
++						lower_parent_dentry->d_inode);
++			/* update no. of links on parent directory */
++			dir->i_nlink = unionfs_get_nlinks(dir);
++		}
++	}
++
++out_unlock:
++	unlock_dir(lower_parent_dentry);
++out:
++	dput(wh_dentry);
++	kfree(name);
++
++	if (!err) {
++		unionfs_postcopyup_setmnt(dentry);
++		unionfs_check_inode(dir);
++		unionfs_check_dentry(dentry);
++	}
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++/* requires sb, dentry, and parent to already be locked */
++static int __unionfs_readlink(struct dentry *dentry, char __user *buf,
++			      int bufsiz)
++{
++	int err;
++	struct dentry *lower_dentry;
++
++	lower_dentry = unionfs_lower_dentry(dentry);
++
++	if (!lower_dentry->d_inode->i_op ||
++	    !lower_dentry->d_inode->i_op->readlink) {
++		err = -EINVAL;
++		goto out;
++	}
++
++	err = lower_dentry->d_inode->i_op->readlink(lower_dentry,
++						    buf, bufsiz);
++	if (err >= 0)
++		fsstack_copy_attr_atime(dentry->d_inode,
++					lower_dentry->d_inode);
++
++out:
++	return err;
++}
++
++static int unionfs_readlink(struct dentry *dentry, char __user *buf,
++			    int bufsiz)
++{
++	int err;
++	struct dentry *parent;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	if (unlikely(!__unionfs_d_revalidate(dentry, parent, false))) {
++		err = -ESTALE;
++		goto out;
++	}
++
++	err = __unionfs_readlink(dentry, buf, bufsiz);
++
++out:
++	unionfs_check_dentry(dentry);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++
++	return err;
++}
++
++static void *unionfs_follow_link(struct dentry *dentry, struct nameidata *nd)
++{
++	char *buf;
++	int len = PAGE_SIZE, err;
++	mm_segment_t old_fs;
++	struct dentry *parent;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	/* This is freed by the put_link method assuming a successful call. */
++	buf = kmalloc(len, GFP_KERNEL);
++	if (unlikely(!buf)) {
++		err = -ENOMEM;
++		goto out;
++	}
++
++	/* read the symlink, and then we will follow it */
++	old_fs = get_fs();
++	set_fs(KERNEL_DS);
++	err = __unionfs_readlink(dentry, buf, len);
++	set_fs(old_fs);
++	if (err < 0) {
++		kfree(buf);
++		buf = NULL;
++		goto out;
++	}
++	buf[err] = 0;
++	nd_set_link(nd, buf);
++	err = 0;
++
++out:
++	if (err >= 0) {
++		unionfs_check_nd(nd);
++		unionfs_check_dentry(dentry);
++	}
++
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++
++	return ERR_PTR(err);
++}
++
++/* this @nd *IS* still used */
++static void unionfs_put_link(struct dentry *dentry, struct nameidata *nd,
++			     void *cookie)
++{
++	struct dentry *parent;
++	char *buf;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	if (unlikely(!__unionfs_d_revalidate(dentry, parent, false)))
++		printk(KERN_ERR
++		       "unionfs: put_link failed to revalidate dentry\n");
++
++	unionfs_check_dentry(dentry);
++#if 0
++	/* XXX: can't run this check b/c this fxn can receive a poisoned 'nd' PTR */
++	unionfs_check_nd(nd);
++#endif
++	buf = nd_get_link(nd);
++	if (!IS_ERR(buf))
++		kfree(buf);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++}
++
++/*
++ * This is a variant of fs/namei.c:permission() or inode_permission() which
++ * skips over EROFS tests (because we perform copyup on EROFS).
++ */
++static int __inode_permission(struct inode *inode, int mask)
++{
++	int retval;
++
++	/* nobody gets write access to an immutable file */
++	if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
++		return -EACCES;
++
++	/* Ordinary permission routines do not understand MAY_APPEND. */
++	if (inode->i_op && inode->i_op->permission) {
++		retval = inode->i_op->permission(inode, mask);
++		if (!retval) {
++			/*
++			 * Exec permission on a regular file is denied if none
++			 * of the execute bits are set.
++			 *
++			 * This check should be done by the ->permission()
++			 * method.
++			 */
++			if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode) &&
++			    !(inode->i_mode & S_IXUGO))
++				return -EACCES;
++		}
++	} else {
++		retval = generic_permission(inode, mask, NULL);
++	}
++	if (retval)
++		return retval;
++
++	return security_inode_permission(inode,
++			mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND));
++}
++
++/*
++ * Don't grab the superblock read-lock in unionfs_permission, which prevents
++ * a deadlock with the branch-management "add branch" code (which grabbed
++ * the write lock).  It is safe to not grab the read lock here, because even
++ * with branch management taking place, there is no chance that
++ * unionfs_permission, or anything it calls, will use stale branch
++ * information.
++ */
++static int unionfs_permission(struct inode *inode, int mask)
++{
++	struct inode *lower_inode = NULL;
++	int err = 0;
++	int bindex, bstart, bend;
++	const int is_file = !S_ISDIR(inode->i_mode);
++	const int write_mask = (mask & MAY_WRITE) && !(mask & MAY_READ);
++	struct inode *inode_grabbed = igrab(inode);
++	struct dentry *dentry = d_find_alias(inode);
++
++	if (dentry)
++		unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	if (!UNIONFS_I(inode)->lower_inodes) {
++		if (is_file)	/* dirs can be unlinked but chdir'ed to */
++			err = -ESTALE;	/* force revalidate */
++		goto out;
++	}
++	bstart = ibstart(inode);
++	bend = ibend(inode);
++	if (unlikely(bstart < 0 || bend < 0)) {
++		/*
++		 * With branch-management, we can get a stale inode here.
++		 * If so, we return ESTALE back to link_path_walk, which
++		 * would discard the dcache entry and re-lookup the
++		 * dentry+inode.  This should be equivalent to issuing
++		 * __unionfs_d_revalidate_chain on nd.dentry here.
++		 */
++		if (is_file)	/* dirs can be unlinked but chdir'ed to */
++			err = -ESTALE;	/* force revalidate */
++		goto out;
++	}
++
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_inode = unionfs_lower_inode_idx(inode, bindex);
++		if (!lower_inode)
++			continue;
++
++		/*
++		 * check the condition for D-F-D underlying files/directories,
++		 * we don't have to check for files, if we are checking for
++		 * directories.
++		 */
++		if (!is_file && !S_ISDIR(lower_inode->i_mode))
++			continue;
++
++		/*
++		 * We check basic permissions, but we ignore any conditions
++		 * such as readonly file systems or branches marked as
++		 * readonly, because those conditions should lead to a
++		 * copyup taking place later on.  However, if user never had
++		 * access to the file, then no copyup could ever take place.
++		 */
++		err = __inode_permission(lower_inode, mask);
++		if (err && err != -EACCES && err != EPERM && bindex > 0) {
++			umode_t mode = lower_inode->i_mode;
++			if ((is_robranch_super(inode->i_sb, bindex) ||
++			     __is_rdonly(lower_inode)) &&
++			    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
++				err = 0;
++			if (IS_COPYUP_ERR(err))
++				err = 0;
++		}
++
++		/*
++		 * NFS HACK: NFSv2/3 return EACCES on readonly-exported,
++		 * locally readonly-mounted file systems, instead of EROFS
++		 * like other file systems do.  So we have no choice here
++		 * but to intercept this and ignore it for NFS branches
++		 * marked readonly.  Specifically, we avoid using NFS's own
++		 * "broken" ->permission method, and rely on
++		 * generic_permission() to do basic checking for us.
++		 */
++		if (err && err == -EACCES &&
++		    is_robranch_super(inode->i_sb, bindex) &&
++		    lower_inode->i_sb->s_magic == NFS_SUPER_MAGIC)
++			err = generic_permission(lower_inode, mask, NULL);
++
++		/*
++		 * The permissions are an intersection of the overall directory
++		 * permissions, so we fail if one fails.
++		 */
++		if (err)
++			goto out;
++
++		/* only the leftmost file matters. */
++		if (is_file || write_mask) {
++			if (is_file && write_mask) {
++				err = get_write_access(lower_inode);
++				if (!err)
++					put_write_access(lower_inode);
++			}
++			break;
++		}
++	}
++	/* sync times which may have changed (asynchronously) below */
++	unionfs_copy_attr_times(inode);
++
++out:
++	unionfs_check_inode(inode);
++	if (dentry) {
++		unionfs_unlock_dentry(dentry);
++		dput(dentry);
++	}
++	iput(inode_grabbed);
++	return err;
++}
++
++static int unionfs_setattr(struct dentry *dentry, struct iattr *ia)
++{
++	int err = 0;
++	struct dentry *lower_dentry;
++	struct dentry *parent;
++	struct inode *inode;
++	struct inode *lower_inode;
++	int bstart, bend, bindex;
++	loff_t size;
++	struct iattr lower_ia;
++
++	/* check if user has permission to change inode */
++	err = inode_change_ok(dentry->d_inode, ia);
++	if (err)
++		goto out_err;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	if (unlikely(!__unionfs_d_revalidate(dentry, parent, false))) {
++		err = -ESTALE;
++		goto out;
++	}
++
++	bstart = dbstart(dentry);
++	bend = dbend(dentry);
++	inode = dentry->d_inode;
++
++	/*
++	 * mode change is for clearing setuid/setgid. Allow lower filesystem
++	 * to reinterpret it in its own way.
++	 */
++	if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
++		ia->ia_valid &= ~ATTR_MODE;
++
++	lower_dentry = unionfs_lower_dentry(dentry);
++	if (!lower_dentry) { /* should never happen after above revalidate */
++		err = -EINVAL;
++		goto out;
++	}
++	lower_inode = unionfs_lower_inode(inode);
++
++	/* check if user has permission to change lower inode */
++	err = inode_change_ok(lower_inode, ia);
++	if (err)
++		goto out;
++
++	/* copyup if the file is on a read only branch */
++	if (is_robranch_super(dentry->d_sb, bstart)
++	    || __is_rdonly(lower_inode)) {
++		/* check if we have a branch to copy up to */
++		if (bstart <= 0) {
++			err = -EACCES;
++			goto out;
++		}
++
++		if (ia->ia_valid & ATTR_SIZE)
++			size = ia->ia_size;
++		else
++			size = i_size_read(inode);
++		/* copyup to next available branch */
++		for (bindex = bstart - 1; bindex >= 0; bindex--) {
++			err = copyup_dentry(parent->d_inode,
++					    dentry, bstart, bindex,
++					    dentry->d_name.name,
++					    dentry->d_name.len,
++					    NULL, size);
++			if (!err)
++				break;
++		}
++		if (err)
++			goto out;
++		/* get updated lower_dentry/inode after copyup */
++		lower_dentry = unionfs_lower_dentry(dentry);
++		lower_inode = unionfs_lower_inode(inode);
++	}
++
++	/*
++	 * If shrinking, first truncate upper level to cancel writing dirty
++	 * pages beyond the new eof; and also if its' maxbytes is more
++	 * limiting (fail with -EFBIG before making any change to the lower
++	 * level).  There is no need to vmtruncate the upper level
++	 * afterwards in the other cases: we fsstack_copy_inode_size from
++	 * the lower level.
++	 */
++	if (ia->ia_valid & ATTR_SIZE) {
++		size = i_size_read(inode);
++		if (ia->ia_size < size || (ia->ia_size > size &&
++		    inode->i_sb->s_maxbytes < lower_inode->i_sb->s_maxbytes)) {
++			err = vmtruncate(inode, ia->ia_size);
++			if (err)
++				goto out;
++		}
++	}
++
++	/* notify the (possibly copied-up) lower inode */
++	/*
++	 * Note: we use lower_dentry->d_inode, because lower_inode may be
++	 * unlinked (no inode->i_sb and i_ino==0.  This happens if someone
++	 * tries to open(), unlink(), then ftruncate() a file.
++	 */
++	/* prepare our own lower struct iattr (with our own lower file) */
++	memcpy(&lower_ia, ia, sizeof(lower_ia));
++	if (ia->ia_valid & ATTR_FILE) {
++		lower_ia.ia_file = unionfs_lower_file(ia->ia_file);
++		BUG_ON(!lower_ia.ia_file); // XXX?
++	}
++
++	mutex_lock(&lower_dentry->d_inode->i_mutex);
++	err = notify_change(lower_dentry, &lower_ia);
++	mutex_unlock(&lower_dentry->d_inode->i_mutex);
++	if (err)
++		goto out;
++
++	/* get attributes from the first lower inode */
++	if (ibstart(inode) >= 0)
++		unionfs_copy_attr_all(inode, lower_inode);
++	/*
++	 * unionfs_copy_attr_all will copy the lower times to our inode if
++	 * the lower ones are newer (useful for cache coherency).  However,
++	 * ->setattr is the only place in which we may have to copy the
++	 * lower inode times absolutely, to support utimes(2).
++	 */
++	if (ia->ia_valid & ATTR_MTIME_SET)
++		inode->i_mtime = lower_inode->i_mtime;
++	if (ia->ia_valid & ATTR_CTIME)
++		inode->i_ctime = lower_inode->i_ctime;
++	if (ia->ia_valid & ATTR_ATIME_SET)
++		inode->i_atime = lower_inode->i_atime;
++	fsstack_copy_inode_size(inode, lower_inode);
++
++out:
++	if (!err)
++		unionfs_check_dentry(dentry);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++out_err:
++	return err;
++}
++
++struct inode_operations unionfs_symlink_iops = {
++	.readlink	= unionfs_readlink,
++	.permission	= unionfs_permission,
++	.follow_link	= unionfs_follow_link,
++	.setattr	= unionfs_setattr,
++	.put_link	= unionfs_put_link,
++};
++
++struct inode_operations unionfs_dir_iops = {
++	.create		= unionfs_create,
++	.lookup		= unionfs_lookup,
++	.link		= unionfs_link,
++	.unlink		= unionfs_unlink,
++	.symlink	= unionfs_symlink,
++	.mkdir		= unionfs_mkdir,
++	.rmdir		= unionfs_rmdir,
++	.mknod		= unionfs_mknod,
++	.rename		= unionfs_rename,
++	.permission	= unionfs_permission,
++	.setattr	= unionfs_setattr,
++#ifdef CONFIG_UNION_FS_XATTR
++	.setxattr	= unionfs_setxattr,
++	.getxattr	= unionfs_getxattr,
++	.removexattr	= unionfs_removexattr,
++	.listxattr	= unionfs_listxattr,
++#endif /* CONFIG_UNION_FS_XATTR */
++};
++
++struct inode_operations unionfs_main_iops = {
++	.permission	= unionfs_permission,
++	.setattr	= unionfs_setattr,
++#ifdef CONFIG_UNION_FS_XATTR
++	.setxattr	= unionfs_setxattr,
++	.getxattr	= unionfs_getxattr,
++	.removexattr	= unionfs_removexattr,
++	.listxattr	= unionfs_listxattr,
++#endif /* CONFIG_UNION_FS_XATTR */
++};
+diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c
+new file mode 100644
+index 0000000..b63c17e
+--- /dev/null
++++ b/fs/unionfs/lookup.c
+@@ -0,0 +1,569 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/*
++ * Lookup one path component @name relative to a <base,mnt> path pair.
++ * Behaves nearly the same as lookup_one_len (i.e., return negative dentry
++ * on ENOENT), but uses the @mnt passed, so it can cross bind mounts and
++ * other lower mounts properly.  If @new_mnt is non-null, will fill in the
++ * new mnt there.  Caller is responsible to dput/mntput/path_put returned
++ * @dentry and @new_mnt.
++ */
++struct dentry *__lookup_one(struct dentry *base, struct vfsmount *mnt,
++			    const char *name, struct vfsmount **new_mnt)
++{
++	struct dentry *dentry = NULL;
++	struct nameidata lower_nd;
++	int err;
++
++	/* we use flags=0 to get basic lookup */
++	err = vfs_path_lookup(base, mnt, name, 0, &lower_nd);
++
++	switch (err) {
++	case 0: /* no error */
++		dentry = lower_nd.path.dentry;
++		if (new_mnt)
++			*new_mnt = lower_nd.path.mnt; /* rc already inc'ed */
++		break;
++	case -ENOENT:
++		 /*
++		  * We don't consider ENOENT an error, and we want to return
++		  * a negative dentry (ala lookup_one_len).  As we know
++		  * there was no inode for this name before (-ENOENT), then
++		  * it's safe to call lookup_one_len (which doesn't take a
++		  * vfsmount).
++		  */
++		dentry = lookup_lck_len(name, base, strlen(name));
++		if (new_mnt)
++			*new_mnt = mntget(lower_nd.path.mnt);
++		break;
++	default: /* all other real errors */
++		dentry = ERR_PTR(err);
++		break;
++	}
++
++	return dentry;
++}
++
++/*
++ * This is a utility function that fills in a unionfs dentry.
++ * Caller must lock this dentry with unionfs_lock_dentry.
++ *
++ * Returns: 0 (ok), or -ERRNO if an error occurred.
++ * XXX: get rid of _partial_lookup and make callers call _lookup_full directly
++ */
++int unionfs_partial_lookup(struct dentry *dentry, struct dentry *parent)
++{
++	struct dentry *tmp;
++	int err = -ENOSYS;
++
++	tmp = unionfs_lookup_full(dentry, parent, INTERPOSE_PARTIAL);
++
++	if (!tmp) {
++		err = 0;
++		goto out;
++	}
++	if (IS_ERR(tmp)) {
++		err = PTR_ERR(tmp);
++		goto out;
++	}
++	/* XXX: need to change the interface */
++	BUG_ON(tmp != dentry);
++out:
++	return err;
++}
++
++/* The dentry cache is just so we have properly sized dentries. */
++static struct kmem_cache *unionfs_dentry_cachep;
++int unionfs_init_dentry_cache(void)
++{
++	unionfs_dentry_cachep =
++		kmem_cache_create("unionfs_dentry",
++				  sizeof(struct unionfs_dentry_info),
++				  0, SLAB_RECLAIM_ACCOUNT, NULL);
++
++	return (unionfs_dentry_cachep ? 0 : -ENOMEM);
++}
++
++void unionfs_destroy_dentry_cache(void)
++{
++	if (unionfs_dentry_cachep)
++		kmem_cache_destroy(unionfs_dentry_cachep);
++}
++
++void free_dentry_private_data(struct dentry *dentry)
++{
++	if (!dentry || !dentry->d_fsdata)
++		return;
++	kfree(UNIONFS_D(dentry)->lower_paths);
++	UNIONFS_D(dentry)->lower_paths = NULL;
++	kmem_cache_free(unionfs_dentry_cachep, dentry->d_fsdata);
++	dentry->d_fsdata = NULL;
++}
++
++static inline int __realloc_dentry_private_data(struct dentry *dentry)
++{
++	struct unionfs_dentry_info *info = UNIONFS_D(dentry);
++	void *p;
++	int size;
++
++	BUG_ON(!info);
++
++	size = sizeof(struct path) * sbmax(dentry->d_sb);
++	p = krealloc(info->lower_paths, size, GFP_ATOMIC);
++	if (unlikely(!p))
++		return -ENOMEM;
++
++	info->lower_paths = p;
++
++	info->bstart = -1;
++	info->bend = -1;
++	info->bopaque = -1;
++	info->bcount = sbmax(dentry->d_sb);
++	atomic_set(&info->generation,
++			atomic_read(&UNIONFS_SB(dentry->d_sb)->generation));
++
++	memset(info->lower_paths, 0, size);
++
++	return 0;
++}
++
++/* UNIONFS_D(dentry)->lock must be locked */
++int realloc_dentry_private_data(struct dentry *dentry)
++{
++	if (!__realloc_dentry_private_data(dentry))
++		return 0;
++
++	kfree(UNIONFS_D(dentry)->lower_paths);
++	free_dentry_private_data(dentry);
++	return -ENOMEM;
++}
++
++/* allocate new dentry private data */
++int new_dentry_private_data(struct dentry *dentry, int subclass)
++{
++	struct unionfs_dentry_info *info = UNIONFS_D(dentry);
++
++	BUG_ON(info);
++
++	info = kmem_cache_alloc(unionfs_dentry_cachep, GFP_ATOMIC);
++	if (unlikely(!info))
++		return -ENOMEM;
++
++	mutex_init(&info->lock);
++	mutex_lock_nested(&info->lock, subclass);
++
++	info->lower_paths = NULL;
++
++	dentry->d_fsdata = info;
++
++	if (!__realloc_dentry_private_data(dentry))
++		return 0;
++
++	mutex_unlock(&info->lock);
++	free_dentry_private_data(dentry);
++	return -ENOMEM;
++}
++
++/*
++ * scan through the lower dentry objects, and set bstart to reflect the
++ * starting branch
++ */
++void update_bstart(struct dentry *dentry)
++{
++	int bindex;
++	int bstart = dbstart(dentry);
++	int bend = dbend(dentry);
++	struct dentry *lower_dentry;
++
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (!lower_dentry)
++			continue;
++		if (lower_dentry->d_inode) {
++			dbstart(dentry) = bindex;
++			break;
++		}
++		dput(lower_dentry);
++		unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
++	}
++}
++
++
++/*
++ * Initialize a nameidata structure (the intent part) we can pass to a lower
++ * file system.  Returns 0 on success or -error (only -ENOMEM possible).
++ * Inside that nd structure, this function may also return an allocated
++ * struct file (for open intents).  The caller, when done with this nd, must
++ * kfree the intent file (using release_lower_nd).
++ *
++ * XXX: this code, and the callers of this code, should be redone using
++ * vfs_path_lookup() when (1) the nameidata structure is refactored into a
++ * separate intent-structure, and (2) open_namei() is broken into a VFS-only
++ * function and a method that other file systems can call.
++ */
++int init_lower_nd(struct nameidata *nd, unsigned int flags)
++{
++	int err = 0;
++#ifdef ALLOC_LOWER_ND_FILE
++	/*
++	 * XXX: one day we may need to have the lower return an open file
++	 * for us.  It is not needed in 2.6.23-rc1 for nfs2/nfs3, but may
++	 * very well be needed for nfs4.
++	 */
++	struct file *file;
++#endif /* ALLOC_LOWER_ND_FILE */
++
++	memset(nd, 0, sizeof(struct nameidata));
++	if (!flags)
++		return err;
++
++	switch (flags) {
++	case LOOKUP_CREATE:
++		nd->intent.open.flags |= O_CREAT;
++		/* fall through: shared code for create/open cases */
++	case LOOKUP_OPEN:
++		nd->flags = flags;
++		nd->intent.open.flags |= (FMODE_READ | FMODE_WRITE);
++#ifdef ALLOC_LOWER_ND_FILE
++		file = kzalloc(sizeof(struct file), GFP_KERNEL);
++		if (unlikely(!file)) {
++			err = -ENOMEM;
++			break; /* exit switch statement and thus return */
++		}
++		nd->intent.open.file = file;
++#endif /* ALLOC_LOWER_ND_FILE */
++		break;
++	default:
++		/*
++		 * We should never get here, for now.
++		 * We can add new cases here later on.
++		 */
++		pr_debug("unionfs: unknown nameidata flag 0x%x\n", flags);
++		BUG();
++		break;
++	}
++
++	return err;
++}
++
++void release_lower_nd(struct nameidata *nd, int err)
++{
++	if (!nd->intent.open.file)
++		return;
++	else if (!err)
++		release_open_intent(nd);
++#ifdef ALLOC_LOWER_ND_FILE
++	kfree(nd->intent.open.file);
++#endif /* ALLOC_LOWER_ND_FILE */
++}
++
++/*
++ * Main (and complex) driver function for Unionfs's lookup
++ *
++ * Returns: NULL (ok), ERR_PTR if an error occurred, or a non-null non-error
++ * PTR if d_splice returned a different dentry.
++ *
++ * If lookupmode is INTERPOSE_PARTIAL/REVAL/REVAL_NEG, the passed dentry's
++ * inode info must be locked.  If lookupmode is INTERPOSE_LOOKUP (i.e., a
++ * newly looked-up dentry), then unionfs_lookup_backend will return a locked
++ * dentry's info, which the caller must unlock.
++ */
++struct dentry *unionfs_lookup_full(struct dentry *dentry,
++				   struct dentry *parent, int lookupmode)
++{
++	int err = 0;
++	struct dentry *lower_dentry = NULL;
++	struct vfsmount *lower_mnt;
++	struct vfsmount *lower_dir_mnt;
++	struct dentry *wh_lower_dentry = NULL;
++	struct dentry *lower_dir_dentry = NULL;
++	struct dentry *d_interposed = NULL;
++	int bindex, bstart, bend, bopaque;
++	int opaque, num_positive = 0;
++	const char *name;
++	int namelen;
++	int pos_start, pos_end;
++
++	/*
++	 * We should already have a lock on this dentry in the case of a
++	 * partial lookup, or a revalidation.  Otherwise it is returned from
++	 * new_dentry_private_data already locked.
++	 */
++	verify_locked(dentry);
++	verify_locked(parent);
++
++	/* must initialize dentry operations */
++	dentry->d_op = &unionfs_dops;
++
++	/* We never partial lookup the root directory. */
++	if (IS_ROOT(dentry))
++		goto out;
++
++	name = dentry->d_name.name;
++	namelen = dentry->d_name.len;
++
++	/* No dentries should get created for possible whiteout names. */
++	if (!is_validname(name)) {
++		err = -EPERM;
++		goto out_free;
++	}
++
++	/* Now start the actual lookup procedure. */
++	bstart = dbstart(parent);
++	bend = dbend(parent);
++	bopaque = dbopaque(parent);
++	BUG_ON(bstart < 0);
++
++	/* adjust bend to bopaque if needed */
++	if ((bopaque >= 0) && (bopaque < bend))
++		bend = bopaque;
++
++	/* lookup all possible dentries */
++	for (bindex = bstart; bindex <= bend; bindex++) {
++
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
++
++		/* skip if we already have a positive lower dentry */
++		if (lower_dentry) {
++			if (dbstart(dentry) < 0)
++				dbstart(dentry) = bindex;
++			if (bindex > dbend(dentry))
++				dbend(dentry) = bindex;
++			if (lower_dentry->d_inode)
++				num_positive++;
++			continue;
++		}
++
++		lower_dir_dentry =
++			unionfs_lower_dentry_idx(parent, bindex);
++		/* if the lower dentry's parent does not exist, skip this */
++		if (!lower_dir_dentry || !lower_dir_dentry->d_inode)
++			continue;
++
++		/* also skip it if the parent isn't a directory. */
++		if (!S_ISDIR(lower_dir_dentry->d_inode->i_mode))
++			continue; /* XXX: should be BUG_ON */
++
++		/* check for whiteouts: stop lookup if found */
++		wh_lower_dentry = lookup_whiteout(name, lower_dir_dentry);
++		if (IS_ERR(wh_lower_dentry)) {
++			err = PTR_ERR(wh_lower_dentry);
++			goto out_free;
++		}
++		if (wh_lower_dentry->d_inode) {
++			dbend(dentry) = dbopaque(dentry) = bindex;
++			if (dbstart(dentry) < 0)
++				dbstart(dentry) = bindex;
++			dput(wh_lower_dentry);
++			break;
++		}
++		dput(wh_lower_dentry);
++
++		/* Now do regular lookup; lookup @name */
++		lower_dir_mnt = unionfs_lower_mnt_idx(parent, bindex);
++		lower_mnt = NULL; /* XXX: needed? */
++
++		lower_dentry = __lookup_one(lower_dir_dentry, lower_dir_mnt,
++					    name, &lower_mnt);
++
++		if (IS_ERR(lower_dentry)) {
++			err = PTR_ERR(lower_dentry);
++			goto out_free;
++		}
++		unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry);
++		if (!lower_mnt)
++			lower_mnt = unionfs_mntget(dentry->d_sb->s_root,
++						   bindex);
++		unionfs_set_lower_mnt_idx(dentry, bindex, lower_mnt);
++
++		/* adjust dbstart/end */
++		if (dbstart(dentry) < 0)
++			dbstart(dentry) = bindex;
++		if (bindex > dbend(dentry))
++			dbend(dentry) = bindex;
++		/*
++		 * We always store the lower dentries above, and update
++		 * dbstart/dbend, even if the whole unionfs dentry is
++		 * negative (i.e., no lower inodes).
++		 */
++		if (!lower_dentry->d_inode)
++			continue;
++		num_positive++;
++
++		/*
++		 * check if we just found an opaque directory, if so, stop
++		 * lookups here.
++		 */
++		if (!S_ISDIR(lower_dentry->d_inode->i_mode))
++			continue;
++		opaque = is_opaque_dir(dentry, bindex);
++		if (opaque < 0) {
++			err = opaque;
++			goto out_free;
++		} else if (opaque) {
++			dbend(dentry) = dbopaque(dentry) = bindex;
++			break;
++		}
++		dbend(dentry) = bindex;
++
++		/* update parent directory's atime with the bindex */
++		fsstack_copy_attr_atime(parent->d_inode,
++					lower_dir_dentry->d_inode);
++	}
++
++	/* sanity checks, then decide if to process a negative dentry */
++	BUG_ON(dbstart(dentry) < 0 && dbend(dentry) >= 0);
++	BUG_ON(dbstart(dentry) >= 0 && dbend(dentry) < 0);
++
++	if (num_positive > 0)
++		goto out_positive;
++
++	/*** handle NEGATIVE dentries ***/
++
++	/*
++	 * If negative, keep only first lower negative dentry, to save on
++	 * memory.
++	 */
++	if (dbstart(dentry) < dbend(dentry)) {
++		path_put_lowers(dentry, dbstart(dentry) + 1,
++				dbend(dentry), false);
++		dbend(dentry) = dbstart(dentry);
++	}
++	if (lookupmode == INTERPOSE_PARTIAL)
++		goto out;
++	if (lookupmode == INTERPOSE_LOOKUP) {
++		/*
++		 * If all we found was a whiteout in the first available
++		 * branch, then create a negative dentry for a possibly new
++		 * file to be created.
++		 */
++		if (dbopaque(dentry) < 0)
++			goto out;
++		/* XXX: need to get mnt here */
++		bindex = dbstart(dentry);
++		if (unionfs_lower_dentry_idx(dentry, bindex))
++			goto out;
++		lower_dir_dentry =
++			unionfs_lower_dentry_idx(parent, bindex);
++		if (!lower_dir_dentry || !lower_dir_dentry->d_inode)
++			goto out;
++		if (!S_ISDIR(lower_dir_dentry->d_inode->i_mode))
++			goto out; /* XXX: should be BUG_ON */
++		/* XXX: do we need to cross bind mounts here? */
++		lower_dentry = lookup_lck_len(name, lower_dir_dentry, namelen);
++		if (IS_ERR(lower_dentry)) {
++			err = PTR_ERR(lower_dentry);
++			goto out;
++		}
++		/* XXX: need to mntget/mntput as needed too! */
++		unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry);
++		/* XXX: wrong mnt for crossing bind mounts! */
++		lower_mnt = unionfs_mntget(dentry->d_sb->s_root, bindex);
++		unionfs_set_lower_mnt_idx(dentry, bindex, lower_mnt);
++
++		goto out;
++	}
++
++	/* if we're revalidating a positive dentry, don't make it negative */
++	if (lookupmode != INTERPOSE_REVAL)
++		d_add(dentry, NULL);
++
++	goto out;
++
++out_positive:
++	/*** handle POSITIVE dentries ***/
++
++	/*
++	 * This unionfs dentry is positive (at least one lower inode
++	 * exists), so scan entire dentry from beginning to end, and remove
++	 * any negative lower dentries, if any.  Then, update dbstart/dbend
++	 * to reflect the start/end of positive dentries.
++	 */
++	pos_start = pos_end = -1;
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry,
++							bindex);
++		if (lower_dentry && lower_dentry->d_inode) {
++			if (pos_start < 0)
++				pos_start = bindex;
++			if (bindex > pos_end)
++				pos_end = bindex;
++			continue;
++		}
++		path_put_lowers(dentry, bindex, bindex, false);
++	}
++	if (pos_start >= 0)
++		dbstart(dentry) = pos_start;
++	if (pos_end >= 0)
++		dbend(dentry) = pos_end;
++
++	/* Partial lookups need to re-interpose, or throw away older negs. */
++	if (lookupmode == INTERPOSE_PARTIAL) {
++		if (dentry->d_inode) {
++			unionfs_reinterpose(dentry);
++			goto out;
++		}
++
++		/*
++		 * This dentry was positive, so it is as if we had a
++		 * negative revalidation.
++		 */
++		lookupmode = INTERPOSE_REVAL_NEG;
++		update_bstart(dentry);
++	}
++
++	/*
++	 * Interpose can return a dentry if d_splice returned a different
++	 * dentry.
++	 */
++	d_interposed = unionfs_interpose(dentry, dentry->d_sb, lookupmode);
++	if (IS_ERR(d_interposed))
++		err = PTR_ERR(d_interposed);
++	else if (d_interposed)
++		dentry = d_interposed;
++
++	if (!err)
++		goto out;
++	d_drop(dentry);
++
++out_free:
++	/* should dput/mntput all the underlying dentries on error condition */
++	if (dbstart(dentry) >= 0)
++		path_put_lowers_all(dentry, false);
++	/* free lower_paths unconditionally */
++	kfree(UNIONFS_D(dentry)->lower_paths);
++	UNIONFS_D(dentry)->lower_paths = NULL;
++
++out:
++	if (dentry && UNIONFS_D(dentry)) {
++		BUG_ON(dbstart(dentry) < 0 && dbend(dentry) >= 0);
++		BUG_ON(dbstart(dentry) >= 0 && dbend(dentry) < 0);
++	}
++	if (d_interposed && UNIONFS_D(d_interposed)) {
++		BUG_ON(dbstart(d_interposed) < 0 && dbend(d_interposed) >= 0);
++		BUG_ON(dbstart(d_interposed) >= 0 && dbend(d_interposed) < 0);
++	}
++
++	if (!err && d_interposed)
++		return d_interposed;
++	return ERR_PTR(err);
++}
+diff --git a/fs/unionfs/main.c b/fs/unionfs/main.c
+new file mode 100644
+index 0000000..9ee58eb
+--- /dev/null
++++ b/fs/unionfs/main.c
+@@ -0,0 +1,762 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++
++static void unionfs_fill_inode(struct dentry *dentry,
++			       struct inode *inode)
++{
++	struct inode *lower_inode;
++	struct dentry *lower_dentry;
++	int bindex, bstart, bend;
++
++	bstart = dbstart(dentry);
++	bend = dbend(dentry);
++
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (!lower_dentry) {
++			unionfs_set_lower_inode_idx(inode, bindex, NULL);
++			continue;
++		}
++
++		/* Initialize the lower inode to the new lower inode. */
++		if (!lower_dentry->d_inode)
++			continue;
++
++		unionfs_set_lower_inode_idx(inode, bindex,
++					    igrab(lower_dentry->d_inode));
++	}
++
++	ibstart(inode) = dbstart(dentry);
++	ibend(inode) = dbend(dentry);
++
++	/* Use attributes from the first branch. */
++	lower_inode = unionfs_lower_inode(inode);
++
++	/* Use different set of inode ops for symlinks & directories */
++	if (S_ISLNK(lower_inode->i_mode))
++		inode->i_op = &unionfs_symlink_iops;
++	else if (S_ISDIR(lower_inode->i_mode))
++		inode->i_op = &unionfs_dir_iops;
++
++	/* Use different set of file ops for directories */
++	if (S_ISDIR(lower_inode->i_mode))
++		inode->i_fop = &unionfs_dir_fops;
++
++	/* properly initialize special inodes */
++	if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) ||
++	    S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode))
++		init_special_inode(inode, lower_inode->i_mode,
++				   lower_inode->i_rdev);
++
++	/* all well, copy inode attributes */
++	unionfs_copy_attr_all(inode, lower_inode);
++	fsstack_copy_inode_size(inode, lower_inode);
++}
++
++/*
++ * Connect a unionfs inode dentry/inode with several lower ones.  This is
++ * the classic stackable file system "vnode interposition" action.
++ *
++ * @sb: unionfs's super_block
++ */
++struct dentry *unionfs_interpose(struct dentry *dentry, struct super_block *sb,
++				 int flag)
++{
++	int err = 0;
++	struct inode *inode;
++	int need_fill_inode = 1;
++	struct dentry *spliced = NULL;
++
++	verify_locked(dentry);
++
++	/*
++	 * We allocate our new inode below by calling unionfs_iget,
++	 * which will initialize some of the new inode's fields
++	 */
++
++	/*
++	 * On revalidate we've already got our own inode and just need
++	 * to fix it up.
++	 */
++	if (flag == INTERPOSE_REVAL) {
++		inode = dentry->d_inode;
++		UNIONFS_I(inode)->bstart = -1;
++		UNIONFS_I(inode)->bend = -1;
++		atomic_set(&UNIONFS_I(inode)->generation,
++			   atomic_read(&UNIONFS_SB(sb)->generation));
++
++		UNIONFS_I(inode)->lower_inodes =
++			kcalloc(sbmax(sb), sizeof(struct inode *), GFP_KERNEL);
++		if (unlikely(!UNIONFS_I(inode)->lower_inodes)) {
++			err = -ENOMEM;
++			goto out;
++		}
++	} else {
++		/* get unique inode number for unionfs */
++		inode = unionfs_iget(sb, iunique(sb, UNIONFS_ROOT_INO));
++		if (IS_ERR(inode)) {
++			err = PTR_ERR(inode);
++			goto out;
++		}
++		if (atomic_read(&inode->i_count) > 1)
++			goto skip;
++	}
++
++	need_fill_inode = 0;
++	unionfs_fill_inode(dentry, inode);
++
++skip:
++	/* only (our) lookup wants to do a d_add */
++	switch (flag) {
++	case INTERPOSE_DEFAULT:
++		/* for operations which create new inodes */
++		d_add(dentry, inode);
++		break;
++	case INTERPOSE_REVAL_NEG:
++		d_instantiate(dentry, inode);
++		break;
++	case INTERPOSE_LOOKUP:
++		spliced = d_splice_alias(inode, dentry);
++		if (spliced && spliced != dentry) {
++			/*
++			 * d_splice can return a dentry if it was
++			 * disconnected and had to be moved.  We must ensure
++			 * that the private data of the new dentry is
++			 * correct and that the inode info was filled
++			 * properly.  Finally we must return this new
++			 * dentry.
++			 */
++			spliced->d_op = &unionfs_dops;
++			spliced->d_fsdata = dentry->d_fsdata;
++			dentry->d_fsdata = NULL;
++			dentry = spliced;
++			if (need_fill_inode) {
++				need_fill_inode = 0;
++				unionfs_fill_inode(dentry, inode);
++			}
++			goto out_spliced;
++		} else if (!spliced) {
++			if (need_fill_inode) {
++				need_fill_inode = 0;
++				unionfs_fill_inode(dentry, inode);
++				goto out_spliced;
++			}
++		}
++		break;
++	case INTERPOSE_REVAL:
++		/* Do nothing. */
++		break;
++	default:
++		printk(KERN_CRIT "unionfs: invalid interpose flag passed!\n");
++		BUG();
++	}
++	goto out;
++
++out_spliced:
++	if (!err)
++		return spliced;
++out:
++	return ERR_PTR(err);
++}
++
++/* like interpose above, but for an already existing dentry */
++void unionfs_reinterpose(struct dentry *dentry)
++{
++	struct dentry *lower_dentry;
++	struct inode *inode;
++	int bindex, bstart, bend;
++
++	verify_locked(dentry);
++
++	/* This is pre-allocated inode */
++	inode = dentry->d_inode;
++
++	bstart = dbstart(dentry);
++	bend = dbend(dentry);
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (!lower_dentry)
++			continue;
++
++		if (!lower_dentry->d_inode)
++			continue;
++		if (unionfs_lower_inode_idx(inode, bindex))
++			continue;
++		unionfs_set_lower_inode_idx(inode, bindex,
++					    igrab(lower_dentry->d_inode));
++	}
++	ibstart(inode) = dbstart(dentry);
++	ibend(inode) = dbend(dentry);
++}
++
++/*
++ * make sure the branch we just looked up (nd) makes sense:
++ *
++ * 1) we're not trying to stack unionfs on top of unionfs
++ * 2) it exists
++ * 3) is a directory
++ */
++int check_branch(struct nameidata *nd)
++{
++	/* XXX: remove in ODF code -- stacking unions allowed there */
++	if (!strcmp(nd->path.dentry->d_sb->s_type->name, UNIONFS_NAME))
++		return -EINVAL;
++	if (!nd->path.dentry->d_inode)
++		return -ENOENT;
++	if (!S_ISDIR(nd->path.dentry->d_inode->i_mode))
++		return -ENOTDIR;
++	return 0;
++}
++
++/* checks if two lower_dentries have overlapping branches */
++static int is_branch_overlap(struct dentry *dent1, struct dentry *dent2)
++{
++	struct dentry *dent = NULL;
++
++	dent = dent1;
++	while ((dent != dent2) && (dent->d_parent != dent))
++		dent = dent->d_parent;
++
++	if (dent == dent2)
++		return 1;
++
++	dent = dent2;
++	while ((dent != dent1) && (dent->d_parent != dent))
++		dent = dent->d_parent;
++
++	return (dent == dent1);
++}
++
++/*
++ * Parse "ro" or "rw" options, but default to "rw" if no mode options was
++ * specified.  Fill the mode bits in @perms.  If encounter an unknown
++ * string, return -EINVAL.  Otherwise return 0.
++ */
++int parse_branch_mode(const char *name, int *perms)
++{
++	if (!name || !strcmp(name, "rw")) {
++		*perms = MAY_READ | MAY_WRITE;
++		return 0;
++	}
++	if (!strcmp(name, "ro")) {
++		*perms = MAY_READ;
++		return 0;
++	}
++	return -EINVAL;
++}
++
++/*
++ * parse the dirs= mount argument
++ *
++ * We don't need to lock the superblock private data's rwsem, as we get
++ * called only by unionfs_read_super - it is still a long time before anyone
++ * can even get a reference to us.
++ */
++static int parse_dirs_option(struct super_block *sb, struct unionfs_dentry_info
++			     *lower_root_info, char *options)
++{
++	struct nameidata nd;
++	char *name;
++	int err = 0;
++	int branches = 1;
++	int bindex = 0;
++	int i = 0;
++	int j = 0;
++	struct dentry *dent1;
++	struct dentry *dent2;
++
++	if (options[0] == '\0') {
++		printk(KERN_ERR "unionfs: no branches specified\n");
++		err = -EINVAL;
++		goto out_return;
++	}
++
++	/*
++	 * Each colon means we have a separator, this is really just a rough
++	 * guess, since strsep will handle empty fields for us.
++	 */
++	for (i = 0; options[i]; i++)
++		if (options[i] == ':')
++			branches++;
++
++	/* allocate space for underlying pointers to lower dentry */
++	UNIONFS_SB(sb)->data =
++		kcalloc(branches, sizeof(struct unionfs_data), GFP_KERNEL);
++	if (unlikely(!UNIONFS_SB(sb)->data)) {
++		err = -ENOMEM;
++		goto out_return;
++	}
++
++	lower_root_info->lower_paths =
++		kcalloc(branches, sizeof(struct path), GFP_KERNEL);
++	if (unlikely(!lower_root_info->lower_paths)) {
++		err = -ENOMEM;
++		/* free the underlying pointer array */
++		kfree(UNIONFS_SB(sb)->data);
++		UNIONFS_SB(sb)->data = NULL;
++		goto out_return;
++	}
++
++	/* now parsing a string such as "b1:b2=rw:b3=ro:b4" */
++	branches = 0;
++	while ((name = strsep(&options, ":")) != NULL) {
++		int perms;
++		char *mode = strchr(name, '=');
++
++		if (!name)
++			continue;
++		if (!*name) {	/* bad use of ':' (extra colons) */
++			err = -EINVAL;
++			goto out;
++		}
++
++		branches++;
++
++		/* strip off '=' if any */
++		if (mode)
++			*mode++ = '\0';
++
++		err = parse_branch_mode(mode, &perms);
++		if (err) {
++			printk(KERN_ERR "unionfs: invalid mode \"%s\" for "
++			       "branch %d\n", mode, bindex);
++			goto out;
++		}
++		/* ensure that leftmost branch is writeable */
++		if (!bindex && !(perms & MAY_WRITE)) {
++			printk(KERN_ERR "unionfs: leftmost branch cannot be "
++			       "read-only (use \"-o ro\" to create a "
++			       "read-only union)\n");
++			err = -EINVAL;
++			goto out;
++		}
++
++		err = path_lookup(name, LOOKUP_FOLLOW, &nd);
++		if (err) {
++			printk(KERN_ERR "unionfs: error accessing "
++			       "lower directory '%s' (error %d)\n",
++			       name, err);
++			goto out;
++		}
++
++		err = check_branch(&nd);
++		if (err) {
++			printk(KERN_ERR "unionfs: lower directory "
++			       "'%s' is not a valid branch\n", name);
++			path_put(&nd.path);
++			goto out;
++		}
++
++		lower_root_info->lower_paths[bindex].dentry = nd.path.dentry;
++		lower_root_info->lower_paths[bindex].mnt = nd.path.mnt;
++
++		set_branchperms(sb, bindex, perms);
++		set_branch_count(sb, bindex, 0);
++		new_branch_id(sb, bindex);
++
++		if (lower_root_info->bstart < 0)
++			lower_root_info->bstart = bindex;
++		lower_root_info->bend = bindex;
++		bindex++;
++	}
++
++	if (branches == 0) {
++		printk(KERN_ERR "unionfs: no branches specified\n");
++		err = -EINVAL;
++		goto out;
++	}
++
++	BUG_ON(branches != (lower_root_info->bend + 1));
++
++	/*
++	 * Ensure that no overlaps exist in the branches.
++	 *
++	 * This test is required because the Linux kernel has no support
++	 * currently for ensuring coherency between stackable layers and
++	 * branches.  If we were to allow overlapping branches, it would be
++	 * possible, for example, to delete a file via one branch, which
++	 * would not be reflected in another branch.  Such incoherency could
++	 * lead to inconsistencies and even kernel oopses.  Rather than
++	 * implement hacks to work around some of these cache-coherency
++	 * problems, we prevent branch overlapping, for now.  A complete
++	 * solution will involve proper kernel/VFS support for cache
++	 * coherency, at which time we could safely remove this
++	 * branch-overlapping test.
++	 */
++	for (i = 0; i < branches; i++) {
++		dent1 = lower_root_info->lower_paths[i].dentry;
++		for (j = i + 1; j < branches; j++) {
++			dent2 = lower_root_info->lower_paths[j].dentry;
++			if (is_branch_overlap(dent1, dent2)) {
++				printk(KERN_ERR "unionfs: branches %d and "
++				       "%d overlap\n", i, j);
++				err = -EINVAL;
++				goto out;
++			}
++		}
++	}
++
++out:
++	if (err) {
++		for (i = 0; i < branches; i++)
++			path_put(&lower_root_info->lower_paths[i]);
++
++		kfree(lower_root_info->lower_paths);
++		kfree(UNIONFS_SB(sb)->data);
++
++		/*
++		 * MUST clear the pointers to prevent potential double free if
++		 * the caller dies later on
++		 */
++		lower_root_info->lower_paths = NULL;
++		UNIONFS_SB(sb)->data = NULL;
++	}
++out_return:
++	return err;
++}
++
++/*
++ * Parse mount options.  See the manual page for usage instructions.
++ *
++ * Returns the dentry object of the lower-level (lower) directory;
++ * We want to mount our stackable file system on top of that lower directory.
++ */
++static struct unionfs_dentry_info *unionfs_parse_options(
++					 struct super_block *sb,
++					 char *options)
++{
++	struct unionfs_dentry_info *lower_root_info;
++	char *optname;
++	int err = 0;
++	int bindex;
++	int dirsfound = 0;
++
++	/* allocate private data area */
++	err = -ENOMEM;
++	lower_root_info =
++		kzalloc(sizeof(struct unionfs_dentry_info), GFP_KERNEL);
++	if (unlikely(!lower_root_info))
++		goto out_error;
++	lower_root_info->bstart = -1;
++	lower_root_info->bend = -1;
++	lower_root_info->bopaque = -1;
++
++	while ((optname = strsep(&options, ",")) != NULL) {
++		char *optarg;
++
++		if (!optname || !*optname)
++			continue;
++
++		optarg = strchr(optname, '=');
++		if (optarg)
++			*optarg++ = '\0';
++
++		/*
++		 * All of our options take an argument now. Insert ones that
++		 * don't, above this check.
++		 */
++		if (!optarg) {
++			printk(KERN_ERR "unionfs: %s requires an argument\n",
++			       optname);
++			err = -EINVAL;
++			goto out_error;
++		}
++
++		if (!strcmp("dirs", optname)) {
++			if (++dirsfound > 1) {
++				printk(KERN_ERR
++				       "unionfs: multiple dirs specified\n");
++				err = -EINVAL;
++				goto out_error;
++			}
++			err = parse_dirs_option(sb, lower_root_info, optarg);
++			if (err)
++				goto out_error;
++			continue;
++		}
++
++		err = -EINVAL;
++		printk(KERN_ERR
++		       "unionfs: unrecognized option '%s'\n", optname);
++		goto out_error;
++	}
++	if (dirsfound != 1) {
++		printk(KERN_ERR "unionfs: dirs option required\n");
++		err = -EINVAL;
++		goto out_error;
++	}
++	goto out;
++
++out_error:
++	if (lower_root_info && lower_root_info->lower_paths) {
++		for (bindex = lower_root_info->bstart;
++		     bindex >= 0 && bindex <= lower_root_info->bend;
++		     bindex++)
++			path_put(&lower_root_info->lower_paths[bindex]);
++	}
++
++	kfree(lower_root_info->lower_paths);
++	kfree(lower_root_info);
++
++	kfree(UNIONFS_SB(sb)->data);
++	UNIONFS_SB(sb)->data = NULL;
++
++	lower_root_info = ERR_PTR(err);
++out:
++	return lower_root_info;
++}
++
++/*
++ * our custom d_alloc_root work-alike
++ *
++ * we can't use d_alloc_root if we want to use our own interpose function
++ * unchanged, so we simply call our own "fake" d_alloc_root
++ */
++static struct dentry *unionfs_d_alloc_root(struct super_block *sb)
++{
++	struct dentry *ret = NULL;
++
++	if (sb) {
++		static const struct qstr name = {
++			.name = "/",
++			.len = 1
++		};
++
++		ret = d_alloc(NULL, &name);
++		if (likely(ret)) {
++			ret->d_op = &unionfs_dops;
++			ret->d_sb = sb;
++			ret->d_parent = ret;
++		}
++	}
++	return ret;
++}
++
++/*
++ * There is no need to lock the unionfs_super_info's rwsem as there is no
++ * way anyone can have a reference to the superblock at this point in time.
++ */
++static int unionfs_read_super(struct super_block *sb, void *raw_data,
++			      int silent)
++{
++	int err = 0;
++	struct unionfs_dentry_info *lower_root_info = NULL;
++	int bindex, bstart, bend;
++
++	if (!raw_data) {
++		printk(KERN_ERR
++		       "unionfs: read_super: missing data argument\n");
++		err = -EINVAL;
++		goto out;
++	}
++
++	/* Allocate superblock private data */
++	sb->s_fs_info = kzalloc(sizeof(struct unionfs_sb_info), GFP_KERNEL);
++	if (unlikely(!UNIONFS_SB(sb))) {
++		printk(KERN_CRIT "unionfs: read_super: out of memory\n");
++		err = -ENOMEM;
++		goto out;
++	}
++
++	UNIONFS_SB(sb)->bend = -1;
++	atomic_set(&UNIONFS_SB(sb)->generation, 1);
++	init_rwsem(&UNIONFS_SB(sb)->rwsem);
++	UNIONFS_SB(sb)->high_branch_id = -1; /* -1 == invalid branch ID */
++
++	lower_root_info = unionfs_parse_options(sb, raw_data);
++	if (IS_ERR(lower_root_info)) {
++		printk(KERN_ERR
++		       "unionfs: read_super: error while parsing options "
++		       "(err = %ld)\n", PTR_ERR(lower_root_info));
++		err = PTR_ERR(lower_root_info);
++		lower_root_info = NULL;
++		goto out_free;
++	}
++	if (lower_root_info->bstart == -1) {
++		err = -ENOENT;
++		goto out_free;
++	}
++
++	/* set the lower superblock field of upper superblock */
++	bstart = lower_root_info->bstart;
++	BUG_ON(bstart != 0);
++	sbend(sb) = bend = lower_root_info->bend;
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		struct dentry *d = lower_root_info->lower_paths[bindex].dentry;
++		atomic_inc(&d->d_sb->s_active);
++		unionfs_set_lower_super_idx(sb, bindex, d->d_sb);
++	}
++
++	/* max Bytes is the maximum bytes from highest priority branch */
++	sb->s_maxbytes = unionfs_lower_super_idx(sb, 0)->s_maxbytes;
++
++	/*
++	 * Our c/m/atime granularity is 1 ns because we may stack on file
++	 * systems whose granularity is as good.  This is important for our
++	 * time-based cache coherency.
++	 */
++	sb->s_time_gran = 1;
++
++	sb->s_op = &unionfs_sops;
++
++	/* See comment next to the definition of unionfs_d_alloc_root */
++	sb->s_root = unionfs_d_alloc_root(sb);
++	if (unlikely(!sb->s_root)) {
++		err = -ENOMEM;
++		goto out_dput;
++	}
++
++	/* link the upper and lower dentries */
++	sb->s_root->d_fsdata = NULL;
++	err = new_dentry_private_data(sb->s_root, UNIONFS_DMUTEX_ROOT);
++	if (unlikely(err))
++		goto out_freedpd;
++
++	/* Set the lower dentries for s_root */
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		struct dentry *d;
++		struct vfsmount *m;
++
++		d = lower_root_info->lower_paths[bindex].dentry;
++		m = lower_root_info->lower_paths[bindex].mnt;
++
++		unionfs_set_lower_dentry_idx(sb->s_root, bindex, d);
++		unionfs_set_lower_mnt_idx(sb->s_root, bindex, m);
++	}
++	dbstart(sb->s_root) = bstart;
++	dbend(sb->s_root) = bend;
++
++	/* Set the generation number to one, since this is for the mount. */
++	atomic_set(&UNIONFS_D(sb->s_root)->generation, 1);
++
++	/*
++	 * Call interpose to create the upper level inode.  Only
++	 * INTERPOSE_LOOKUP can return a value other than 0 on err.
++	 */
++	err = PTR_ERR(unionfs_interpose(sb->s_root, sb, 0));
++	unionfs_unlock_dentry(sb->s_root);
++	if (!err)
++		goto out;
++	/* else fall through */
++
++out_freedpd:
++	if (UNIONFS_D(sb->s_root)) {
++		kfree(UNIONFS_D(sb->s_root)->lower_paths);
++		free_dentry_private_data(sb->s_root);
++	}
++	dput(sb->s_root);
++
++out_dput:
++	if (lower_root_info && !IS_ERR(lower_root_info)) {
++		for (bindex = lower_root_info->bstart;
++		     bindex <= lower_root_info->bend; bindex++) {
++			struct dentry *d;
++			d = lower_root_info->lower_paths[bindex].dentry;
++			/* drop refs we took earlier */
++			atomic_dec(&d->d_sb->s_active);
++			path_put(&lower_root_info->lower_paths[bindex]);
++		}
++		kfree(lower_root_info->lower_paths);
++		kfree(lower_root_info);
++		lower_root_info = NULL;
++	}
++
++out_free:
++	kfree(UNIONFS_SB(sb)->data);
++	kfree(UNIONFS_SB(sb));
++	sb->s_fs_info = NULL;
++
++out:
++	if (lower_root_info && !IS_ERR(lower_root_info)) {
++		kfree(lower_root_info->lower_paths);
++		kfree(lower_root_info);
++	}
++	return err;
++}
++
++static int unionfs_get_sb(struct file_system_type *fs_type,
++			  int flags, const char *dev_name,
++			  void *raw_data, struct vfsmount *mnt)
++{
++	int err;
++	err = get_sb_nodev(fs_type, flags, raw_data, unionfs_read_super, mnt);
++	if (!err)
++		UNIONFS_SB(mnt->mnt_sb)->dev_name =
++			kstrdup(dev_name, GFP_KERNEL);
++	return err;
++}
++
++static struct file_system_type unionfs_fs_type = {
++	.owner		= THIS_MODULE,
++	.name		= UNIONFS_NAME,
++	.get_sb		= unionfs_get_sb,
++	.kill_sb	= generic_shutdown_super,
++	.fs_flags	= FS_REVAL_DOT,
++};
++
++static int __init init_unionfs_fs(void)
++{
++	int err;
++
++	pr_info("Registering unionfs " UNIONFS_VERSION "\n");
++
++	err = unionfs_init_filldir_cache();
++	if (unlikely(err))
++		goto out;
++	err = unionfs_init_inode_cache();
++	if (unlikely(err))
++		goto out;
++	err = unionfs_init_dentry_cache();
++	if (unlikely(err))
++		goto out;
++	err = init_sioq();
++	if (unlikely(err))
++		goto out;
++	err = register_filesystem(&unionfs_fs_type);
++out:
++	if (unlikely(err)) {
++		stop_sioq();
++		unionfs_destroy_filldir_cache();
++		unionfs_destroy_inode_cache();
++		unionfs_destroy_dentry_cache();
++	}
++	return err;
++}
++
++static void __exit exit_unionfs_fs(void)
++{
++	stop_sioq();
++	unionfs_destroy_filldir_cache();
++	unionfs_destroy_inode_cache();
++	unionfs_destroy_dentry_cache();
++	unregister_filesystem(&unionfs_fs_type);
++	pr_info("Completed unionfs module unload\n");
++}
++
++MODULE_AUTHOR("Erez Zadok, Filesystems and Storage Lab, Stony Brook University"
++	      " (http://www.fsl.cs.sunysb.edu)");
++MODULE_DESCRIPTION("Unionfs " UNIONFS_VERSION
++		   " (http://unionfs.filesystems.org)");
++MODULE_LICENSE("GPL");
++
++module_init(init_unionfs_fs);
++module_exit(exit_unionfs_fs);
+diff --git a/fs/unionfs/mmap.c b/fs/unionfs/mmap.c
+new file mode 100644
+index 0000000..1f70535
+--- /dev/null
++++ b/fs/unionfs/mmap.c
+@@ -0,0 +1,89 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2006      Shaya Potter
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++
++/*
++ * XXX: we need a dummy readpage handler because generic_file_mmap (which we
++ * use in unionfs_mmap) checks for the existence of
++ * mapping->a_ops->readpage, else it returns -ENOEXEC.  The VFS will need to
++ * be fixed to allow a file system to define vm_ops->fault without any
++ * address_space_ops whatsoever.
++ *
++ * Otherwise, we don't want to use our readpage method at all.
++ */
++static int unionfs_readpage(struct file *file, struct page *page)
++{
++	BUG();
++	return -EINVAL;
++}
++
++static int unionfs_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
++{
++	int err;
++	struct file *file, *lower_file;
++	const struct vm_operations_struct *lower_vm_ops;
++	struct vm_area_struct lower_vma;
++
++	BUG_ON(!vma);
++	memcpy(&lower_vma, vma, sizeof(struct vm_area_struct));
++	file = lower_vma.vm_file;
++	lower_vm_ops = UNIONFS_F(file)->lower_vm_ops;
++	BUG_ON(!lower_vm_ops);
++
++	lower_file = unionfs_lower_file(file);
++	BUG_ON(!lower_file);
++	/*
++	 * XXX: vm_ops->fault may be called in parallel.  Because we have to
++	 * resort to temporarily changing the vma->vm_file to point to the
++	 * lower file, a concurrent invocation of unionfs_fault could see a
++	 * different value.  In this workaround, we keep a different copy of
++	 * the vma structure in our stack, so we never expose a different
++	 * value of the vma->vm_file called to us, even temporarily.  A
++	 * better fix would be to change the calling semantics of ->fault to
++	 * take an explicit file pointer.
++	 */
++	lower_vma.vm_file = lower_file;
++	err = lower_vm_ops->fault(&lower_vma, vmf);
++	return err;
++}
++
++/*
++ * XXX: the default address_space_ops for unionfs is empty.  We cannot set
++ * our inode->i_mapping->a_ops to NULL because too many code paths expect
++ * the a_ops vector to be non-NULL.
++ */
++struct address_space_operations unionfs_aops = {
++	/* empty on purpose */
++};
++
++/*
++ * XXX: we need a second, dummy address_space_ops vector, to be used
++ * temporarily during unionfs_mmap, because the latter calls
++ * generic_file_mmap, which checks if ->readpage exists, else returns
++ * -ENOEXEC.
++ */
++struct address_space_operations unionfs_dummy_aops = {
++	.readpage	= unionfs_readpage,
++};
++
++struct vm_operations_struct unionfs_vm_ops = {
++	.fault		= unionfs_fault,
++};
+diff --git a/fs/unionfs/rdstate.c b/fs/unionfs/rdstate.c
+new file mode 100644
+index 0000000..f745fbc
+--- /dev/null
++++ b/fs/unionfs/rdstate.c
+@@ -0,0 +1,285 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/* This file contains the routines for maintaining readdir state. */
++
++/*
++ * There are two structures here, rdstate which is a hash table
++ * of the second structure which is a filldir_node.
++ */
++
++/*
++ * This is a struct kmem_cache for filldir nodes, because we allocate a lot
++ * of them and they shouldn't waste memory.  If the node has a small name
++ * (as defined by the dentry structure), then we use an inline name to
++ * preserve kmalloc space.
++ */
++static struct kmem_cache *unionfs_filldir_cachep;
++
++int unionfs_init_filldir_cache(void)
++{
++	unionfs_filldir_cachep =
++		kmem_cache_create("unionfs_filldir",
++				  sizeof(struct filldir_node), 0,
++				  SLAB_RECLAIM_ACCOUNT, NULL);
++
++	return (unionfs_filldir_cachep ? 0 : -ENOMEM);
++}
++
++void unionfs_destroy_filldir_cache(void)
++{
++	if (unionfs_filldir_cachep)
++		kmem_cache_destroy(unionfs_filldir_cachep);
++}
++
++/*
++ * This is a tuning parameter that tells us roughly how big to make the
++ * hash table in directory entries per page.  This isn't perfect, but
++ * at least we get a hash table size that shouldn't be too overloaded.
++ * The following averages are based on my home directory.
++ * 14.44693	Overall
++ * 12.29	Single Page Directories
++ * 117.93	Multi-page directories
++ */
++#define DENTPAGE 4096
++#define DENTPERONEPAGE 12
++#define DENTPERPAGE 118
++#define MINHASHSIZE 1
++static int guesstimate_hash_size(struct inode *inode)
++{
++	struct inode *lower_inode;
++	int bindex;
++	int hashsize = MINHASHSIZE;
++
++	if (UNIONFS_I(inode)->hashsize > 0)
++		return UNIONFS_I(inode)->hashsize;
++
++	for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
++		lower_inode = unionfs_lower_inode_idx(inode, bindex);
++		if (!lower_inode)
++			continue;
++
++		if (i_size_read(lower_inode) == DENTPAGE)
++			hashsize += DENTPERONEPAGE;
++		else
++			hashsize += (i_size_read(lower_inode) / DENTPAGE) *
++				DENTPERPAGE;
++	}
++
++	return hashsize;
++}
++
++int init_rdstate(struct file *file)
++{
++	BUG_ON(sizeof(loff_t) !=
++	       (sizeof(unsigned int) + sizeof(unsigned int)));
++	BUG_ON(UNIONFS_F(file)->rdstate != NULL);
++
++	UNIONFS_F(file)->rdstate = alloc_rdstate(file->f_path.dentry->d_inode,
++						 fbstart(file));
++
++	return (UNIONFS_F(file)->rdstate ? 0 : -ENOMEM);
++}
++
++struct unionfs_dir_state *find_rdstate(struct inode *inode, loff_t fpos)
++{
++	struct unionfs_dir_state *rdstate = NULL;
++	struct list_head *pos;
++
++	spin_lock(&UNIONFS_I(inode)->rdlock);
++	list_for_each(pos, &UNIONFS_I(inode)->readdircache) {
++		struct unionfs_dir_state *r =
++			list_entry(pos, struct unionfs_dir_state, cache);
++		if (fpos == rdstate2offset(r)) {
++			UNIONFS_I(inode)->rdcount--;
++			list_del(&r->cache);
++			rdstate = r;
++			break;
++		}
++	}
++	spin_unlock(&UNIONFS_I(inode)->rdlock);
++	return rdstate;
++}
++
++struct unionfs_dir_state *alloc_rdstate(struct inode *inode, int bindex)
++{
++	int i = 0;
++	int hashsize;
++	unsigned long mallocsize = sizeof(struct unionfs_dir_state);
++	struct unionfs_dir_state *rdstate;
++
++	hashsize = guesstimate_hash_size(inode);
++	mallocsize += hashsize * sizeof(struct list_head);
++	mallocsize = __roundup_pow_of_two(mallocsize);
++
++	/* This should give us about 500 entries anyway. */
++	if (mallocsize > PAGE_SIZE)
++		mallocsize = PAGE_SIZE;
++
++	hashsize = (mallocsize - sizeof(struct unionfs_dir_state)) /
++		sizeof(struct list_head);
++
++	rdstate = kmalloc(mallocsize, GFP_KERNEL);
++	if (unlikely(!rdstate))
++		return NULL;
++
++	spin_lock(&UNIONFS_I(inode)->rdlock);
++	if (UNIONFS_I(inode)->cookie >= (MAXRDCOOKIE - 1))
++		UNIONFS_I(inode)->cookie = 1;
++	else
++		UNIONFS_I(inode)->cookie++;
++
++	rdstate->cookie = UNIONFS_I(inode)->cookie;
++	spin_unlock(&UNIONFS_I(inode)->rdlock);
++	rdstate->offset = 1;
++	rdstate->access = jiffies;
++	rdstate->bindex = bindex;
++	rdstate->dirpos = 0;
++	rdstate->hashentries = 0;
++	rdstate->size = hashsize;
++	for (i = 0; i < rdstate->size; i++)
++		INIT_LIST_HEAD(&rdstate->list[i]);
++
++	return rdstate;
++}
++
++static void free_filldir_node(struct filldir_node *node)
++{
++	if (node->namelen >= DNAME_INLINE_LEN_MIN)
++		kfree(node->name);
++	kmem_cache_free(unionfs_filldir_cachep, node);
++}
++
++void free_rdstate(struct unionfs_dir_state *state)
++{
++	struct filldir_node *tmp;
++	int i;
++
++	for (i = 0; i < state->size; i++) {
++		struct list_head *head = &(state->list[i]);
++		struct list_head *pos, *n;
++
++		/* traverse the list and deallocate space */
++		list_for_each_safe(pos, n, head) {
++			tmp = list_entry(pos, struct filldir_node, file_list);
++			list_del(&tmp->file_list);
++			free_filldir_node(tmp);
++		}
++	}
++
++	kfree(state);
++}
++
++struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate,
++				       const char *name, int namelen,
++				       int is_whiteout)
++{
++	int index;
++	unsigned int hash;
++	struct list_head *head;
++	struct list_head *pos;
++	struct filldir_node *cursor = NULL;
++	int found = 0;
++
++	BUG_ON(namelen <= 0);
++
++	hash = full_name_hash(name, namelen);
++	index = hash % rdstate->size;
++
++	head = &(rdstate->list[index]);
++	list_for_each(pos, head) {
++		cursor = list_entry(pos, struct filldir_node, file_list);
++
++		if (cursor->namelen == namelen && cursor->hash == hash &&
++		    !strncmp(cursor->name, name, namelen)) {
++			/*
++			 * a duplicate exists, and hence no need to create
++			 * entry to the list
++			 */
++			found = 1;
++
++			/*
++			 * if a duplicate is found in this branch, and is
++			 * not due to the caller looking for an entry to
++			 * whiteout, then the file system may be corrupted.
++			 */
++			if (unlikely(!is_whiteout &&
++				     cursor->bindex == rdstate->bindex))
++				printk(KERN_ERR "unionfs: filldir: possible "
++				       "I/O error: a file is duplicated "
++				       "in the same branch %d: %s\n",
++				       rdstate->bindex, cursor->name);
++			break;
++		}
++	}
++
++	if (!found)
++		cursor = NULL;
++
++	return cursor;
++}
++
++int add_filldir_node(struct unionfs_dir_state *rdstate, const char *name,
++		     int namelen, int bindex, int whiteout)
++{
++	struct filldir_node *new;
++	unsigned int hash;
++	int index;
++	int err = 0;
++	struct list_head *head;
++
++	BUG_ON(namelen <= 0);
++
++	hash = full_name_hash(name, namelen);
++	index = hash % rdstate->size;
++	head = &(rdstate->list[index]);
++
++	new = kmem_cache_alloc(unionfs_filldir_cachep, GFP_KERNEL);
++	if (unlikely(!new)) {
++		err = -ENOMEM;
++		goto out;
++	}
++
++	INIT_LIST_HEAD(&new->file_list);
++	new->namelen = namelen;
++	new->hash = hash;
++	new->bindex = bindex;
++	new->whiteout = whiteout;
++
++	if (namelen < DNAME_INLINE_LEN_MIN) {
++		new->name = new->iname;
++	} else {
++		new->name = kmalloc(namelen + 1, GFP_KERNEL);
++		if (unlikely(!new->name)) {
++			kmem_cache_free(unionfs_filldir_cachep, new);
++			new = NULL;
++			goto out;
++		}
++	}
++
++	memcpy(new->name, name, namelen);
++	new->name[namelen] = '\0';
++
++	rdstate->hashentries++;
++
++	list_add(&(new->file_list), head);
++out:
++	return err;
++}
+diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c
+new file mode 100644
+index 0000000..936700e
+--- /dev/null
++++ b/fs/unionfs/rename.c
+@@ -0,0 +1,517 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/*
++ * This is a helper function for rename, used when rename ends up with hosed
++ * over dentries and we need to revert.
++ */
++static int unionfs_refresh_lower_dentry(struct dentry *dentry,
++					struct dentry *parent, int bindex)
++{
++	struct dentry *lower_dentry;
++	struct dentry *lower_parent;
++	int err = 0;
++
++	verify_locked(dentry);
++
++	lower_parent = unionfs_lower_dentry_idx(parent, bindex);
++
++	BUG_ON(!S_ISDIR(lower_parent->d_inode->i_mode));
++
++	lower_dentry = lookup_one_len(dentry->d_name.name, lower_parent,
++				      dentry->d_name.len);
++	if (IS_ERR(lower_dentry)) {
++		err = PTR_ERR(lower_dentry);
++		goto out;
++	}
++
++	dput(unionfs_lower_dentry_idx(dentry, bindex));
++	iput(unionfs_lower_inode_idx(dentry->d_inode, bindex));
++	unionfs_set_lower_inode_idx(dentry->d_inode, bindex, NULL);
++
++	if (!lower_dentry->d_inode) {
++		dput(lower_dentry);
++		unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
++	} else {
++		unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry);
++		unionfs_set_lower_inode_idx(dentry->d_inode, bindex,
++					    igrab(lower_dentry->d_inode));
++	}
++
++out:
++	return err;
++}
++
++static int __unionfs_rename(struct inode *old_dir, struct dentry *old_dentry,
++			    struct dentry *old_parent,
++			    struct inode *new_dir, struct dentry *new_dentry,
++			    struct dentry *new_parent,
++			    int bindex)
++{
++	int err = 0;
++	struct dentry *lower_old_dentry;
++	struct dentry *lower_new_dentry;
++	struct dentry *lower_old_dir_dentry;
++	struct dentry *lower_new_dir_dentry;
++	struct dentry *trap;
++
++	lower_new_dentry = unionfs_lower_dentry_idx(new_dentry, bindex);
++	lower_old_dentry = unionfs_lower_dentry_idx(old_dentry, bindex);
++
++	if (!lower_new_dentry) {
++		lower_new_dentry =
++			create_parents(new_parent->d_inode,
++				       new_dentry, new_dentry->d_name.name,
++				       bindex);
++		if (IS_ERR(lower_new_dentry)) {
++			err = PTR_ERR(lower_new_dentry);
++			if (IS_COPYUP_ERR(err))
++				goto out;
++			printk(KERN_ERR "unionfs: error creating directory "
++			       "tree for rename, bindex=%d err=%d\n",
++			       bindex, err);
++			goto out;
++		}
++	}
++
++	/* check for and remove whiteout, if any */
++	err = check_unlink_whiteout(new_dentry, lower_new_dentry, bindex);
++	if (err > 0) /* ignore if whiteout found and successfully removed */
++		err = 0;
++	if (err)
++		goto out;
++
++	/* check of old_dentry branch is writable */
++	err = is_robranch_super(old_dentry->d_sb, bindex);
++	if (err)
++		goto out;
++
++	dget(lower_old_dentry);
++	dget(lower_new_dentry);
++	lower_old_dir_dentry = dget_parent(lower_old_dentry);
++	lower_new_dir_dentry = dget_parent(lower_new_dentry);
++
++	trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
++	/* source should not be ancenstor of target */
++	if (trap == lower_old_dentry) {
++		err = -EINVAL;
++		goto out_err_unlock;
++	}
++	/* target should not be ancenstor of source */
++	if (trap == lower_new_dentry) {
++		err = -ENOTEMPTY;
++		goto out_err_unlock;
++	}
++	err = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
++			 lower_new_dir_dentry->d_inode, lower_new_dentry);
++out_err_unlock:
++	if (!err) {
++		/* update parent dir times */
++		fsstack_copy_attr_times(old_dir, lower_old_dir_dentry->d_inode);
++		fsstack_copy_attr_times(new_dir, lower_new_dir_dentry->d_inode);
++	}
++	unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
++
++	dput(lower_old_dir_dentry);
++	dput(lower_new_dir_dentry);
++	dput(lower_old_dentry);
++	dput(lower_new_dentry);
++
++out:
++	if (!err) {
++		/* Fixup the new_dentry. */
++		if (bindex < dbstart(new_dentry))
++			dbstart(new_dentry) = bindex;
++		else if (bindex > dbend(new_dentry))
++			dbend(new_dentry) = bindex;
++	}
++
++	return err;
++}
++
++/*
++ * Main rename code.  This is sufficiently complex, that it's documented in
++ * Documentation/filesystems/unionfs/rename.txt.  This routine calls
++ * __unionfs_rename() above to perform some of the work.
++ */
++static int do_unionfs_rename(struct inode *old_dir,
++			     struct dentry *old_dentry,
++			     struct dentry *old_parent,
++			     struct inode *new_dir,
++			     struct dentry *new_dentry,
++			     struct dentry *new_parent)
++{
++	int err = 0;
++	int bindex;
++	int old_bstart, old_bend;
++	int new_bstart, new_bend;
++	int do_copyup = -1;
++	int local_err = 0;
++	int eio = 0;
++	int revert = 0;
++
++	old_bstart = dbstart(old_dentry);
++	old_bend = dbend(old_dentry);
++
++	new_bstart = dbstart(new_dentry);
++	new_bend = dbend(new_dentry);
++
++	/* Rename source to destination. */
++	err = __unionfs_rename(old_dir, old_dentry, old_parent,
++			       new_dir, new_dentry, new_parent,
++			       old_bstart);
++	if (err) {
++		if (!IS_COPYUP_ERR(err))
++			goto out;
++		do_copyup = old_bstart - 1;
++	} else {
++		revert = 1;
++	}
++
++	/*
++	 * Unlink all instances of destination that exist to the left of
++	 * bstart of source. On error, revert back, goto out.
++	 */
++	for (bindex = old_bstart - 1; bindex >= new_bstart; bindex--) {
++		struct dentry *unlink_dentry;
++		struct dentry *unlink_dir_dentry;
++
++		BUG_ON(bindex < 0);
++		unlink_dentry = unionfs_lower_dentry_idx(new_dentry, bindex);
++		if (!unlink_dentry)
++			continue;
++
++		unlink_dir_dentry = lock_parent(unlink_dentry);
++		err = is_robranch_super(old_dir->i_sb, bindex);
++		if (!err)
++			err = vfs_unlink(unlink_dir_dentry->d_inode,
++					 unlink_dentry);
++
++		fsstack_copy_attr_times(new_parent->d_inode,
++					unlink_dir_dentry->d_inode);
++		/* propagate number of hard-links */
++		new_parent->d_inode->i_nlink =
++			unionfs_get_nlinks(new_parent->d_inode);
++
++		unlock_dir(unlink_dir_dentry);
++		if (!err) {
++			if (bindex != new_bstart) {
++				dput(unlink_dentry);
++				unionfs_set_lower_dentry_idx(new_dentry,
++							     bindex, NULL);
++			}
++		} else if (IS_COPYUP_ERR(err)) {
++			do_copyup = bindex - 1;
++		} else if (revert) {
++			goto revert;
++		}
++	}
++
++	if (do_copyup != -1) {
++		for (bindex = do_copyup; bindex >= 0; bindex--) {
++			/*
++			 * copyup the file into some left directory, so that
++			 * you can rename it
++			 */
++			err = copyup_dentry(old_parent->d_inode,
++					    old_dentry, old_bstart, bindex,
++					    old_dentry->d_name.name,
++					    old_dentry->d_name.len, NULL,
++					    i_size_read(old_dentry->d_inode));
++			/* if copyup failed, try next branch to the left */
++			if (err)
++				continue;
++			/*
++			 * create whiteout before calling __unionfs_rename
++			 * because the latter will change the old_dentry's
++			 * lower name and parent dir, resulting in the
++			 * whiteout getting created in the wrong dir.
++			 */
++			err = create_whiteout(old_dentry, bindex);
++			if (err) {
++				printk(KERN_ERR "unionfs: can't create a "
++				       "whiteout for %s in rename (err=%d)\n",
++				       old_dentry->d_name.name, err);
++				continue;
++			}
++			err = __unionfs_rename(old_dir, old_dentry, old_parent,
++					       new_dir, new_dentry, new_parent,
++					       bindex);
++			break;
++		}
++	}
++
++	/* make it opaque */
++	if (S_ISDIR(old_dentry->d_inode->i_mode)) {
++		err = make_dir_opaque(old_dentry, dbstart(old_dentry));
++		if (err)
++			goto revert;
++	}
++
++	/*
++	 * Create whiteout for source, only if:
++	 * (1) There is more than one underlying instance of source.
++	 * (We did a copy_up is taken care of above).
++	 */
++	if ((old_bstart != old_bend) && (do_copyup == -1)) {
++		err = create_whiteout(old_dentry, old_bstart);
++		if (err) {
++			/* can't fix anything now, so we exit with -EIO */
++			printk(KERN_ERR "unionfs: can't create a whiteout for "
++			       "%s in rename!\n", old_dentry->d_name.name);
++			err = -EIO;
++		}
++	}
++
++out:
++	return err;
++
++revert:
++	/* Do revert here. */
++	local_err = unionfs_refresh_lower_dentry(new_dentry, new_parent,
++						 old_bstart);
++	if (local_err) {
++		printk(KERN_ERR "unionfs: revert failed in rename: "
++		       "the new refresh failed\n");
++		eio = -EIO;
++	}
++
++	local_err = unionfs_refresh_lower_dentry(old_dentry, old_parent,
++						 old_bstart);
++	if (local_err) {
++		printk(KERN_ERR "unionfs: revert failed in rename: "
++		       "the old refresh failed\n");
++		eio = -EIO;
++		goto revert_out;
++	}
++
++	if (!unionfs_lower_dentry_idx(new_dentry, bindex) ||
++	    !unionfs_lower_dentry_idx(new_dentry, bindex)->d_inode) {
++		printk(KERN_ERR "unionfs: revert failed in rename: "
++		       "the object disappeared from under us!\n");
++		eio = -EIO;
++		goto revert_out;
++	}
++
++	if (unionfs_lower_dentry_idx(old_dentry, bindex) &&
++	    unionfs_lower_dentry_idx(old_dentry, bindex)->d_inode) {
++		printk(KERN_ERR "unionfs: revert failed in rename: "
++		       "the object was created underneath us!\n");
++		eio = -EIO;
++		goto revert_out;
++	}
++
++	local_err = __unionfs_rename(new_dir, new_dentry, new_parent,
++				     old_dir, old_dentry, old_parent,
++				     old_bstart);
++
++	/* If we can't fix it, then we cop-out with -EIO. */
++	if (local_err) {
++		printk(KERN_ERR "unionfs: revert failed in rename!\n");
++		eio = -EIO;
++	}
++
++	local_err = unionfs_refresh_lower_dentry(new_dentry, new_parent,
++						 bindex);
++	if (local_err)
++		eio = -EIO;
++	local_err = unionfs_refresh_lower_dentry(old_dentry, old_parent,
++						 bindex);
++	if (local_err)
++		eio = -EIO;
++
++revert_out:
++	if (eio)
++		err = eio;
++	return err;
++}
++
++/*
++ * We can't copyup a directory, because it may involve huge numbers of
++ * children, etc.  Doing that in the kernel would be bad, so instead we
++ * return EXDEV to the user-space utility that caused this, and let the
++ * user-space recurse and ask us to copy up each file separately.
++ */
++static int may_rename_dir(struct dentry *dentry, struct dentry *parent)
++{
++	int err, bstart;
++
++	err = check_empty(dentry, parent, NULL);
++	if (err == -ENOTEMPTY) {
++		if (is_robranch(dentry))
++			return -EXDEV;
++	} else if (err) {
++		return err;
++	}
++
++	bstart = dbstart(dentry);
++	if (dbend(dentry) == bstart || dbopaque(dentry) == bstart)
++		return 0;
++
++	dbstart(dentry) = bstart + 1;
++	err = check_empty(dentry, parent, NULL);
++	dbstart(dentry) = bstart;
++	if (err == -ENOTEMPTY)
++		err = -EXDEV;
++	return err;
++}
++
++/*
++ * The locking rules in unionfs_rename are complex.  We could use a simpler
++ * superblock-level name-space lock for renames and copy-ups.
++ */
++int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry,
++		   struct inode *new_dir, struct dentry *new_dentry)
++{
++	int err = 0;
++	struct dentry *wh_dentry;
++	struct dentry *old_parent, *new_parent;
++	int valid = true;
++
++	unionfs_read_lock(old_dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	old_parent = dget_parent(old_dentry);
++	new_parent = dget_parent(new_dentry);
++	/* un/lock parent dentries only if they differ from old/new_dentry */
++	if (old_parent != old_dentry &&
++	    old_parent != new_dentry)
++		unionfs_lock_dentry(old_parent, UNIONFS_DMUTEX_REVAL_PARENT);
++	if (new_parent != old_dentry &&
++	    new_parent != new_dentry &&
++	    new_parent != old_parent)
++		unionfs_lock_dentry(new_parent, UNIONFS_DMUTEX_REVAL_CHILD);
++	unionfs_double_lock_dentry(old_dentry, new_dentry);
++
++	valid = __unionfs_d_revalidate(old_dentry, old_parent, false);
++	if (!valid) {
++		err = -ESTALE;
++		goto out;
++	}
++	if (!d_deleted(new_dentry) && new_dentry->d_inode) {
++		valid = __unionfs_d_revalidate(new_dentry, new_parent, false);
++		if (!valid) {
++			err = -ESTALE;
++			goto out;
++		}
++	}
++
++	if (!S_ISDIR(old_dentry->d_inode->i_mode))
++		err = unionfs_partial_lookup(old_dentry, old_parent);
++	else
++		err = may_rename_dir(old_dentry, old_parent);
++
++	if (err)
++		goto out;
++
++	err = unionfs_partial_lookup(new_dentry, new_parent);
++	if (err)
++		goto out;
++
++	/*
++	 * if new_dentry is already lower because of whiteout,
++	 * simply override it even if the whited-out dir is not empty.
++	 */
++	wh_dentry = find_first_whiteout(new_dentry);
++	if (!IS_ERR(wh_dentry)) {
++		dput(wh_dentry);
++	} else if (new_dentry->d_inode) {
++		if (S_ISDIR(old_dentry->d_inode->i_mode) !=
++		    S_ISDIR(new_dentry->d_inode->i_mode)) {
++			err = S_ISDIR(old_dentry->d_inode->i_mode) ?
++				-ENOTDIR : -EISDIR;
++			goto out;
++		}
++
++		if (S_ISDIR(new_dentry->d_inode->i_mode)) {
++			struct unionfs_dir_state *namelist = NULL;
++			/* check if this unionfs directory is empty or not */
++			err = check_empty(new_dentry, new_parent, &namelist);
++			if (err)
++				goto out;
++
++			if (!is_robranch(new_dentry))
++				err = delete_whiteouts(new_dentry,
++						       dbstart(new_dentry),
++						       namelist);
++
++			free_rdstate(namelist);
++
++			if (err)
++				goto out;
++		}
++	}
++
++	err = do_unionfs_rename(old_dir, old_dentry, old_parent,
++				new_dir, new_dentry, new_parent);
++	if (err)
++		goto out;
++
++	/*
++	 * force re-lookup since the dir on ro branch is not renamed, and
++	 * lower dentries still indicate the un-renamed ones.
++	 */
++	if (S_ISDIR(old_dentry->d_inode->i_mode))
++		atomic_dec(&UNIONFS_D(old_dentry)->generation);
++	else
++		unionfs_postcopyup_release(old_dentry);
++	if (new_dentry->d_inode && !S_ISDIR(new_dentry->d_inode->i_mode)) {
++		unionfs_postcopyup_release(new_dentry);
++		unionfs_postcopyup_setmnt(new_dentry);
++		if (!unionfs_lower_inode(new_dentry->d_inode)) {
++			/*
++			 * If we get here, it means that no copyup was
++			 * needed, and that a file by the old name already
++			 * existing on the destination branch; that file got
++			 * renamed earlier in this function, so all we need
++			 * to do here is set the lower inode.
++			 */
++			struct inode *inode;
++			inode = unionfs_lower_inode(old_dentry->d_inode);
++			igrab(inode);
++			unionfs_set_lower_inode_idx(new_dentry->d_inode,
++						    dbstart(new_dentry),
++						    inode);
++		}
++	}
++	/* if all of this renaming succeeded, update our times */
++	unionfs_copy_attr_times(old_dentry->d_inode);
++	unionfs_copy_attr_times(new_dentry->d_inode);
++	unionfs_check_inode(old_dir);
++	unionfs_check_inode(new_dir);
++	unionfs_check_dentry(old_dentry);
++	unionfs_check_dentry(new_dentry);
++
++out:
++	if (err)		/* clear the new_dentry stuff created */
++		d_drop(new_dentry);
++
++	unionfs_double_unlock_dentry(old_dentry, new_dentry);
++	if (new_parent != old_dentry &&
++	    new_parent != new_dentry &&
++	    new_parent != old_parent)
++		unionfs_unlock_dentry(new_parent);
++	if (old_parent != old_dentry &&
++	    old_parent != new_dentry)
++		unionfs_unlock_dentry(old_parent);
++	dput(new_parent);
++	dput(old_parent);
++	unionfs_read_unlock(old_dentry->d_sb);
++
++	return err;
++}
+diff --git a/fs/unionfs/sioq.c b/fs/unionfs/sioq.c
+new file mode 100644
+index 0000000..760c580
+--- /dev/null
++++ b/fs/unionfs/sioq.c
+@@ -0,0 +1,101 @@
++/*
++ * Copyright (c) 2006-2010 Erez Zadok
++ * Copyright (c) 2006      Charles P. Wright
++ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2006      Junjiro Okajima
++ * Copyright (c) 2006      David P. Quigley
++ * Copyright (c) 2006-2010 Stony Brook University
++ * Copyright (c) 2006-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/*
++ * Super-user IO work Queue - sometimes we need to perform actions which
++ * would fail due to the unix permissions on the parent directory (e.g.,
++ * rmdir a directory which appears empty, but in reality contains
++ * whiteouts).
++ */
++
++static struct workqueue_struct *superio_workqueue;
++
++int __init init_sioq(void)
++{
++	int err;
++
++	superio_workqueue = create_workqueue("unionfs_siod");
++	if (!IS_ERR(superio_workqueue))
++		return 0;
++
++	err = PTR_ERR(superio_workqueue);
++	printk(KERN_ERR "unionfs: create_workqueue failed %d\n", err);
++	superio_workqueue = NULL;
++	return err;
++}
++
++void stop_sioq(void)
++{
++	if (superio_workqueue)
++		destroy_workqueue(superio_workqueue);
++}
++
++void run_sioq(work_func_t func, struct sioq_args *args)
++{
++	INIT_WORK(&args->work, func);
++
++	init_completion(&args->comp);
++	while (!queue_work(superio_workqueue, &args->work)) {
++		/* TODO: do accounting if needed */
++		schedule();
++	}
++	wait_for_completion(&args->comp);
++}
++
++void __unionfs_create(struct work_struct *work)
++{
++	struct sioq_args *args = container_of(work, struct sioq_args, work);
++	struct create_args *c = &args->create;
++
++	args->err = vfs_create(c->parent, c->dentry, c->mode, c->nd);
++	complete(&args->comp);
++}
++
++void __unionfs_mkdir(struct work_struct *work)
++{
++	struct sioq_args *args = container_of(work, struct sioq_args, work);
++	struct mkdir_args *m = &args->mkdir;
++
++	args->err = vfs_mkdir(m->parent, m->dentry, m->mode);
++	complete(&args->comp);
++}
++
++void __unionfs_mknod(struct work_struct *work)
++{
++	struct sioq_args *args = container_of(work, struct sioq_args, work);
++	struct mknod_args *m = &args->mknod;
++
++	args->err = vfs_mknod(m->parent, m->dentry, m->mode, m->dev);
++	complete(&args->comp);
++}
++
++void __unionfs_symlink(struct work_struct *work)
++{
++	struct sioq_args *args = container_of(work, struct sioq_args, work);
++	struct symlink_args *s = &args->symlink;
++
++	args->err = vfs_symlink(s->parent, s->dentry, s->symbuf);
++	complete(&args->comp);
++}
++
++void __unionfs_unlink(struct work_struct *work)
++{
++	struct sioq_args *args = container_of(work, struct sioq_args, work);
++	struct unlink_args *u = &args->unlink;
++
++	args->err = vfs_unlink(u->parent, u->dentry);
++	complete(&args->comp);
++}
+diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h
+new file mode 100644
+index 0000000..b26d248
+--- /dev/null
++++ b/fs/unionfs/sioq.h
+@@ -0,0 +1,91 @@
++/*
++ * Copyright (c) 2006-2010 Erez Zadok
++ * Copyright (c) 2006      Charles P. Wright
++ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2006      Junjiro Okajima
++ * Copyright (c) 2006      David P. Quigley
++ * Copyright (c) 2006-2010 Stony Brook University
++ * Copyright (c) 2006-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef _SIOQ_H
++#define _SIOQ_H
++
++struct deletewh_args {
++	struct unionfs_dir_state *namelist;
++	struct dentry *dentry;
++	int bindex;
++};
++
++struct is_opaque_args {
++	struct dentry *dentry;
++};
++
++struct create_args {
++	struct inode *parent;
++	struct dentry *dentry;
++	umode_t mode;
++	struct nameidata *nd;
++};
++
++struct mkdir_args {
++	struct inode *parent;
++	struct dentry *dentry;
++	umode_t mode;
++};
++
++struct mknod_args {
++	struct inode *parent;
++	struct dentry *dentry;
++	umode_t mode;
++	dev_t dev;
++};
++
++struct symlink_args {
++	struct inode *parent;
++	struct dentry *dentry;
++	char *symbuf;
++};
++
++struct unlink_args {
++	struct inode *parent;
++	struct dentry *dentry;
++};
++
++
++struct sioq_args {
++	struct completion comp;
++	struct work_struct work;
++	int err;
++	void *ret;
++
++	union {
++		struct deletewh_args deletewh;
++		struct is_opaque_args is_opaque;
++		struct create_args create;
++		struct mkdir_args mkdir;
++		struct mknod_args mknod;
++		struct symlink_args symlink;
++		struct unlink_args unlink;
++	};
++};
++
++/* Extern definitions for SIOQ functions */
++extern int __init init_sioq(void);
++extern void stop_sioq(void);
++extern void run_sioq(work_func_t func, struct sioq_args *args);
++
++/* Extern definitions for our privilege escalation helpers */
++extern void __unionfs_create(struct work_struct *work);
++extern void __unionfs_mkdir(struct work_struct *work);
++extern void __unionfs_mknod(struct work_struct *work);
++extern void __unionfs_symlink(struct work_struct *work);
++extern void __unionfs_unlink(struct work_struct *work);
++extern void __delete_whiteouts(struct work_struct *work);
++extern void __is_opaque_dir(struct work_struct *work);
++
++#endif /* not _SIOQ_H */
+diff --git a/fs/unionfs/subr.c b/fs/unionfs/subr.c
+new file mode 100644
+index 0000000..570a344
+--- /dev/null
++++ b/fs/unionfs/subr.c
+@@ -0,0 +1,95 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/*
++ * returns the right n_link value based on the inode type
++ */
++int unionfs_get_nlinks(const struct inode *inode)
++{
++	/* don't bother to do all the work since we're unlinked */
++	if (inode->i_nlink == 0)
++		return 0;
++
++	if (!S_ISDIR(inode->i_mode))
++		return unionfs_lower_inode(inode)->i_nlink;
++
++	/*
++	 * For directories, we return 1. The only place that could cares
++	 * about links is readdir, and there's d_type there so even that
++	 * doesn't matter.
++	 */
++	return 1;
++}
++
++/* copy a/m/ctime from the lower branch with the newest times */
++void unionfs_copy_attr_times(struct inode *upper)
++{
++	int bindex;
++	struct inode *lower;
++
++	if (!upper)
++		return;
++	if (ibstart(upper) < 0) {
++#ifdef CONFIG_UNION_FS_DEBUG
++		WARN_ON(ibstart(upper) < 0);
++#endif /* CONFIG_UNION_FS_DEBUG */
++		return;
++	}
++	for (bindex = ibstart(upper); bindex <= ibend(upper); bindex++) {
++		lower = unionfs_lower_inode_idx(upper, bindex);
++		if (!lower)
++			continue; /* not all lower dir objects may exist */
++		if (unlikely(timespec_compare(&upper->i_mtime,
++					      &lower->i_mtime) < 0))
++			upper->i_mtime = lower->i_mtime;
++		if (unlikely(timespec_compare(&upper->i_ctime,
++					      &lower->i_ctime) < 0))
++			upper->i_ctime = lower->i_ctime;
++		if (unlikely(timespec_compare(&upper->i_atime,
++					      &lower->i_atime) < 0))
++			upper->i_atime = lower->i_atime;
++	}
++}
++
++/*
++ * A unionfs/fanout version of fsstack_copy_attr_all.  Uses a
++ * unionfs_get_nlinks to properly calcluate the number of links to a file.
++ * Also, copies the max() of all a/m/ctimes for all lower inodes (which is
++ * important if the lower inode is a directory type)
++ */
++void unionfs_copy_attr_all(struct inode *dest,
++			   const struct inode *src)
++{
++	dest->i_mode = src->i_mode;
++	dest->i_uid = src->i_uid;
++	dest->i_gid = src->i_gid;
++	dest->i_rdev = src->i_rdev;
++
++	unionfs_copy_attr_times(dest);
++
++	dest->i_blkbits = src->i_blkbits;
++	dest->i_flags = src->i_flags;
++
++	/*
++	 * Update the nlinks AFTER updating the above fields, because the
++	 * get_links callback may depend on them.
++	 */
++	dest->i_nlink = unionfs_get_nlinks(dest);
++}
+diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c
+new file mode 100644
+index 0000000..a8f5571
+--- /dev/null
++++ b/fs/unionfs/super.c
+@@ -0,0 +1,1048 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/*
++ * The inode cache is used with alloc_inode for both our inode info and the
++ * vfs inode.
++ */
++static struct kmem_cache *unionfs_inode_cachep;
++
++struct inode *unionfs_iget(struct super_block *sb, unsigned long ino)
++{
++	int size;
++	struct unionfs_inode_info *info;
++	struct inode *inode;
++
++	inode = iget_locked(sb, ino);
++	if (!inode)
++		return ERR_PTR(-ENOMEM);
++	if (!(inode->i_state & I_NEW))
++		return inode;
++
++	info = UNIONFS_I(inode);
++	memset(info, 0, offsetof(struct unionfs_inode_info, vfs_inode));
++	info->bstart = -1;
++	info->bend = -1;
++	atomic_set(&info->generation,
++		   atomic_read(&UNIONFS_SB(inode->i_sb)->generation));
++	spin_lock_init(&info->rdlock);
++	info->rdcount = 1;
++	info->hashsize = -1;
++	INIT_LIST_HEAD(&info->readdircache);
++
++	size = sbmax(inode->i_sb) * sizeof(struct inode *);
++	info->lower_inodes = kzalloc(size, GFP_KERNEL);
++	if (unlikely(!info->lower_inodes)) {
++		printk(KERN_CRIT "unionfs: no kernel memory when allocating "
++		       "lower-pointer array!\n");
++		iget_failed(inode);
++		return ERR_PTR(-ENOMEM);
++	}
++
++	inode->i_version++;
++	inode->i_op = &unionfs_main_iops;
++	inode->i_fop = &unionfs_main_fops;
++
++	inode->i_mapping->a_ops = &unionfs_aops;
++
++	/*
++	 * reset times so unionfs_copy_attr_all can keep out time invariants
++	 * right (upper inode time being the max of all lower ones).
++	 */
++	inode->i_atime.tv_sec = inode->i_atime.tv_nsec = 0;
++	inode->i_mtime.tv_sec = inode->i_mtime.tv_nsec = 0;
++	inode->i_ctime.tv_sec = inode->i_ctime.tv_nsec = 0;
++	unlock_new_inode(inode);
++	return inode;
++}
++
++/*
++ * we now define delete_inode, because there are two VFS paths that may
++ * destroy an inode: one of them calls clear inode before doing everything
++ * else that's needed, and the other is fine.  This way we truncate the inode
++ * size (and its pages) and then clear our own inode, which will do an iput
++ * on our and the lower inode.
++ *
++ * No need to lock sb info's rwsem.
++ */
++static void unionfs_delete_inode(struct inode *inode)
++{
++#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
++	spin_lock(&inode->i_lock);
++#endif
++	i_size_write(inode, 0);	/* every f/s seems to do that */
++#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
++	spin_unlock(&inode->i_lock);
++#endif
++
++	if (inode->i_data.nrpages)
++		truncate_inode_pages(&inode->i_data, 0);
++
++	clear_inode(inode);
++}
++
++/*
++ * final actions when unmounting a file system
++ *
++ * No need to lock rwsem.
++ */
++static void unionfs_put_super(struct super_block *sb)
++{
++	int bindex, bstart, bend;
++	struct unionfs_sb_info *spd;
++	int leaks = 0;
++
++	spd = UNIONFS_SB(sb);
++	if (!spd)
++		return;
++
++	bstart = sbstart(sb);
++	bend = sbend(sb);
++
++	/* Make sure we have no leaks of branchget/branchput. */
++	for (bindex = bstart; bindex <= bend; bindex++)
++		if (unlikely(branch_count(sb, bindex) != 0)) {
++			printk(KERN_CRIT
++			       "unionfs: branch %d has %d references left!\n",
++			       bindex, branch_count(sb, bindex));
++			leaks = 1;
++		}
++	WARN_ON(leaks != 0);
++
++	/* decrement lower super references */
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		struct super_block *s;
++		s = unionfs_lower_super_idx(sb, bindex);
++		unionfs_set_lower_super_idx(sb, bindex, NULL);
++		atomic_dec(&s->s_active);
++	}
++
++	kfree(spd->dev_name);
++	kfree(spd->data);
++	kfree(spd);
++	sb->s_fs_info = NULL;
++}
++
++/*
++ * Since people use this to answer the "How big of a file can I write?"
++ * question, we report the size of the highest priority branch as the size of
++ * the union.
++ */
++static int unionfs_statfs(struct dentry *dentry, struct kstatfs *buf)
++{
++	int err	= 0;
++	struct super_block *sb;
++	struct dentry *lower_dentry;
++	struct dentry *parent;
++	bool valid;
++
++	sb = dentry->d_sb;
++
++	unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;
++		goto out;
++	}
++	unionfs_check_dentry(dentry);
++
++	lower_dentry = unionfs_lower_dentry(sb->s_root);
++	err = vfs_statfs(lower_dentry, buf);
++
++	/* set return buf to our f/s to avoid confusing user-level utils */
++	buf->f_type = UNIONFS_SUPER_MAGIC;
++	/*
++	 * Our maximum file name can is shorter by a few bytes because every
++	 * file name could potentially be whited-out.
++	 *
++	 * XXX: this restriction goes away with ODF.
++	 */
++	unionfs_set_max_namelen(&buf->f_namelen);
++
++	/*
++	 * reset two fields to avoid confusing user-land.
++	 * XXX: is this still necessary?
++	 */
++	memset(&buf->f_fsid, 0, sizeof(__kernel_fsid_t));
++	memset(&buf->f_spare, 0, sizeof(buf->f_spare));
++
++out:
++	unionfs_check_dentry(dentry);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(sb);
++	return err;
++}
++
++/* handle mode changing during remount */
++static noinline_for_stack int do_remount_mode_option(
++					char *optarg,
++					int cur_branches,
++					struct unionfs_data *new_data,
++					struct path *new_lower_paths)
++{
++	int err = -EINVAL;
++	int perms, idx;
++	char *modename = strchr(optarg, '=');
++	struct nameidata nd;
++
++	/* by now, optarg contains the branch name */
++	if (!*optarg) {
++		printk(KERN_ERR
++		       "unionfs: no branch specified for mode change\n");
++		goto out;
++	}
++	if (!modename) {
++		printk(KERN_ERR "unionfs: branch \"%s\" requires a mode\n",
++		       optarg);
++		goto out;
++	}
++	*modename++ = '\0';
++	err = parse_branch_mode(modename, &perms);
++	if (err) {
++		printk(KERN_ERR "unionfs: invalid mode \"%s\" for \"%s\"\n",
++		       modename, optarg);
++		goto out;
++	}
++
++	/*
++	 * Find matching branch index.  For now, this assumes that nothing
++	 * has been mounted on top of this Unionfs stack.  Once we have /odf
++	 * and cache-coherency resolved, we'll address the branch-path
++	 * uniqueness.
++	 */
++	err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
++	if (err) {
++		printk(KERN_ERR "unionfs: error accessing "
++		       "lower directory \"%s\" (error %d)\n",
++		       optarg, err);
++		goto out;
++	}
++	for (idx = 0; idx < cur_branches; idx++)
++		if (nd.path.mnt == new_lower_paths[idx].mnt &&
++		    nd.path.dentry == new_lower_paths[idx].dentry)
++			break;
++	path_put(&nd.path);	/* no longer needed */
++	if (idx == cur_branches) {
++		err = -ENOENT;	/* err may have been reset above */
++		printk(KERN_ERR "unionfs: branch \"%s\" "
++		       "not found\n", optarg);
++		goto out;
++	}
++	/* check/change mode for existing branch */
++	/* we don't warn if perms==branchperms */
++	new_data[idx].branchperms = perms;
++	err = 0;
++out:
++	return err;
++}
++
++/* handle branch deletion during remount */
++static noinline_for_stack int do_remount_del_option(
++					char *optarg, int cur_branches,
++					struct unionfs_data *new_data,
++					struct path *new_lower_paths)
++{
++	int err = -EINVAL;
++	int idx;
++	struct nameidata nd;
++
++	/* optarg contains the branch name to delete */
++
++	/*
++	 * Find matching branch index.  For now, this assumes that nothing
++	 * has been mounted on top of this Unionfs stack.  Once we have /odf
++	 * and cache-coherency resolved, we'll address the branch-path
++	 * uniqueness.
++	 */
++	err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
++	if (err) {
++		printk(KERN_ERR "unionfs: error accessing "
++		       "lower directory \"%s\" (error %d)\n",
++		       optarg, err);
++		goto out;
++	}
++	for (idx = 0; idx < cur_branches; idx++)
++		if (nd.path.mnt == new_lower_paths[idx].mnt &&
++		    nd.path.dentry == new_lower_paths[idx].dentry)
++			break;
++	path_put(&nd.path);	/* no longer needed */
++	if (idx == cur_branches) {
++		printk(KERN_ERR "unionfs: branch \"%s\" "
++		       "not found\n", optarg);
++		err = -ENOENT;
++		goto out;
++	}
++	/* check if there are any open files on the branch to be deleted */
++	if (atomic_read(&new_data[idx].open_files) > 0) {
++		err = -EBUSY;
++		goto out;
++	}
++
++	/*
++	 * Now we have to delete the branch.  First, release any handles it
++	 * has.  Then, move the remaining array indexes past "idx" in
++	 * new_data and new_lower_paths one to the left.  Finally, adjust
++	 * cur_branches.
++	 */
++	path_put(&new_lower_paths[idx]);
++
++	if (idx < cur_branches - 1) {
++		/* if idx==cur_branches-1, we delete last branch: easy */
++		memmove(&new_data[idx], &new_data[idx+1],
++			(cur_branches - 1 - idx) *
++			sizeof(struct unionfs_data));
++		memmove(&new_lower_paths[idx], &new_lower_paths[idx+1],
++			(cur_branches - 1 - idx) * sizeof(struct path));
++	}
++
++	err = 0;
++out:
++	return err;
++}
++
++/* handle branch insertion during remount */
++static noinline_for_stack int do_remount_add_option(
++					char *optarg, int cur_branches,
++					struct unionfs_data *new_data,
++					struct path *new_lower_paths,
++					int *high_branch_id)
++{
++	int err = -EINVAL;
++	int perms;
++	int idx = 0;		/* default: insert at beginning */
++	char *new_branch , *modename = NULL;
++	struct nameidata nd;
++
++	/*
++	 * optarg can be of several forms:
++	 *
++	 * /bar:/foo		insert /foo before /bar
++	 * /bar:/foo=ro		insert /foo in ro mode before /bar
++	 * /foo			insert /foo in the beginning (prepend)
++	 * :/foo		insert /foo at the end (append)
++	 */
++	if (*optarg == ':') {	/* append? */
++		new_branch = optarg + 1; /* skip ':' */
++		idx = cur_branches;
++		goto found_insertion_point;
++	}
++	new_branch = strchr(optarg, ':');
++	if (!new_branch) {	/* prepend? */
++		new_branch = optarg;
++		goto found_insertion_point;
++	}
++	*new_branch++ = '\0';	/* holds path+mode of new branch */
++
++	/*
++	 * Find matching branch index.  For now, this assumes that nothing
++	 * has been mounted on top of this Unionfs stack.  Once we have /odf
++	 * and cache-coherency resolved, we'll address the branch-path
++	 * uniqueness.
++	 */
++	err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
++	if (err) {
++		printk(KERN_ERR "unionfs: error accessing "
++		       "lower directory \"%s\" (error %d)\n",
++		       optarg, err);
++		goto out;
++	}
++	for (idx = 0; idx < cur_branches; idx++)
++		if (nd.path.mnt == new_lower_paths[idx].mnt &&
++		    nd.path.dentry == new_lower_paths[idx].dentry)
++			break;
++	path_put(&nd.path);	/* no longer needed */
++	if (idx == cur_branches) {
++		printk(KERN_ERR "unionfs: branch \"%s\" "
++		       "not found\n", optarg);
++		err = -ENOENT;
++		goto out;
++	}
++
++	/*
++	 * At this point idx will hold the index where the new branch should
++	 * be inserted before.
++	 */
++found_insertion_point:
++	/* find the mode for the new branch */
++	if (new_branch)
++		modename = strchr(new_branch, '=');
++	if (modename)
++		*modename++ = '\0';
++	if (!new_branch || !*new_branch) {
++		printk(KERN_ERR "unionfs: null new branch\n");
++		err = -EINVAL;
++		goto out;
++	}
++	err = parse_branch_mode(modename, &perms);
++	if (err) {
++		printk(KERN_ERR "unionfs: invalid mode \"%s\" for "
++		       "branch \"%s\"\n", modename, new_branch);
++		goto out;
++	}
++	err = path_lookup(new_branch, LOOKUP_FOLLOW, &nd);
++	if (err) {
++		printk(KERN_ERR "unionfs: error accessing "
++		       "lower directory \"%s\" (error %d)\n",
++		       new_branch, err);
++		goto out;
++	}
++	/*
++	 * It's probably safe to check_mode the new branch to insert.  Note:
++	 * we don't allow inserting branches which are unionfs's by
++	 * themselves (check_branch returns EINVAL in that case).  This is
++	 * because this code base doesn't support stacking unionfs: the ODF
++	 * code base supports that correctly.
++	 */
++	err = check_branch(&nd);
++	if (err) {
++		printk(KERN_ERR "unionfs: lower directory "
++		       "\"%s\" is not a valid branch\n", optarg);
++		path_put(&nd.path);
++		goto out;
++	}
++
++	/*
++	 * Now we have to insert the new branch.  But first, move the bits
++	 * to make space for the new branch, if needed.  Finally, adjust
++	 * cur_branches.
++	 * We don't release nd here; it's kept until umount/remount.
++	 */
++	if (idx < cur_branches) {
++		/* if idx==cur_branches, we append: easy */
++		memmove(&new_data[idx+1], &new_data[idx],
++			(cur_branches - idx) * sizeof(struct unionfs_data));
++		memmove(&new_lower_paths[idx+1], &new_lower_paths[idx],
++			(cur_branches - idx) * sizeof(struct path));
++	}
++	new_lower_paths[idx].dentry = nd.path.dentry;
++	new_lower_paths[idx].mnt = nd.path.mnt;
++
++	new_data[idx].sb = nd.path.dentry->d_sb;
++	atomic_set(&new_data[idx].open_files, 0);
++	new_data[idx].branchperms = perms;
++	new_data[idx].branch_id = ++*high_branch_id; /* assign new branch ID */
++
++	err = 0;
++out:
++	return err;
++}
++
++
++/*
++ * Support branch management options on remount.
++ *
++ * See Documentation/filesystems/unionfs/ for details.
++ *
++ * @flags: numeric mount options
++ * @options: mount options string
++ *
++ * This function can rearrange a mounted union dynamically, adding and
++ * removing branches, including changing branch modes.  Clearly this has to
++ * be done safely and atomically.  Luckily, the VFS already calls this
++ * function with lock_super(sb) and lock_kernel() held, preventing
++ * concurrent mixing of new mounts, remounts, and unmounts.  Moreover,
++ * do_remount_sb(), our caller function, already called shrink_dcache_sb(sb)
++ * to purge dentries/inodes from our superblock, and also called
++ * fsync_super(sb) to purge any dirty pages.  So we're good.
++ *
++ * XXX: however, our remount code may also need to invalidate mapped pages
++ * so as to force them to be re-gotten from the (newly reconfigured) lower
++ * branches.  This has to wait for proper mmap and cache coherency support
++ * in the VFS.
++ *
++ */
++static int unionfs_remount_fs(struct super_block *sb, int *flags,
++			      char *options)
++{
++	int err = 0;
++	int i;
++	char *optionstmp, *tmp_to_free;	/* kstrdup'ed of "options" */
++	char *optname;
++	int cur_branches = 0;	/* no. of current branches */
++	int new_branches = 0;	/* no. of branches actually left in the end */
++	int add_branches;	/* est. no. of branches to add */
++	int del_branches;	/* est. no. of branches to del */
++	int max_branches;	/* max possible no. of branches */
++	struct unionfs_data *new_data = NULL, *tmp_data = NULL;
++	struct path *new_lower_paths = NULL, *tmp_lower_paths = NULL;
++	struct inode **new_lower_inodes = NULL;
++	int new_high_branch_id;	/* new high branch ID */
++	int size;		/* memory allocation size, temp var */
++	int old_ibstart, old_ibend;
++
++	unionfs_write_lock(sb);
++
++	/*
++	 * The VFS will take care of "ro" and "rw" flags, and we can safely
++	 * ignore MS_SILENT, but anything else left over is an error.  So we
++	 * need to check if any other flags may have been passed (none are
++	 * allowed/supported as of now).
++	 */
++	if ((*flags & ~(MS_RDONLY | MS_SILENT)) != 0) {
++		printk(KERN_ERR
++		       "unionfs: remount flags 0x%x unsupported\n", *flags);
++		err = -EINVAL;
++		goto out_error;
++	}
++
++	/*
++	 * If 'options' is NULL, it's probably because the user just changed
++	 * the union to a "ro" or "rw" and the VFS took care of it.  So
++	 * nothing to do and we're done.
++	 */
++	if (!options || options[0] == '\0')
++		goto out_error;
++
++	/*
++	 * Find out how many branches we will have in the end, counting
++	 * "add" and "del" commands.  Copy the "options" string because
++	 * strsep modifies the string and we need it later.
++	 */
++	tmp_to_free = kstrdup(options, GFP_KERNEL);
++	optionstmp = tmp_to_free;
++	if (unlikely(!optionstmp)) {
++		err = -ENOMEM;
++		goto out_free;
++	}
++	cur_branches = sbmax(sb); /* current no. branches */
++	new_branches = sbmax(sb);
++	del_branches = 0;
++	add_branches = 0;
++	new_high_branch_id = sbhbid(sb); /* save current high_branch_id */
++	while ((optname = strsep(&optionstmp, ",")) != NULL) {
++		char *optarg;
++
++		if (!optname || !*optname)
++			continue;
++
++		optarg = strchr(optname, '=');
++		if (optarg)
++			*optarg++ = '\0';
++
++		if (!strcmp("add", optname))
++			add_branches++;
++		else if (!strcmp("del", optname))
++			del_branches++;
++	}
++	kfree(tmp_to_free);
++	/* after all changes, will we have at least one branch left? */
++	if ((new_branches + add_branches - del_branches) < 1) {
++		printk(KERN_ERR
++		       "unionfs: no branches left after remount\n");
++		err = -EINVAL;
++		goto out_free;
++	}
++
++	/*
++	 * Since we haven't actually parsed all the add/del options, nor
++	 * have we checked them for errors, we don't know for sure how many
++	 * branches we will have after all changes have taken place.  In
++	 * fact, the total number of branches left could be less than what
++	 * we have now.  So we need to allocate space for a temporary
++	 * placeholder that is at least as large as the maximum number of
++	 * branches we *could* have, which is the current number plus all
++	 * the additions.  Once we're done with these temp placeholders, we
++	 * may have to re-allocate the final size, copy over from the temp,
++	 * and then free the temps (done near the end of this function).
++	 */
++	max_branches = cur_branches + add_branches;
++	/* allocate space for new pointers to lower dentry */
++	tmp_data = kcalloc(max_branches,
++			   sizeof(struct unionfs_data), GFP_KERNEL);
++	if (unlikely(!tmp_data)) {
++		err = -ENOMEM;
++		goto out_free;
++	}
++	/* allocate space for new pointers to lower paths */
++	tmp_lower_paths = kcalloc(max_branches,
++				  sizeof(struct path), GFP_KERNEL);
++	if (unlikely(!tmp_lower_paths)) {
++		err = -ENOMEM;
++		goto out_free;
++	}
++	/* copy current info into new placeholders, incrementing refcnts */
++	memcpy(tmp_data, UNIONFS_SB(sb)->data,
++	       cur_branches * sizeof(struct unionfs_data));
++	memcpy(tmp_lower_paths, UNIONFS_D(sb->s_root)->lower_paths,
++	       cur_branches * sizeof(struct path));
++	for (i = 0; i < cur_branches; i++)
++		path_get(&tmp_lower_paths[i]); /* drop refs at end of fxn */
++
++	/*******************************************************************
++	 * For each branch command, do path_lookup on the requested branch,
++	 * and apply the change to a temp branch list.  To handle errors, we
++	 * already dup'ed the old arrays (above), and increased the refcnts
++	 * on various f/s objects.  So now we can do all the path_lookups
++	 * and branch-management commands on the new arrays.  If it fail mid
++	 * way, we free the tmp arrays and *put all objects.  If we succeed,
++	 * then we free old arrays and *put its objects, and then replace
++	 * the arrays with the new tmp list (we may have to re-allocate the
++	 * memory because the temp lists could have been larger than what we
++	 * actually needed).
++	 *******************************************************************/
++
++	while ((optname = strsep(&options, ",")) != NULL) {
++		char *optarg;
++
++		if (!optname || !*optname)
++			continue;
++		/*
++		 * At this stage optname holds a comma-delimited option, but
++		 * without the commas.  Next, we need to break the string on
++		 * the '=' symbol to separate CMD=ARG, where ARG itself can
++		 * be KEY=VAL.  For example, in mode=/foo=rw, CMD is "mode",
++		 * KEY is "/foo", and VAL is "rw".
++		 */
++		optarg = strchr(optname, '=');
++		if (optarg)
++			*optarg++ = '\0';
++		/* incgen remount option (instead of old ioctl) */
++		if (!strcmp("incgen", optname)) {
++			err = 0;
++			goto out_no_change;
++		}
++
++		/*
++		 * All of our options take an argument now.  (Insert ones
++		 * that don't above this check.)  So at this stage optname
++		 * contains the CMD part and optarg contains the ARG part.
++		 */
++		if (!optarg || !*optarg) {
++			printk(KERN_ERR "unionfs: all remount options require "
++			       "an argument (%s)\n", optname);
++			err = -EINVAL;
++			goto out_release;
++		}
++
++		if (!strcmp("add", optname)) {
++			err = do_remount_add_option(optarg, new_branches,
++						    tmp_data,
++						    tmp_lower_paths,
++						    &new_high_branch_id);
++			if (err)
++				goto out_release;
++			new_branches++;
++			if (new_branches > UNIONFS_MAX_BRANCHES) {
++				printk(KERN_ERR "unionfs: command exceeds "
++				       "%d branches\n", UNIONFS_MAX_BRANCHES);
++				err = -E2BIG;
++				goto out_release;
++			}
++			continue;
++		}
++		if (!strcmp("del", optname)) {
++			err = do_remount_del_option(optarg, new_branches,
++						    tmp_data,
++						    tmp_lower_paths);
++			if (err)
++				goto out_release;
++			new_branches--;
++			continue;
++		}
++		if (!strcmp("mode", optname)) {
++			err = do_remount_mode_option(optarg, new_branches,
++						     tmp_data,
++						     tmp_lower_paths);
++			if (err)
++				goto out_release;
++			continue;
++		}
++
++		/*
++		 * When you use "mount -o remount,ro", mount(8) will
++		 * reportedly pass the original dirs= string from
++		 * /proc/mounts.  So for now, we have to ignore dirs= and
++		 * not consider it an error, unless we want to allow users
++		 * to pass dirs= in remount.  Note that to allow the VFS to
++		 * actually process the ro/rw remount options, we have to
++		 * return 0 from this function.
++		 */
++		if (!strcmp("dirs", optname)) {
++			printk(KERN_WARNING
++			       "unionfs: remount ignoring option \"%s\"\n",
++			       optname);
++			continue;
++		}
++
++		err = -EINVAL;
++		printk(KERN_ERR
++		       "unionfs: unrecognized option \"%s\"\n", optname);
++		goto out_release;
++	}
++
++out_no_change:
++
++	/******************************************************************
++	 * WE'RE ALMOST DONE: check if leftmost branch might be read-only,
++	 * see if we need to allocate a small-sized new vector, copy the
++	 * vectors to their correct place, release the refcnt of the older
++	 * ones, and return.  Also handle invalidating any pages that will
++	 * have to be re-read.
++	 *******************************************************************/
++
++	if (!(tmp_data[0].branchperms & MAY_WRITE)) {
++		printk(KERN_ERR "unionfs: leftmost branch cannot be read-only "
++		       "(use \"remount,ro\" to create a read-only union)\n");
++		err = -EINVAL;
++		goto out_release;
++	}
++
++	/* (re)allocate space for new pointers to lower dentry */
++	size = new_branches * sizeof(struct unionfs_data);
++	new_data = krealloc(tmp_data, size, GFP_KERNEL);
++	if (unlikely(!new_data)) {
++		err = -ENOMEM;
++		goto out_release;
++	}
++
++	/* allocate space for new pointers to lower paths */
++	size = new_branches * sizeof(struct path);
++	new_lower_paths = krealloc(tmp_lower_paths, size, GFP_KERNEL);
++	if (unlikely(!new_lower_paths)) {
++		err = -ENOMEM;
++		goto out_release;
++	}
++
++	/* allocate space for new pointers to lower inodes */
++	new_lower_inodes = kcalloc(new_branches,
++				   sizeof(struct inode *), GFP_KERNEL);
++	if (unlikely(!new_lower_inodes)) {
++		err = -ENOMEM;
++		goto out_release;
++	}
++
++	/*
++	 * OK, just before we actually put the new set of branches in place,
++	 * we need to ensure that our own f/s has no dirty objects left.
++	 * Luckily, do_remount_sb() already calls shrink_dcache_sb(sb) and
++	 * fsync_super(sb), taking care of dentries, inodes, and dirty
++	 * pages.  So all that's left is for us to invalidate any leftover
++	 * (non-dirty) pages to ensure that they will be re-read from the
++	 * new lower branches (and to support mmap).
++	 */
++
++	/*
++	 * Once we finish the remounting successfully, our superblock
++	 * generation number will have increased.  This will be detected by
++	 * our dentry-revalidation code upon subsequent f/s operations
++	 * through unionfs.  The revalidation code will rebuild the union of
++	 * lower inodes for a given unionfs inode and invalidate any pages
++	 * of such "stale" inodes (by calling our purge_inode_data
++	 * function).  This revalidation will happen lazily and
++	 * incrementally, as users perform operations on cached inodes.  We
++	 * would like to encourage this revalidation to happen sooner if
++	 * possible, so we like to try to invalidate as many other pages in
++	 * our superblock as we can.  We used to call drop_pagecache_sb() or
++	 * a variant thereof, but either method was racy (drop_caches alone
++	 * is known to be racy).  So now we let the revalidation happen on a
++	 * per file basis in ->d_revalidate.
++	 */
++
++	/* grab new lower super references; release old ones */
++	for (i = 0; i < new_branches; i++)
++		atomic_inc(&new_data[i].sb->s_active);
++	for (i = 0; i < sbmax(sb); i++)
++		atomic_dec(&UNIONFS_SB(sb)->data[i].sb->s_active);
++
++	/* copy new vectors into their correct place */
++	tmp_data = UNIONFS_SB(sb)->data;
++	UNIONFS_SB(sb)->data = new_data;
++	new_data = NULL;	/* so don't free good pointers below */
++	tmp_lower_paths = UNIONFS_D(sb->s_root)->lower_paths;
++	UNIONFS_D(sb->s_root)->lower_paths = new_lower_paths;
++	new_lower_paths = NULL;	/* so don't free good pointers below */
++
++	/* update our unionfs_sb_info and root dentry index of last branch */
++	i = sbmax(sb);		/* save no. of branches to release at end */
++	sbend(sb) = new_branches - 1;
++	dbend(sb->s_root) = new_branches - 1;
++	old_ibstart = ibstart(sb->s_root->d_inode);
++	old_ibend = ibend(sb->s_root->d_inode);
++	ibend(sb->s_root->d_inode) = new_branches - 1;
++	UNIONFS_D(sb->s_root)->bcount = new_branches;
++	new_branches = i; /* no. of branches to release below */
++
++	/*
++	 * Update lower inodes: 3 steps
++	 * 1. grab ref on all new lower inodes
++	 */
++	for (i = dbstart(sb->s_root); i <= dbend(sb->s_root); i++) {
++		struct dentry *lower_dentry =
++			unionfs_lower_dentry_idx(sb->s_root, i);
++		igrab(lower_dentry->d_inode);
++		new_lower_inodes[i] = lower_dentry->d_inode;
++	}
++	/* 2. release reference on all older lower inodes */
++	iput_lowers(sb->s_root->d_inode, old_ibstart, old_ibend, true);
++	/* 3. update root dentry's inode to new lower_inodes array */
++	UNIONFS_I(sb->s_root->d_inode)->lower_inodes = new_lower_inodes;
++	new_lower_inodes = NULL;
++
++	/* maxbytes may have changed */
++	sb->s_maxbytes = unionfs_lower_super_idx(sb, 0)->s_maxbytes;
++	/* update high branch ID */
++	sbhbid(sb) = new_high_branch_id;
++
++	/* update our sb->generation for revalidating objects */
++	i = atomic_inc_return(&UNIONFS_SB(sb)->generation);
++	atomic_set(&UNIONFS_D(sb->s_root)->generation, i);
++	atomic_set(&UNIONFS_I(sb->s_root->d_inode)->generation, i);
++	if (!(*flags & MS_SILENT))
++		pr_info("unionfs: %s: new generation number %d\n",
++			UNIONFS_SB(sb)->dev_name, i);
++	/* finally, update the root dentry's times */
++	unionfs_copy_attr_times(sb->s_root->d_inode);
++	err = 0;		/* reset to success */
++
++	/*
++	 * The code above falls through to the next label, and releases the
++	 * refcnts of the older ones (stored in tmp_*): if we fell through
++	 * here, it means success.  However, if we jump directly to this
++	 * label from any error above, then an error occurred after we
++	 * grabbed various refcnts, and so we have to release the
++	 * temporarily constructed structures.
++	 */
++out_release:
++	/* no need to cleanup/release anything in tmp_data */
++	if (tmp_lower_paths)
++		for (i = 0; i < new_branches; i++)
++			path_put(&tmp_lower_paths[i]);
++out_free:
++	kfree(tmp_lower_paths);
++	kfree(tmp_data);
++	kfree(new_lower_paths);
++	kfree(new_data);
++	kfree(new_lower_inodes);
++out_error:
++	unionfs_check_dentry(sb->s_root);
++	unionfs_write_unlock(sb);
++	return err;
++}
++
++/*
++ * Called by iput() when the inode reference count reached zero
++ * and the inode is not hashed anywhere.  Used to clear anything
++ * that needs to be, before the inode is completely destroyed and put
++ * on the inode free list.
++ *
++ * No need to lock sb info's rwsem.
++ */
++static void unionfs_clear_inode(struct inode *inode)
++{
++	int bindex, bstart, bend;
++	struct inode *lower_inode;
++	struct list_head *pos, *n;
++	struct unionfs_dir_state *rdstate;
++
++	list_for_each_safe(pos, n, &UNIONFS_I(inode)->readdircache) {
++		rdstate = list_entry(pos, struct unionfs_dir_state, cache);
++		list_del(&rdstate->cache);
++		free_rdstate(rdstate);
++	}
++
++	/*
++	 * Decrement a reference to a lower_inode, which was incremented
++	 * by our read_inode when it was created initially.
++	 */
++	bstart = ibstart(inode);
++	bend = ibend(inode);
++	if (bstart >= 0) {
++		for (bindex = bstart; bindex <= bend; bindex++) {
++			lower_inode = unionfs_lower_inode_idx(inode, bindex);
++			if (!lower_inode)
++				continue;
++			unionfs_set_lower_inode_idx(inode, bindex, NULL);
++			/* see Documentation/filesystems/unionfs/issues.txt */
++			lockdep_off();
++			iput(lower_inode);
++			lockdep_on();
++		}
++	}
++
++	kfree(UNIONFS_I(inode)->lower_inodes);
++	UNIONFS_I(inode)->lower_inodes = NULL;
++}
++
++static struct inode *unionfs_alloc_inode(struct super_block *sb)
++{
++	struct unionfs_inode_info *i;
++
++	i = kmem_cache_alloc(unionfs_inode_cachep, GFP_KERNEL);
++	if (unlikely(!i))
++		return NULL;
++
++	/* memset everything up to the inode to 0 */
++	memset(i, 0, offsetof(struct unionfs_inode_info, vfs_inode));
++
++	i->vfs_inode.i_version = 1;
++	return &i->vfs_inode;
++}
++
++static void unionfs_destroy_inode(struct inode *inode)
++{
++	kmem_cache_free(unionfs_inode_cachep, UNIONFS_I(inode));
++}
++
++/* unionfs inode cache constructor */
++static void init_once(void *obj)
++{
++	struct unionfs_inode_info *i = obj;
++
++	inode_init_once(&i->vfs_inode);
++}
++
++int unionfs_init_inode_cache(void)
++{
++	int err = 0;
++
++	unionfs_inode_cachep =
++		kmem_cache_create("unionfs_inode_cache",
++				  sizeof(struct unionfs_inode_info), 0,
++				  SLAB_RECLAIM_ACCOUNT, init_once);
++	if (unlikely(!unionfs_inode_cachep))
++		err = -ENOMEM;
++	return err;
++}
++
++/* unionfs inode cache destructor */
++void unionfs_destroy_inode_cache(void)
++{
++	if (unionfs_inode_cachep)
++		kmem_cache_destroy(unionfs_inode_cachep);
++}
++
++/*
++ * Called when we have a dirty inode, right here we only throw out
++ * parts of our readdir list that are too old.
++ *
++ * No need to grab sb info's rwsem.
++ */
++static int unionfs_write_inode(struct inode *inode,
++			       struct writeback_control *wbc)
++{
++	struct list_head *pos, *n;
++	struct unionfs_dir_state *rdstate;
++
++	spin_lock(&UNIONFS_I(inode)->rdlock);
++	list_for_each_safe(pos, n, &UNIONFS_I(inode)->readdircache) {
++		rdstate = list_entry(pos, struct unionfs_dir_state, cache);
++		/* We keep this list in LRU order. */
++		if ((rdstate->access + RDCACHE_JIFFIES) > jiffies)
++			break;
++		UNIONFS_I(inode)->rdcount--;
++		list_del(&rdstate->cache);
++		free_rdstate(rdstate);
++	}
++	spin_unlock(&UNIONFS_I(inode)->rdlock);
++
++	return 0;
++}
++
++/*
++ * Used only in nfs, to kill any pending RPC tasks, so that subsequent
++ * code can actually succeed and won't leave tasks that need handling.
++ */
++static void unionfs_umount_begin(struct super_block *sb)
++{
++	struct super_block *lower_sb;
++	int bindex, bstart, bend;
++
++	unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD);
++
++	bstart = sbstart(sb);
++	bend = sbend(sb);
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_sb = unionfs_lower_super_idx(sb, bindex);
++
++		if (lower_sb && lower_sb->s_op &&
++		    lower_sb->s_op->umount_begin)
++			lower_sb->s_op->umount_begin(lower_sb);
++	}
++
++	unionfs_read_unlock(sb);
++}
++
++static int unionfs_show_options(struct seq_file *m, struct vfsmount *mnt)
++{
++	struct super_block *sb = mnt->mnt_sb;
++	int ret = 0;
++	char *tmp_page;
++	char *path;
++	int bindex, bstart, bend;
++	int perms;
++
++	unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD);
++
++	unionfs_lock_dentry(sb->s_root, UNIONFS_DMUTEX_CHILD);
++
++	tmp_page = (char *) __get_free_page(GFP_KERNEL);
++	if (unlikely(!tmp_page)) {
++		ret = -ENOMEM;
++		goto out;
++	}
++
++	bstart = sbstart(sb);
++	bend = sbend(sb);
++
++	seq_printf(m, ",dirs=");
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		struct path p;
++		p.dentry = unionfs_lower_dentry_idx(sb->s_root, bindex);
++		p.mnt = unionfs_lower_mnt_idx(sb->s_root, bindex);
++		path = d_path(&p, tmp_page, PAGE_SIZE);
++		if (IS_ERR(path)) {
++			ret = PTR_ERR(path);
++			goto out;
++		}
++
++		perms = branchperms(sb, bindex);
++
++		seq_printf(m, "%s=%s", path,
++			   perms & MAY_WRITE ? "rw" : "ro");
++		if (bindex != bend)
++			seq_printf(m, ":");
++	}
++
++out:
++	free_page((unsigned long) tmp_page);
++
++	unionfs_unlock_dentry(sb->s_root);
++
++	unionfs_read_unlock(sb);
++
++	return ret;
++}
++
++struct super_operations unionfs_sops = {
++	.delete_inode	= unionfs_delete_inode,
++	.put_super	= unionfs_put_super,
++	.statfs		= unionfs_statfs,
++	.remount_fs	= unionfs_remount_fs,
++	.clear_inode	= unionfs_clear_inode,
++	.umount_begin	= unionfs_umount_begin,
++	.show_options	= unionfs_show_options,
++	.write_inode	= unionfs_write_inode,
++	.alloc_inode	= unionfs_alloc_inode,
++	.destroy_inode	= unionfs_destroy_inode,
++};
+diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
+new file mode 100644
+index 0000000..d49c834
+--- /dev/null
++++ b/fs/unionfs/union.h
+@@ -0,0 +1,669 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef _UNION_H_
++#define _UNION_H_
++
++#include <linux/dcache.h>
++#include <linux/file.h>
++#include <linux/list.h>
++#include <linux/fs.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/mount.h>
++#include <linux/namei.h>
++#include <linux/page-flags.h>
++#include <linux/pagemap.h>
++#include <linux/poll.h>
++#include <linux/security.h>
++#include <linux/seq_file.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/smp_lock.h>
++#include <linux/statfs.h>
++#include <linux/string.h>
++#include <linux/vmalloc.h>
++#include <linux/writeback.h>
++#include <linux/buffer_head.h>
++#include <linux/xattr.h>
++#include <linux/fs_stack.h>
++#include <linux/magic.h>
++#include <linux/log2.h>
++#include <linux/poison.h>
++#include <linux/mman.h>
++#include <linux/backing-dev.h>
++#include <linux/splice.h>
++
++#include <asm/system.h>
++
++#include <linux/union_fs.h>
++
++/* the file system name */
++#define UNIONFS_NAME "unionfs"
++
++/* unionfs root inode number */
++#define UNIONFS_ROOT_INO     1
++
++/* number of times we try to get a unique temporary file name */
++#define GET_TMPNAM_MAX_RETRY	5
++
++/* maximum number of branches we support, to avoid memory blowup */
++#define UNIONFS_MAX_BRANCHES	128
++
++/* minimum time (seconds) required for time-based cache-coherency */
++#define UNIONFS_MIN_CC_TIME	3
++
++/* Operations vectors defined in specific files. */
++extern struct file_operations unionfs_main_fops;
++extern struct file_operations unionfs_dir_fops;
++extern struct inode_operations unionfs_main_iops;
++extern struct inode_operations unionfs_dir_iops;
++extern struct inode_operations unionfs_symlink_iops;
++extern struct super_operations unionfs_sops;
++extern struct dentry_operations unionfs_dops;
++extern struct address_space_operations unionfs_aops, unionfs_dummy_aops;
++extern struct vm_operations_struct unionfs_vm_ops;
++
++/* How long should an entry be allowed to persist */
++#define RDCACHE_JIFFIES	(5*HZ)
++
++/* compatibility with Real-Time patches */
++#ifdef CONFIG_PREEMPT_RT
++# define unionfs_rw_semaphore	compat_rw_semaphore
++#else /* not CONFIG_PREEMPT_RT */
++# define unionfs_rw_semaphore	rw_semaphore
++#endif /* not CONFIG_PREEMPT_RT */
++
++/* file private data. */
++struct unionfs_file_info {
++	int bstart;
++	int bend;
++	atomic_t generation;
++
++	struct unionfs_dir_state *rdstate;
++	struct file **lower_files;
++	int *saved_branch_ids; /* IDs of branches when file was opened */
++	const struct vm_operations_struct *lower_vm_ops;
++	bool wrote_to_file;	/* for delayed copyup */
++};
++
++/* unionfs inode data in memory */
++struct unionfs_inode_info {
++	int bstart;
++	int bend;
++	atomic_t generation;
++	/* Stuff for readdir over NFS. */
++	spinlock_t rdlock;
++	struct list_head readdircache;
++	int rdcount;
++	int hashsize;
++	int cookie;
++
++	/* The lower inodes */
++	struct inode **lower_inodes;
++
++	struct inode vfs_inode;
++};
++
++/* unionfs dentry data in memory */
++struct unionfs_dentry_info {
++	/*
++	 * The semaphore is used to lock the dentry as soon as we get into a
++	 * unionfs function from the VFS.  Our lock ordering is that children
++	 * go before their parents.
++	 */
++	struct mutex lock;
++	int bstart;
++	int bend;
++	int bopaque;
++	int bcount;
++	atomic_t generation;
++	struct path *lower_paths;
++};
++
++/* These are the pointers to our various objects. */
++struct unionfs_data {
++	struct super_block *sb;	/* lower super_block */
++	atomic_t open_files;	/* number of open files on branch */
++	int branchperms;
++	int branch_id;		/* unique branch ID at re/mount time */
++};
++
++/* unionfs super-block data in memory */
++struct unionfs_sb_info {
++	int bend;
++
++	atomic_t generation;
++
++	/*
++	 * This rwsem is used to make sure that a branch management
++	 * operation...
++	 *   1) will not begin before all currently in-flight operations
++	 *      complete.
++	 *   2) any new operations do not execute until the currently
++	 *      running branch management operation completes.
++	 *
++	 * The write_lock_owner records the PID of the task which grabbed
++	 * the rw_sem for writing.  If the same task also tries to grab the
++	 * read lock, we allow it.  This prevents a self-deadlock when
++	 * branch-management is used on a pivot_root'ed union, because we
++	 * have to ->lookup paths which belong to the same union.
++	 */
++	struct unionfs_rw_semaphore rwsem;
++	pid_t write_lock_owner;	/* PID of rw_sem owner (write lock) */
++	int high_branch_id;	/* last unique branch ID given */
++	char *dev_name;		/* to identify different unions in pr_debug */
++	struct unionfs_data *data;
++};
++
++/*
++ * structure for making the linked list of entries by readdir on left branch
++ * to compare with entries on right branch
++ */
++struct filldir_node {
++	struct list_head file_list;	/* list for directory entries */
++	char *name;		/* name entry */
++	int hash;		/* name hash */
++	int namelen;		/* name len since name is not 0 terminated */
++
++	/*
++	 * we can check for duplicate whiteouts and files in the same branch
++	 * in order to return -EIO.
++	 */
++	int bindex;
++
++	/* is this a whiteout entry? */
++	int whiteout;
++
++	/* Inline name, so we don't need to separately kmalloc small ones */
++	char iname[DNAME_INLINE_LEN_MIN];
++};
++
++/* Directory hash table. */
++struct unionfs_dir_state {
++	unsigned int cookie;	/* the cookie, based off of rdversion */
++	unsigned int offset;	/* The entry we have returned. */
++	int bindex;
++	loff_t dirpos;		/* offset within the lower level directory */
++	int size;		/* How big is the hash table? */
++	int hashentries;	/* How many entries have been inserted? */
++	unsigned long access;
++
++	/* This cache list is used when the inode keeps us around. */
++	struct list_head cache;
++	struct list_head list[0];
++};
++
++/* externs needed for fanout.h or sioq.h */
++extern int unionfs_get_nlinks(const struct inode *inode);
++extern void unionfs_copy_attr_times(struct inode *upper);
++extern void unionfs_copy_attr_all(struct inode *dest, const struct inode *src);
++
++/* include miscellaneous macros */
++#include "fanout.h"
++#include "sioq.h"
++
++/* externs for cache creation/deletion routines */
++extern void unionfs_destroy_filldir_cache(void);
++extern int unionfs_init_filldir_cache(void);
++extern int unionfs_init_inode_cache(void);
++extern void unionfs_destroy_inode_cache(void);
++extern int unionfs_init_dentry_cache(void);
++extern void unionfs_destroy_dentry_cache(void);
++
++/* Initialize and free readdir-specific  state. */
++extern int init_rdstate(struct file *file);
++extern struct unionfs_dir_state *alloc_rdstate(struct inode *inode,
++					       int bindex);
++extern struct unionfs_dir_state *find_rdstate(struct inode *inode,
++					      loff_t fpos);
++extern void free_rdstate(struct unionfs_dir_state *state);
++extern int add_filldir_node(struct unionfs_dir_state *rdstate,
++			    const char *name, int namelen, int bindex,
++			    int whiteout);
++extern struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate,
++					      const char *name, int namelen,
++					      int is_whiteout);
++
++extern struct dentry **alloc_new_dentries(int objs);
++extern struct unionfs_data *alloc_new_data(int objs);
++
++/* We can only use 32-bits of offset for rdstate --- blech! */
++#define DIREOF (0xfffff)
++#define RDOFFBITS 20		/* This is the number of bits in DIREOF. */
++#define MAXRDCOOKIE (0xfff)
++/* Turn an rdstate into an offset. */
++static inline off_t rdstate2offset(struct unionfs_dir_state *buf)
++{
++	off_t tmp;
++
++	tmp = ((buf->cookie & MAXRDCOOKIE) << RDOFFBITS)
++		| (buf->offset & DIREOF);
++	return tmp;
++}
++
++/* Macros for locking a super_block. */
++enum unionfs_super_lock_class {
++	UNIONFS_SMUTEX_NORMAL,
++	UNIONFS_SMUTEX_PARENT,	/* when locking on behalf of file */
++	UNIONFS_SMUTEX_CHILD,	/* when locking on behalf of dentry */
++};
++static inline void unionfs_read_lock(struct super_block *sb, int subclass)
++{
++	if (UNIONFS_SB(sb)->write_lock_owner &&
++	    UNIONFS_SB(sb)->write_lock_owner == current->pid)
++		return;
++	down_read_nested(&UNIONFS_SB(sb)->rwsem, subclass);
++}
++static inline void unionfs_read_unlock(struct super_block *sb)
++{
++	if (UNIONFS_SB(sb)->write_lock_owner &&
++	    UNIONFS_SB(sb)->write_lock_owner == current->pid)
++		return;
++	up_read(&UNIONFS_SB(sb)->rwsem);
++}
++static inline void unionfs_write_lock(struct super_block *sb)
++{
++	down_write(&UNIONFS_SB(sb)->rwsem);
++	UNIONFS_SB(sb)->write_lock_owner = current->pid;
++}
++static inline void unionfs_write_unlock(struct super_block *sb)
++{
++	up_write(&UNIONFS_SB(sb)->rwsem);
++	UNIONFS_SB(sb)->write_lock_owner = 0;
++}
++
++static inline void unionfs_double_lock_dentry(struct dentry *d1,
++					      struct dentry *d2)
++{
++	BUG_ON(d1 == d2);
++	if (d1 < d2) {
++		unionfs_lock_dentry(d1, UNIONFS_DMUTEX_PARENT);
++		unionfs_lock_dentry(d2, UNIONFS_DMUTEX_CHILD);
++	} else {
++		unionfs_lock_dentry(d2, UNIONFS_DMUTEX_PARENT);
++		unionfs_lock_dentry(d1, UNIONFS_DMUTEX_CHILD);
++	}
++}
++
++static inline void unionfs_double_unlock_dentry(struct dentry *d1,
++						struct dentry *d2)
++{
++	BUG_ON(d1 == d2);
++	if (d1 < d2) { /* unlock in reverse order than double_lock_dentry */
++		unionfs_unlock_dentry(d1);
++		unionfs_unlock_dentry(d2);
++	} else {
++		unionfs_unlock_dentry(d2);
++		unionfs_unlock_dentry(d1);
++	}
++}
++
++static inline void unionfs_double_lock_parents(struct dentry *p1,
++					       struct dentry *p2)
++{
++	if (p1 == p2) {
++		unionfs_lock_dentry(p1, UNIONFS_DMUTEX_REVAL_PARENT);
++		return;
++	}
++	if (p1 < p2) {
++		unionfs_lock_dentry(p1, UNIONFS_DMUTEX_REVAL_PARENT);
++		unionfs_lock_dentry(p2, UNIONFS_DMUTEX_REVAL_CHILD);
++	} else {
++		unionfs_lock_dentry(p2, UNIONFS_DMUTEX_REVAL_PARENT);
++		unionfs_lock_dentry(p1, UNIONFS_DMUTEX_REVAL_CHILD);
++	}
++}
++
++static inline void unionfs_double_unlock_parents(struct dentry *p1,
++						 struct dentry *p2)
++{
++	if (p1 == p2) {
++		unionfs_unlock_dentry(p1);
++		return;
++	}
++	if (p1 < p2) { /* unlock in reverse order of double_lock_parents */
++		unionfs_unlock_dentry(p1);
++		unionfs_unlock_dentry(p2);
++	} else {
++		unionfs_unlock_dentry(p2);
++		unionfs_unlock_dentry(p1);
++	}
++}
++
++extern int new_dentry_private_data(struct dentry *dentry, int subclass);
++extern int realloc_dentry_private_data(struct dentry *dentry);
++extern void free_dentry_private_data(struct dentry *dentry);
++extern void update_bstart(struct dentry *dentry);
++extern int init_lower_nd(struct nameidata *nd, unsigned int flags);
++extern void release_lower_nd(struct nameidata *nd, int err);
++
++/*
++ * EXTERNALS:
++ */
++
++/* replicates the directory structure up to given dentry in given branch */
++extern struct dentry *create_parents(struct inode *dir, struct dentry *dentry,
++				     const char *name, int bindex);
++
++/* partial lookup */
++extern int unionfs_partial_lookup(struct dentry *dentry,
++				  struct dentry *parent);
++extern struct dentry *unionfs_lookup_full(struct dentry *dentry,
++					  struct dentry *parent,
++					  int lookupmode);
++
++/* copies a file from dbstart to newbindex branch */
++extern int copyup_file(struct inode *dir, struct file *file, int bstart,
++		       int newbindex, loff_t size);
++extern int copyup_named_file(struct inode *dir, struct file *file,
++			     char *name, int bstart, int new_bindex,
++			     loff_t len);
++/* copies a dentry from dbstart to newbindex branch */
++extern int copyup_dentry(struct inode *dir, struct dentry *dentry,
++			 int bstart, int new_bindex, const char *name,
++			 int namelen, struct file **copyup_file, loff_t len);
++/* helper functions for post-copyup actions */
++extern void unionfs_postcopyup_setmnt(struct dentry *dentry);
++extern void unionfs_postcopyup_release(struct dentry *dentry);
++
++/* Is this directory empty: 0 if it is empty, -ENOTEMPTY if not. */
++extern int check_empty(struct dentry *dentry, struct dentry *parent,
++		       struct unionfs_dir_state **namelist);
++/* whiteout and opaque directory helpers */
++extern char *alloc_whname(const char *name, int len);
++extern bool is_whiteout_name(char **namep, int *namelenp);
++extern bool is_validname(const char *name);
++extern struct dentry *lookup_whiteout(const char *name,
++				      struct dentry *lower_parent);
++extern struct dentry *find_first_whiteout(struct dentry *dentry);
++extern int unlink_whiteout(struct dentry *wh_dentry);
++extern int check_unlink_whiteout(struct dentry *dentry,
++				 struct dentry *lower_dentry, int bindex);
++extern int create_whiteout(struct dentry *dentry, int start);
++extern int delete_whiteouts(struct dentry *dentry, int bindex,
++			    struct unionfs_dir_state *namelist);
++extern int is_opaque_dir(struct dentry *dentry, int bindex);
++extern int make_dir_opaque(struct dentry *dir, int bindex);
++extern void unionfs_set_max_namelen(long *namelen);
++
++extern void unionfs_reinterpose(struct dentry *this_dentry);
++extern struct super_block *unionfs_duplicate_super(struct super_block *sb);
++
++/* Locking functions. */
++extern int unionfs_setlk(struct file *file, int cmd, struct file_lock *fl);
++extern int unionfs_getlk(struct file *file, struct file_lock *fl);
++
++/* Common file operations. */
++extern int unionfs_file_revalidate(struct file *file, struct dentry *parent,
++				   bool willwrite);
++extern int unionfs_open(struct inode *inode, struct file *file);
++extern int unionfs_file_release(struct inode *inode, struct file *file);
++extern int unionfs_flush(struct file *file, fl_owner_t id);
++extern long unionfs_ioctl(struct file *file, unsigned int cmd,
++			  unsigned long arg);
++extern int unionfs_fsync(struct file *file, int datasync);
++extern int unionfs_fasync(int fd, struct file *file, int flag);
++
++/* Inode operations */
++extern struct inode *unionfs_iget(struct super_block *sb, unsigned long ino);
++extern int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry,
++			  struct inode *new_dir, struct dentry *new_dentry);
++extern int unionfs_unlink(struct inode *dir, struct dentry *dentry);
++extern int unionfs_rmdir(struct inode *dir, struct dentry *dentry);
++
++extern bool __unionfs_d_revalidate(struct dentry *dentry,
++				   struct dentry *parent, bool willwrite);
++extern bool is_negative_lower(const struct dentry *dentry);
++extern bool is_newer_lower(const struct dentry *dentry);
++extern void purge_sb_data(struct super_block *sb);
++
++/* The values for unionfs_interpose's flag. */
++#define INTERPOSE_DEFAULT	0
++#define INTERPOSE_LOOKUP	1
++#define INTERPOSE_REVAL		2
++#define INTERPOSE_REVAL_NEG	3
++#define INTERPOSE_PARTIAL	4
++
++extern struct dentry *unionfs_interpose(struct dentry *this_dentry,
++					struct super_block *sb, int flag);
++
++#ifdef CONFIG_UNION_FS_XATTR
++/* Extended attribute functions. */
++extern void *unionfs_xattr_alloc(size_t size, size_t limit);
++static inline void unionfs_xattr_kfree(const void *p)
++{
++	kfree(p);
++}
++extern ssize_t unionfs_getxattr(struct dentry *dentry, const char *name,
++				void *value, size_t size);
++extern int unionfs_removexattr(struct dentry *dentry, const char *name);
++extern ssize_t unionfs_listxattr(struct dentry *dentry, char *list,
++				 size_t size);
++extern int unionfs_setxattr(struct dentry *dentry, const char *name,
++			    const void *value, size_t size, int flags);
++#endif /* CONFIG_UNION_FS_XATTR */
++
++/* The root directory is unhashed, but isn't deleted. */
++static inline int d_deleted(struct dentry *d)
++{
++	return d_unhashed(d) && (d != d->d_sb->s_root);
++}
++
++/* unionfs_permission, check if we should bypass error to facilitate copyup */
++#define IS_COPYUP_ERR(err) ((err) == -EROFS)
++
++/* unionfs_open, check if we need to copyup the file */
++#define OPEN_WRITE_FLAGS (O_WRONLY | O_RDWR | O_APPEND)
++#define IS_WRITE_FLAG(flag) ((flag) & OPEN_WRITE_FLAGS)
++
++static inline int branchperms(const struct super_block *sb, int index)
++{
++	BUG_ON(index < 0);
++	return UNIONFS_SB(sb)->data[index].branchperms;
++}
++
++static inline int set_branchperms(struct super_block *sb, int index, int perms)
++{
++	BUG_ON(index < 0);
++	UNIONFS_SB(sb)->data[index].branchperms = perms;
++	return perms;
++}
++
++/* check if readonly lower inode, but possibly unlinked (no inode->i_sb) */
++static inline int __is_rdonly(const struct inode *inode)
++{
++	/* if unlinked, can't be readonly (?) */
++	if (!inode->i_sb)
++		return 0;
++	return IS_RDONLY(inode);
++
++}
++/* Is this file on a read-only branch? */
++static inline int is_robranch_super(const struct super_block *sb, int index)
++{
++	int ret;
++
++	ret = (!(branchperms(sb, index) & MAY_WRITE)) ? -EROFS : 0;
++	return ret;
++}
++
++/* Is this file on a read-only branch? */
++static inline int is_robranch_idx(const struct dentry *dentry, int index)
++{
++	struct super_block *lower_sb;
++
++	BUG_ON(index < 0);
++
++	if (!(branchperms(dentry->d_sb, index) & MAY_WRITE))
++		return -EROFS;
++
++	lower_sb = unionfs_lower_super_idx(dentry->d_sb, index);
++	BUG_ON(lower_sb == NULL);
++	/*
++	 * test sb flags directly, not IS_RDONLY(lower_inode) because the
++	 * lower_dentry could be a negative.
++	 */
++	if (lower_sb->s_flags & MS_RDONLY)
++		return -EROFS;
++
++	return 0;
++}
++
++static inline int is_robranch(const struct dentry *dentry)
++{
++	int index;
++
++	index = UNIONFS_D(dentry)->bstart;
++	BUG_ON(index < 0);
++
++	return is_robranch_idx(dentry, index);
++}
++
++/*
++ * EXTERNALS:
++ */
++extern int check_branch(struct nameidata *nd);
++extern int parse_branch_mode(const char *name, int *perms);
++
++/* locking helpers */
++static inline struct dentry *lock_parent(struct dentry *dentry)
++{
++	struct dentry *dir = dget_parent(dentry);
++	mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
++	return dir;
++}
++static inline struct dentry *lock_parent_wh(struct dentry *dentry)
++{
++	struct dentry *dir = dget_parent(dentry);
++
++	mutex_lock_nested(&dir->d_inode->i_mutex, UNIONFS_DMUTEX_WHITEOUT);
++	return dir;
++}
++
++static inline void unlock_dir(struct dentry *dir)
++{
++	mutex_unlock(&dir->d_inode->i_mutex);
++	dput(dir);
++}
++
++/* lock base inode mutex before calling lookup_one_len */
++static inline struct dentry *lookup_lck_len(const char *name,
++					    struct dentry *base, int len)
++{
++	struct dentry *d;
++	mutex_lock(&base->d_inode->i_mutex);
++	d = lookup_one_len(name, base, len);
++	mutex_unlock(&base->d_inode->i_mutex);
++	return d;
++}
++
++static inline struct vfsmount *unionfs_mntget(struct dentry *dentry,
++					      int bindex)
++{
++	struct vfsmount *mnt;
++
++	BUG_ON(!dentry || bindex < 0);
++
++	mnt = mntget(unionfs_lower_mnt_idx(dentry, bindex));
++#ifdef CONFIG_UNION_FS_DEBUG
++	if (!mnt)
++		pr_debug("unionfs: mntget: mnt=%p bindex=%d\n",
++			 mnt, bindex);
++#endif /* CONFIG_UNION_FS_DEBUG */
++
++	return mnt;
++}
++
++static inline void unionfs_mntput(struct dentry *dentry, int bindex)
++{
++	struct vfsmount *mnt;
++
++	if (!dentry && bindex < 0)
++		return;
++	BUG_ON(!dentry || bindex < 0);
++
++	mnt = unionfs_lower_mnt_idx(dentry, bindex);
++#ifdef CONFIG_UNION_FS_DEBUG
++	/*
++	 * Directories can have NULL lower objects in between start/end, but
++	 * NOT if at the start/end range.  We cannot verify that this dentry
++	 * is a type=DIR, because it may already be a negative dentry.  But
++	 * if dbstart is greater than dbend, we know that this couldn't have
++	 * been a regular file: it had to have been a directory.
++	 */
++	if (!mnt && !(bindex > dbstart(dentry) && bindex < dbend(dentry)))
++		pr_debug("unionfs: mntput: mnt=%p bindex=%d\n", mnt, bindex);
++#endif /* CONFIG_UNION_FS_DEBUG */
++	mntput(mnt);
++}
++
++#ifdef CONFIG_UNION_FS_DEBUG
++
++/* useful for tracking code reachability */
++#define UDBG pr_debug("DBG:%s:%s:%d\n", __FILE__, __func__, __LINE__)
++
++#define unionfs_check_inode(i)	__unionfs_check_inode((i),	\
++	__FILE__, __func__, __LINE__)
++#define unionfs_check_dentry(d)	__unionfs_check_dentry((d),	\
++	__FILE__, __func__, __LINE__)
++#define unionfs_check_file(f)	__unionfs_check_file((f),	\
++	__FILE__, __func__, __LINE__)
++#define unionfs_check_nd(n)	__unionfs_check_nd((n),		\
++	__FILE__, __func__, __LINE__)
++#define show_branch_counts(sb)	__show_branch_counts((sb),	\
++	__FILE__, __func__, __LINE__)
++#define show_inode_times(i)	__show_inode_times((i),		\
++	__FILE__, __func__, __LINE__)
++#define show_dinode_times(d)	__show_dinode_times((d),	\
++	__FILE__, __func__, __LINE__)
++#define show_inode_counts(i)	__show_inode_counts((i),	\
++	__FILE__, __func__, __LINE__)
++
++extern void __unionfs_check_inode(const struct inode *inode, const char *fname,
++				  const char *fxn, int line);
++extern void __unionfs_check_dentry(const struct dentry *dentry,
++				   const char *fname, const char *fxn,
++				   int line);
++extern void __unionfs_check_file(const struct file *file,
++				 const char *fname, const char *fxn, int line);
++extern void __unionfs_check_nd(const struct nameidata *nd,
++			       const char *fname, const char *fxn, int line);
++extern void __show_branch_counts(const struct super_block *sb,
++				 const char *file, const char *fxn, int line);
++extern void __show_inode_times(const struct inode *inode,
++			       const char *file, const char *fxn, int line);
++extern void __show_dinode_times(const struct dentry *dentry,
++				const char *file, const char *fxn, int line);
++extern void __show_inode_counts(const struct inode *inode,
++				const char *file, const char *fxn, int line);
++
++#else /* not CONFIG_UNION_FS_DEBUG */
++
++/* we leave useful hooks for these check functions throughout the code */
++#define unionfs_check_inode(i)		do { } while (0)
++#define unionfs_check_dentry(d)		do { } while (0)
++#define unionfs_check_file(f)		do { } while (0)
++#define unionfs_check_nd(n)		do { } while (0)
++#define show_branch_counts(sb)		do { } while (0)
++#define show_inode_times(i)		do { } while (0)
++#define show_dinode_times(d)		do { } while (0)
++#define show_inode_counts(i)		do { } while (0)
++
++#endif /* not CONFIG_UNION_FS_DEBUG */
++
++#endif	/* not _UNION_H_ */
+diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c
+new file mode 100644
+index 0000000..542c513
+--- /dev/null
++++ b/fs/unionfs/unlink.c
+@@ -0,0 +1,278 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/*
++ * Helper function for Unionfs's unlink operation.
++ *
++ * The main goal of this function is to optimize the unlinking of non-dir
++ * objects in unionfs by deleting all possible lower inode objects from the
++ * underlying branches having same dentry name as the non-dir dentry on
++ * which this unlink operation is called.  This way we delete as many lower
++ * inodes as possible, and save space.  Whiteouts need to be created in
++ * branch0 only if unlinking fails on any of the lower branch other than
++ * branch0, or if a lower branch is marked read-only.
++ *
++ * Also, while unlinking a file, if we encounter any dir type entry in any
++ * intermediate branch, then we remove the directory by calling vfs_rmdir.
++ * The following special cases are also handled:
++
++ * (1) If an error occurs in branch0 during vfs_unlink, then we return
++ *     appropriate error.
++ *
++ * (2) If we get an error during unlink in any of other lower branch other
++ *     than branch0, then we create a whiteout in branch0.
++ *
++ * (3) If a whiteout already exists in any intermediate branch, we delete
++ *     all possible inodes only up to that branch (this is an "opaqueness"
++ *     as as per Documentation/filesystems/unionfs/concepts.txt).
++ *
++ */
++static int unionfs_unlink_whiteout(struct inode *dir, struct dentry *dentry,
++				   struct dentry *parent)
++{
++	struct dentry *lower_dentry;
++	struct dentry *lower_dir_dentry;
++	int bindex;
++	int err = 0;
++
++	err = unionfs_partial_lookup(dentry, parent);
++	if (err)
++		goto out;
++
++	/* trying to unlink all possible valid instances */
++	for (bindex = dbstart(dentry); bindex <= dbend(dentry); bindex++) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++		if (!lower_dentry || !lower_dentry->d_inode)
++			continue;
++
++		lower_dir_dentry = lock_parent(lower_dentry);
++
++		/* avoid destroying the lower inode if the object is in use */
++		dget(lower_dentry);
++		err = is_robranch_super(dentry->d_sb, bindex);
++		if (!err) {
++			/* see Documentation/filesystems/unionfs/issues.txt */
++			lockdep_off();
++			if (!S_ISDIR(lower_dentry->d_inode->i_mode))
++				err = vfs_unlink(lower_dir_dentry->d_inode,
++								lower_dentry);
++			else
++				err = vfs_rmdir(lower_dir_dentry->d_inode,
++								lower_dentry);
++			lockdep_on();
++		}
++
++		/* if lower object deletion succeeds, update inode's times */
++		if (!err)
++			unionfs_copy_attr_times(dentry->d_inode);
++		dput(lower_dentry);
++		fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
++		unlock_dir(lower_dir_dentry);
++
++		if (err)
++			break;
++	}
++
++	/*
++	 * Create the whiteout in branch 0 (highest priority) only if (a)
++	 * there was an error in any intermediate branch other than branch 0
++	 * due to failure of vfs_unlink/vfs_rmdir or (b) a branch marked or
++	 * mounted read-only.
++	 */
++	if (err) {
++		if ((bindex == 0) ||
++		    ((bindex == dbstart(dentry)) &&
++		     (!IS_COPYUP_ERR(err))))
++			goto out;
++		else {
++			if (!IS_COPYUP_ERR(err))
++				pr_debug("unionfs: lower object deletion "
++					     "failed in branch:%d\n", bindex);
++			err = create_whiteout(dentry, sbstart(dentry->d_sb));
++		}
++	}
++
++out:
++	if (!err)
++		inode_dec_link_count(dentry->d_inode);
++
++	/* We don't want to leave negative leftover dentries for revalidate. */
++	if (!err && (dbopaque(dentry) != -1))
++		update_bstart(dentry);
++
++	return err;
++}
++
++int unionfs_unlink(struct inode *dir, struct dentry *dentry)
++{
++	int err = 0;
++	struct inode *inode = dentry->d_inode;
++	struct dentry *parent;
++	int valid;
++
++	BUG_ON(S_ISDIR(inode->i_mode));
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;
++		goto out;
++	}
++	unionfs_check_dentry(dentry);
++
++	err = unionfs_unlink_whiteout(dir, dentry, parent);
++	/* call d_drop so the system "forgets" about us */
++	if (!err) {
++		unionfs_postcopyup_release(dentry);
++		unionfs_postcopyup_setmnt(parent);
++		if (inode->i_nlink == 0) /* drop lower inodes */
++			iput_lowers_all(inode, false);
++		d_drop(dentry);
++		/*
++		 * if unlink/whiteout succeeded, parent dir mtime has
++		 * changed
++		 */
++		unionfs_copy_attr_times(dir);
++	}
++
++out:
++	if (!err) {
++		unionfs_check_dentry(dentry);
++		unionfs_check_inode(dir);
++	}
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++static int unionfs_rmdir_first(struct inode *dir, struct dentry *dentry,
++			       struct unionfs_dir_state *namelist)
++{
++	int err;
++	struct dentry *lower_dentry;
++	struct dentry *lower_dir_dentry = NULL;
++
++	/* Here we need to remove whiteout entries. */
++	err = delete_whiteouts(dentry, dbstart(dentry), namelist);
++	if (err)
++		goto out;
++
++	lower_dentry = unionfs_lower_dentry(dentry);
++
++	lower_dir_dentry = lock_parent(lower_dentry);
++
++	/* avoid destroying the lower inode if the file is in use */
++	dget(lower_dentry);
++	err = is_robranch(dentry);
++	if (!err)
++		err = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
++	dput(lower_dentry);
++
++	fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
++	/* propagate number of hard-links */
++	dentry->d_inode->i_nlink = unionfs_get_nlinks(dentry->d_inode);
++
++out:
++	if (lower_dir_dentry)
++		unlock_dir(lower_dir_dentry);
++	return err;
++}
++
++int unionfs_rmdir(struct inode *dir, struct dentry *dentry)
++{
++	int err = 0;
++	struct unionfs_dir_state *namelist = NULL;
++	struct dentry *parent;
++	int dstart, dend;
++	bool valid;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;
++		goto out;
++	}
++	unionfs_check_dentry(dentry);
++
++	/* check if this unionfs directory is empty or not */
++	err = check_empty(dentry, parent, &namelist);
++	if (err)
++		goto out;
++
++	err = unionfs_rmdir_first(dir, dentry, namelist);
++	dstart = dbstart(dentry);
++	dend = dbend(dentry);
++	/*
++	 * We create a whiteout for the directory if there was an error to
++	 * rmdir the first directory entry in the union.  Otherwise, we
++	 * create a whiteout only if there is no chance that a lower
++	 * priority branch might also have the same named directory.  IOW,
++	 * if there is not another same-named directory at a lower priority
++	 * branch, then we don't need to create a whiteout for it.
++	 */
++	if (!err) {
++		if (dstart < dend)
++			err = create_whiteout(dentry, dstart);
++	} else {
++		int new_err;
++
++		if (dstart == 0)
++			goto out;
++
++		/* exit if the error returned was NOT -EROFS */
++		if (!IS_COPYUP_ERR(err))
++			goto out;
++
++		new_err = create_whiteout(dentry, dstart - 1);
++		if (new_err != -EEXIST)
++			err = new_err;
++	}
++
++out:
++	/*
++	 * Drop references to lower dentry/inode so storage space for them
++	 * can be reclaimed.  Then, call d_drop so the system "forgets"
++	 * about us.
++	 */
++	if (!err) {
++		iput_lowers_all(dentry->d_inode, false);
++		dput(unionfs_lower_dentry_idx(dentry, dstart));
++		unionfs_set_lower_dentry_idx(dentry, dstart, NULL);
++		d_drop(dentry);
++		/* update our lower vfsmnts, in case a copyup took place */
++		unionfs_postcopyup_setmnt(dentry);
++		unionfs_check_dentry(dentry);
++		unionfs_check_inode(dir);
++	}
++
++	if (namelist)
++		free_rdstate(namelist);
++
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
+diff --git a/fs/unionfs/whiteout.c b/fs/unionfs/whiteout.c
+new file mode 100644
+index 0000000..405073a
+--- /dev/null
++++ b/fs/unionfs/whiteout.c
+@@ -0,0 +1,584 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/*
++ * whiteout and opaque directory helpers
++ */
++
++/* What do we use for whiteouts. */
++#define UNIONFS_WHPFX ".wh."
++#define UNIONFS_WHLEN 4
++/*
++ * If a directory contains this file, then it is opaque.  We start with the
++ * .wh. flag so that it is blocked by lookup.
++ */
++#define UNIONFS_DIR_OPAQUE_NAME "__dir_opaque"
++#define UNIONFS_DIR_OPAQUE UNIONFS_WHPFX UNIONFS_DIR_OPAQUE_NAME
++
++/* construct whiteout filename */
++char *alloc_whname(const char *name, int len)
++{
++	char *buf;
++
++	buf = kmalloc(len + UNIONFS_WHLEN + 1, GFP_KERNEL);
++	if (unlikely(!buf))
++		return ERR_PTR(-ENOMEM);
++
++	strcpy(buf, UNIONFS_WHPFX);
++	strlcat(buf, name, len + UNIONFS_WHLEN + 1);
++
++	return buf;
++}
++
++/*
++ * XXX: this can be inline or CPP macro, but is here to keep all whiteout
++ * code in one place.
++ */
++void unionfs_set_max_namelen(long *namelen)
++{
++	*namelen -= UNIONFS_WHLEN;
++}
++
++/* check if @namep is a whiteout, update @namep and @namelenp accordingly */
++bool is_whiteout_name(char **namep, int *namelenp)
++{
++	if (*namelenp > UNIONFS_WHLEN &&
++	    !strncmp(*namep, UNIONFS_WHPFX, UNIONFS_WHLEN)) {
++		*namep += UNIONFS_WHLEN;
++		*namelenp -= UNIONFS_WHLEN;
++		return true;
++	}
++	return false;
++}
++
++/* is the filename valid == !(whiteout for a file or opaque dir marker) */
++bool is_validname(const char *name)
++{
++	if (!strncmp(name, UNIONFS_WHPFX, UNIONFS_WHLEN))
++		return false;
++	if (!strncmp(name, UNIONFS_DIR_OPAQUE_NAME,
++		     sizeof(UNIONFS_DIR_OPAQUE_NAME) - 1))
++		return false;
++	return true;
++}
++
++/*
++ * Look for a whiteout @name in @lower_parent directory.  If error, return
++ * ERR_PTR.  Caller must dput() the returned dentry if not an error.
++ *
++ * XXX: some callers can reuse the whname allocated buffer to avoid repeated
++ * free then re-malloc calls.  Need to provide a different API for those
++ * callers.
++ */
++struct dentry *lookup_whiteout(const char *name, struct dentry *lower_parent)
++{
++	char *whname = NULL;
++	int err = 0, namelen;
++	struct dentry *wh_dentry = NULL;
++
++	namelen = strlen(name);
++	whname = alloc_whname(name, namelen);
++	if (unlikely(IS_ERR(whname))) {
++		err = PTR_ERR(whname);
++		goto out;
++	}
++
++	/* check if whiteout exists in this branch: lookup .wh.foo */
++	wh_dentry = lookup_lck_len(whname, lower_parent, strlen(whname));
++	if (IS_ERR(wh_dentry)) {
++		err = PTR_ERR(wh_dentry);
++		goto out;
++	}
++
++	/* check if negative dentry (ENOENT) */
++	if (!wh_dentry->d_inode)
++		goto out;
++
++	/* whiteout found: check if valid type */
++	if (!S_ISREG(wh_dentry->d_inode->i_mode)) {
++		printk(KERN_ERR "unionfs: invalid whiteout %s entry type %d\n",
++		       whname, wh_dentry->d_inode->i_mode);
++		dput(wh_dentry);
++		err = -EIO;
++		goto out;
++	}
++
++out:
++	kfree(whname);
++	if (err)
++		wh_dentry = ERR_PTR(err);
++	return wh_dentry;
++}
++
++/* find and return first whiteout in parent directory, else ENOENT */
++struct dentry *find_first_whiteout(struct dentry *dentry)
++{
++	int bindex, bstart, bend;
++	struct dentry *parent, *lower_parent, *wh_dentry;
++
++	parent = dget_parent(dentry);
++
++	bstart = dbstart(parent);
++	bend = dbend(parent);
++	wh_dentry = ERR_PTR(-ENOENT);
++
++	for (bindex = bstart; bindex <= bend; bindex++) {
++		lower_parent = unionfs_lower_dentry_idx(parent, bindex);
++		if (!lower_parent)
++			continue;
++		wh_dentry = lookup_whiteout(dentry->d_name.name, lower_parent);
++		if (IS_ERR(wh_dentry))
++			continue;
++		if (wh_dentry->d_inode)
++			break;
++		dput(wh_dentry);
++		wh_dentry = ERR_PTR(-ENOENT);
++	}
++
++	dput(parent);
++
++	return wh_dentry;
++}
++
++/*
++ * Unlink a whiteout dentry.  Returns 0 or -errno.  Caller must hold and
++ * release dentry reference.
++ */
++int unlink_whiteout(struct dentry *wh_dentry)
++{
++	int err;
++	struct dentry *lower_dir_dentry;
++
++	/* dget and lock parent dentry */
++	lower_dir_dentry = lock_parent_wh(wh_dentry);
++
++	/* see Documentation/filesystems/unionfs/issues.txt */
++	lockdep_off();
++	err = vfs_unlink(lower_dir_dentry->d_inode, wh_dentry);
++	lockdep_on();
++	unlock_dir(lower_dir_dentry);
++
++	/*
++	 * Whiteouts are special files and should be deleted no matter what
++	 * (as if they never existed), in order to allow this create
++	 * operation to succeed.  This is especially important in sticky
++	 * directories: a whiteout may have been created by one user, but
++	 * the newly created file may be created by another user.
++	 * Therefore, in order to maintain Unix semantics, if the vfs_unlink
++	 * above failed, then we have to try to directly unlink the
++	 * whiteout.  Note: in the ODF version of unionfs, whiteout are
++	 * handled much more cleanly.
++	 */
++	if (err == -EPERM) {
++		struct inode *inode = lower_dir_dentry->d_inode;
++		err = inode->i_op->unlink(inode, wh_dentry);
++	}
++	if (err)
++		printk(KERN_ERR "unionfs: could not unlink whiteout %s, "
++		       "err = %d\n", wh_dentry->d_name.name, err);
++
++	return err;
++
++}
++
++/*
++ * Helper function when creating new objects (create, symlink, mknod, etc.).
++ * Checks to see if there's a whiteout in @lower_dentry's parent directory,
++ * whose name is taken from @dentry.  Then tries to remove that whiteout, if
++ * found.  If <dentry,bindex> is a branch marked readonly, return -EROFS.
++ * If it finds both a regular file and a whiteout, return -EIO (this should
++ * never happen).
++ *
++ * Return 0 if no whiteout was found.  Return 1 if one was found and
++ * successfully removed.  Therefore a value >= 0 tells the caller that
++ * @lower_dentry belongs to a good branch to create the new object in).
++ * Return -ERRNO if an error occurred during whiteout lookup or in trying to
++ * unlink the whiteout.
++ */
++int check_unlink_whiteout(struct dentry *dentry, struct dentry *lower_dentry,
++			  int bindex)
++{
++	int err;
++	struct dentry *wh_dentry = NULL;
++	struct dentry *lower_dir_dentry = NULL;
++
++	/* look for whiteout dentry first */
++	lower_dir_dentry = dget_parent(lower_dentry);
++	wh_dentry = lookup_whiteout(dentry->d_name.name, lower_dir_dentry);
++	dput(lower_dir_dentry);
++	if (IS_ERR(wh_dentry)) {
++		err = PTR_ERR(wh_dentry);
++		goto out;
++	}
++
++	if (!wh_dentry->d_inode) { /* no whiteout exists*/
++		err = 0;
++		goto out_dput;
++	}
++
++	/* check if regular file and whiteout were both found */
++	if (unlikely(lower_dentry->d_inode)) {
++		err = -EIO;
++		printk(KERN_ERR "unionfs: found both whiteout and regular "
++		       "file in directory %s (branch %d)\n",
++		       lower_dir_dentry->d_name.name, bindex);
++		goto out_dput;
++	}
++
++	/* check if branch is writeable */
++	err = is_robranch_super(dentry->d_sb, bindex);
++	if (err)
++		goto out_dput;
++
++	/* .wh.foo has been found, so let's unlink it */
++	err = unlink_whiteout(wh_dentry);
++	if (!err)
++		err = 1; /* a whiteout was found and successfully removed */
++out_dput:
++	dput(wh_dentry);
++out:
++	return err;
++}
++
++/*
++ * Pass an unionfs dentry and an index.  It will try to create a whiteout
++ * for the filename in dentry, and will try in branch 'index'.  On error,
++ * it will proceed to a branch to the left.
++ */
++int create_whiteout(struct dentry *dentry, int start)
++{
++	int bstart, bend, bindex;
++	struct dentry *lower_dir_dentry;
++	struct dentry *lower_dentry;
++	struct dentry *lower_wh_dentry;
++	struct nameidata nd;
++	char *name = NULL;
++	int err = -EINVAL;
++
++	verify_locked(dentry);
++
++	bstart = dbstart(dentry);
++	bend = dbend(dentry);
++
++	/* create dentry's whiteout equivalent */
++	name = alloc_whname(dentry->d_name.name, dentry->d_name.len);
++	if (unlikely(IS_ERR(name))) {
++		err = PTR_ERR(name);
++		goto out;
++	}
++
++	for (bindex = start; bindex >= 0; bindex--) {
++		lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++
++		if (!lower_dentry) {
++			/*
++			 * if lower dentry is not present, create the
++			 * entire lower dentry directory structure and go
++			 * ahead.  Since we want to just create whiteout, we
++			 * only want the parent dentry, and hence get rid of
++			 * this dentry.
++			 */
++			lower_dentry = create_parents(dentry->d_inode,
++						      dentry,
++						      dentry->d_name.name,
++						      bindex);
++			if (!lower_dentry || IS_ERR(lower_dentry)) {
++				int ret = PTR_ERR(lower_dentry);
++				if (!IS_COPYUP_ERR(ret))
++					printk(KERN_ERR
++					       "unionfs: create_parents for "
++					       "whiteout failed: bindex=%d "
++					       "err=%d\n", bindex, ret);
++				continue;
++			}
++		}
++
++		lower_wh_dentry =
++			lookup_lck_len(name, lower_dentry->d_parent,
++				       dentry->d_name.len + UNIONFS_WHLEN);
++		if (IS_ERR(lower_wh_dentry))
++			continue;
++
++		/*
++		 * The whiteout already exists. This used to be impossible,
++		 * but now is possible because of opaqueness.
++		 */
++		if (lower_wh_dentry->d_inode) {
++			dput(lower_wh_dentry);
++			err = 0;
++			goto out;
++		}
++
++		err = init_lower_nd(&nd, LOOKUP_CREATE);
++		if (unlikely(err < 0))
++			goto out;
++		lower_dir_dentry = lock_parent_wh(lower_wh_dentry);
++		err = is_robranch_super(dentry->d_sb, bindex);
++		if (!err)
++			err = vfs_create(lower_dir_dentry->d_inode,
++					 lower_wh_dentry,
++					 current_umask() & S_IRUGO,
++					 &nd);
++		unlock_dir(lower_dir_dentry);
++		dput(lower_wh_dentry);
++		release_lower_nd(&nd, err);
++
++		if (!err || !IS_COPYUP_ERR(err))
++			break;
++	}
++
++	/* set dbopaque so that lookup will not proceed after this branch */
++	if (!err)
++		dbopaque(dentry) = bindex;
++
++out:
++	kfree(name);
++	return err;
++}
++
++/*
++ * Delete all of the whiteouts in a given directory for rmdir.
++ *
++ * lower directory inode should be locked
++ */
++static int do_delete_whiteouts(struct dentry *dentry, int bindex,
++			       struct unionfs_dir_state *namelist)
++{
++	int err = 0;
++	struct dentry *lower_dir_dentry = NULL;
++	struct dentry *lower_dentry;
++	char *name = NULL, *p;
++	struct inode *lower_dir;
++	int i;
++	struct list_head *pos;
++	struct filldir_node *cursor;
++
++	/* Find out lower parent dentry */
++	lower_dir_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++	BUG_ON(!S_ISDIR(lower_dir_dentry->d_inode->i_mode));
++	lower_dir = lower_dir_dentry->d_inode;
++	BUG_ON(!S_ISDIR(lower_dir->i_mode));
++
++	err = -ENOMEM;
++	name = __getname();
++	if (unlikely(!name))
++		goto out;
++	strcpy(name, UNIONFS_WHPFX);
++	p = name + UNIONFS_WHLEN;
++
++	err = 0;
++	for (i = 0; !err && i < namelist->size; i++) {
++		list_for_each(pos, &namelist->list[i]) {
++			cursor =
++				list_entry(pos, struct filldir_node,
++					   file_list);
++			/* Only operate on whiteouts in this branch. */
++			if (cursor->bindex != bindex)
++				continue;
++			if (!cursor->whiteout)
++				continue;
++
++			strlcpy(p, cursor->name, PATH_MAX - UNIONFS_WHLEN);
++			lower_dentry =
++				lookup_lck_len(name, lower_dir_dentry,
++					       cursor->namelen +
++					       UNIONFS_WHLEN);
++			if (IS_ERR(lower_dentry)) {
++				err = PTR_ERR(lower_dentry);
++				break;
++			}
++			if (lower_dentry->d_inode)
++				err = vfs_unlink(lower_dir, lower_dentry);
++			dput(lower_dentry);
++			if (err)
++				break;
++		}
++	}
++
++	__putname(name);
++
++	/* After all of the removals, we should copy the attributes once. */
++	fsstack_copy_attr_times(dentry->d_inode, lower_dir_dentry->d_inode);
++
++out:
++	return err;
++}
++
++
++void __delete_whiteouts(struct work_struct *work)
++{
++	struct sioq_args *args = container_of(work, struct sioq_args, work);
++	struct deletewh_args *d = &args->deletewh;
++
++	args->err = do_delete_whiteouts(d->dentry, d->bindex, d->namelist);
++	complete(&args->comp);
++}
++
++/* delete whiteouts in a dir (for rmdir operation) using sioq if necessary */
++int delete_whiteouts(struct dentry *dentry, int bindex,
++		     struct unionfs_dir_state *namelist)
++{
++	int err;
++	struct super_block *sb;
++	struct dentry *lower_dir_dentry;
++	struct inode *lower_dir;
++	struct sioq_args args;
++
++	sb = dentry->d_sb;
++
++	BUG_ON(!S_ISDIR(dentry->d_inode->i_mode));
++	BUG_ON(bindex < dbstart(dentry));
++	BUG_ON(bindex > dbend(dentry));
++	err = is_robranch_super(sb, bindex);
++	if (err)
++		goto out;
++
++	lower_dir_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++	BUG_ON(!S_ISDIR(lower_dir_dentry->d_inode->i_mode));
++	lower_dir = lower_dir_dentry->d_inode;
++	BUG_ON(!S_ISDIR(lower_dir->i_mode));
++
++	if (!inode_permission(lower_dir, MAY_WRITE | MAY_EXEC)) {
++		err = do_delete_whiteouts(dentry, bindex, namelist);
++	} else {
++		args.deletewh.namelist = namelist;
++		args.deletewh.dentry = dentry;
++		args.deletewh.bindex = bindex;
++		run_sioq(__delete_whiteouts, &args);
++		err = args.err;
++	}
++
++out:
++	return err;
++}
++
++/****************************************************************************
++ * Opaque directory helpers                                                 *
++ ****************************************************************************/
++
++/*
++ * is_opaque_dir: returns 0 if it is NOT an opaque dir, 1 if it is, and
++ * -errno if an error occurred trying to figure this out.
++ */
++int is_opaque_dir(struct dentry *dentry, int bindex)
++{
++	int err = 0;
++	struct dentry *lower_dentry;
++	struct dentry *wh_lower_dentry;
++	struct inode *lower_inode;
++	struct sioq_args args;
++
++	lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++	lower_inode = lower_dentry->d_inode;
++
++	BUG_ON(!S_ISDIR(lower_inode->i_mode));
++
++	mutex_lock(&lower_inode->i_mutex);
++
++	if (!inode_permission(lower_inode, MAY_EXEC)) {
++		wh_lower_dentry =
++			lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
++				       sizeof(UNIONFS_DIR_OPAQUE) - 1);
++	} else {
++		args.is_opaque.dentry = lower_dentry;
++		run_sioq(__is_opaque_dir, &args);
++		wh_lower_dentry = args.ret;
++	}
++
++	mutex_unlock(&lower_inode->i_mutex);
++
++	if (IS_ERR(wh_lower_dentry)) {
++		err = PTR_ERR(wh_lower_dentry);
++		goto out;
++	}
++
++	/* This is an opaque dir iff wh_lower_dentry is positive */
++	err = !!wh_lower_dentry->d_inode;
++
++	dput(wh_lower_dentry);
++out:
++	return err;
++}
++
++void __is_opaque_dir(struct work_struct *work)
++{
++	struct sioq_args *args = container_of(work, struct sioq_args, work);
++
++	args->ret = lookup_one_len(UNIONFS_DIR_OPAQUE, args->is_opaque.dentry,
++				   sizeof(UNIONFS_DIR_OPAQUE) - 1);
++	complete(&args->comp);
++}
++
++int make_dir_opaque(struct dentry *dentry, int bindex)
++{
++	int err = 0;
++	struct dentry *lower_dentry, *diropq;
++	struct inode *lower_dir;
++	struct nameidata nd;
++	const struct cred *old_creds;
++	struct cred *new_creds;
++
++	/*
++	 * Opaque directory whiteout markers are special files (like regular
++	 * whiteouts), and should appear to the users as if they don't
++	 * exist.  They should be created/deleted regardless of directory
++	 * search/create permissions, but only for the duration of this
++	 * creation of the .wh.__dir_opaque: file.  Note, this does not
++	 * circumvent normal ->permission).
++	 */
++	new_creds = prepare_creds();
++	if (unlikely(!new_creds)) {
++		err = -ENOMEM;
++		goto out_err;
++	}
++	cap_raise(new_creds->cap_effective, CAP_DAC_READ_SEARCH);
++	cap_raise(new_creds->cap_effective, CAP_DAC_OVERRIDE);
++	old_creds = override_creds(new_creds);
++
++	lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
++	lower_dir = lower_dentry->d_inode;
++	BUG_ON(!S_ISDIR(dentry->d_inode->i_mode) ||
++	       !S_ISDIR(lower_dir->i_mode));
++
++	mutex_lock(&lower_dir->i_mutex);
++	diropq = lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
++				sizeof(UNIONFS_DIR_OPAQUE) - 1);
++	if (IS_ERR(diropq)) {
++		err = PTR_ERR(diropq);
++		goto out;
++	}
++
++	err = init_lower_nd(&nd, LOOKUP_CREATE);
++	if (unlikely(err < 0))
++		goto out;
++	if (!diropq->d_inode)
++		err = vfs_create(lower_dir, diropq, S_IRUGO, &nd);
++	if (!err)
++		dbopaque(dentry) = bindex;
++	release_lower_nd(&nd, err);
++
++	dput(diropq);
++
++out:
++	mutex_unlock(&lower_dir->i_mutex);
++	revert_creds(old_creds);
++out_err:
++	return err;
++}
+diff --git a/fs/unionfs/xattr.c b/fs/unionfs/xattr.c
+new file mode 100644
+index 0000000..9002e06
+--- /dev/null
++++ b/fs/unionfs/xattr.c
+@@ -0,0 +1,173 @@
++/*
++ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2006 Charles P. Wright
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2005-2006 Junjiro Okajima
++ * Copyright (c) 2005      Arun M. Krishnakumar
++ * Copyright (c) 2004-2006 David P. Quigley
++ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
++ * Copyright (c) 2003      Puja Gupta
++ * Copyright (c) 2003      Harikesavan Krishnan
++ * Copyright (c) 2003-2010 Stony Brook University
++ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include "union.h"
++
++/* This is lifted from fs/xattr.c */
++void *unionfs_xattr_alloc(size_t size, size_t limit)
++{
++	void *ptr;
++
++	if (size > limit)
++		return ERR_PTR(-E2BIG);
++
++	if (!size)		/* size request, no buffer is needed */
++		return NULL;
++
++	ptr = kmalloc(size, GFP_KERNEL);
++	if (unlikely(!ptr))
++		return ERR_PTR(-ENOMEM);
++	return ptr;
++}
++
++/*
++ * BKL held by caller.
++ * dentry->d_inode->i_mutex locked
++ */
++ssize_t unionfs_getxattr(struct dentry *dentry, const char *name, void *value,
++			 size_t size)
++{
++	struct dentry *lower_dentry = NULL;
++	struct dentry *parent;
++	int err = -EOPNOTSUPP;
++	bool valid;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;
++		goto out;
++	}
++
++	lower_dentry = unionfs_lower_dentry(dentry);
++
++	err = vfs_getxattr(lower_dentry, (char *) name, value, size);
++
++out:
++	unionfs_check_dentry(dentry);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++/*
++ * BKL held by caller.
++ * dentry->d_inode->i_mutex locked
++ */
++int unionfs_setxattr(struct dentry *dentry, const char *name,
++		     const void *value, size_t size, int flags)
++{
++	struct dentry *lower_dentry = NULL;
++	struct dentry *parent;
++	int err = -EOPNOTSUPP;
++	bool valid;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;
++		goto out;
++	}
++
++	lower_dentry = unionfs_lower_dentry(dentry);
++
++	err = vfs_setxattr(lower_dentry, (char *) name, (void *) value,
++			   size, flags);
++
++out:
++	unionfs_check_dentry(dentry);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++/*
++ * BKL held by caller.
++ * dentry->d_inode->i_mutex locked
++ */
++int unionfs_removexattr(struct dentry *dentry, const char *name)
++{
++	struct dentry *lower_dentry = NULL;
++	struct dentry *parent;
++	int err = -EOPNOTSUPP;
++	bool valid;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;
++		goto out;
++	}
++
++	lower_dentry = unionfs_lower_dentry(dentry);
++
++	err = vfs_removexattr(lower_dentry, (char *) name);
++
++out:
++	unionfs_check_dentry(dentry);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
++
++/*
++ * BKL held by caller.
++ * dentry->d_inode->i_mutex locked
++ */
++ssize_t unionfs_listxattr(struct dentry *dentry, char *list, size_t size)
++{
++	struct dentry *lower_dentry = NULL;
++	struct dentry *parent;
++	int err = -EOPNOTSUPP;
++	char *encoded_list = NULL;
++	bool valid;
++
++	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
++	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
++	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
++
++	valid = __unionfs_d_revalidate(dentry, parent, false);
++	if (unlikely(!valid)) {
++		err = -ESTALE;
++		goto out;
++	}
++
++	lower_dentry = unionfs_lower_dentry(dentry);
++
++	encoded_list = list;
++	err = vfs_listxattr(lower_dentry, encoded_list, size);
++
++out:
++	unionfs_check_dentry(dentry);
++	unionfs_unlock_dentry(dentry);
++	unionfs_unlock_parent(dentry, parent);
++	unionfs_read_unlock(dentry->d_sb);
++	return err;
++}
+diff --git a/include/linux/fs_stack.h b/include/linux/fs_stack.h
+index da317c7..64f1ced 100644
+--- a/include/linux/fs_stack.h
++++ b/include/linux/fs_stack.h
+@@ -1,7 +1,19 @@
++/*
++ * Copyright (c) 2006-2009 Erez Zadok
++ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2006-2009 Stony Brook University
++ * Copyright (c) 2006-2009 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
+ #ifndef _LINUX_FS_STACK_H
+ #define _LINUX_FS_STACK_H
+ 
+-/* This file defines generic functions used primarily by stackable
++/*
++ * This file defines generic functions used primarily by stackable
+  * filesystems; none of these functions require i_mutex to be held.
+  */
+ 
+diff --git a/include/linux/magic.h b/include/linux/magic.h
+index eb9800f..9770154 100644
+--- a/include/linux/magic.h
++++ b/include/linux/magic.h
+@@ -47,6 +47,8 @@
+ #define REISER2FS_SUPER_MAGIC_STRING	"ReIsEr2Fs"
+ #define REISER2FS_JR_SUPER_MAGIC_STRING	"ReIsEr3Fs"
+ 
++#define UNIONFS_SUPER_MAGIC 0xf15f083d
++
+ #define SMB_SUPER_MAGIC		0x517B
+ #define USBDEVICE_SUPER_MAGIC	0x9fa2
+ #define CGROUP_SUPER_MAGIC	0x27e0eb
+diff --git a/include/linux/namei.h b/include/linux/namei.h
+index 05b441d..dca6f9a 100644
+--- a/include/linux/namei.h
++++ b/include/linux/namei.h
+@@ -72,6 +72,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
+ 
+ extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
+ 		int (*open)(struct inode *, struct file *));
++extern void release_open_intent(struct nameidata *);
+ 
+ extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
+ 
+diff --git a/include/linux/splice.h b/include/linux/splice.h
+index 997c3b4..54f5501 100644
+--- a/include/linux/splice.h
++++ b/include/linux/splice.h
+@@ -81,6 +81,11 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *,
+ 			      struct splice_pipe_desc *);
+ extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
+ 				      splice_direct_actor *);
++extern long vfs_splice_from(struct pipe_inode_info *pipe, struct file *out,
++			    loff_t *ppos, size_t len, unsigned int flags);
++extern long vfs_splice_to(struct file *in, loff_t *ppos,
++			  struct pipe_inode_info *pipe, size_t len,
++			  unsigned int flags);
+ 
+ /*
+  * for dynamic pipe sizing
+diff --git a/include/linux/union_fs.h b/include/linux/union_fs.h
+new file mode 100644
+index 0000000..c84d97e
+--- /dev/null
++++ b/include/linux/union_fs.h
+@@ -0,0 +1,22 @@
++/*
++ * Copyright (c) 2003-2009 Erez Zadok
++ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
++ * Copyright (c) 2003-2009 Stony Brook University
++ * Copyright (c) 2003-2009 The Research Foundation of SUNY
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef _LINUX_UNION_FS_H
++#define _LINUX_UNION_FS_H
++
++/*
++ * DEFINITIONS FOR USER AND KERNEL CODE:
++ */
++# define UNIONFS_IOCTL_INCGEN		_IOR(0x15, 11, int)
++# define UNIONFS_IOCTL_QUERYFILE	_IOR(0x15, 15, int)
++
++#endif /* _LINUX_UNIONFS_H */
++
+diff --git a/security/security.c b/security/security.c
+index 351942a..69505f7 100644
+--- a/security/security.c
++++ b/security/security.c
+@@ -529,6 +529,7 @@ int security_inode_permission(struct inode *inode, int mask)
+ 		return 0;
+ 	return security_ops->inode_permission(inode, mask);
+ }
++EXPORT_SYMBOL(security_inode_permission);
+ 
+ int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
+ {
diff --git a/recipes/linux/linux-ts75xx_2.6.35.bb b/recipes/linux/linux-ts75xx_2.6.35.bb
new file mode 100644
index 0000000..116efea
--- /dev/null
+++ b/recipes/linux/linux-ts75xx_2.6.35.bb
@@ -0,0 +1,141 @@
+DESCRIPTION = "Linux Kernel"
+SECTION = "kernel"
+LICENSE = "GPLv2"
+PR = "r0"
+STABLEV = "11"
+
+inherit kernel siteinfo
+
+# Mark archs/machines that this kernel supports
+DEFAULT_PREFERENCE = "-1"
+DEFAULT_PREFERENCE_ts75xx = "1"
+
+SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/${P}.tar.bz2;name=kernel \
+           ${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/patch-${PV}.${STABLEV}.bz2;apply=yes;name=stablepatch \
+           file://defconfig "
+
+SRC_URI_ts75xx = "\
+        ${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/longterm/v${PV}/linux-${PV}.${STABLEV}.tar.bz2;name=kernel \
+# backported patches
+        file://ts7500-${PV}.${STABLEV}.patch;apply=yes \
+        file://cavium-userspace-irq-${PV}.patch \
+	file://unionfs-2.5.8_for_2.6.35.11.patch \
+        file://defconfig "
+
+SRC_URI[kernel.md5sum] = "4c9ee33801f5ad0f4d5e615fac66d535"
+SRC_URI[kernel.sha256sum] = "43e30da359dc95edb0b927632a318e6dae1f6e78d954c2e35281e808d00352eb"
+
+do_correct_kernel_dir() {
+        mv ${WORKDIR}/linux-${PV}.${STABLEV} ${S}
+}
+
+addtask correct_kernel_dir after do_unpack before do_patch
+
+do_configure_prepend() {
+
+        # Create a blank .config file
+        echo "" > ${S}/.config
+
+        #
+        # oabi / eabi support
+        #
+        echo "CONFIG_AEABI=y"                   >> ${S}/.config
+        echo "CONFIG_OABI_COMPAT=y"             >> ${S}/.config
+
+        #
+        # disable thumb support in the kernel
+        #
+        sed -i -e /CONFIG_ARM_THUMB/d ${WORKDIR}/defconfig
+        echo "CONFIG_ARM_THUMB=n" >> ${S}/.config
+
+        #
+        # endian support
+        #
+        if [ "${SITEINFO_ENDIANNESS}" = "be" ]; then
+                echo "CONFIG_CPU_BIG_ENDIAN=y"          >> ${S}/.config
+        fi
+        echo "CONFIG_CMDLINE=\"${CMDLINE}\"" >> ${S}/.config
+
+        # copy the defconfig over to the .config
+        sed -e '/CONFIG_AEABI/d' \
+            -e '/CONFIG_OABI_COMPAT=/d' \
+            -e '/CONFIG_CMDLINE=/d' \
+            -e '/CONFIG_CPU_BIG_ENDIAN/d' \
+            -e '/CONFIG_LOCALVERSION/d' \
+            -e '/CONFIG_LOCALVERSION_AUTO/d' \
+	    -e '/CONFIG_MISC_FILESYSTEMS/d' \
+	    -e '/CONFIG_UNION_FS/d' \
+            < '${WORKDIR}/defconfig' >>'${S}/.config'
+        echo 'CONFIG_LOCALVERSION="${LOCALVERSION}"' >>${S}/.config
+        echo '# CONFIG_LOCALVERSION_AUTO is not set' >>${S}/.config
+	
+	# Add unionfs support
+	echo "CONFIG_MISC_FILESYSTEMS=y" >> ${S}/.config
+	echo "CONFIG_UNION_FS=y" >> ${S}/.config
+
+        # Newer versions of udev mandate that sysfs doesn't have deprecated entries
+        if [ "${UDEV_GE_141}" = "1" ] ; then
+            sed -e /CONFIG_SYSFS_DEPRECATED/d \
+                -e /CONFIG_SYSFS_DEPRECATED_V2/d \
+                -e /CONFIG_HOTPLUG/d \
+                -e /CONFIG_UEVENT_HELPER_PATH/d \
+                -e /CONFIG_UNIX/d \
+                -e /CONFIG_SYSFS/d \
+                -e /CONFIG_PROC_FS/d \
+                -e /CONFIG_TMPFS/d \
+                -e /CONFIG_INOTIFY_USER/d \
+                -e /CONFIG_SIGNALFD/d \
+                -e /CONFIG_TMPFS_POSIX_ACL/d \
+                -e /CONFIG_BLK_DEV_BSG/d \
+                -i '${S}/.config'
+            echo '# CONFIG_SYSFS_DEPRECATED is not set' >> ${S}/.config
+            echo '# CONFIG_SYSFS_DEPRECATED_V2 is not set' >> ${S}/.config
+            echo 'CONFIG_HOTPLUG=y' >> ${S}/.config
+            echo 'CONFIG_UEVENT_HELPER_PATH=""' >> ${S}/.config
+            echo 'CONFIG_UNIX=y' >> ${S}/.config
+            echo 'CONFIG_SYSFS=y' >> ${S}/.config
+            echo 'CONFIG_PROC_FS=y' >> ${S}/.config
+            echo 'CONFIG_TMPFS=y' >> ${S}/.config
+            echo 'CONFIG_INOTIFY_USER=y' >> ${S}/.config
+            echo 'CONFIG_SIGNALFD=y' >> ${S}/.config
+            echo 'CONFIG_TMPFS_POSIX_ACL=y' >> ${S}/.config
+            echo 'CONFIG_BLK_DEV_BSG=y' >> ${S}/.config
+            echo 'CONFIG_DEVTMPFS=y' >> ${S}/.config
+            echo 'CONFIG_DEVTMPFS_MOUNT=y' >> ${S}/.config
+        fi
+
+        # Newer inits like systemd need cgroup support
+        if [ "${KERNEL_ENABLE_CGROUPS}" = "1" ] ; then
+            sed -e /CONFIG_CGROUP_SCHED/d \
+                -e /CONFIG_CGROUPS/d \
+                -i '${S}/.config'
+            echo 'CONFIG_CGROUP_SCHED=y' >> ${S}/.config
+            echo 'CONFIG_CGROUPS=y' >> ${S}/.config
+            echo 'CONFIG_CGROUP_NS=y' >> ${S}/.config
+            echo 'CONFIG_CGROUP_FREEZER=y' >> ${S}/.config
+            echo 'CONFIG_CGROUP_DEVICE=y' >> ${S}/.config
+            echo 'CONFIG_CPUSETS=y' >> ${S}/.config
+            echo 'CONFIG_PROC_PID_CPUSET=y' >> ${S}/.config
+            echo 'CONFIG_CGROUP_CPUACCT=y' >> ${S}/.config
+            echo 'CONFIG_RESOURCE_COUNTERS=y' >> ${S}/.config
+        fi
+        yes '' | oe_runmake oldconfig
+}
+
+do_configure_append() {
+        if test -e scripts/Makefile.fwinst ; then
+                sed -i -e "s:-m0644:-m 0644:g" scripts/Makefile.fwinst
+        fi
+}
+
+do_install_append() {
+        oe_runmake headers_install INSTALL_HDR_PATH=${D}${exec_prefix}/src/linux-${KERNEL_VERSION} ARCH=$ARCH
+}
+
+do_populate_sysroot() {
+	:
+}
+
+PACKAGES =+ "kernel-headers"
+
+FILES_kernel-headers = "${exec_prefix}/src/linux*"
-- 
1.7.3.4




^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 4/6] Add recipes for building TS75xx userspace utilities
  2011-03-30 14:07 [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
  2011-03-30 14:07 ` [PATCH 2/6] Allows the use of the angstrom distribution with ARM cores that do not support THUMB_INTERWORK instructions UDel V2G Team
  2011-03-30 14:07 ` [PATCH 3/6] Add kernel support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
@ 2011-03-30 14:07 ` UDel V2G Team
  2011-03-30 14:40   ` Marcin Juszkiewicz
  2011-03-30 14:07 ` [PATCH 5/6] Added images for the TS7500 ARM SBCs UDel V2G Team
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: UDel V2G Team @ 2011-03-30 14:07 UTC (permalink / raw)
  To: openembedded-devel

Support for building the following userspace utilities is provided:
* canctl
* dioctl
* dmxctl
* jed2vme
* sdctl
* ts7500ctl
* spiflashctl
* xuartctl

The original source for these utilities is:

ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7550-linux/sources/

This commit includes a minimal set of patches for building these utilities
with EABI and the latest kernel

Signed-off-by: UDel V2G Team <v2g.udel@gmail.com>
---
 recipes/ts7500/canctl_0.0.1.bb               |   29 ++
 recipes/ts7500/dioctl_0.0.1.bb               |   53 +++
 recipes/ts7500/dmxctl_0.0.1.bb               |   23 +
 recipes/ts7500/files/group                   |   22 +
 recipes/ts7500/files/linuxrc-fastboot        |  156 +++++++
 recipes/ts7500/files/linuxrc-nandmount       |  148 ++++++
 recipes/ts7500/files/linuxrc-sdmount         |  136 ++++++
 recipes/ts7500/files/linuxrc-sdroot          |  179 ++++++++
 recipes/ts7500/files/linuxrc-sdroot-readonly |  188 ++++++++
 recipes/ts7500/files/linuxrc-usbroot         |  163 +++++++
 recipes/ts7500/files/passwd                  |    9 +
 recipes/ts7500/files/ts-utils.patch          |   68 +++
 recipes/ts7500/files/ts7500.subr             |  633 ++++++++++++++++++++++++++
 recipes/ts7500/spictl_0.0.1.bb               |   26 +
 recipes/ts7500/ts-initrd_0.0.1.bb            |   46 ++
 recipes/ts7500/ts-utils_0.0.1.bb             |   60 +++
 recipes/ts7500/ts7500_0.0.1.bb               |    7 +
 17 files changed, 1946 insertions(+), 0 deletions(-)
 create mode 100644 recipes/ts7500/canctl_0.0.1.bb
 create mode 100644 recipes/ts7500/dioctl_0.0.1.bb
 create mode 100644 recipes/ts7500/dmxctl_0.0.1.bb
 create mode 100644 recipes/ts7500/files/group
 create mode 100644 recipes/ts7500/files/linuxrc-fastboot
 create mode 100644 recipes/ts7500/files/linuxrc-nandmount
 create mode 100644 recipes/ts7500/files/linuxrc-sdmount
 create mode 100644 recipes/ts7500/files/linuxrc-sdroot
 create mode 100644 recipes/ts7500/files/linuxrc-sdroot-readonly
 create mode 100644 recipes/ts7500/files/linuxrc-usbroot
 create mode 100644 recipes/ts7500/files/passwd
 create mode 100644 recipes/ts7500/files/ts-utils.patch
 create mode 100644 recipes/ts7500/files/ts7500.subr
 create mode 100644 recipes/ts7500/spictl_0.0.1.bb
 create mode 100644 recipes/ts7500/ts-initrd_0.0.1.bb
 create mode 100644 recipes/ts7500/ts-utils_0.0.1.bb
 create mode 100644 recipes/ts7500/ts7500_0.0.1.bb

diff --git a/recipes/ts7500/canctl_0.0.1.bb b/recipes/ts7500/canctl_0.0.1.bb
new file mode 100644
index 0000000..7bf8f15
--- /dev/null
+++ b/recipes/ts7500/canctl_0.0.1.bb
@@ -0,0 +1,29 @@
+DESCRIPTION = "TS 7500 canctl scripts"
+PR = "r0"
+DEPENDS = ""
+SRC_URI = " \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/canctl.tar.gz \
+"
+
+SRC_URI[md5sum] = "322da336b9e49aeb532bf2aa9e6d8f56"
+SRC_URI[sha256sum] = "91e22495b912e971630e87fb82620c6b1f0ce1c983f31e2fd1171b1e9ef6ff37"
+
+S = "${WORKDIR}/canctl"
+
+do_compile () {
+	   ${CC}${CFLAGS} -g -DOMIT_BOARDID -c -o canctl.o canctl.c 
+	   ${CC}${CFLAGS} -g -DOMIT_BOARDID -c -o sock.o sock.c
+	   ${CC}${CFLAGS} -g -DOMIT_BOARDID -c -o peekpoke.o peekpoke.c
+	   ${CC}${CFLAGS} -g -DOMIT_BOARDID -c -o ts.o ts.c
+	   ${CC}${CFLAGS} -g -DOMIT_BOARDID -c -o cavium.o cavium.c
+	   ${CC}${CFLAGS} -g -DOMIT_BOARDID -c -o prosoft.o prosoft.c
+	   ${CC}${CFLAGS} -g -DOMIT_BOARDID -c -o opt.o opt.c
+	   ${CC}${CFLAGS} -g -DOMIT_BOARDID ${LDFLAGS} -o canctl canctl.o sock.o peekpoke.o ts.o cavium.o prosoft.o opt.o
+}
+
+do_install () {
+	   install -d ${D}${base_sbindir}/
+	   install -m 0755 ${S}/canctl ${D}${base_sbindir}/
+}
+
+FILES_${PN} = "${base_sbindir}/canctl"
diff --git a/recipes/ts7500/dioctl_0.0.1.bb b/recipes/ts7500/dioctl_0.0.1.bb
new file mode 100644
index 0000000..4fa032e
--- /dev/null
+++ b/recipes/ts7500/dioctl_0.0.1.bb
@@ -0,0 +1,53 @@
+DESCRIPTION = "TS 7500 dioctl Scripts"
+PR = "r0"
+DEPENDS = ""
+SRC_URI = " \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/dioctl-latest.tar.gz \
+"
+
+SRC_URI[md5sum] = "4d93e6075913732dd4bcf2f71b2b967f"
+SRC_URI[sha256sum] = "f9e22cb5ae3cab49f702207bdcd67ef340ab18bb808777337453362494566d52"
+
+S = "${WORKDIR}/dioctl"
+
+do_compile () {
+	   # Compile the files
+	   ${CC}${CFLAGS} -g -Os -c -o dioctl.o dioctl.c
+	   ${CC}${CFLAGS} -g -Os -c -o diomain.o diomain.c
+	   ${CC}${CFLAGS} -g -Os -c -o dioserv.o dioserv.c
+	   ${CC}${CFLAGS} -g -Os -c -o lock.o lock.c
+	   ${CC}${CFLAGS} -g -Os -c -o ring.o ring.c
+	   ${CC}${CFLAGS} -g -Os -c -o server.o server.c
+	   ${CC}${CFLAGS} -g -Os -c -o sock.o sock.c
+	   ${CC}${CFLAGS} -g -Os -c -o watch.o watch.c
+	   ${CC}${CFLAGS} -g -Os -c -o waitq.o waitq.c
+	   ${CC}${CFLAGS} -g -Os -c -o file.o file.c
+	   ${CC}${CFLAGS} -g -Os -c -o opt.o opt.c	   
+	   ${CC}${CFLAGS} -g -Os -c -o peekpoke.o peekpoke.c
+	   ${CC}${CFLAGS} -g -Os -c -o ts.o ts.c
+	   ${CC}${CFLAGS} -g -Os -c -o ts75xx.o ts75xx.c
+	   ${CC}${CFLAGS} -g -Os -c -o ts4200.o ts4200.c
+	   ${CC}${CFLAGS} -g -Os -c -o ts4500.o ts4500.c
+	   ${CC}${CFLAGS} -g -Os -c -o ts4800.o ts4800.c
+	   ${CC}${CFLAGS} -g -Os -c -o dioname.o dioname.c
+	   ${CC}${CFLAGS} -g -Os -c -o cavium.o cavium.c	 
+	   
+	   # Now build the binaries
+	   ${CC}${CFLAGS} -g ${LDFLAGS} -o dioctl  dioctl.o diomain.o dioserv.o lock.o ring.o server.o sock.o watch.o waitq.o file.o opt.o peekpoke.o ts.o ts4500.o ts4200.o cavium.o dioname.o ts4800.o ts75xx.o
+	   ${AR} rcs libdioctl.a dioctl.o opt.o sock.o dioname.o
+	   ${CC}${CFLAGS} -shared ${LDFLAGS} -Wl,-soname,libdioctl.so.1 -o ${S}/libdioctl.so.1.0.1  dioctl.o opt.o sock.o dioname.o
+	   ${CC}${CFLAGS} ${LDFLAGS} diotest1.c -L${S} -ldioctl -o diotest1
+	   ${CC}${CFLAGS} ${LDFLAGS} diotest2.c -L${S} -ldioctl -lpthread -o diotest2
+	   ${CC}${CFLAGS} ${LDFLAGS} diotest3.c -L${S} -ldioctl -o diotest3
+}
+
+do_install () {
+	   install -d ${D}${base_sbindir}/
+	   install -m 0755 ${S}/dioctl ${D}${base_sbindir}/
+	   install -m 0755 ${S}/diotest1 ${D}${base_sbindir}/
+	   install -m 0755 ${S}/diotest2 ${D}${base_sbindir}/
+	   install -m 0755 ${S}/diotest3 ${D}${base_sbindir}/
+	   install -d ${D}${base_libdir}/
+	   install -m 0755 ${S}/libdioctl.a ${D}${base_libdir}/
+	   install -m 0755 ${S}/libdioctl.so.1.0.1 ${D}${base_libdir}/
+}
diff --git a/recipes/ts7500/dmxctl_0.0.1.bb b/recipes/ts7500/dmxctl_0.0.1.bb
new file mode 100644
index 0000000..8ee7c1f
--- /dev/null
+++ b/recipes/ts7500/dmxctl_0.0.1.bb
@@ -0,0 +1,23 @@
+DESCRIPTION = "TS 7500 dmxctl Utility Script"
+PR = "r0"
+DEPENDS = ""
+SRC_URI = " \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/dmxctl.tar.gz \
+"
+SRC_URI[md5sum] = "76c0c5b8b232f9c9da377d593b46fb6d"
+SRC_URI[sha256sum] = "2c39b8e7777ffed48ecf65cce0d3d9067ab4c9f7a647a7d2156e961964ca63e6"
+
+S = "${WORKDIR}/dmx"
+
+do_compile () {
+	   ${CC}${CFLAGS} -g -c -o file.o file.c
+	   ${CC}${CFLAGS} -g -c -o sock.o sock.c
+	   ${CC}${CFLAGS} -g -c -o opt.o opt.c 
+	   ${CC}${CFLAGS} -g -c -o dmxctl.o dmxctl.c
+	   ${CC}${CFLAGS} -g ${LDFLAGS} -o dmxctl dmxctl.o sock.o file.o opt.o
+}
+
+do_install () {
+	   install -d ${D}${base_sbindir}/
+	   install -m 0755 ${S}/dmxctl ${D}${base_sbindir}/
+}
diff --git a/recipes/ts7500/files/group b/recipes/ts7500/files/group
new file mode 100644
index 0000000..863273e
--- /dev/null
+++ b/recipes/ts7500/files/group
@@ -0,0 +1,22 @@
+bin:x:1:daemon
+console:x:21:
+daemon:x:2:
+ftp:x:49:
+kmem:x:9:
+lock:x:54:
+man:x:62:
+nobody:x:65533:
+nogroup:x:65534:nobody
+ntp:!:103:
+public:x:32:
+root:x:0:
+shadow:x:15:
+sshd:!:65:
+sys:x:3:
+trusted:x:42:
+tty:x:5:
+utmp:x:22:
+uucp:x:14:
+wheel:x:10:
+www:x:8:
+users:x:100:
diff --git a/recipes/ts7500/files/linuxrc-fastboot b/recipes/ts7500/files/linuxrc-fastboot
new file mode 100644
index 0000000..259793f
--- /dev/null
+++ b/recipes/ts7500/files/linuxrc-fastboot
@@ -0,0 +1,156 @@
+#!/bin/sh
+
+export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/mnt/root/bin:/mnt/root/sbin:/mnt/root
+mount -t proc proc /proc
+mount -t sysfs sysfs /sys
+mount -t devpts devpts /dev/pts
+  
+ifconfig lo 127.0.0.1 up
+route add -net 127.0.0.0 netmask 255.0.0.0 lo
+xuartctl --server
+
+# If the RESET switch is being pushed, 
+# set the CONSOLE to the DB9 port (/dev/pts/#)
+eval `ts7500ctl --getdio`
+let dio9="(dio >> 9) & 0x1"
+XCONSOLE=0
+
+if [ "$dio9" == "1" ]; then
+  export CONSOLE=/dev/ttyS0
+else
+  eval `xuartctl --server --port 0 </dev/null 2>&1`
+  if [ "$ttyname" == "" ]; then
+    export CONSOLE=/dev/ttyS0
+  else
+    export CONSOLE=$ttyname
+    XCONSOLE=1
+    # If the RESET switch is being pushed, wait until released
+    while [ "$dio9" == "0" ]; do
+    	eval `ts7500ctl --getdio`
+    	let dio9="(dio >> 9) & 0x1"
+    done
+  fi
+fi
+                
+let x=`devmem 0x79000040`
+sec=$((x / 100000))
+tenths=$((x % 100000 / 1000))
+export BOOTTIME=`printf "%d.%02d" $sec $tenths`
+
+setconsole $CONSOLE
+stty -F $CONSOLE ospeed 115200 sane > /dev/null 2>&1
+hostname ts7500                                   
+ts7500ctl --resetswitchon --setrng --getrtc --autofeed 2 -d
+ts7500ctl --loadfpga=ts7500_bitstream.vme.gz
+
+# Get the model # and boot device (NAND, mSD, SPI flash)
+eval `ts7500ctl --info`
+export bootdev model
+
+# If this is a 4500/8200, we need to set DIO-7 HIGH
+# (EN_USB_5V) for the USB's to work
+if [ "$model" = "0x4500" ]; then
+	eval `ts7500ctl --getdioreg`
+	let diodir="diodir | (1<<7)"
+	let dio_out="dio_out | (1<<7)"
+	ts7500ctl --setdio $dio_out --setdiodir $diodir
+fi
+
+# If there is a USB drive, mount it
+# If it has 'tsinit', execute it
+# (this allows software auto-update)                                
+devmem 0xc8000004 32 0x106
+devmem 0xcc000060 32 0x1
+let x=`devmem 0xcc000068`
+let y=`devmem 0xcc000064`
+x=$(((x | y) & 0x1))
+if [ "$x" -eq 1 ]; then
+  (
+        ts7500ctl --redledon
+	mount -t tmpfs tmpfs /lib/modules
+	tar -x -z -f /modules.tar.gz -C /
+	modprobe scsi_mod
+	modprobe sd_mod
+	modprobe usbcore
+	modprobe ehci_hcd
+	modprobe usb_storage
+	modprobe smsc95xx
+	modprobe ohci_hcd
+	umount /lib/modules
+	x=0
+	while [ "$x" -lt 150 -a ! -e /sys/block/sda ]; do
+		x=$((x+1))
+		sleep .1
+	done
+	mount -o ro /dev/sda1 /mnt/usbdev
+	if [ -x /mnt/usbdev/tsinit ]; then 
+		/mnt/usbdev/tsinit <$CONSOLE >$CONSOLE 2>&1
+	fi
+	umount /mnt/usbdev
+	ts7500ctl --redledoff
+  ) &
+fi
+
+(
+  mount -t tmpfs none /dev/shm
+  ifconfig eth0 192.168.0.50
+  telnetd
+  mount -t tmpfs tmpfs /tmp
+
+  # If booted from NAND, mount NAND's Linux partition
+  # If booted from mSD, mount mSD's Linux partition
+    
+  # Model: 7550, 7551, etc. (NOT 7500) -- these boards have NAND
+  if [ "$model" != "0x7500" ]; then
+    nandctl -X -z 131072 --nbdserver lun0:disc,lun0:part1,lun0:part2,lun0:part3,lun0:part4
+    nbd-client 127.0.0.1 7525 /dev/nbd0
+    nbd-client 127.0.0.1 7526 /dev/nbd1
+    nbd-client 127.0.0.1 7527 /dev/nbd2
+    nbd-client 127.0.0.1 7528 /dev/nbd3
+    nbd-client 127.0.0.1 7529 /dev/nbd4
+    if [ "$bootdev" == "0x0" ]; then
+      mount -oro /dev/nbd3 /mnt/root
+    fi
+  fi
+ 
+  # Model: 7500 or 7551, 7552, etc.  (NOT 7550) -- these boards have mSD
+  if [ "$model" != "0x7550" ]; then
+    eval `sdctl -z 65536 --nbdserver lun0:disc,lun0:part1,lun0:part2,lun0:part3,lun0:part4 2>&1`
+    if [ "$cardsize_sectors" == "0" ]; then
+      killall sdctl >> $CONSOLE 2>&1
+    else
+      nbd-client 127.0.0.1 7500 /dev/nbd5
+      nbd-client 127.0.0.1 7501 /dev/nbd6
+      nbd-client 127.0.0.1 7502 /dev/nbd7
+      nbd-client 127.0.0.1 7503 /dev/nbd8
+      nbd-client 127.0.0.1 7504 /dev/nbd9
+      if [ "$bootdev" == "0x1" ]; then
+        mount -oro /dev/nbd9 /mnt/root
+      fi
+    fi
+  fi
+
+  # Software auto-update  
+  if [ -x /mnt/root/tsinit ]; then
+    /mnt/root/tsinit $XCONSOLE < $CONSOLE > $CONSOLE 2>&1
+  fi
+  
+) </dev/null >/dev/null 2>&1 &
+
+(
+  export ENV=/shinit
+  exec setsid cttyhack /bin/sh -i
+) <$CONSOLE >$CONSOLE 2>&1
+wait
+
+if [ -e /mnt/root/linuxrc ]; then
+  killall busybox telnetd >/dev/null 2>&1
+
+  cd /mnt/root
+  #pivot_root . ./initrd
+  #./bin/mount -n --move ./initrd/sys ./sys
+  #./bin/mount -n --move ./initrd/proc ./proc
+  /bin/mount -t proc none /mnt/root/proc
+  /bin/mount -t sysfs none /mnt/root/sysfs 
+  exec /usr/sbin/chroot /mnt/root /linuxrc < .$CONSOLE > .$CONSOLE 2>&1
+fi
diff --git a/recipes/ts7500/files/linuxrc-nandmount b/recipes/ts7500/files/linuxrc-nandmount
new file mode 100644
index 0000000..d6f8ef4
--- /dev/null
+++ b/recipes/ts7500/files/linuxrc-nandmount
@@ -0,0 +1,148 @@
+#!/bin/sh
+
+export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/mnt/root/bin:/mnt/root/sbin:/mnt/root
+mount -t proc proc /proc
+mount -t sysfs sysfs /sys
+mount -t devpts devpts /dev/pts
+  
+ifconfig lo 127.0.0.1 up
+route add -net 127.0.0.0 netmask 255.0.0.0 lo
+xuartctl --server
+
+# If the RESET switch is being pushed, 
+# set the CONSOLE to the DB9 port (/dev/pts/#)
+eval `ts7500ctl --getdio`
+let dio9="(dio >> 9) & 0x1"
+XCONSOLE=0
+
+if [ "$dio9" == "1" ]; then
+  export CONSOLE=/dev/ttyS0
+else
+  eval `xuartctl --server --port 0 </dev/null 2>&1`
+  if [ "$ttyname" == "" ]; then
+    export CONSOLE=/dev/ttyS0
+  else
+    export CONSOLE=$ttyname
+    XCONSOLE=1
+    # If the RESET switch is being pushed, wait until released
+    while [ "$dio9" == "0" ]; do
+    	eval `ts7500ctl --getdio`
+    	let dio9="(dio >> 9) & 0x1"
+    done
+  fi
+fi
+                
+let x=`devmem 0x79000040`
+sec=$((x / 100000))
+tenths=$((x % 100000 / 1000))
+export BOOTTIME=`printf "%d.%02d" $sec $tenths`
+
+setconsole $CONSOLE
+stty -F $CONSOLE ospeed 115200 sane > /dev/null 2>&1
+hostname ts7500                                   
+ts7500ctl --resetswitchon --setrng --getrtc --autofeed 2 -d
+ts7500ctl --loadfpga=ts7500_bitstream.vme.gz
+
+# Get the model # and boot device (NAND, mSD, SPI flash)
+eval `ts7500ctl --info`
+export bootdev model
+
+# If this is a 4500/8200, we need to set DIO-7 HIGH
+# (EN_USB_5V) for the USB's to work
+if [ "$model" = "0x4500" ]; then
+	eval `ts7500ctl --getdioreg`
+	let diodir="diodir | (1<<7)"
+	let dio_out="dio_out | (1<<7)"
+	ts7500ctl --setdio $dio_out --setdiodir $diodir
+fi
+
+# If there is a USB drive, mount it
+# If it has 'tsinit', execute it
+# (this allows software auto-update)                                
+devmem 0xc8000004 32 0x106
+devmem 0xcc000060 32 0x1
+let x=`devmem 0xcc000068`
+let y=`devmem 0xcc000064`
+x=$(((x | y) & 0x1))
+if [ "$x" -eq 1 ]; then
+  (
+        ts7500ctl --redledon
+	mount -t tmpfs tmpfs /lib/modules
+	tar -x -z -f /modules.tar.gz -C /
+	modprobe scsi_mod
+	modprobe sd_mod
+	modprobe usbcore
+	modprobe ehci_hcd
+	modprobe usb_storage
+	modprobe smsc95xx
+	modprobe ohci_hcd
+	umount /lib/modules
+	x=0
+	while [ "$x" -lt 150 -a ! -e /sys/block/sda ]; do
+		x=$((x+1))
+		sleep .1
+	done
+	mount -o ro /dev/sda1 /mnt/usbdev
+	if [ -x /mnt/usbdev/tsinit ]; then 
+		/mnt/usbdev/tsinit <$CONSOLE >$CONSOLE 2>&1
+	fi
+	umount /mnt/usbdev
+	ts7500ctl --redledoff
+  ) &
+fi
+
+(
+  mount -t tmpfs none /dev/shm
+  ifconfig eth0 192.168.0.9
+  telnetd
+  mount -t tmpfs tmpfs /tmp
+
+  # If 7500, mount mSD; else mount NAND
+  if [ "$model" = "0x7500" ]; then
+    	eval `sdctl -z 65536 --nbdserver lun0:disc,lun0:part1,lun0:part2,lun0:part3,lun0:part4 2>&1`
+    	if [ "$cardsize_sectors" == "0" ]; then
+      		killall sdctl >> $CONSOLE 2>&1
+    	else
+      		nbd-client 127.0.0.1 7500 /dev/nbd5
+      		nbd-client 127.0.0.1 7501 /dev/nbd6
+      		nbd-client 127.0.0.1 7502 /dev/nbd7
+      		nbd-client 127.0.0.1 7503 /dev/nbd8
+      		nbd-client 127.0.0.1 7504 /dev/nbd9
+      		if [ "$bootdev" == "0x1" ]; then
+        		mount -oro /dev/nbd9 /mnt/root
+      		fi
+      	fi
+  else
+    	nandctl -X -z 131072 --nbdserver lun0:disc,lun0:part1,lun0:part2,lun0:part3,lun0:part4
+    	nbd-client 127.0.0.1 7525 /dev/nbd0
+    	nbd-client 127.0.0.1 7526 /dev/nbd1
+    	nbd-client 127.0.0.1 7527 /dev/nbd2
+    	nbd-client 127.0.0.1 7528 /dev/nbd3
+    	nbd-client 127.0.0.1 7529 /dev/nbd4
+      	mount -oro /dev/nbd3 /mnt/root
+  fi
+ 
+
+  # Software auto-update  
+  if [ -x /mnt/root/tsinit ]; then
+    /mnt/root/tsinit $XCONSOLE < $CONSOLE > $CONSOLE 2>&1
+  fi
+  
+) </dev/null >/dev/null 2>&1 &
+
+(
+  export ENV=/shinit
+  exec setsid cttyhack /bin/sh -i
+) <$CONSOLE >$CONSOLE 2>&1
+wait
+
+if [ -e /mnt/root/sbin/init ]; then
+  killall busybox telnetd >/dev/null 2>&1
+
+  cd /mnt/root
+  pivot_root . ./initrd
+  ./bin/mount -n --move ./initrd/sys ./sys
+  ./bin/mount -n --move ./initrd/proc ./proc
+  exec ./usr/sbin/chroot . ./sbin/init < .$CONSOLE > .$CONSOLE 2>&1
+fi
+
diff --git a/recipes/ts7500/files/linuxrc-sdmount b/recipes/ts7500/files/linuxrc-sdmount
new file mode 100644
index 0000000..f642320
--- /dev/null
+++ b/recipes/ts7500/files/linuxrc-sdmount
@@ -0,0 +1,136 @@
+#!/bin/sh
+
+export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/mnt/root/bin:/mnt/root/sbin:/mnt/root
+mount -t proc proc /proc
+mount -t sysfs sysfs /sys
+mount -t devpts devpts /dev/pts
+  
+ifconfig lo 127.0.0.1 up
+route add -net 127.0.0.0 netmask 255.0.0.0 lo
+xuartctl --server
+
+# If the RESET switch is being pushed, 
+# set the CONSOLE to the DB9 port (/dev/pts/#)
+eval `ts7500ctl --getdio`
+let dio9="(dio >> 9) & 0x1"
+XCONSOLE=0
+
+if [ "$dio9" == "1" ]; then
+  export CONSOLE=/dev/ttyS0
+else
+  eval `xuartctl --server --port 0 </dev/null 2>&1`
+  if [ "$ttyname" == "" ]; then
+    export CONSOLE=/dev/ttyS0
+  else
+    export CONSOLE=$ttyname
+    XCONSOLE=1
+    # If the RESET switch is being pushed, wait until released
+    while [ "$dio9" == "0" ]; do
+    	eval `ts7500ctl --getdio`
+    	let dio9="(dio >> 9) & 0x1"
+    done
+  fi
+fi
+                
+let x=`devmem 0x79000040`
+sec=$((x / 100000))
+tenths=$((x % 100000 / 1000))
+export BOOTTIME=`printf "%d.%02d" $sec $tenths`
+
+setconsole $CONSOLE
+stty -F $CONSOLE ospeed 115200 sane > /dev/null 2>&1
+hostname ts7500                                   
+ts7500ctl --resetswitchon --setrng --getrtc --autofeed 2 -d
+ts7500ctl --loadfpga=ts7500_bitstream.vme.gz
+
+# Get the model # and boot device (NAND, mSD, SPI flash)
+eval `ts7500ctl --info`
+export bootdev model
+
+# If this is a 4500/8200, we need to set DIO-7 HIGH
+# (EN_USB_5V) for the USB's to work
+if [ "$model" = "0x4500" ]; then
+	eval `ts7500ctl --getdioreg`
+	let diodir="diodir | (1<<7)"
+	let dio_out="dio_out | (1<<7)"
+	ts7500ctl --setdio $dio_out --setdiodir $diodir
+fi
+
+# If there is a USB drive, mount it
+# If it has 'tsinit', execute it
+# (this allows software auto-update)                                
+devmem 0xc8000004 32 0x106
+devmem 0xcc000060 32 0x1
+let x=`devmem 0xcc000068`
+let y=`devmem 0xcc000064`
+x=$(((x | y) & 0x1))
+if [ "$x" -eq 1 ]; then
+  (
+        ts7500ctl --redledon
+	mount -t tmpfs tmpfs /lib/modules
+	tar -x -z -f /modules.tar.gz -C /
+	modprobe scsi_mod
+	modprobe sd_mod
+	modprobe usbcore
+	modprobe ehci_hcd
+	modprobe usb_storage
+	modprobe smsc95xx
+	modprobe ohci_hcd
+	umount /lib/modules
+	x=0
+	while [ "$x" -lt 150 -a ! -e /sys/block/sda ]; do
+		x=$((x+1))
+		sleep .1
+	done
+	mount -o ro /dev/sda1 /mnt/usbdev
+	if [ -x /mnt/usbdev/tsinit ]; then 
+		/mnt/usbdev/tsinit <$CONSOLE >$CONSOLE 2>&1
+	fi
+	umount /mnt/usbdev
+	ts7500ctl --redledoff
+  ) &
+fi
+
+(
+  mount -t tmpfs none /dev/shm
+  ifconfig eth0 192.168.0.9
+  telnetd
+  mount -t tmpfs tmpfs /tmp
+
+  # Always mount mSD, if present
+  eval `sdctl -z 65536 --nbdserver lun0:disc,lun0:part1,lun0:part2,lun0:part3,lun0:part4 2>&1`
+  if [ "$cardsize_sectors" == "0" ]; then
+	killall sdctl >> $CONSOLE 2>&1
+  else
+ 	nbd-client 127.0.0.1 7500 /dev/nbd5
+ 	nbd-client 127.0.0.1 7501 /dev/nbd6
+ 	nbd-client 127.0.0.1 7502 /dev/nbd7
+ 	nbd-client 127.0.0.1 7503 /dev/nbd8
+ 	nbd-client 127.0.0.1 7504 /dev/nbd9
+      	mount -oro /dev/nbd9 /mnt/root
+  fi
+ 
+
+  # Software auto-update  
+  if [ -x /mnt/root/tsinit ]; then
+    /mnt/root/tsinit $XCONSOLE < $CONSOLE > $CONSOLE 2>&1
+  fi
+  
+) </dev/null >/dev/null 2>&1 &
+
+(
+  export ENV=/shinit
+  exec setsid cttyhack /bin/sh -i
+) <$CONSOLE >$CONSOLE 2>&1
+wait
+
+if [ -e /mnt/root/sbin/init ]; then
+  killall busybox telnetd >/dev/null 2>&1
+
+  cd /mnt/root
+  pivot_root . ./initrd
+  ./bin/mount -n --move ./initrd/sys ./sys
+  ./bin/mount -n --move ./initrd/proc ./proc
+  exec ./usr/sbin/chroot . ./sbin/init < .$CONSOLE > .$CONSOLE 2>&1
+fi
+
diff --git a/recipes/ts7500/files/linuxrc-sdroot b/recipes/ts7500/files/linuxrc-sdroot
new file mode 100644
index 0000000..be0e715
--- /dev/null
+++ b/recipes/ts7500/files/linuxrc-sdroot
@@ -0,0 +1,179 @@
+#!/bin/sh
+
+export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/mnt/root/bin:/mnt/root/sbin:/mnt/root
+export INIT=sbin/init.sysvinit
+mount -t proc proc /proc
+mount -t sysfs sysfs /sys
+  
+ifconfig lo 127.0.0.1 up
+route add -net 127.0.0.0 netmask 255.0.0.0 lo
+xuartctl --server
+
+# If the RESET switch is being pushed,
+# set the CONSOLE to the DB9 port (/dev/pts/#)
+eval `ts7500ctl --getdio`
+let dio9="(dio >> 9) & 0x1"
+XCONSOLE=0
+
+if [ "$dio9" == "1" ]; then
+  export CONSOLE=/dev/ttyS0
+else
+  eval `xuartctl --server --port 0 </dev/null 2>&1`
+  if [ "$ttyname" == "" ]; then
+    export CONSOLE=/dev/ttyS0
+  else
+    export CONSOLE=$ttyname
+    XCONSOLE=1
+    # If the RESET switch is being pushed, wait until released
+    while [ "$dio9" == "0" ]; do
+	    eval `ts7500ctl --getdio`
+	    let dio9="(dio >> 9) & 0x1"
+    done
+  fi
+fi
+                
+setconsole $CONSOLE
+stty -F $CONSOLE ospeed 115200 sane > /dev/null 2>&1
+stty -F /dev/ttyS1 ospeed 115200 sane > /dev/null 2>&1          
+hostname ts7500    
+echo "Loading initrd..." > $CONSOLE
+ts7500ctl --resetswitchon --setrng --getrtc --autofeed 2 -d > $CONSOLE
+ts7500ctl --loadfpga=/ts7500/ts7500_bitstream.vme.gz > $CONSOLE
+
+# Get the model # and boot device (NAND, mSD, SPI flash)
+eval `ts7500ctl --info`
+export bootdev model
+
+# If this is a 4500/8200, we need to set DIO-7 HIGH                             
+# (EN_USB_5V) for the USB's to work
+if [ "$model" = "0x4500" ]; then                                                
+	eval `ts7500ctl --getdioreg`
+	let diodir="diodir | (1<<7)"
+	let dio_out="dio_out | (1<<7)"
+	ts7500ctl --setdio $dio_out --setdiodir $diodir
+fi
+                                
+# If there is a USB drive, mount it
+# If it has 'tsinit', execute it
+# (this allows software auto-update)
+echo "Checking for a USB drive..." > $CONSOLE
+devmem 0xc8000004 32 0x106
+devmem 0xcc000060 32 0x1
+let x=`devmem 0xcc000068`
+let y=`devmem 0xcc000064`
+x=$(((x | y) & 0x1))
+if [ "$x" -eq 1 ]; then
+  (
+      echo "USB Drive found! Loading modules..." > $CONSOLE                               
+        ts7500ctl --redledon
+	mount -t tmpfs tmpfs /lib/modules
+	tar -x -z -f /modules.tar.gz -C /
+	modprobe scsi_mod
+	modprobe sd_mod
+	modprobe usbcore
+	modprobe ehci_hcd
+	modprobe usb_storage
+        modprobe smsc95xx                                  
+        modprobe ohci_hcd
+	umount /lib/modules
+	x=0
+	while [ "$x" -lt 150 -a ! -e /sys/block/sda ]; do
+		x=$((x+1))
+		sleep .1
+	done
+	mount -o ro /dev/sda1 /mnt/usbdev
+	if [ -x /mnt/usbdev/tsinit ]; then 
+	    echo "Loading auto init script from USB drive!" > $CONSOLE
+		/mnt/usbdev/tsinit <$CONSOLE >$CONSOLE 2>&1
+	fi
+	umount /mnt/usbdev
+	ts7500ctl --redledoff
+  ) &
+fi
+
+(
+  # If booted from NAND, mount NAND's Linux partition
+  # If booted from mSD, mount mSD's Linux partition
+    
+  # Model: 7550, 7551, etc. (NOT 7500) -- these boards have NAND
+  if [ "$model" != "0x7500" ]; then
+    nandctl -X -z 131072 --nbdserver lun0:disc,lun0:part1,lun0:part2,lun0:part3,lun0:part4
+    nbd-client 127.0.0.1 7525 /dev/nbd0
+    nbd-client 127.0.0.1 7526 /dev/nbd1
+    nbd-client 127.0.0.1 7527 /dev/nbd2
+    nbd-client 127.0.0.1 7528 /dev/nbd3
+    nbd-client 127.0.0.1 7529 /dev/nbd4
+    if [ "$bootdev" == "0x0" ]; then
+      mount -oro /dev/nbd3 /mnt/root
+    fi
+  fi
+  
+  # Model: 7500 or 7551, 7552, etc.  (NOT 7550) -- these boards have mSD
+  if [ "$model" != "0x7550" ]; then
+    echo "Mounting sdcard..." > $CONSOLE                               
+    eval `sdctl -z 65536 --nbdserver lun0:disc,lun0:part1,lun0:part2,lun0:part3,lun0:part4 > $CONSOLE 2>&1`
+    if [ "$cardsize_sectors" == "0" ]; then
+      killall sdctl >> $CONSOLE 2>&1
+    else
+      nbd-client 127.0.0.1 7500 /dev/nbd5
+      nbd-client 127.0.0.1 7501 /dev/nbd6
+      nbd-client 127.0.0.1 7502 /dev/nbd7
+      nbd-client 127.0.0.1 7503 /dev/nbd8
+      nbd-client 127.0.0.1 7504 /dev/nbd9
+      if [ "$bootdev" == "0x1" ]; then	  
+          mount -oro /dev/nbd8 /mnt/root
+	  mount -oro /dev/nbd9 /mnt/root/var
+      fi
+    fi
+  fi
+  echo "   > Done loading SD Card!" > $CONSOLE
+  # Software auto-update
+  if [ -x /mnt/root/tsinit ]; then
+    /mnt/root/tsinit $XCONSOLE < $CONSOLE > $CONSOLE 2>&1
+  fi
+  
+) </dev/null >/dev/null 2>&1 
+
+if [ -e /mnt/root/notrootfs -o -e /mnt/root/fastboot -o ! -e /mnt/root/$INIT  ]; then
+  if [ -e /mnt/root/fastboot ]; then
+    echo ">> File 'fastboot' found. Booting to initrd instead..." > $CONSOLE
+  else
+    echo ">> SD Card failed. Booting to initrd..." > $CONSOLE
+  fi
+
+  (                                                                             
+    mount -t devpts devpts /dev/pts
+    mount -t tmpfs none /dev/shm
+    ifconfig eth0 192.168.0.50
+    telnetd
+    mount -t tmpfs tmpfs /tmp
+  ) </dev/null >/dev/null 2>&1
+
+  (
+    let x=`devmem 0x79000040`
+    sec=$((x / 100000))
+    tenths=$((x % 100000 / 1000))
+    export BOOTTIME=`printf "%d.%02d" $sec $tenths`
+    export ENV=/shinit
+    exec setsid cttyhack /bin/sh -i
+  ) <$CONSOLE >$CONSOLE 2>&1
+  wait
+fi
+
+if [ -e /mnt/root/$INIT  ]; then
+  killall busybox telnetd >/dev/null 2>&1
+  #cd /mnt/root
+  #pivot_root . ./initrd
+  #./bin/mount -n --move ./initrd/sys ./sys
+  #./bin/mount -n --move ./initrd/proc ./proc
+  echo "Mounting filesystems read/write..." > $CONSOLE
+  /bin/mount -o remount,rw /mnt/root                                            
+  /bin/mount -o remount,rw /mnt/root/var  
+  echo "Done!" > $CONSOLE
+  /bin/mount -t proc none /mnt/root/proc
+  /bin/mount -t sysfs none /mnt/root/sys 
+  /bin/mount -o bind /dev /mnt/root/dev
+  /bin/mkdir /mnt/root/dev/pts
+  /bin/mount -o bind /dev/pts /mnt/root/dev/pts
+  exec /usr/sbin/chroot /mnt/root /$INIT < .$CONSOLE > .$CONSOLE 2>&1
+fi
diff --git a/recipes/ts7500/files/linuxrc-sdroot-readonly b/recipes/ts7500/files/linuxrc-sdroot-readonly
new file mode 100644
index 0000000..baa9f38
--- /dev/null
+++ b/recipes/ts7500/files/linuxrc-sdroot-readonly
@@ -0,0 +1,188 @@
+#!/bin/sh
+
+export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/mnt/root/bin:/mnt/root/sbin:/mnt/root
+export INIT=sbin/init.sysvinit
+mount -t proc proc /proc
+mount -t sysfs sysfs /sys
+  
+ifconfig lo 127.0.0.1 up
+route add -net 127.0.0.0 netmask 255.0.0.0 lo
+xuartctl --server
+
+# If the RESET switch is being pushed,
+# set the CONSOLE to the DB9 port (/dev/pts/#)
+eval `ts7500ctl --getdio`
+let dio9="(dio >> 9) & 0x1"
+XCONSOLE=0
+
+if [ "$dio9" == "1" ]; then
+  export CONSOLE=/dev/ttyS0
+else
+  eval `xuartctl --server --port 0 </dev/null 2>&1`
+  if [ "$ttyname" == "" ]; then
+    export CONSOLE=/dev/ttyS0
+  else
+    export CONSOLE=$ttyname
+    XCONSOLE=1
+    # If the RESET switch is being pushed, wait until released
+    while [ "$dio9" == "0" ]; do
+	    eval `ts7500ctl --getdio`
+	    let dio9="(dio >> 9) & 0x1"
+    done
+  fi
+fi
+                
+setconsole $CONSOLE
+stty -F $CONSOLE ospeed 115200 sane > /dev/null 2>&1
+stty -F /dev/ttyS1 ospeed 115200 sane > /dev/null 2>&1          
+hostname ts7500    
+echo "Loading initrd..." > $CONSOLE
+ts7500ctl --resetswitchon --setrng --getrtc --autofeed 2 -d > $CONSOLE
+ts7500ctl --loadfpga=/ts7500/ts7500_bitstream.vme.gz > $CONSOLE
+
+# Get the model # and boot device (NAND, mSD, SPI flash)
+eval `ts7500ctl --info`
+export bootdev model
+
+# If this is a 4500/8200, we need to set DIO-7 HIGH                             
+# (EN_USB_5V) for the USB's to work
+if [ "$model" = "0x4500" ]; then                                                
+	eval `ts7500ctl --getdioreg`
+	let diodir="diodir | (1<<7)"
+	let dio_out="dio_out | (1<<7)"
+	ts7500ctl --setdio $dio_out --setdiodir $diodir
+fi
+                                
+# If there is a USB drive, mount it
+# If it has 'tsinit', execute it
+# (this allows software auto-update)
+echo "Checking for a USB drive..." > $CONSOLE
+devmem 0xc8000004 32 0x106
+devmem 0xcc000060 32 0x1
+let x=`devmem 0xcc000068`
+let y=`devmem 0xcc000064`
+x=$(((x | y) & 0x1))
+if [ "$x" -eq 1 ]; then
+  (
+      echo "USB Drive found! Loading modules..." > $CONSOLE                               
+        ts7500ctl --redledon
+	mount -t tmpfs tmpfs /lib/modules
+	tar -x -z -f /modules.tar.gz -C /
+	modprobe scsi_mod
+	modprobe sd_mod
+	modprobe usbcore
+	modprobe ehci_hcd
+	modprobe usb_storage
+        modprobe smsc95xx                                  
+        modprobe ohci_hcd
+	umount /lib/modules
+	x=0
+	while [ "$x" -lt 150 -a ! -e /sys/block/sda ]; do
+		x=$((x+1))
+		sleep .1
+	done
+	mount -o ro /dev/sda1 /mnt/usbdev
+	if [ -x /mnt/usbdev/tsinit ]; then 
+	    echo "Loading auto init script from USB drive!" > $CONSOLE
+		/mnt/usbdev/tsinit <$CONSOLE >$CONSOLE 2>&1
+	fi
+	umount /mnt/usbdev
+	ts7500ctl --redledoff
+  ) &
+fi
+
+(
+  # If booted from NAND, mount NAND's Linux partition
+  # If booted from mSD, mount mSD's Linux partition
+    
+  # Model: 7550, 7551, etc. (NOT 7500) -- these boards have NAND
+  if [ "$model" != "0x7500" ]; then
+    nandctl -X -z 131072 --nbdserver lun0:disc,lun0:part1,lun0:part2,lun0:part3,lun0:part4
+    nbd-client 127.0.0.1 7525 /dev/nbd0
+    nbd-client 127.0.0.1 7526 /dev/nbd1
+    nbd-client 127.0.0.1 7527 /dev/nbd2
+    nbd-client 127.0.0.1 7528 /dev/nbd3
+    nbd-client 127.0.0.1 7529 /dev/nbd4
+    if [ "$bootdev" == "0x0" ]; then
+      mount -oro /dev/nbd3 /mnt/root
+    fi
+  fi
+  
+  # Model: 7500 or 7551, 7552, etc.  (NOT 7550) -- these boards have mSD
+  if [ "$model" != "0x7550" ]; then
+    echo "Mounting sdcard..." > $CONSOLE                               
+    eval `sdctl -z 65536 --nbdserver lun0:disc,lun0:part1,lun0:part2,lun0:part3,lun0:part4 > /dev/null 2>&1`
+    if [ "$cardsize_sectors" == "0" ]; then
+      killall sdctl >> $CONSOLE 2>&1
+    else
+      nbd-client 127.0.0.1 7500 /dev/nbd5
+      nbd-client 127.0.0.1 7501 /dev/nbd6
+      nbd-client 127.0.0.1 7502 /dev/nbd7
+      nbd-client 127.0.0.1 7503 /dev/nbd8
+      nbd-client 127.0.0.1 7504 /dev/nbd9
+      if [ "$bootdev" == "0x1" ]; then	 
+	  mkdir /mnt/root.ro /mnt/root.var
+          mount -oro /dev/nbd8 /mnt/root.ro
+	  mount -oro /dev/nbd9 /mnt/root.var
+      fi
+    fi
+  fi
+  
+  # Software auto-update
+  if [ -x /mnt/root.ro/tsinit ]; then
+    /mnt/root.ro/tsinit $XCONSOLE < $CONSOLE > $CONSOLE 2>&1
+  fi
+  
+) </dev/null >/dev/null 2>&1 
+
+if [ -e /mnt/root.ro/notrootfs -o -e /mnt/root.ro/fastboot -o ! -e /mnt/root.ro/$INIT ]; then
+  if [ -e /mnt/root.ro/fastboot ]; then
+    echo ">> File 'fastboot' found. Booting to initrd instead..." > $CONSOLE
+  else
+    echo ">> SD Card failed. Booting to initrd..." > $CONSOLE
+  fi
+
+  (                                                                             
+    mount -t devpts devpts /dev/pts
+    mount -t tmpfs none /dev/shm
+    ifconfig eth0 192.168.0.50
+    telnetd
+    mount -t tmpfs tmpfs /tmp
+  ) </dev/null >/dev/null 2>&1
+
+  (
+    let x=`devmem 0x79000040`
+    sec=$((x / 100000))
+    tenths=$((x % 100000 / 1000))
+    export BOOTTIME=`printf "%d.%02d" $sec $tenths`
+    export ENV=/shinit
+    exec setsid cttyhack /bin/sh -i
+  ) <$CONSOLE >$CONSOLE 2>&1
+  wait
+fi
+
+if [ -e /mnt/root.ro/$INIT ]; then
+  killall busybox telnetd >/dev/null 2>&1
+  #cd /mnt/root
+  #pivot_root . ./initrd
+  #./bin/mount -n --move ./initrd/sys ./sys
+  #./bin/mount -n --move ./initrd/proc ./proc
+  echo "Mounting unionfs..." > $CONSOLE
+  /bin/mkdir /mnt/root.ro /mnt/root.rw /mnt/root.var
+  /bin/mount -o remount,rw /mnt/root.var 
+  /bin/mount -t tmpfs root.rw /mnt/root.rw
+  /bin/mount -t unionfs -o dirs=/mnt/root.rw=rw:/mnt/root.var=rw:/mnt/root.ro=ro unionfs /mnt/root/
+  /bin/chmod 755 /mnt/root
+  /bin/mkdir /mnt/root/ro /mnt/root/rw /mnt/root/vardir
+  /bin/mount --move /mnt/root.ro /mnt/root/ro
+  /bin/mount --move /mnt/root.rw /mnt/root/rw
+  /bin/mount --move /mnt/root.var /mnt/root/vardir
+  echo "Done mounting unionfs!" > $CONSOLE
+
+  /bin/mount -t proc none /mnt/root/proc
+  /bin/mount -t sysfs none /mnt/root/sys 
+  /bin/mount -o bind /dev /mnt/root/dev
+  /bin/mkdir /mnt/root/dev/pts
+  /bin/mount -o bind /dev/pts /mnt/root/dev/pts
+  exec /usr/sbin/chroot /mnt/root /$INIT < .$CONSOLE > .$CONSOLE 2>&1
+fi
diff --git a/recipes/ts7500/files/linuxrc-usbroot b/recipes/ts7500/files/linuxrc-usbroot
new file mode 100644
index 0000000..c210884
--- /dev/null
+++ b/recipes/ts7500/files/linuxrc-usbroot
@@ -0,0 +1,163 @@
+#!/bin/sh
+
+export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/mnt/root/bin:/mnt/root/sbin:/mnt/root
+mount -t proc proc /proc
+mount -t sysfs sysfs /sys
+  
+ifconfig lo 127.0.0.1 up
+route add -net 127.0.0.0 netmask 255.0.0.0 lo
+xuartctl --server
+
+eval `ts7500ctl --getdio`
+let dio9="(dio >> 9) & 0x1"
+XCONSOLE=0
+
+# If the RESET switch is being pushed,
+# set the CONSOLE to the DB9 port (/dev/pts/#)
+if [ "$dio9" == "1" ]; then
+  export CONSOLE=/dev/ttyS0
+else
+  eval `xuartctl --server --port 0 </dev/null 2>&1`
+  if [ "$ttyname" == "" ]; then
+    export CONSOLE=/dev/ttyS0
+  else
+    export CONSOLE=$ttyname
+    XCONSOLE=1
+    # If the RESET switch is being pushed, wait until released
+    while [ "$dio9" == "0" ]; do
+	  eval `ts7500ctl --getdio`
+	  let dio9="(dio >> 9) & 0x1"
+    done
+  fi
+fi
+                
+setconsole $CONSOLE
+stty -F $CONSOLE ospeed 115200 sane > /dev/null 2>&1
+hostname ts7500                                   
+ts7500ctl --resetswitchon --setrng --getrtc --autofeed 2 -d
+ts7500ctl --loadfpga=ts7500_bitstream.vme.gz
+
+# Get the model # and boot device (NAND, mSD, SPI flash)
+eval `ts7500ctl --info`
+export bootdev model
+
+# If this is a 4500/8200, we need to set DIO-7 HIGH
+# (EN_USB_5V) for the USB's to work
+if [ "$model" = "0x4500" ]; then
+	eval `ts7500ctl --getdioreg`
+	let diodir="diodir | (1<<7)"
+	let dio_out="dio_out | (1<<7)"
+	ts500ctl --setdio $dio_out --setdiodir $diodir
+fi
+ 
+# If there is a USB drive, mount it
+# If it has 'tsinit', execute it
+# (this allows software auto-update)                                
+devmem 0xc8000004 32 0x106
+devmem 0xcc000060 32 0x1
+let x=`devmem 0xcc000068`
+let y=`devmem 0xcc000064`
+x=$(((x | y) & 0x1))
+if [ "$x" -eq 1 ]; then
+  (
+  	echo "Booting from USB device ... " > $CONSOLE
+        ts7500ctl --redledon
+	mount -t tmpfs tmpfs /lib/modules
+	tar -x -z -f /modules.tar.gz -C /
+	modprobe scsi_mod
+	modprobe sd_mod
+	modprobe usbcore
+	modprobe ehci_hcd
+	modprobe usb_storage
+        modprobe smsc95xx                                  
+        modprobe ohci_hcd
+	umount /lib/modules
+	x=0
+	while [ "$x" -lt 150 -a ! -e /sys/block/sda ]; do
+		x=$((x+1))
+		sleep .1
+	done
+	mount -o ro /dev/sda4 /mnt/root
+
+	ts7500ctl --redledoff
+  ) 
+fi
+
+(
+  # If booted from NAND, mount NAND's Linux partition
+  # If booted from mSD, mount mSD's Linux partition
+    
+  # Model: 7550, 7551, etc. (NOT 7500) -- these boards have NAND
+  if [ "$model" != "0x7500" ]; then
+    nandctl -X -z 131072 --nbdserver lun0:disc,lun0:part1,lun0:part2,lun0:part3,lun0:part4
+    nbd-client 127.0.0.1 7525 /dev/nbd0
+    nbd-client 127.0.0.1 7526 /dev/nbd1
+    nbd-client 127.0.0.1 7527 /dev/nbd2
+    nbd-client 127.0.0.1 7528 /dev/nbd3
+    nbd-client 127.0.0.1 7529 /dev/nbd4
+    if [ "$bootdev" == "0x0" ]; then
+      mkdir /mnt/nand_root
+      mount -oro /dev/nbd3 /mnt/nand_root
+    fi
+  fi
+  
+  # Model: 7500 or 7551, 7552, etc.  (NOT 7550) -- these boards have mSD 
+  if [ "$model" != "0x7550" ]; then
+    eval `sdctl -z 65536 --nbdserver lun0:disc,lun0:part1,lun0:part2,lun0:part3,lun0:part4 2>&1`
+    if [ "$cardsize_sectors" == "0" ]; then
+      killall sdctl >> $CONSOLE 2>&1
+    else
+      nbd-client 127.0.0.1 7500 /dev/nbd5
+      nbd-client 127.0.0.1 7501 /dev/nbd6
+      nbd-client 127.0.0.1 7502 /dev/nbd7
+      nbd-client 127.0.0.1 7503 /dev/nbd8
+      nbd-client 127.0.0.1 7504 /dev/nbd9
+      if [ "$bootdev" == "0x1" ]; then
+        mount /mnt/sd_root 
+        mount -oro /dev/nbd9 /mnt/sd_root
+      fi
+    fi
+  fi
+  
+  # Software auto-update
+  if [ -x /mnt/root/tsinit ]; then
+    /mnt/root/tsinit $XCONSOLE < $CONSOLE > $CONSOLE 2>&1
+  fi
+  
+) </dev/null >/dev/null 2>&1 
+
+if [ -e /mnt/root/notrootfs -o -e /mnt/root/fastboot -o ! -e /mnt/root/sbin/init ]; then
+  if [ -e /mnt/root/fastboot ]; then
+    echo ">> File 'fastboot' found. Booting to initrd instead..." > $CONSOLE
+  else
+    echo ">> USB Drive failed. Booting to initrd..." > $CONSOLE
+  fi
+
+  (                                                                             
+    mount -t devpts devpts /dev/pts
+    mount -t tmpfs none /dev/shm
+    ifconfig eth0 192.168.0.50
+    telnetd
+    mount -t tmpfs tmpfs /tmp
+  ) </dev/null >/dev/null 2>&1
+
+  (
+    let x=`devmem 0x79000040`
+    sec=$((x / 100000))
+    tenths=$((x % 100000 / 1000))
+    export BOOTTIME=`printf "%d.%02d" $sec $tenths`
+    export ENV=/shinit
+    exec setsid cttyhack /bin/sh -i
+  ) <$CONSOLE >$CONSOLE 2>&1
+  wait
+fi
+
+if [ -e /mnt/root/sbin/init ]; then
+  killall busybox telnetd 
+  cd /mnt/root
+  pivot_root . ./initrd
+  ./bin/mount -n --move ./initrd/sys ./sys
+  ./bin/mount -n --move ./initrd/proc ./proc
+  exec ./usr/sbin/chroot . ./sbin/init < .$CONSOLE > .$CONSOLE 2>&1
+fi
+
diff --git a/recipes/ts7500/files/passwd b/recipes/ts7500/files/passwd
new file mode 100644
index 0000000..0891d68
--- /dev/null
+++ b/recipes/ts7500/files/passwd
@@ -0,0 +1,9 @@
+root::0:0:root:/home/root:/bin/sh
+daemon:*:1:1:daemon:/usr/sbin:/bin/sh
+bin:*:2:2:bin:/bin:/bin/sh
+sys:*:3:3:sys:/dev:/bin/sh
+sync:*:4:65534:sync:/bin:/bin/sync
+man:*:6:12:man:/var/cache/man:/bin/sh
+proxy:*:13:13:proxy:/bin:/bin/sh
+nobody:*:65534:65534:nobody:/nonexistent:/bin/sh
+v2g::500:500:UD-V2G GIV-User,,,:/home/v2g:/bin/sh
diff --git a/recipes/ts7500/files/ts-utils.patch b/recipes/ts7500/files/ts-utils.patch
new file mode 100644
index 0000000..b337a7d
--- /dev/null
+++ b/recipes/ts7500/files/ts-utils.patch
@@ -0,0 +1,68 @@
+diff -rupN old/jed2vme.c new/jed2vme.c
+--- old/jed2vme.c	2011-03-09 11:34:07.000000000 -0500
++++ new/jed2vme.c	2011-03-09 11:34:38.000000000 -0500
+@@ -18,6 +18,7 @@
+  */
+ #include <stdio.h>
+ #include <stdlib.h>
++#include <string.h>
+ #include <assert.h>
+ 
+ static unsigned char preamble[] = {
+diff -rupN old/sdctl.c new/sdctl.c
+--- old/sdctl.c	2011-03-09 11:51:29.000000000 -0500
++++ new/sdctl.c	2011-03-09 11:34:10.000000000 -0500
+@@ -16,6 +16,7 @@
+  *  WITHOUT THE PRIOR WRITTEN CONSENT OF TECHNOLOGIC SYSTEMS  COULD
+  *  SUBJECT THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+  */
++#include <errno.h>
+ #include <assert.h>
+ #include <string.h>
+ #include <fcntl.h>
+@@ -82,7 +83,11 @@ static volatile unsigned int *cvspiregs,
+ #define MEM_GETPGD       _IOR(0xaa, 1, unsigned long)
+ #ifndef PPC
+ #define __NR_cacheflush __ARM_NR_cacheflush
+-static inline _syscall3(int,cacheflush,unsigned long,beg,unsigned long,end,int,flags);
++// static inline _syscall3(int,cacheflush,unsigned long,beg,unsigned long,end,int,flags);
++static inline int cacheflush (unsigned long beg, unsigned long end, int flags)
++{
++  return syscall(__NR_cacheflush, beg, end, flags);
++}
+ #endif
+ 
+ static int devmem, devkmem;
+diff -rupN old/spiflashctl.c new/spiflashctl.c
+--- old/spiflashctl.c	2011-03-09 11:34:07.000000000 -0500
++++ new/spiflashctl.c	2011-03-09 11:37:00.000000000 -0500
+@@ -17,6 +17,7 @@
+  *  SUBJECT THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+  */
+ 
++#include <errno.h>
+ #include <assert.h>
+ #include <string.h>
+ #include <fcntl.h>
+diff -rupN old/ts7500ctl.c new/ts7500ctl.c
+--- old/ts7500ctl.c	2011-03-09 11:52:15.000000000 -0500
++++ new/ts7500ctl.c	2011-03-09 11:34:10.000000000 -0500
+@@ -16,6 +16,7 @@
+  *  WITHOUT THE PRIOR WRITTEN CONSENT OF TECHNOLOGIC SYSTEMS  COULD
+  *  SUBJECT THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
+  */
++#include <errno.h>
+ #include <assert.h>
+ #include <string.h>
+ #include <fcntl.h>
+diff -rupN old/xuartctl.c new/xuartctl.c
+--- old/xuartctl.c	2011-03-09 11:34:07.000000000 -0500
++++ new/xuartctl.c	2011-03-09 11:40:47.000000000 -0500
+@@ -18,6 +18,7 @@
+  * CRIMINAL AND CIVIL LIABILITY.
+  */
+ 
++#include <limits.h>
+ #include <sys/socket.h>
+ #include <stdio.h>
+ #include <stdlib.h>
diff --git a/recipes/ts7500/files/ts7500.subr b/recipes/ts7500/files/ts7500.subr
new file mode 100644
index 0000000..b2ee180
--- /dev/null
+++ b/recipes/ts7500/files/ts7500.subr
@@ -0,0 +1,633 @@
+warn1="WARNING: do NOT power-down while saving/copying!"
+img="[kernel+initrd]"
+
+# ----------------------------------------------------------
+# Display the given number in binary format
+printbin() {
+# NOTE: assume only 7 digits, since getdio() only seem to give 7
+#       will only print the first 7 digits either way
+
+	digits="1 2 3 4 5 6 7"
+	# Loop thru the given hex digits
+	for digit in $digits; do
+		num=`echo $1 | cut -c${digit}`
+		if 	[ "$num" = "a" ]; then num="10"
+		elif 	[ "$num" = "b" ]; then num="11"
+		elif 	[ "$num" = "c" ]; then num="12"
+		elif 	[ "$num" = "d" ]; then num="13"
+		elif 	[ "$num" = "e" ]; then num="14"
+		elif 	[ "$num" = "f" ]; then num="15"
+		fi
+
+		# Loop thru the 4 binary digits:
+		# AND with 0x8 to get the MSB, display it
+		# SHIFT left, do the next digit
+		loops="1 2 3 4 "
+		for loop in $loops; do
+			bin=$((num&0x8));
+			if [ "$bin" = "0" ]; then 
+				echo -n "0"
+			else 
+				echo -n "1" 
+			fi
+			num=$((num<<1))
+		done
+		echo -n " "	
+	done	
+	# echo	
+}
+
+
+cvtime() {
+	local x sec tenths
+	let x=`devmem 0x79000040`
+	sec=$((x / 100000))
+	tenths=$((x % 100000 / 1000))
+	printf "%d.%02d" $sec $tenths
+	
+# Return the value read from mem
+return $x
+}
+
+
+usbload() {
+	mount -t tmpfs tmpfs /lib/modules
+	tar -x -z -f /modules.tar.gz -C /
+	modprobe scsi_mod
+	modprobe sd_mod
+	modprobe usbcore
+	modprobe ehci_hcd
+	modprobe usb_storage
+	umount /lib/modules
+}
+
+
+save() {
+	# Determine the boot device used:
+	# 	media		dev
+	#--------------------
+	# NAND/SPI-0	0 (NOTE: must determine model also!)
+	# mSD			1
+	# SPI-1			2
+	#--------------------
+	# 
+	local dev=`ts7500ctl -i | grep bootdev | cut -d= -f2 | cut -c3-`
+	if [ $dev -eq 0 ]; then
+		# Determine the model
+		local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+		if [ $model -eq 7500 ]; then
+			flashsave
+		else
+			nandsave
+		fi
+	elif [ $dev -eq 1 ]; then
+		sdsave
+	elif [ $dev -eq 2 ]; then
+		flash1save
+	fi
+}
+
+
+sdsave() {
+	echo "$warn1"
+	echo -n "Saving [initrd] to mSD ... "
+	mount -o remount,ro /
+	sdctl -W 32 -k part3 -z 65536 -i /dev/ram0 >/dev/null 2>&1
+	mount -o remount,rw /
+	echo "done"
+}
+
+
+nandsave() {
+	echo "$warn1"
+	echo -n "Saving [initrd] to NAND ... "
+	mount -o remount,ro /
+	nandctl -W 16 -k part2 -z 131072 -X -i /dev/ram0 >/dev/null 2>&1
+	mount -o remount,rw /
+	echo "done"
+}
+
+
+flashsave() {
+# Determine the model
+# If this is NOT a 7500, skip
+local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+if [ "$model" -ne 7500 ]; then
+	echo "TS-${model} does NOT have ON-board FLASH -- ABORTING"
+	echo "('flash1save' = save to OFF-board FLASH)"
+	echo "('nandsave'   = save to NAND)"
+	return
+fi
+
+	echo "$warn1"
+	echo -n "Saving [initrd] to ON-board FLASH ... "
+	mount -o remount,ro /
+	spiflashctl -W 32 -k part2 -z 65536 -i /dev/ram0 > /dev/null 2>&1
+	mount -o remount,rw /
+	echo "done"
+}
+
+
+flash1save() {
+	echo "$warn1"
+	echo -n "Saving [initrd] to OFF-board FLASH ... "
+	mount -o remount,ro /
+	spiflashctl -l 1 -W 32 -k part2 -z 65536 -i /dev/ram0 > /dev/null 2>&1
+	mount -o remount,rw /
+	echo "done"
+}
+
+
+flashallsave() {
+	flashsave
+	flash1save
+}
+	
+
+# ----------------------------------------------------------
+# Copy from micro SD
+sd2flash() {
+# Determine the model
+# If this is a 7550 or 7551, skip (NO micro SD on these boards)
+local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+if [ "$model" -eq 7550 -o $model -eq 7551 ]; then
+	echo "TS-${model} does NOT have micro SD -- ABORTING"
+	echo "(Try: flash2flash, nand2flash)"
+	return
+fi
+
+	echo "$warn1"
+	echo -n "Copying $img mSD --> ON-board FLASH ..."
+	sdctl -R 32 -z 65536 -k part2 > /tmp/image 2>/dev/null
+	spiflashctl -W 32 -z 65536 -k part1 -i /tmp/image > /dev/null 2>&1
+	rm /tmp/image
+	wait
+	
+	sdctl -R 32 -z 65536 -k part3 > /tmp/image 2>/dev/null
+	spiflashctl -W 32 -z 65536 -k part2 -i /tmp/image > /dev/null 2>&1
+	rm /tmp/image
+	echo "done"
+}
+
+sd2flash1() {
+# Determine the model
+# If this is a 7550 or 7551, skip (NO micro SD on these boards)
+local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+if [ "$model" -eq 7550 -o $model -eq 7551 ]; then
+	echo "TS-${model} does NOT have micro SD -- ABORTING"
+	echo "(Try: flash2flash, nand2flash)"
+	return
+fi
+
+	echo "$warn1"
+	echo -n "Copying $img mSD --> OFF-board FLASH ..."
+	sdctl -R 32 -z 65536 -k part2 > /tmp/image 2>/dev/null
+	spiflashctl -l 1 -W 32 -z 65536 -k part1 -i /tmp/image > /dev/null 2>&1
+	rm /tmp/image
+	wait
+	
+	sdctl -R 32 -z 65536 -k part3 > /tmp/image 2>/dev/null
+	spiflashctl -l 1 -W 32 -z 65536 -k part2 -i /tmp/image > /dev/null 2>&1
+	rm /tmp/image
+	echo "done"
+}
+
+
+sd2nand() {
+# Determine the model
+# If this is a 7550 or 7551, skip (NO micro SD on these boards)
+local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+if [ "$model" -eq 7550 -o "$model" -eq 7551 ]; then
+	echo "TS-${model} does NOT have micro SD -- ABORTING"
+	echo "(Try: flash2nand)"
+	return
+fi
+
+	echo "$warn1"
+	echo -n "Copying $img mSD --> NAND ... "
+	sdctl -R 32 -z 65536 -k part2 > /tmp/image 2>/dev/null
+	nandctl -W 16 -z 131072 -k part1 -X -i /tmp/image > /dev/null 2>&1
+	# sdctl -R 4095 -z 512 -k kernel > /tmp/image 2>/dev/null
+	# nandctl -W 4095 -z 512 -k kernel -X -i /tmp/image > /dev/null 2>&1
+	rm /tmp/image
+	wait
+	
+	sdctl -R 32 -z 65536 -k part3 > /tmp/image 2>/dev/null
+	nandctl -W 16 -z 131072 -k part2 -X -i /tmp/image >/dev/null 2>&1
+	rm /tmp/image
+	echo "done"
+}
+
+# ----------------------------------------------------------
+# Copy from FLASH
+flash2flash() {
+# Determine the model
+# If this is NOT a 7500, skip (only the 7500 has ON-board FLASH)
+local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+if [ "$model" -ne 7500 ]; then
+	echo "TS-${model} does NOT have ON-board FLASH -- ABORTING"
+	echo "(Try: sd2flash, nand2flash)"
+	return
+fi
+
+	# Determine the boot media, so we can copy from there
+	local dev=`ts7500ctl -i | grep bootdev | cut -d= -f2 | cut -c3-`
+	echo "$warn1"
+	if [ $dev -eq 0 ]; then
+		echo -n "Copying $img ON-board FLASH --> OFF-board FLASH ... "
+		spiflashctl -R 64 -z 65536 > /tmp/image 2>/dev/null
+		spiflashctl -l 1 -W 64 -z 65536 -i /tmp/image > /dev/null 2>&1
+	elif [ $dev -eq 2 ]; then
+		echo -n "Copying $img OFF-board FLASH --> ON-board FLASH ... "
+		spiflashctl -l 1 -R 64 -z 65536 > /tmp/image 2>/dev/null
+		spiflashctl -W 64 -z 65536 -i /tmp/image > /dev/null 2>&1
+	fi
+
+	rm /tmp/image
+	echo "done"
+}
+
+
+flash2sd() {
+# Determine the model
+# If this is a 7550 or 7551, skip (NO micro SD on these boards)
+local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+if [ "$model" -eq 7550 -o $model -eq 7551 ]; then
+	echo "TS-${model} does NOT have micro SD -- ABORTING"
+	return
+fi
+
+	# Determine the boot media, so we can copy from there
+	local dev=`ts7500ctl -i | grep bootdev | cut -d= -f2 | cut -c3-`
+	# Assume FLASH-0
+	local lun=""
+	local flash="ON-board"
+	if [ $dev -eq 2 ]; then
+		lun="-l 1"
+		flash="OFF-board"
+	fi
+	
+	echo "$warn1"
+	echo -n "Copying $img $flash FLASH --> mSD ... "
+	spiflashctl ${lun} -R 32 -z 65536 -k part1 > /tmp/image 2>/dev/null
+	sdctl -W 32 -z 65536 -k part2 -i /tmp/image >/dev/null 2>&1
+	rm /tmp/image
+	wait
+	
+	spiflashctl ${lun} -R 32 -z 65536 -k part2 > /tmp/image 2>/dev/null
+	sdctl -W 32 -z 65536 -k part3 -i /tmp/image >/dev/null 2>&1
+	rm /tmp/image
+	echo "done"
+}
+
+
+flash2nand() {
+# Determine the model
+# If this is a 7500, skip (NO NAND on this board)
+local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+if [ "$model" -eq 7500 ]; then
+	echo "TS-${model} does NOT have NAND -- ABORTING"
+	echo "(Try: flash2flash, flash2sd)"
+	return
+fi
+
+	echo "$warn1"
+	echo -n "Copying $img OFF-board FLASH --> NAND ... "
+	spiflashctl -l 1 -R 64 -z 65536 > /tmp/image 2>/dev/null
+	nandctl -W 32 -z 131072 -X -i /tmp/image > /dev/null 2>&1
+	rm /tmp/image
+	echo "done"
+}
+
+
+# ----------------------------------------------------------
+# Copy from NAND
+nand2flash() {
+# Determine the model
+# If this is a 7500, skip (NO NAND on this board)
+local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+if [ "$model" -eq 7500 ]; then
+	echo "TS-${model} does NOT have NAND -- ABORTING"
+	echo "(Try: flash2flash, sd2flash)"
+	return
+fi
+
+	echo "$warn1"
+	echo "Copying $img NAND --> OFF-board FLASH ... "
+	nandctl -R 32 -z 131072 -X > /tmp/image 2>/dev/null
+	spiflashctl -l 1 -W 64 -z 65536 -i /tmp/image > /dev/null 2>&1
+	rm /tmp/image
+	echo "done"
+}
+
+
+nand2sd() {
+# Determine the model
+# If this is a 7550 or 7551, skip (NO micro SD on these boards)
+local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+if [ "$model" -eq 7550 -o "$model" -eq 7551 ]; then
+	echo "TS-${model} does NOT have micro SD -- ABORTING"
+	echo "(Try: nand2flash)"
+	return
+fi
+
+	echo "$warn1"
+	echo "Copying $img NAND --> mSD ... "
+	nandctl -R 16 -z 131072 -k part1 -X > /tmp/image 2>/dev/null
+	sdctl -W 32 -z 65536 -k part2 -i /tmp/image >/dev/null 2>&1
+	rm /tmp/image
+	wait
+	
+	nandctl -R 16 -z 131072 -k part2 -X > /tmp/image 2>/dev/null
+	sdctl -W 32 -z 65536 -k part3 -i /tmp/image >/dev/null 2>&1
+	rm /tmp/image
+	echo "done"
+}
+
+
+recover() {
+# 'Un-brick" a board
+# [try to] copy the kernel/initrd images from the boot device to ...
+
+# Scenarios:
+# Model	Boot		Recover
+#==============================
+# 7500	FLASH-1	(2)	FLASH-0/mSD
+# 7500	FLASH-0	(0)	mSD
+# 7500	mSD		(1)	FLASH-0
+# 7550	FLASH-1	(2)	NAND
+# 7550	NAND	(0)	-----
+# 7551	FLASH-1	(2)	NAND
+# 7551	NAND	(0)	-----
+# 7552	FLASH-1	(2)	NAND/mSD
+# 7552	mSD		(1)	NAND
+# 7552	NAND	(0)	mSD
+# 7553	FLASH-1	(2)	NAND/mSD
+# 7553	mSD		(1)	NAND
+# 7553	NAND	(0)	mSD
+
+# 	media		dev
+#--------------------
+# NAND/FLASH-0	0 (NOTE: must determine model also!)
+# mSD		1
+# FLASH-1	2
+#--------------------
+# 
+	# Determine the boot device and model
+	local dev=`ts7500ctl -i | grep bootdev | cut -d= -f2 | cut -c3-`
+	local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+	local device
+	if [ $dev -eq 0 ]; then
+		if [ $model -eq 7500 ]; then
+			device="ONboard FLASH"
+		else
+			device="NAND"
+		fi
+	elif [ $dev -eq 1 ]; then
+		device="micro SD"
+	elif [ $dev -eq 2 ]; then
+		device="OFFboard FLASH"
+	fi
+	
+	echo "(TS-${model}, booted from ${device}) "
+
+	# Determine what to recover
+	# 7500
+	if [ $model -eq 7500 ]; then
+		# from FLASH-1 --> FLASH-0/mSD
+		if [ $dev -eq 2 ]; then
+			echo -n "Recover FLASH-0 ? --> [y/n]: "
+			read ans
+			if [ "$ans" = "y" ]; then
+				flash2flash
+			fi
+			echo -n "Recover micro SD ? --> [y/n]: "
+			read ans
+			if [ "$ans" = "y" ]; then
+				flash2sd
+			fi
+		# from FLASH-0 --> mSD
+		elif [ $dev -eq 0 ]; then
+			echo -n "Recover micro SD ? --> [y/n]: "
+			read ans
+			if [ "$ans" = "y" ]; then
+				flash2sd
+			fi
+		# from mSD --> FLASH-0
+		elif [ $dev -eq 1 ]; then
+			echo -n "Recover FLASH-0 ? --> [y/n]: "
+			read ans
+			if [ "$ans" = "y" ]; then
+				sd2flash
+			fi
+		fi
+	# 7550/7551
+	elif [ $model -eq 7550 -o $model -eq 7551 ]; then
+		# from FLASH-1 --> NAND
+		if [ $dev -eq 2 ]; then
+			echo -n "Recover NAND ? --> [y/n]: "
+			read ans
+			if [ "$ans" = "y" ]; then
+				flash2nand
+			fi
+		# from NAND --> nothing to recover!
+		elif [ $dev -eq 0 ]; then
+			echo "NOTHING to recover -- try \"nand2flash\""
+		fi
+	# 7552/7553
+	elif [ $model -eq 7552 -o $model -eq 7553 ]; then
+		# from FLASH-1 --> NAND/mSD
+		if [ $dev -eq 2 ]; then
+			echo -n "Recover NAND ? --> [y/n]: "
+			read ans
+			if [ "$ans" = "y" ]; then
+				flash2nand
+			fi
+			echo -n "Recover micro SD ? --> [y/n]: "
+			read ans
+			if [ "$ans" = "y" ]; then
+				flash2sd
+			fi
+		# from mSD --> NAND
+		elif [ $dev -eq 1 ]; then
+			echo -n "Recover NAND ? --> enter [y/n]: "
+			read ans
+			if [ "$ans" = "y" ]; then
+				sd2nand
+			fi
+		# from NAND --> mSD
+		elif [ $dev -eq 0 ]; then
+			echo -n "Recover micro SD ? --> enter [y/n]: "
+			read ans
+			if [ "$ans" = "y" ]; then
+				nand2sd
+			fi
+		fi
+	fi
+}
+
+
+#Usage: setdiopin <pin> <1,0,Z> <b>
+# Second arg:
+#	1= ON, 0= OFF, z= input mode
+# Third arg:
+#	if present, print DIO reg in binary
+setdiopin() {
+	if [ -z "$dio_out" ]; then
+		eval `ts7500ctl --getdioreg`
+	fi
+	case $2 in
+	0)
+		let diodir="diodir | (1<<$1)"
+		let dio_out="dio_out & ~(1<<$1)"
+		;;
+	1)
+		let diodir="diodir | (1<<$1)"
+		let dio_out="dio_out | (1<<$1)" 
+		;;
+	z|Z)
+		let diodir="diodir & ~(1<<$1)"
+		;;
+	esac
+	ts7500ctl --setdio $dio_out --setdiodir $diodir
+	
+	if [ "$3" = "b" ]; then
+		local dir=`ts7500ctl --getdioreg | grep diodir | cut -dx -f2`
+		echo -n "DIR= "
+		printbin $dir
+		echo
+		local out=`ts7500ctl --getdioreg | grep dio_out | cut -dx -f2`
+		echo -n "OUT= "
+		printbin $out
+		echo
+	fi
+	#return $dionum
+}
+
+
+#Usage: getdiopin <pin>
+getdiopin() {
+	local x dio
+	eval `ts7500ctl --getdio`
+	let x="(dio >> $1) & 0x1"
+	echo $x
+	return $x
+}
+
+
+#TS-752 utility functions
+setrelay() {
+	local x
+	let x="$1"
+	setdiopin 39 $((x & 0x1))
+	setdiopin 37 $(((x >> 1) & 0x1)) 
+	setdiopin 35 $(((x >> 2) & 0x1)) 
+
+# Return the value given
+# NOTE: maybe we can return the ACTUAL relay status?-JW
+return $x	
+}
+
+
+setout() {
+	local x
+	let x="$1"
+	setdiopin 33 $((x & 0x1))
+	setdiopin 31 $(((x >> 1) & 0x1)) 
+	setdiopin 29 $(((x >> 2) & 0x1)) 
+	
+# Return the value given
+# NOTE: maybe we can return the ACTUAL pin status?-JW
+return $x
+}
+
+
+getin() {
+	local x dio
+	eval `ts7500ctl --getdio`
+	let x="(dio >> 40) & 1"
+	let x="x | (((dio >> 38) & 1) << 1)"
+	let x="x | (((dio >> 36) & 1) << 2)"
+	let x="x | (((dio >> 34) & 1) << 3)"
+	let x="x | (((dio >> 32) & 1) << 4)"
+	let x="x | (((dio >> 30) & 1) << 5)"
+	let x="x | (((dio >> 28) & 1) << 6)"
+	let x="x | (((dio >> 26) & 1) << 7)"
+	if [ -z "$1" ]; then
+		printf "0x%x\n" $x
+		return $x
+	else
+		echo $(((x >> ($1 - 1)) & 1))
+		return $(((x >> ($1 - 1)) & 1)) 
+	fi
+}
+
+
+tshelp() {
+	echo "usbload:"
+	echo -e "\tLoad USB kernel drivers"
+	echo "setdiopin <pin> <1,0,Z> <b>:"
+	echo -e "\tSet DIO header pin 1-44 (b=dump binary)"
+	echo "getdiopin <pin>:"
+	echo -e "\tGet DIO input state"
+	echo "setrelay <val>:"
+	echo -e "\tTurn on/off TS-752 relays according to 3-bit val"
+	echo "setout <val>:"
+	echo -e "\tSet 3-bit TS-752 output val"
+	echo "getin:"
+	echo -e "\tReturn 8 bit TS-752 inputs"
+	echo "gettemp:"
+	echo -e "\tReturn Temp. Sensor reading"
+	echo "save:"
+	echo -e "\tSave initrd back to boot device (NANS, SD or SPI flash)"
+	echo "sd2nand/nand2sd, sd2flash/flash2sd, nand2flash/flash2nand, etc:"
+	echo -e "\tCopy kernel+initrd images from one media to another"
+	echo "recover:"
+	echo -e "\tRecover kernel+initrd images"
+	echo "sbcTest:"
+	echo -e "\tRun TS production tests (NOTE: need loop-back testers)"
+	echo "exit:" 
+	echo -e "\tBoot SD card (if present) or filesystem mounted at /mnt/root"
+}
+
+
+gettemp() {
+# Determine the board model
+# If 7500 or 7550, use local function
+# For all other boards, use "ts7500ctl --gettemp"
+local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
+if [ "$model" -ne 7500 -a $model -ne 7550 ]; then
+	ts7500ctl --gettemp
+	return
+fi
+
+	local n x val
+	setdiopin 22 0
+	setdiopin 12 Z
+	n=0
+	while [ $n -lt 13 ]; do
+		setdiopin 14 0
+		setdiopin 14 1
+		x=`getdiopin 12`
+		if [ "$x" -eq 0 ]; then
+			let val="val << 1"
+		else
+			let val="(val << 1) | 1"
+		fi
+		let n="n + 1"
+	done
+	setdiopin 22 Z
+	setdiopin 14 Z
+	if [ $((val & 0x1000)) -ne 0 ]; then
+		val=$(((~(val & 0xfff) & 0xfff) + 1))
+		val=$((val * 62500))
+		printf "-%d." $((val / 1000000))
+		printf "%d\n" $(((val % 1000000) / 100000))
+	else
+		val=$((val * 62500))
+		printf "%d." $((val / 1000000))
+		printf "%d\n" $(((val % 1000000) / 100000))
+	fi
+	
+	return $val
+}
diff --git a/recipes/ts7500/spictl_0.0.1.bb b/recipes/ts7500/spictl_0.0.1.bb
new file mode 100644
index 0000000..bc0a392
--- /dev/null
+++ b/recipes/ts7500/spictl_0.0.1.bb
@@ -0,0 +1,26 @@
+DESCRIPTION = "TS 7500 spictl scripts"
+PR = "r0"
+DEPENDS = ""
+SRC_URI = " \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/spictl.tar.gz \
+"
+
+SRC_URI[md5sum] = "8144833fecbf9162ec47a7ec7e6695a5"
+SRC_URI[sha256sum] = "5ebdb995b58a7c914ab8c9213a41789095285139ee82a89a4fb73bfc3e0f7a13"
+
+S = "${WORKDIR}/spictl"
+
+do_compile () {
+	   ${CC}${CFLAGS} -g -c -o spictl.o spictl.c
+	   ${CC}${CFLAGS} -g -c -o sock.o sock.c
+	   ${CC}${CFLAGS} -g -c -o peekpoke.o peekpoke.c
+	   ${CC}${CFLAGS} -g -c -o opt.o opt.c
+	   ${CC}${CFLAGS} -g -c -o cavium.o cavium.c
+	   ${CC}${CFLAGS} -g -c -o file.o file.c
+	   ${CC}${CFLAGS} -g ${LDFLAGS} -o spictl spictl.o sock.o peekpoke.o opt.o cavium.o file.o
+}
+
+do_install () {
+	   install -d ${D}${base_sbindir}/
+	   install -m 0755 ${S}/spictl ${D}${base_sbindir}/
+}
diff --git a/recipes/ts7500/ts-initrd_0.0.1.bb b/recipes/ts7500/ts-initrd_0.0.1.bb
new file mode 100644
index 0000000..8954bd9
--- /dev/null
+++ b/recipes/ts7500/ts-initrd_0.0.1.bb
@@ -0,0 +1,46 @@
+DESCRIPTION = "TS 7500 initrd scripts"
+PR = "r0"
+DEPENDS = ""
+SRC_URI = " \
+	file://linuxrc-sdroot \
+	file://linuxrc-sdroot-readonly \
+	file://linuxrc-fastboot \
+	file://linuxrc-sdmount \
+	file://linuxrc-usbroot \
+	file://linuxrc-nandmount \  
+	file://passwd \
+	file://group \
+	file://ts7500_opencore_can.vme.comp \
+	file://ts7500.subr \
+"
+
+S= "${WORKDIR}"
+
+do_install () {
+	   install -d ${D}/ts7500
+	   install -m 0755 ${WORKDIR}/linuxrc-sdroot ${D}/ts7500
+	   install -m 0755 ${WORKDIR}/linuxrc-sdroot-readonly ${D}/ts7500
+	   install -m 0755 ${WORKDIR}/linuxrc-fastboot ${D}/ts7500
+	   install -m 0755 ${WORKDIR}/linuxrc-sdmount ${D}/ts7500
+	   install -m 0755 ${WORKDIR}/linuxrc-usbroot ${D}/ts7500
+	   install -m 0755 ${WORKDIR}/linuxrc-nandmount ${D}/ts7500
+	   install -m 0755 ${WORKDIR}/ts7500_opencore_can.vme.comp -T ${D}/ts7500/ts7500_opencore_can.vme.gz
+	   install -m 0755 ${WORKDIR}/ts7500.subr ${D}/ts7500
+	   install -d ${D}/${sysconfdir}
+	   install -m 0755 ${WORKDIR}/passwd ${D}/${sysconfdir}/passwd
+	   install -m 0755 ${WORKDIR}/group ${D}/${sysconfdir}/group
+	   
+}
+
+FILES_${PN} = "/ \
+	    /ts7500/linuxrc-sdroot \
+	    /ts7500/linuxrc-sdroot-readonly \
+	    /ts7500/linuxrc-fastboot \
+	    /ts7500/linuxrc-sdmount \
+	    /ts7500/linuxrc-usbroot \
+	    /ts7500/linuxrc-nandmount \
+	    /ts7500/ts7500.subr \
+	    /ts7500/ts7500_opencore_can.vme.gz \
+	    ${sysconfdir}/passwd \
+	    ${sysconfdir}/group \
+	    "
\ No newline at end of file
diff --git a/recipes/ts7500/ts-utils_0.0.1.bb b/recipes/ts7500/ts-utils_0.0.1.bb
new file mode 100644
index 0000000..bd7a72e
--- /dev/null
+++ b/recipes/ts7500/ts-utils_0.0.1.bb
@@ -0,0 +1,60 @@
+DESCRIPTION = "TS 7500 Utility Scripts"
+PR = "r0"
+DEPENDS = ""
+SRC_URI = " \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/jed2vme.c;name=jed2vmec \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/sdcore2.c;name=sdcore2c \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/sdctl.c;name=sdctlc \	
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/vmopcode.h;name=vmopcodeh \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/ispvm.c;name=ispvmc \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/ts7500ctl.c;name=ts7500ctlc \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/spiflashctl.c;name=spiflashctlc \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/xuartcore.c;name=xuartcorec \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/xuartcore.h;name=xuartcoreh \
+	ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/xuartctl.c;name=xuartctlc \
+	file://ts-utils.patch \
+"
+
+S = "${WORKDIR}"
+
+do_compile () {
+	   ${CC}${CFLAGS} -g ${LDFLAGS} -o jed2vme jed2vme.c
+	   ${CC}${CFLAGS} -g ${LDFLAGS} -o sdctl sdctl.c
+	   ${CC}${CFLAGS} -g -c -o ispvm.o ispvm.c
+	   ${CC}${CFLAGS} -g -c -o ts7500ctl.o ts7500ctl.c
+	   ${CC}${CFLAGS} -g ${LDFLAGS} -o ts7500ctl ts7500ctl.o ispvm.o	
+	   ${CC}${CFLAGS} -g ${LDFLAGS} -o spiflashctl spiflashctl.c
+	   ${CC}${CFLAGS} -g -c -o xuartcore.o xuartcore.c
+	   ${CC}${CFLAGS} -g -c -o xuartctl.o xuartctl.c
+	   ${CC}${CFLAGS} -g ${LDFLAGS} -o xuartctl xuartctl.o -lutil
+}
+
+do_install () {
+	   install -d ${D}${base_sbindir}/
+     	   install -m 0755 ${S}/jed2vme ${D}${base_sbindir}/
+   	   install -m 0755 ${S}/sdctl ${D}${base_sbindir}/
+	   install -m 0755 ${S}/ts7500ctl ${D}${base_sbindir}/
+   	   install -m 0755 ${S}/spiflashctl ${D}${base_sbindir}/
+   	   install -m 0755 ${S}/xuartctl ${D}${base_sbindir}/
+}
+
+SRC_URI[ispvmc.md5sum] = "99d3a017c52fd9cbb0c97f4a829eda0b"
+SRC_URI[ispvmc.sha256sum] = "548b0b53861ee6cdb4f13859ec428ad2f3aa53e8237fbca54463c1eb6f47be9d"
+SRC_URI[jed2vmec.md5sum] = "65ca2ecada2c6d1bbb489561f2f5f039"
+SRC_URI[jed2vmec.sha256sum] = "7351011403b6254b2cdb46d9958f4be81023565fcd91d21fbf51d5cce0491d4a"
+SRC_URI[sdcore2c.md5sum] = "3ad3f7ed650cf140b2ed2d83f0fc05b2"
+SRC_URI[sdcore2c.sha256sum] = "1246031ab3715ece923c276a180c2322851b625ad27b13241cd6219daf16dc99"
+SRC_URI[sdctlc.md5sum] = "4e0b1cd33afd0da7babeca66b03b5d5e"
+SRC_URI[sdctlc.sha256sum] = "9760853e2f04724116f0bef6786a4d2ac5e532fedcd53ae42a16bce528fbbeaa"
+SRC_URI[spiflashctlc.md5sum] = "e42e593409000451e7d6c0c61d5827c8"
+SRC_URI[spiflashctlc.sha256sum] = "c221ff69f905d793698afcdf5d4212d60685bb11adf8b128a4947088958695f4"
+SRC_URI[ts7500ctlc.md5sum] = "52ca09f12aa09d8271e699f471761ff5"
+SRC_URI[ts7500ctlc.sha256sum] = "8ee9b6af97d7632c089c837a763e5fca5976c4e13607028cd181d55ec0fb1a8e"
+SRC_URI[vmopcodeh.md5sum] = "64b1ae9de8e0e059ad06e9bd777f3edb"
+SRC_URI[vmopcodeh.sha256sum] = "7c55ea5854b481c1b09fca38f89a6d3ca24199f931509cd2756d9931f21c4be2"
+SRC_URI[xuartcorec.md5sum] = "376e7aff2fc724681599711f34922eb4"
+SRC_URI[xuartcorec.sha256sum] = "88c1d619cad4c675c068857cac189a2838adf84d8340f298e8b279dd414abfef"
+SRC_URI[xuartcoreh.md5sum] = "1ccd2b36c06718224925e1ff4c5cd293"
+SRC_URI[xuartcoreh.sha256sum] = "a0a5021513659ab069b8507fdedd835b5b47c962cd30ea68d1a017d94c1210ba"
+SRC_URI[xuartctlc.md5sum] = "a5825b26b9fef3af1532915f2bba2b43"
+SRC_URI[xuartctlc.sha256sum] = "0897a08ac7bbab07592ce41e664ce1c3887b23318a21f42b8ad3a0d06286c6c9"
diff --git a/recipes/ts7500/ts7500_0.0.1.bb b/recipes/ts7500/ts7500_0.0.1.bb
new file mode 100644
index 0000000..de4f398
--- /dev/null
+++ b/recipes/ts7500/ts7500_0.0.1.bb
@@ -0,0 +1,7 @@
+DESCRIPTION = "TS 7500 Utility Scripts"
+MAINTAINER = "Sachin Kamboj"
+PR = "r0"
+# ALLOW_EMPTY = 1
+DEPENDS = "canctl ts-utils  dioctl  dmxctl  spictl nbd"
+RDEPENDS = "canctl ts-utils  dioctl  dmxctl  spictl nbd-client"
+PROVIDES = "ts7500"
-- 
1.7.3.4




^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 5/6] Added images for the TS7500 ARM SBCs
  2011-03-30 14:07 [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
                   ` (2 preceding siblings ...)
  2011-03-30 14:07 ` [PATCH 4/6] Add recipes for building TS75xx userspace utilities UDel V2G Team
@ 2011-03-30 14:07 ` UDel V2G Team
  2011-03-30 14:33   ` Marcin Juszkiewicz
  2011-03-30 14:07 ` [PATCH 6/6] Adds custom defconfigs for Technologic Systems " UDel V2G Team
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: UDel V2G Team @ 2011-03-30 14:07 UTC (permalink / raw)
  To: openembedded-devel

* This commit includes two images - one for building the initrd image and the other for
  building the rootfs image.

Signed-off-by: UDel V2G Team <v2g.udel@gmail.com>
---
 files/device_table-ts75xx.txt         |   66 +++++++++++
 recipes/images/ts75xx-initrd-image.bb |   89 ++++++++++++++
 recipes/images/ts75xx-rootfs-image.bb |  206 +++++++++++++++++++++++++++++++++
 3 files changed, 361 insertions(+), 0 deletions(-)
 create mode 100644 files/device_table-ts75xx.txt
 create mode 100644 recipes/images/ts75xx-initrd-image.bb
 create mode 100644 recipes/images/ts75xx-rootfs-image.bb

diff --git a/files/device_table-ts75xx.txt b/files/device_table-ts75xx.txt
new file mode 100644
index 0000000..feacaa0
--- /dev/null
+++ b/files/device_table-ts75xx.txt
@@ -0,0 +1,66 @@
+#<path> <type> <mode>   <uid>   <gid>   <major> <minor> <start> <inc>   <count>
+#/dev/mem    c      640      0       0       1       1       0        0        -
+#
+#type can be one of: 
+#    f  A regular file
+#    d  Directory
+#    c  Character special device file
+#    b  Block special device file
+#    p  Fifo (named pipe)
+/dev            d       755     0       0       -       -       -       -       -
+/dev/initctl    p       600     0       0       -       -       -       -       -
+/dev/pts	d	775	0	0	-	-	-	-	-
+/dev/shm	d	775	0	0	-	-	-	-	-
+/var		d	775	0	0	-	-	-	-	-
+/boot/var/empty	d	755	0	3	-	-	-	-
+/dev/apm_bios	c	660	0	46	10	134	-	-	-
+/dev/console	c	660	0	5	5	1	-	-
+/dev/full	c	666	0	7	-	-	-
+/dev/i2c0	c	660	0	0	89	0	-	-	-
+/dev/kmem	c	640	0	15	1	2	-	-	-
+/dev/kmsg	c	640	0	0	1	11	-	-	-
+/dev/loop0	b	660	0	11	7	0	-	-	-
+/dev/loop1	b	660	0	11	7	1	-	-	-
+/dev/mem	c	640	0	15	1	1	-	-	-
+/dev/mtd	c	660	0	6	90	0	0	2	8
+/dev/mtdblock	b	640	0	0	31	0	0	1	8
+/dev/nbd0	b	664	0	0	43	0	-	-	-
+/dev/nbd1	b	664	0	0	43	1	-	-	-
+/dev/nbd2	b	664	0	0	43	2	-	-	-
+/dev/nbd3	b	664	0	0	43	3	-	-	-
+/dev/nbd4	b	664	0	0	43	4	-	-	-
+/dev/nbd5	b	664	0	0	43	5	-	-	-
+/dev/nbd6	b	664	0	0	43	6	-	-	-
+/dev/nbd7	b	664	0	0	43	7	-	-	-
+/dev/nbd8	b	664	0	0	43	8	-	-	-
+/dev/nbd9	b	664	0	0	43	9	-	-	-
+/dev/nbd10	b	664	0	0	43	10	-	-	-
+/dev/nbd11	b	664	0	0	43	11	-	-	-
+/dev/nbd12	b	664	0	0	43	12	-	-	-
+/dev/nbd13	b	664	0	0	43	13	-	-	-
+/dev/nbd14	b	664	0	0	43	14	-	-	-
+/dev/nbd15	b	664	0	0	43	15	-	-	-
+/dev/null	c	666	0	0	1	3	-	-	-
+/dev/port	c	640	0	15	1	4	-	-	-
+/dev/ppp	c	640	0	0	108	0	-	-	-
+/dev/psaux	c	660	0	0	10	1	-	-	-
+/dev/ptmx	c	666	0	5	5	2	-	-	-
+/dev/ram0	b	644	0	0	1	0	0	1	4
+/dev/ram1	b	660	0	0	1	1	0	1	4
+/dev/ram2	b	660	0	0	1	2	0	1	4
+/dev/ram3	b	660	0	0	1	3	0	1	4
+/dev/random	c	444	0	0	1	8	-	-	-
+/dev/rtc	c	660	0	47	10	135	-	-	-
+/dev/sda	b	660	0	6	8	0	-	-	-
+/dev/sda1	b	660	0	6	8	1	-	-	-
+/dev/sda2	b	660	0	6	8	2	-	-	-
+/dev/sda3	b	660	0	6	8	3	-	-	-
+/dev/sda4	b	660	0	6	8	4	-	-	-
+/dev/tty	c	664	0	5	5	0	-	-	-
+/dev/ttyS0	c	660	0	5	4	64	0	1	2
+/dev/ttyS1	c	660	0	5	4	65	0	1	2
+/dev/ttyUSB	c	660	0	5	188	0	0	1	2
+/dev/urandom	c	644	0	0	1	9	-	-	-
+/dev/usbdev1.1_ep00	c	660	0	5	254	0	-	-	-
+/dev/usbdev1.1_ep81	c	660	0	5	254	1	-	-	-
+/dev/zero	c	644	0	0	1	5	-	-	-
diff --git a/recipes/images/ts75xx-initrd-image.bb b/recipes/images/ts75xx-initrd-image.bb
new file mode 100644
index 0000000..306bf3a
--- /dev/null
+++ b/recipes/images/ts75xx-initrd-image.bb
@@ -0,0 +1,89 @@
+# This is an initrd recipe for the Technologic Systems TS7500 board
+#
+# The generated initrd image will be very similar to stock initrd
+# that can be downloaded from:
+# ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/binaries/ts-images/
+# with a few changes:
+# 1. All the linuxrc and ts-bitstreams have been moved to the ts7500 directory
+# 2. The linuxrc scripts have been modified to mount the third partition 
+#    of the SD card as root (/) and the fourth partition as /var
+# 3. All the ts utilities included in /sbin now use the EABI, so the OABI
+#    support in the kernel is no longer needed
+# 4. Unionfs is not built into the kernel, so it no longer needs to be
+#    loaded as a module.
+
+# Use a newer version of busybox since it includes the nbd-client applet.
+# We no longer need to build the nbd-client program since we enable this.
+DEPENDS = "busybox-1.18.3"
+
+IMAGE_INSTALL = "busybox canctl dioctl dmxctl spictl ts-utils ts-initrd \
+	      kernel-module-crash \
+	      kernel-module-ehci-hcd \
+	      kernel-module-input-core \
+	      kernel-module-inthandler \
+	      kernel-module-scsi-mod \
+	      kernel-module-scsi-wait-scan \
+	      kernel-module-sd-mod \
+	      kernel-module-sg \
+	      kernel-module-usbcore \
+	      kernel-module-usb-storage \
+	      "
+IMAGE_LINGUAS = ""
+
+# We don't need a login manager or init scripts 
+IMAGE_LOGIN_MANAGER = ""
+
+# Include minimum init and init scripts
+IMAGE_DEV_MANAGER = "busybox-mdev"
+IMAGE_INIT_MANAGER = ""
+IMAGE_INITSCRIPTS = ""
+
+# This should build all the correct device tables.
+IMAGE_DEVICE_TABLES = "files/device_table-ts75xx.txt"
+
+fix_image () {
+	  echo "Fixing Image... ${IMAGE_ROOTFS}"
+	  # Delete extra files
+	  for file in "${IMAGE_ROOTFS}/usr/bin/opkg* \
+	      ${IMAGE_ROOTFS}/usr/bin/update-alternatives \
+	      ${IMAGE_ROOTFS}/usr/lib/* \
+	      ${IMAGE_ROOTFS}/usr/share/* \
+	      ${IMAGE_ROOTFS}/var/lib/opkg \
+	      ${IMAGE_ROOTFS}/sbin/diotest* \
+	      ${IMAGE_ROOTFS}/sbin/dioctl \
+	      ${IMAGE_ROOTFS}/lib/libdioctl.so.1.0.1 \
+	      ${IMAGE_ROOTFS}/lib/modules \
+	      ${IMAGE_ROOTFS}/etc/* \
+	      ${IMAGE_ROOTFS}/var/*" ; 
+          do rm -r ${file} ; done
+	  
+	  # Make extra nodes
+	  for file in "${IMAGE_ROOTFS}/mnt/root \
+	      ${IMAGE_ROOTFS}/mnt/root/var \
+	      ${IMAGE_ROOTFS}/lib/modules \
+	      ${IMAGE_ROOTFS}/proc \
+	      ${IMAGE_ROOTFS}/sys \
+	      ${IMAGE_ROOTFS}/var/run \
+	      ${IMAGE_ROOTFS}/var/lock" ; 
+          do mkdir -p ${file} ; done
+	  
+	  # Copy over the linuxrc scripts
+	  cp ${IMAGE_ROOTFS}/ts7500/linuxrc-sdroot-readonly ${IMAGE_ROOTFS}/linuxrc
+}
+
+create_modules_gz () {
+	  OLDPWD=`pwd`
+	  cd ${IMAGE_ROOTFS}
+	  tar cvzf ${IMAGE_ROOTFS}/modules.tar.gz lib/modules
+	  cd $OLDPWD
+}
+
+# Remove any kernel-image that the kernel-module-* packages may have pulled in.
+PACKAGE_REMOVE = "kernel-image-* update-modules"
+ROOTFS_POSTPROCESS_COMMAND += "create_modules_gz ; opkg-cl ${IPKG_ARGS} -force-depends \
+                                remove ${PACKAGE_REMOVE}; "
+
+IMAGE_PREPROCESS_COMMAND += "fix_image ; "
+
+export IMAGE_BASENAME = "ts75xx-initrd-image"
+inherit image
diff --git a/recipes/images/ts75xx-rootfs-image.bb b/recipes/images/ts75xx-rootfs-image.bb
new file mode 100644
index 0000000..689d264
--- /dev/null
+++ b/recipes/images/ts75xx-rootfs-image.bb
@@ -0,0 +1,206 @@
+# This is an rootfs recipe for the Technologic Systems TS7500 board
+#
+# The TS7500 boards are meant to be booted using an initrd 
+# partition - so most of the init scripts in the rcS.d directory
+# and not needed. This image deletes those unneeded scripts. 
+# See the ts75xx-initrd-image.bb for the recipe for
+# building the initrd image. 
+#
+# This recipe also includes java. Feel free to disable it if not needed.
+
+IMAGE_PREPROCESS_COMMAND = "create_etc_timestamp ; "
+IMAGE_INIT_MANAGER = "sysvinit"
+DISTRO_SSH_DAEMON = "openssh"
+BUILD_ALL_DEPS = "1"
+
+IMAGE_DEVICE_TABLES = "files/device_table-ts75xx.txt"
+
+DEPENDS = "\
+	task-proper-tools \
+	${DISTRO_SSH_DAEMON} \
+	${@base_contains('MACHINE_FEATURES', 'ext2', 'task-base-ext2', '', d)} \
+	${@base_contains('MACHINE_FEATURES', 'usbhost', 'task-base-usbhost', '', d)} \
+	canctl dioctl dmxctl spictl ts-utils ts-initrd \
+	coreutils \
+	findutils \
+	bash \
+	python \
+	ntp \
+	cron \
+	nano \
+	task-java \
+	dhclient \
+	dhcpcd \
+	"
+
+KERNEL_MODULES = "\
+     	kernel-module-aes-generic \
+     	kernel-module-ansi-cprng \
+	kernel-module-arptable-filter \
+     	kernel-module-arp-tables \
+     	kernel-module-arpt-mangle \
+     	kernel-module-atkbd \
+     	kernel-module-cn \
+     	kernel-module-crash \
+     	kernel-module-crc-itu-t \
+     	kernel-module-ehci-hcd \
+     	kernel-module-firmware-class \
+     	kernel-module-hid \
+     	kernel-module-input-core \
+     	kernel-module-inthandler \
+     	kernel-module-ip-queue \
+     	kernel-module-iptable-filter \
+     	kernel-module-iptable-mangle \
+     	kernel-module-iptable-nat \
+     	kernel-module-iptable-raw \
+     	kernel-module-ip-tables \
+     	kernel-module-ipt-addrtype \
+     	kernel-module-ipt-ah \
+     	kernel-module-ipt-ecn \
+     	kernel-module-ipt-log \
+     	kernel-module-ipt-masquerade \
+    	kernel-module-ipt-netmap \
+     	kernel-module-ipt-redirect \
+     	kernel-module-ipt-reject \
+     	kernel-module-ipt-ulog \
+     	kernel-module-ipv6 \
+     	kernel-module-libps2 \
+     	kernel-module-michael-mic \
+     	kernel-module-mousedev \
+     	kernel-module-nf-conntrack \
+     	kernel-module-nf-conntrack-ipv4 \
+     	kernel-module-nf-conntrack-pptp \
+     	kernel-module-nf-conntrack-proto-gre \
+     	kernel-module-nf-defrag-ipv4 \
+     	kernel-module-nf-nat \
+     	kernel-module-nf-nat-pptp \
+     	kernel-module-nf-nat-proto-gre \
+     	kernel-module-nfnetlink \
+     	kernel-module-nfnetlink-log \
+     	kernel-module-nfnetlink-queue \
+     	kernel-module-ohci-hcd \
+     	kernel-module-psmouse \
+     	kernel-module-r8a66597-udc \
+     	kernel-module-rng-core \
+     	kernel-modules \
+     	kernel-module-scsi-mod \
+     	kernel-module-scsi-wait-scan \
+     	kernel-module-sd-mod \
+     	kernel-module-serio \
+     	kernel-module-serport \
+     	kernel-module-sg \
+     	kernel-module-sha1-generic \
+     	kernel-module-sit \
+     	kernel-module-ssb \
+     	kernel-module-ts-bm \
+     	kernel-module-ts-fsm \
+     	kernel-module-ts-kmp \
+     	kernel-module-tunnel4 \
+     	kernel-module-uhci-hcd \
+     	kernel-module-usbcore \
+     	kernel-module-usbhid \
+     	kernel-module-usbserial \
+     	kernel-module-usb-storage \
+     	kernel-module-xfrm6-mode-beet \
+     	kernel-module-xfrm6-mode-transport \
+     	kernel-module-xfrm6-mode-tunnel \
+     	kernel-module-x-tables \
+     	kernel-module-xt-classify \
+     	kernel-module-xt-comment \
+     	kernel-module-xt-connbytes \
+     	kernel-module-xt-conntrack \
+     	kernel-module-xt-dccp \
+     	kernel-module-xt-helper \
+     	kernel-module-xt-hl \
+     	kernel-module-xt-iprange \
+     	kernel-module-xt-length \
+     	kernel-module-xt-limit \
+     	kernel-module-xt-mac \
+	kernel-module-xt-mark \
+     	kernel-module-xt-nflog \
+     	kernel-module-xt-nfqueue \
+     	kernel-module-xt-notrack \
+     	kernel-module-xt-pkttype \
+     	kernel-module-xt-realm \
+     	kernel-module-xt-sctp \
+     	kernel-module-xt-state \
+     	kernel-module-xt-string \
+     	kernel-module-xt-tcpmss \
+     	kernel-module-xt-tcpudp \
+	"
+
+IMAGE_INSTALL = "\
+	task-proper-tools \
+	${DISTRO_SSH_DAEMON} \
+	${@base_contains('MACHINE_FEATURES', 'ext2', 'task-base-ext2', '', d)} \
+	${@base_contains('MACHINE_FEATURES', 'usbhost', 'task-base-usbhost', '', d)} \
+	kernel-image \
+	${KERNEL_MODULES} \
+	canctl dioctl dmxctl spictl ts-utils ts-initrd \
+	bash \
+	python \
+	ntp \
+	cron \
+	nano \
+	screen \
+	wget \
+	curl \	
+	file \
+	task-java \
+	openjdk-6-vm-cacao \
+        openjdk-6-vm-shark \
+        openjdk-6-vm-zero \
+        openjdk-6-java \
+        openjdk-6-jdk \
+        openjdk-6-jre \
+        iptables \
+	dhclient \	
+	dhcpcd \
+	"
+
+fix_image () {
+          echo "Fixing Image... ${IMAGE_ROOTFS}"
+          # Delete extra files
+          for file in "${IMAGE_ROOTFS}/etc/rcS.d/S03udev \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S03sysfs \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S06alignment \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S10checkroot \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S12udev-cache \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S30procps.sh \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S30ramdisk \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S35mountall.sh \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S37populate-volatile.sh \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S38devpts.sh \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S39ifup \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S40configure \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S45mountnfs.sh \
+	      ${IMAGE_ROOTFS}/etc/rcS.d/S55bootmisc.sh \
+              ${IMAGE_ROOTFS}/var/*" ; 
+          do rm -r ${file} ; done
+          
+          # Make extra nodes
+          for file in "${IMAGE_ROOTFS}/proc \
+              ${IMAGE_ROOTFS}/sys \
+	      ${IMAGE_ROOTFS}/home/root \
+	      ${IMAGE_ROOTFS}/home/v2g \
+	      ${IMAGE_ROOTFS}/tmp" ; 
+          do mkdir -p ${file} ; done
+          
+	  # Fix the opkg-config
+	  echo "src/gz base http://chinook.ceoe.udel.edu/v2g/downloads/ts7500/glibc/ipk/armv4" > ${IMAGE_ROOTFS}/etc/opkg/base-feed.conf
+	  echo "src/gz noarch http://chinook.ceoe.udel.edu/v2g/downloads/ts7500/glibc/ipk/all" > ${IMAGE_ROOTFS}/etc/opkg/noarch-feed.conf
+	  echo "src/gz ts75xx http://chinook.ceoe.udel.edu/v2g/downloads/ts7500/glibc/ipk/ts75xx" > ${IMAGE_ROOTFS}/etc/opkg/ts75xx-feed.conf
+	  
+	  # Fix the non-existent sh link
+	  ln -s /bin/bash ${IMAGE_ROOTFS}/bin/sh
+}
+
+# ROOTFS_POSTPROCESS_COMMAND += "depmod -a ; opkg-cl configure ; "
+
+IMAGE_PREPROCESS_COMMAND += "fix_image ; "
+
+
+export IMAGE_BASENAME = "ts75xx-rootfs-image"
+IMAGE_LINGUAS = ""
+
+inherit image
-- 
1.7.3.4




^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 6/6] Adds custom defconfigs for Technologic Systems TS7500 ARM SBCs
  2011-03-30 14:07 [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
                   ` (3 preceding siblings ...)
  2011-03-30 14:07 ` [PATCH 5/6] Added images for the TS7500 ARM SBCs UDel V2G Team
@ 2011-03-30 14:07 ` UDel V2G Team
  2011-03-31 21:00   ` Khem Raj
  2011-03-30 14:43 ` [PATCH 1/6] Add support for the " Marcin Juszkiewicz
  2011-03-31 20:48 ` Khem Raj
  6 siblings, 1 reply; 20+ messages in thread
From: UDel V2G Team @ 2011-03-30 14:07 UTC (permalink / raw)
  To: openembedded-devel

* Added a busybox defconfig for building a version of busybox that will be
  very similar to the original shipped version

Signed-off-by: UDel V2G Team <v2g.udel@gmail.com>
---
 recipes/busybox/busybox-1.13.2/ts75xx/defconfig |  986 +++++++++++++++++++++++
 recipes/busybox/busybox-1.18.3/ts75xx/defconfig |  986 +++++++++++++++++++++++
 2 files changed, 1972 insertions(+), 0 deletions(-)
 create mode 100644 recipes/busybox/busybox-1.13.2/ts75xx/defconfig
 create mode 100644 recipes/busybox/busybox-1.18.3/ts75xx/defconfig

diff --git a/recipes/busybox/busybox-1.13.2/ts75xx/defconfig b/recipes/busybox/busybox-1.13.2/ts75xx/defconfig
new file mode 100644
index 0000000..4b6658e
--- /dev/null
+++ b/recipes/busybox/busybox-1.13.2/ts75xx/defconfig
@@ -0,0 +1,986 @@
+#
+# Automatically generated make config: don't edit
+# Busybox version: 1.18.3
+# Thu Mar 24 13:42:39 2011
+#
+CONFIG_HAVE_DOT_CONFIG=y
+
+#
+# Busybox Settings
+#
+
+#
+# General Configuration
+#
+# CONFIG_DESKTOP is not set
+# CONFIG_EXTRA_COMPAT is not set
+# CONFIG_INCLUDE_SUSv2 is not set
+# CONFIG_USE_PORTABLE_CODE is not set
+CONFIG_PLATFORM_LINUX=y
+CONFIG_FEATURE_BUFFERS_USE_MALLOC=y
+# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
+# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
+CONFIG_SHOW_USAGE=y
+CONFIG_FEATURE_VERBOSE_USAGE=y
+CONFIG_FEATURE_COMPRESS_USAGE=y
+# CONFIG_FEATURE_INSTALLER is not set
+# CONFIG_INSTALL_NO_USR is not set
+CONFIG_LOCALE_SUPPORT=y
+CONFIG_UNICODE_SUPPORT=y
+# CONFIG_UNICODE_USING_LOCALE is not set
+# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set
+CONFIG_SUBST_WCHAR=63
+CONFIG_LAST_SUPPORTED_WCHAR=767
+# CONFIG_UNICODE_COMBINING_WCHARS is not set
+# CONFIG_UNICODE_WIDE_WCHARS is not set
+# CONFIG_UNICODE_BIDI_SUPPORT is not set
+# CONFIG_UNICODE_NEUTRAL_TABLE is not set
+# CONFIG_UNICODE_PRESERVE_BROKEN is not set
+CONFIG_LONG_OPTS=y
+CONFIG_FEATURE_DEVPTS=y
+# CONFIG_FEATURE_CLEAN_UP is not set
+CONFIG_FEATURE_WTMP=y
+CONFIG_FEATURE_UTMP=y
+CONFIG_FEATURE_PIDFILE=y
+CONFIG_FEATURE_SUID=y
+CONFIG_FEATURE_SUID_CONFIG=y
+CONFIG_FEATURE_SUID_CONFIG_QUIET=y
+# CONFIG_SELINUX is not set
+# CONFIG_FEATURE_PREFER_APPLETS is not set
+CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
+CONFIG_FEATURE_SYSLOG=y
+# CONFIG_FEATURE_HAVE_RPC is not set
+
+#
+# Build Options
+#
+# CONFIG_STATIC is not set
+# CONFIG_PIE is not set
+# CONFIG_NOMMU is not set
+# CONFIG_BUILD_LIBBUSYBOX is not set
+# CONFIG_FEATURE_INDIVIDUAL is not set
+# CONFIG_FEATURE_SHARED_BUSYBOX is not set
+CONFIG_LFS=y
+CONFIG_CROSS_COMPILER_PREFIX=""
+CONFIG_EXTRA_CFLAGS=""
+
+#
+# Debugging Options
+#
+# CONFIG_DEBUG is not set
+# CONFIG_DEBUG_PESSIMIZE is not set
+# CONFIG_WERROR is not set
+CONFIG_NO_DEBUG_LIB=y
+# CONFIG_DMALLOC is not set
+# CONFIG_EFENCE is not set
+
+#
+# Installation Options ("make install" behavior)
+#
+CONFIG_INSTALL_APPLET_SYMLINKS=y
+# CONFIG_INSTALL_APPLET_HARDLINKS is not set
+# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set
+# CONFIG_INSTALL_APPLET_DONT is not set
+# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set
+# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set
+# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set
+CONFIG_PREFIX="./_install"
+
+#
+# Busybox Library Tuning
+#
+CONFIG_PASSWORD_MINLEN=6
+CONFIG_MD5_SIZE_VS_SPEED=2
+CONFIG_FEATURE_FAST_TOP=y
+# CONFIG_FEATURE_ETC_NETWORKS is not set
+CONFIG_FEATURE_USE_TERMIOS=y
+CONFIG_FEATURE_EDITING=y
+CONFIG_FEATURE_EDITING_MAX_LEN=1024
+# CONFIG_FEATURE_EDITING_VI is not set
+CONFIG_FEATURE_EDITING_HISTORY=64
+CONFIG_FEATURE_EDITING_SAVEHISTORY=y
+CONFIG_FEATURE_TAB_COMPLETION=y
+CONFIG_FEATURE_USERNAME_COMPLETION=y
+CONFIG_FEATURE_EDITING_FANCY_PROMPT=y
+# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set
+CONFIG_FEATURE_NON_POSIX_CP=y
+CONFIG_FEATURE_VERBOSE_CP_MESSAGE=y
+CONFIG_FEATURE_COPYBUF_KB=4
+CONFIG_MONOTONIC_SYSCALL=y
+CONFIG_IOCTL_HEX2STR_ERROR=y
+CONFIG_FEATURE_HWIB=y
+
+#
+# Applets
+#
+
+#
+# Archival Utilities
+#
+CONFIG_FEATURE_SEAMLESS_XZ=y
+# CONFIG_FEATURE_SEAMLESS_LZMA is not set
+CONFIG_FEATURE_SEAMLESS_BZ2=y
+CONFIG_FEATURE_SEAMLESS_GZ=y
+CONFIG_FEATURE_SEAMLESS_Z=y
+CONFIG_AR=y
+# CONFIG_FEATURE_AR_LONG_FILENAMES is not set
+CONFIG_FEATURE_AR_CREATE=y
+CONFIG_BUNZIP2=y
+# CONFIG_BZIP2 is not set
+CONFIG_CPIO=y
+# CONFIG_FEATURE_CPIO_O is not set
+# CONFIG_FEATURE_CPIO_P is not set
+# CONFIG_DPKG is not set
+# CONFIG_DPKG_DEB is not set
+# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set
+CONFIG_GUNZIP=y
+CONFIG_GZIP=y
+CONFIG_FEATURE_GZIP_LONG_OPTIONS=y
+CONFIG_LZOP=y
+# CONFIG_LZOP_COMPR_HIGH is not set
+# CONFIG_RPM2CPIO is not set
+# CONFIG_RPM is not set
+CONFIG_TAR=y
+CONFIG_FEATURE_TAR_CREATE=y
+CONFIG_FEATURE_TAR_AUTODETECT=y
+CONFIG_FEATURE_TAR_FROM=y
+CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y
+# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set
+CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y
+CONFIG_FEATURE_TAR_LONG_OPTIONS=y
+CONFIG_FEATURE_TAR_TO_COMMAND=y
+CONFIG_FEATURE_TAR_UNAME_GNAME=y
+CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y
+# CONFIG_FEATURE_TAR_SELINUX is not set
+# CONFIG_UNCOMPRESS is not set
+# CONFIG_UNLZMA is not set
+# CONFIG_FEATURE_LZMA_FAST is not set
+# CONFIG_LZMA is not set
+CONFIG_UNXZ=y
+CONFIG_XZ=y
+CONFIG_UNZIP=y
+
+#
+# Coreutils
+#
+CONFIG_BASENAME=y
+CONFIG_CAT=y
+CONFIG_DATE=y
+CONFIG_FEATURE_DATE_ISOFMT=y
+# CONFIG_FEATURE_DATE_NANO is not set
+CONFIG_FEATURE_DATE_COMPAT=y
+CONFIG_TEST=y
+# CONFIG_FEATURE_TEST_64 is not set
+CONFIG_TR=y
+CONFIG_FEATURE_TR_CLASSES=y
+# CONFIG_FEATURE_TR_EQUIV is not set
+# CONFIG_BASE64=y
+# CONFIG_CAL is not set
+# CONFIG_CATV is not set
+CONFIG_CHGRP=y
+CONFIG_CHMOD=y
+CONFIG_CHOWN=y
+CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y
+CONFIG_CHROOT=y
+# CONFIG_CKSUM is not set
+# CONFIG_COMM is not set
+CONFIG_CP=y
+CONFIG_FEATURE_CP_LONG_OPTIONS=y
+CONFIG_CUT=y
+CONFIG_DD=y
+CONFIG_FEATURE_DD_SIGNAL_HANDLING=y
+CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y
+# CONFIG_FEATURE_DD_IBS_OBS is not set
+CONFIG_DF=y
+CONFIG_FEATURE_DF_FANCY=y
+CONFIG_DIRNAME=y
+# CONFIG_DOS2UNIX is not set
+# CONFIG_UNIX2DOS is not set
+CONFIG_DU=y
+CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y
+CONFIG_ECHO=y
+CONFIG_FEATURE_FANCY_ECHO=y
+CONFIG_ENV=y
+CONFIG_FEATURE_ENV_LONG_OPTIONS=y
+# CONFIG_EXPAND is not set
+# CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set
+CONFIG_EXPR=y
+# CONFIG_EXPR_MATH_SUPPORT_64 is not set
+CONFIG_FALSE=y
+# CONFIG_FOLD is not set
+CONFIG_FSYNC=y
+CONFIG_HEAD=y
+CONFIG_FEATURE_FANCY_HEAD=y
+# CONFIG_HOSTID is not set
+CONFIG_ID=y
+# CONFIG_INSTALL is not set
+# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set
+# CONFIG_LENGTH is not set
+CONFIG_LN=y
+CONFIG_LOGNAME=y
+CONFIG_LS=y
+CONFIG_FEATURE_LS_FILETYPES=y
+CONFIG_FEATURE_LS_FOLLOWLINKS=y
+CONFIG_FEATURE_LS_RECURSIVE=y
+CONFIG_FEATURE_LS_SORTFILES=y
+CONFIG_FEATURE_LS_TIMESTAMPS=y
+CONFIG_FEATURE_LS_USERNAME=y
+CONFIG_FEATURE_LS_COLOR=y
+# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set
+CONFIG_MD5SUM=y
+CONFIG_MKDIR=y
+CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y
+CONFIG_MKFIFO=y
+CONFIG_MKNOD=y
+CONFIG_MV=y
+CONFIG_FEATURE_MV_LONG_OPTIONS=y
+CONFIG_NICE=y
+CONFIG_NOHUP=y
+CONFIG_OD=y
+# CONFIG_PRINTENV is not set
+CONFIG_PRINTF=y
+CONFIG_PWD=y
+CONFIG_READLINK=y
+CONFIG_FEATURE_READLINK_FOLLOW=y
+CONFIG_REALPATH=y
+CONFIG_RM=y
+CONFIG_RMDIR=y
+CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y
+CONFIG_SEQ=y
+# CONFIG_SHA1SUM is not set
+CONFIG_SHA256SUM=y
+CONFIG_SHA512SUM=y
+CONFIG_SLEEP=y
+CONFIG_FEATURE_FANCY_SLEEP=y
+CONFIG_FEATURE_FLOAT_SLEEP=y
+CONFIG_SORT=y
+CONFIG_FEATURE_SORT_BIG=y
+# CONFIG_SPLIT is not set
+# CONFIG_FEATURE_SPLIT_FANCY is not set
+# CONFIG_STAT is not set
+# CONFIG_FEATURE_STAT_FORMAT is not set
+CONFIG_STTY=y
+# CONFIG_SUM is not set
+CONFIG_SYNC=y
+# CONFIG_TAC is not set
+CONFIG_TAIL=y
+CONFIG_FEATURE_FANCY_TAIL=y
+CONFIG_TEE=y
+CONFIG_FEATURE_TEE_USE_BLOCK_IO=y
+CONFIG_TOUCH=y
+CONFIG_TRUE=y
+CONFIG_TTY=y
+CONFIG_UNAME=y
+# CONFIG_UNEXPAND is not set
+# CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set
+CONFIG_UNIQ=y
+CONFIG_USLEEP=y
+CONFIG_UUDECODE=y
+CONFIG_UUENCODE=y
+CONFIG_WC=y
+# CONFIG_FEATURE_WC_LARGE is not set
+CONFIG_WHO=y
+CONFIG_WHOAMI=y
+CONFIG_YES=y
+
+#
+# Common options for cp and mv
+#
+# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set
+
+#
+# Common options for ls, more and telnet
+#
+CONFIG_FEATURE_AUTOWIDTH=y
+
+#
+# Common options for df, du, ls
+#
+CONFIG_FEATURE_HUMAN_READABLE=y
+
+#
+# Common options for md5sum, sha1sum, sha256sum, sha512sum
+#
+CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y
+
+#
+# Console Utilities
+#
+CONFIG_CHVT=y
+CONFIG_FGCONSOLE=y
+CONFIG_CLEAR=y
+CONFIG_DEALLOCVT=y
+CONFIG_DUMPKMAP=y
+# CONFIG_KBD_MODE is not set
+CONFIG_LOADFONT=y
+CONFIG_LOADKMAP=y
+CONFIG_OPENVT=y
+CONFIG_RESET=y
+# CONFIG_RESIZE is not set
+# CONFIG_FEATURE_RESIZE_PRINT is not set
+CONFIG_SETCONSOLE=y
+# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set
+CONFIG_SETFONT=y
+CONFIG_FEATURE_SETFONT_TEXTUAL_MAP=y
+CONFIG_DEFAULT_SETFONT_DIR=""
+# CONFIG_SETKEYCODES is not set
+# CONFIG_SETLOGCONS is not set
+CONFIG_SHOWKEY=y
+
+#
+# Common options for loadfont and setfont
+#
+CONFIG_FEATURE_LOADFONT_PSF2=y
+CONFIG_FEATURE_LOADFONT_RAW=y
+
+#
+# Debian Utilities
+#
+# CONFIG_MKTEMP is not set
+# CONFIG_PIPE_PROGRESS is not set
+# CONFIG_RUN_PARTS is not set
+# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set
+# CONFIG_FEATURE_RUN_PARTS_FANCY is not set
+# CONFIG_START_STOP_DAEMON is not set
+# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set
+# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set
+# CONFIG_WHICH is not set
+
+#
+# Editors
+#
+# CONFIG_PATCH is not set
+# CONFIG_AWK is not set
+# CONFIG_FEATURE_AWK_LIBM is not set
+CONFIG_CMP=y
+# CONFIG_DIFF is not set
+# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set
+# CONFIG_FEATURE_DIFF_DIR is not set
+# CONFIG_ED is not set
+CONFIG_SED=y
+# CONFIG_VI is not set
+CONFIG_FEATURE_VI_MAX_LEN=0
+# CONFIG_FEATURE_VI_8BIT is not set
+# CONFIG_FEATURE_VI_COLON is not set
+# CONFIG_FEATURE_VI_YANKMARK is not set
+# CONFIG_FEATURE_VI_SEARCH is not set
+# CONFIG_FEATURE_VI_USE_SIGNALS is not set
+# CONFIG_FEATURE_VI_DOT_CMD is not set
+# CONFIG_FEATURE_VI_READONLY is not set
+# CONFIG_FEATURE_VI_SETOPTS is not set
+# CONFIG_FEATURE_VI_SET is not set
+# CONFIG_FEATURE_VI_WIN_RESIZE is not set
+# CONFIG_FEATURE_VI_ASK_TERMINAL is not set
+# CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set
+# CONFIG_FEATURE_ALLOW_EXEC is not set
+
+#
+# Finding Utilities
+#
+CONFIG_FIND=y
+CONFIG_FEATURE_FIND_PRINT0=y
+CONFIG_FEATURE_FIND_MTIME=y
+CONFIG_FEATURE_FIND_MMIN=y
+CONFIG_FEATURE_FIND_PERM=y
+CONFIG_FEATURE_FIND_TYPE=y
+CONFIG_FEATURE_FIND_XDEV=y
+CONFIG_FEATURE_FIND_MAXDEPTH=y
+CONFIG_FEATURE_FIND_NEWER=y
+CONFIG_FEATURE_FIND_INUM=y
+CONFIG_FEATURE_FIND_EXEC=y
+CONFIG_FEATURE_FIND_USER=y
+CONFIG_FEATURE_FIND_GROUP=y
+CONFIG_FEATURE_FIND_NOT=y
+CONFIG_FEATURE_FIND_DEPTH=y
+CONFIG_FEATURE_FIND_PAREN=y
+CONFIG_FEATURE_FIND_SIZE=y
+CONFIG_FEATURE_FIND_PRUNE=y
+CONFIG_FEATURE_FIND_DELETE=y
+CONFIG_FEATURE_FIND_PATH=y
+CONFIG_FEATURE_FIND_REGEX=y
+# CONFIG_FEATURE_FIND_CONTEXT is not set
+CONFIG_FEATURE_FIND_LINKS=y
+CONFIG_GREP=y
+CONFIG_FEATURE_GREP_EGREP_ALIAS=y
+CONFIG_FEATURE_GREP_FGREP_ALIAS=y
+CONFIG_FEATURE_GREP_CONTEXT=y
+CONFIG_XARGS=y
+# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set
+CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y
+CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y
+CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y
+
+#
+# Init Utilities
+#
+# CONFIG_BOOTCHARTD is not set
+# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set
+# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set
+# CONFIG_HALT is not set
+# CONFIG_FEATURE_CALL_TELINIT is not set
+CONFIG_TELINIT_PATH=""
+# CONFIG_INIT is not set
+# CONFIG_FEATURE_USE_INITTAB is not set
+# CONFIG_FEATURE_KILL_REMOVED is not set
+CONFIG_FEATURE_KILL_DELAY=0
+# CONFIG_FEATURE_INIT_SCTTY is not set
+# CONFIG_FEATURE_INIT_SYSLOG is not set
+# CONFIG_FEATURE_EXTRA_QUIET is not set
+# CONFIG_FEATURE_INIT_COREDUMPS is not set
+# CONFIG_FEATURE_INITRD is not set
+CONFIG_INIT_TERMINAL_TYPE=""
+# CONFIG_MESG is not set
+
+#
+# Login/Password Management Utilities
+#
+# CONFIG_ADD_SHELL is not set
+# CONFIG_REMOVE_SHELL is not set
+# CONFIG_FEATURE_SHADOWPASSWDS is not set
+# CONFIG_USE_BB_PWD_GRP is not set
+# CONFIG_USE_BB_SHADOW is not set
+# CONFIG_USE_BB_CRYPT is not set
+# CONFIG_USE_BB_CRYPT_SHA is not set
+# CONFIG_ADDUSER is not set
+# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set
+# CONFIG_FEATURE_CHECK_NAMES is not set
+CONFIG_FIRST_SYSTEM_ID=0
+CONFIG_LAST_SYSTEM_ID=0
+# CONFIG_ADDGROUP is not set
+# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set
+# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set
+# CONFIG_DELUSER is not set
+# CONFIG_DELGROUP is not set
+# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set
+CONFIG_GETTY=y
+CONFIG_LOGIN=y
+# CONFIG_PAM is not set
+CONFIG_LOGIN_SCRIPTS=y
+CONFIG_FEATURE_NOLOGIN=y
+CONFIG_FEATURE_SECURETTY=y
+# CONFIG_PASSWD is not set
+# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set
+# CONFIG_CRYPTPW is not set
+# CONFIG_CHPASSWD is not set
+# CONFIG_SU is not set
+# CONFIG_FEATURE_SU_SYSLOG is not set
+# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set
+# CONFIG_SULOGIN is not set
+# CONFIG_VLOCK is not set
+
+#
+# Linux Ext2 FS Progs
+#
+CONFIG_CHATTR=y
+CONFIG_FSCK=y
+# CONFIG_LSATTR is not set
+# CONFIG_TUNE2FS is not set
+
+#
+# Linux Module Utilities
+#
+CONFIG_MODINFO=y
+# CONFIG_MODPROBE_SMALL is not set
+# CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE is not set
+# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set
+CONFIG_INSMOD=y
+CONFIG_RMMOD=y
+CONFIG_LSMOD=y
+CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y
+CONFIG_MODPROBE=y
+CONFIG_FEATURE_MODPROBE_BLACKLIST=y
+# CONFIG_DEPMOD is not set
+
+#
+# Options common to multiple modutils
+#
+# CONFIG_FEATURE_2_4_MODULES is not set
+# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set
+# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set
+# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set
+# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set
+CONFIG_FEATURE_CHECK_TAINTED_MODULE=y
+CONFIG_FEATURE_MODUTILS_ALIAS=y
+CONFIG_FEATURE_MODUTILS_SYMBOLS=y
+CONFIG_DEFAULT_MODULES_DIR="/lib/modules"
+CONFIG_DEFAULT_DEPMOD_FILE="modules.dep"
+
+#
+# Linux System Utilities
+#
+# CONFIG_BLOCKDEV is not set
+# CONFIG_REV is not set
+# CONFIG_ACPID is not set
+# CONFIG_FEATURE_ACPID_COMPAT is not set
+# CONFIG_BLKID is not set
+CONFIG_DMESG=y
+CONFIG_FEATURE_DMESG_PRETTY=y
+# CONFIG_FBSET is not set
+# CONFIG_FEATURE_FBSET_FANCY is not set
+# CONFIG_FEATURE_FBSET_READMODE is not set
+# CONFIG_FDFLUSH is not set
+# CONFIG_FDFORMAT is not set
+CONFIG_FDISK=y
+CONFIG_FDISK_SUPPORT_LARGE_DISKS=y
+CONFIG_FEATURE_FDISK_WRITABLE=y
+# CONFIG_FEATURE_AIX_LABEL is not set
+# CONFIG_FEATURE_SGI_LABEL is not set
+# CONFIG_FEATURE_SUN_LABEL is not set
+CONFIG_FEATURE_OSF_LABEL=y
+# CONFIG_FEATURE_GPT_LABEL is not set
+CONFIG_FEATURE_FDISK_ADVANCED=y
+# CONFIG_FINDFS is not set
+# CONFIG_FLOCK is not set
+CONFIG_FREERAMDISK=y
+# CONFIG_FSCK_MINIX is not set
+CONFIG_MKFS_EXT2=y
+# CONFIG_MKFS_MINIX is not set
+# CONFIG_FEATURE_MINIX2 is not set
+# CONFIG_MKFS_REISER is not set
+CONFIG_MKFS_VFAT=y
+CONFIG_GETOPT=y
+CONFIG_FEATURE_GETOPT_LONG=y
+# CONFIG_HEXDUMP is not set
+# CONFIG_FEATURE_HEXDUMP_REVERSE is not set
+# CONFIG_HD is not set
+# CONFIG_HWCLOCK is not set
+# CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set
+# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set
+# CONFIG_IPCRM is not set
+# CONFIG_IPCS is not set
+# CONFIG_LOSETUP is not set
+# CONFIG_LSPCI is not set
+# CONFIG_LSUSB is not set
+CONFIG_MDEV=y
+CONFIG_FEATURE_MDEV_CONF=y
+CONFIG_FEATURE_MDEV_RENAME=y
+CONFIG_FEATURE_MDEV_RENAME_REGEXP=y
+CONFIG_FEATURE_MDEV_EXEC=y
+CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y
+# CONFIG_MKSWAP is not set
+# CONFIG_FEATURE_MKSWAP_UUID is not set
+CONFIG_MORE=y
+CONFIG_MOUNT=y
+# CONFIG_FEATURE_MOUNT_FAKE is not set
+CONFIG_FEATURE_MOUNT_VERBOSE=y
+CONFIG_FEATURE_MOUNT_HELPERS=y
+# CONFIG_FEATURE_MOUNT_LABEL is not set
+# CONFIG_FEATURE_MOUNT_NFS is not set
+# CONFIG_FEATURE_MOUNT_CIFS is not set
+CONFIG_FEATURE_MOUNT_FLAGS=y
+CONFIG_FEATURE_MOUNT_FSTAB=y
+CONFIG_PIVOT_ROOT=y
+# CONFIG_RDATE is not set
+# CONFIG_RDEV is not set
+# CONFIG_READPROFILE is not set
+# CONFIG_RTCWAKE is not set
+# CONFIG_SCRIPT is not set
+# CONFIG_SCRIPTREPLAY is not set
+# CONFIG_SETARCH is not set
+# CONFIG_SWAPONOFF is not set
+# CONFIG_FEATURE_SWAPON_PRI is not set
+CONFIG_SWITCH_ROOT=y
+CONFIG_UMOUNT=y
+CONFIG_FEATURE_UMOUNT_ALL=y
+
+#
+# Common options for mount/umount
+#
+CONFIG_FEATURE_MOUNT_LOOP=y
+CONFIG_FEATURE_MOUNT_LOOP_CREATE=y
+# CONFIG_FEATURE_MTAB_SUPPORT is not set
+# CONFIG_VOLUMEID is not set
+# CONFIG_FEATURE_VOLUMEID_EXT is not set
+# CONFIG_FEATURE_VOLUMEID_BTRFS is not set
+# CONFIG_FEATURE_VOLUMEID_REISERFS is not set
+# CONFIG_FEATURE_VOLUMEID_FAT is not set
+# CONFIG_FEATURE_VOLUMEID_HFS is not set
+# CONFIG_FEATURE_VOLUMEID_JFS is not set
+# CONFIG_FEATURE_VOLUMEID_XFS is not set
+# CONFIG_FEATURE_VOLUMEID_NTFS is not set
+# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set
+# CONFIG_FEATURE_VOLUMEID_UDF is not set
+# CONFIG_FEATURE_VOLUMEID_LUKS is not set
+# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set
+# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set
+# CONFIG_FEATURE_VOLUMEID_ROMFS is not set
+# CONFIG_FEATURE_VOLUMEID_SYSV is not set
+# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set
+# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set
+
+#
+# Miscellaneous Utilities
+#
+# CONFIG_CONSPY is not set
+# CONFIG_NANDWRITE is not set
+# CONFIG_NANDDUMP is not set
+# CONFIG_UBIATTACH is not set
+# CONFIG_UBIDETACH is not set
+# CONFIG_ADJTIMEX is not set
+# CONFIG_BBCONFIG is not set
+# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set
+# CONFIG_BEEP is not set
+CONFIG_FEATURE_BEEP_FREQ=0
+CONFIG_FEATURE_BEEP_LENGTH_MS=0
+# CONFIG_CHAT is not set
+# CONFIG_FEATURE_CHAT_NOFAIL is not set
+# CONFIG_FEATURE_CHAT_TTY_HIFI is not set
+# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set
+# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set
+# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set
+# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set
+# CONFIG_FEATURE_CHAT_CLR_ABORT is not set
+# CONFIG_CHRT is not set
+# CONFIG_CROND is not set
+# CONFIG_FEATURE_CROND_D is not set
+# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set
+CONFIG_FEATURE_CROND_DIR=""
+# CONFIG_CRONTAB is not set
+# CONFIG_DC is not set
+# CONFIG_FEATURE_DC_LIBM is not set
+# CONFIG_DEVFSD is not set
+# CONFIG_DEVFSD_MODLOAD is not set
+# CONFIG_DEVFSD_FG_NP is not set
+# CONFIG_DEVFSD_VERBOSE is not set
+# CONFIG_FEATURE_DEVFS is not set
+CONFIG_DEVMEM=y
+# CONFIG_EJECT is not set
+# CONFIG_FEATURE_EJECT_SCSI is not set
+# CONFIG_FBSPLASH is not set
+# CONFIG_FLASHCP is not set
+# CONFIG_FLASH_LOCK is not set
+# CONFIG_FLASH_UNLOCK is not set
+# CONFIG_FLASH_ERASEALL is not set
+# CONFIG_IONICE is not set
+# CONFIG_INOTIFYD is not set
+# CONFIG_LAST is not set
+# CONFIG_FEATURE_LAST_SMALL is not set
+# CONFIG_FEATURE_LAST_FANCY is not set
+# CONFIG_LESS is not set
+CONFIG_FEATURE_LESS_MAXLINES=0
+# CONFIG_FEATURE_LESS_BRACKETS is not set
+# CONFIG_FEATURE_LESS_FLAGS is not set
+# CONFIG_FEATURE_LESS_MARKS is not set
+# CONFIG_FEATURE_LESS_REGEXP is not set
+# CONFIG_FEATURE_LESS_WINCH is not set
+# CONFIG_FEATURE_LESS_DASHCMD is not set
+# CONFIG_FEATURE_LESS_LINENUMS is not set
+# CONFIG_HDPARM is not set
+# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set
+# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set
+# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set
+# CONFIG_MAKEDEVS is not set
+# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
+# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
+# CONFIG_MAN is not set
+# CONFIG_MICROCOM is not set
+# CONFIG_MOUNTPOINT is not set
+# CONFIG_MT is not set
+# CONFIG_RAIDAUTORUN is not set
+CONFIG_READAHEAD=y
+# CONFIG_RFKILL is not set
+# CONFIG_RUNLEVEL is not set
+# CONFIG_RX is not set
+CONFIG_SETSID=y
+# CONFIG_STRINGS is not set
+# CONFIG_TASKSET is not set
+# CONFIG_FEATURE_TASKSET_FANCY is not set
+# CONFIG_TIME is not set
+# CONFIG_TIMEOUT is not set
+# CONFIG_TTYSIZE is not set
+# CONFIG_VOLNAME is not set
+# CONFIG_WALL is not set
+CONFIG_WATCHDOG=y
+
+#
+# Networking Utilities
+#
+CONFIG_NBDCLIENT=y
+# CONFIG_NC=y
+# CONFIG_NC_SERVER=y
+# CONFIG_NC_EXTRA=y
+# CONFIG_NC_110_COMPAT is not set
+CONFIG_FEATURE_IPV6=y
+# CONFIG_FEATURE_UNIX_LOCAL is not set
+CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y
+# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set
+# CONFIG_ARP is not set
+# CONFIG_ARPING is not set
+# CONFIG_BRCTL is not set
+# CONFIG_FEATURE_BRCTL_FANCY is not set
+# CONFIG_FEATURE_BRCTL_SHOW is not set
+# CONFIG_DNSD is not set
+# CONFIG_ETHER_WAKE is not set
+# CONFIG_FAKEIDENTD is not set
+# CONFIG_FTPD=y
+# CONFIG_FEATURE_FTP_WRITE=y
+# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y
+# CONFIG_FTPGET is not set
+# CONFIG_FTPPUT is not set
+# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
+CONFIG_HOSTNAME=y
+# CONFIG_HTTPD=y
+# CONFIG_FEATURE_HTTPD_RANGES=y
+# CONFIG_FEATURE_HTTPD_USE_SENDFILE=y
+# CONFIG_FEATURE_HTTPD_SETUID=y
+# CONFIG_FEATURE_HTTPD_BASIC_AUTH=y
+# CONFIG_FEATURE_HTTPD_AUTH_MD5=y
+# CONFIG_FEATURE_HTTPD_CGI=y
+# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y
+# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y
+# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y
+# CONFIG_FEATURE_HTTPD_ERROR_PAGES=y
+# CONFIG_FEATURE_HTTPD_PROXY=y
+# CONFIG_FEATURE_HTTPD_GZIP=y
+CONFIG_IFCONFIG=y
+CONFIG_FEATURE_IFCONFIG_STATUS=y
+# CONFIG_FEATURE_IFCONFIG_SLIP is not set
+# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set
+CONFIG_FEATURE_IFCONFIG_HW=y
+CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y
+# CONFIG_IFENSLAVE is not set
+CONFIG_IFPLUGD=y
+CONFIG_IFUPDOWN=y
+CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate"
+# CONFIG_FEATURE_IFUPDOWN_IP is not set
+# CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN is not set
+CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN=y
+CONFIG_FEATURE_IFUPDOWN_IPV4=y
+CONFIG_FEATURE_IFUPDOWN_IPV6=y
+CONFIG_FEATURE_IFUPDOWN_MAPPING=y
+# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set
+# CONFIG_INETD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set
+# CONFIG_FEATURE_INETD_RPC is not set
+CONFIG_IP=y
+CONFIG_FEATURE_IP_ADDRESS=y
+CONFIG_FEATURE_IP_LINK=y
+CONFIG_FEATURE_IP_ROUTE=y
+CONFIG_FEATURE_IP_TUNNEL=y
+# CONFIG_FEATURE_IP_RULE is not set
+# CONFIG_FEATURE_IP_SHORT_FORMS is not set
+# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set
+# CONFIG_IPADDR is not set
+# CONFIG_IPLINK is not set
+# CONFIG_IPROUTE is not set
+# CONFIG_IPTUNNEL is not set
+# CONFIG_IPRULE is not set
+# CONFIG_IPCALC is not set
+# CONFIG_FEATURE_IPCALC_FANCY is not set
+# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set
+# CONFIG_NAMEIF is not set
+# CONFIG_FEATURE_NAMEIF_EXTENDED is not set
+CONFIG_NETSTAT=y
+CONFIG_FEATURE_NETSTAT_WIDE=y
+CONFIG_FEATURE_NETSTAT_PRG=y
+CONFIG_NSLOOKUP=y
+CONFIG_NTPD=y
+CONFIG_FEATURE_NTPD_SERVER=y
+CONFIG_PING=y
+CONFIG_PING6=y
+CONFIG_FEATURE_FANCY_PING=y
+# CONFIG_PSCAN is not set
+CONFIG_ROUTE=y
+# CONFIG_SLATTACH is not set
+# CONFIG_TCPSVD is not set
+CONFIG_TELNET=y
+# CONFIG_FEATURE_TELNET_TTYPE is not set
+CONFIG_FEATURE_TELNET_AUTOLOGIN=y
+CONFIG_TELNETD=y
+# CONFIG_FEATURE_TELNETD_STANDALONE is not set
+# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set
+# CONFIG_TFTP=y
+# CONFIG_TFTPD is not set
+
+#
+# Common options for tftp/tftpd
+#
+# CONFIG_FEATURE_TFTP_GET=y
+# CONFIG_FEATURE_TFTP_PUT=y
+# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
+# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set
+# CONFIG_TFTP_DEBUG is not set
+# CONFIG_TRACEROUTE=y
+# CONFIG_TRACEROUTE6=y
+# CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
+# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y
+# CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y
+# CONFIG_TUNCTL=y
+CONFIG_FEATURE_TUNCTL_UG=y
+CONFIG_UDHCPD=y
+CONFIG_DHCPRELAY=y
+CONFIG_DUMPLEASES=y
+# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set
+CONFIG_DHCPD_LEASES_FILE="/var/lib/misc/udhcpd.leases"
+CONFIG_UDHCPC=y
+CONFIG_FEATURE_UDHCPC_ARPING=y
+# CONFIG_FEATURE_UDHCP_PORT is not set
+CONFIG_UDHCP_DEBUG=9
+# CONFIG_FEATURE_UDHCP_RFC3397 is not set
+CONFIG_UDHCPC_DEFAULT_SCRIPT="@DATADIR@/udhcpc/default.script"
+CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80
+CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n"
+# CONFIG_UDPSVD is not set
+# CONFIG_VCONFIG is not set
+CONFIG_WGET=y
+CONFIG_FEATURE_WGET_STATUSBAR=y
+CONFIG_FEATURE_WGET_AUTHENTICATION=y
+CONFIG_FEATURE_WGET_LONG_OPTIONS=y
+CONFIG_FEATURE_WGET_TIMEOUT=y
+# CONFIG_ZCIP is not set
+
+#
+# Print Utilities
+#
+# CONFIG_LPD is not set
+# CONFIG_LPR is not set
+# CONFIG_LPQ is not set
+
+#
+# Mail Utilities
+#
+# CONFIG_MAKEMIME is not set
+CONFIG_FEATURE_MIME_CHARSET=""
+# CONFIG_POPMAILDIR is not set
+# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set
+# CONFIG_REFORMIME is not set
+# CONFIG_FEATURE_REFORMIME_COMPAT is not set
+# CONFIG_SENDMAIL is not set
+
+#
+# Process Utilities
+#
+# CONFIG_IOSTAT is not set
+# CONFIG_MPSTAT is not set
+# CONFIG_PMAP is not set
+# CONFIG_POWERTOP is not set
+# CONFIG_SMEMCAP is not set
+# CONFIG_FREE is not set
+# CONFIG_FUSER is not set
+CONFIG_KILL=y
+CONFIG_KILLALL=y
+# CONFIG_KILLALL5 is not set
+# CONFIG_NMETER is not set
+# CONFIG_PGREP is not set
+CONFIG_PIDOF=y
+CONFIG_FEATURE_PIDOF_SINGLE=y
+CONFIG_FEATURE_PIDOF_OMIT=y
+# CONFIG_PKILL is not set
+CONFIG_PS=y
+CONFIG_FEATURE_PS_WIDE=y
+# CONFIG_FEATURE_PS_TIME is not set
+# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set
+# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set
+# CONFIG_RENICE is not set
+# CONFIG_BB_SYSCTL is not set
+# CONFIG_TOP is not set
+# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set
+# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set
+# CONFIG_FEATURE_TOP_SMP_CPU is not set
+# CONFIG_FEATURE_TOP_DECIMALS is not set
+# CONFIG_FEATURE_TOP_SMP_PROCESS is not set
+# CONFIG_FEATURE_TOPMEM is not set
+# CONFIG_FEATURE_SHOW_THREADS is not set
+# CONFIG_UPTIME is not set
+# CONFIG_WATCH is not set
+
+#
+# Runit Utilities
+#
+# CONFIG_RUNSV is not set
+# CONFIG_RUNSVDIR is not set
+# CONFIG_FEATURE_RUNSVDIR_LOG is not set
+# CONFIG_SV is not set
+CONFIG_SV_DEFAULT_SERVICE_DIR=""
+# CONFIG_SVLOGD is not set
+# CONFIG_CHPST is not set
+# CONFIG_SETUIDGID is not set
+# CONFIG_ENVUIDGID is not set
+# CONFIG_ENVDIR is not set
+# CONFIG_SOFTLIMIT is not set
+# CONFIG_CHCON is not set
+# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set
+# CONFIG_GETENFORCE is not set
+# CONFIG_GETSEBOOL is not set
+# CONFIG_LOAD_POLICY is not set
+# CONFIG_MATCHPATHCON is not set
+# CONFIG_RESTORECON is not set
+# CONFIG_RUNCON is not set
+# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set
+# CONFIG_SELINUXENABLED is not set
+# CONFIG_SETENFORCE is not set
+# CONFIG_SETFILES is not set
+# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set
+# CONFIG_SETSEBOOL is not set
+# CONFIG_SESTATUS is not set
+
+#
+# Shells
+#
+CONFIG_ASH=y
+CONFIG_ASH_BASH_COMPAT=y
+CONFIG_ASH_JOB_CONTROL=y
+CONFIG_ASH_ALIAS=y
+CONFIG_ASH_GETOPTS=y
+CONFIG_ASH_BUILTIN_ECHO=y
+CONFIG_ASH_BUILTIN_PRINTF=y
+CONFIG_ASH_BUILTIN_TEST=y
+# CONFIG_ASH_CMDCMD is not set
+# CONFIG_ASH_MAIL is not set
+# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_ASH_RANDOM_SUPPORT is not set
+CONFIG_ASH_EXPAND_PRMT=y
+CONFIG_CTTYHACK=y
+# CONFIG_HUSH is not set
+# CONFIG_HUSH_BASH_COMPAT is not set
+# CONFIG_HUSH_BRACE_EXPANSION is not set
+# CONFIG_HUSH_HELP is not set
+# CONFIG_HUSH_INTERACTIVE is not set
+# CONFIG_HUSH_SAVEHISTORY is not set
+# CONFIG_HUSH_JOB is not set
+# CONFIG_HUSH_TICK is not set
+# CONFIG_HUSH_IF is not set
+# CONFIG_HUSH_LOOPS is not set
+# CONFIG_HUSH_CASE is not set
+# CONFIG_HUSH_FUNCTIONS is not set
+# CONFIG_HUSH_LOCAL is not set
+# CONFIG_HUSH_RANDOM_SUPPORT is not set
+# CONFIG_HUSH_EXPORT_N is not set
+# CONFIG_HUSH_MODE_X is not set
+# CONFIG_MSH is not set
+CONFIG_FEATURE_SH_IS_ASH=y
+# CONFIG_FEATURE_SH_IS_HUSH is not set
+# CONFIG_FEATURE_SH_IS_NONE is not set
+# CONFIG_FEATURE_BASH_IS_ASH is not set
+# CONFIG_FEATURE_BASH_IS_HUSH is not set
+CONFIG_FEATURE_BASH_IS_NONE=y
+CONFIG_SH_MATH_SUPPORT=y
+CONFIG_SH_MATH_SUPPORT_64=y
+CONFIG_FEATURE_SH_EXTRA_QUIET=y
+# CONFIG_FEATURE_SH_STANDALONE is not set
+# CONFIG_FEATURE_SH_NOFORK is not set
+
+#
+# System Logging Utilities
+#
+CONFIG_SYSLOGD=y
+CONFIG_FEATURE_ROTATE_LOGFILE=y
+CONFIG_FEATURE_REMOTE_LOG=y
+CONFIG_FEATURE_SYSLOGD_DUP=y
+CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256
+CONFIG_FEATURE_IPC_SYSLOG=y
+CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16
+CONFIG_LOGREAD=y
+CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING=y
+CONFIG_KLOGD=y
+CONFIG_FEATURE_KLOGD_KLOGCTL=y
+CONFIG_LOGGER=y
diff --git a/recipes/busybox/busybox-1.18.3/ts75xx/defconfig b/recipes/busybox/busybox-1.18.3/ts75xx/defconfig
new file mode 100644
index 0000000..4b6658e
--- /dev/null
+++ b/recipes/busybox/busybox-1.18.3/ts75xx/defconfig
@@ -0,0 +1,986 @@
+#
+# Automatically generated make config: don't edit
+# Busybox version: 1.18.3
+# Thu Mar 24 13:42:39 2011
+#
+CONFIG_HAVE_DOT_CONFIG=y
+
+#
+# Busybox Settings
+#
+
+#
+# General Configuration
+#
+# CONFIG_DESKTOP is not set
+# CONFIG_EXTRA_COMPAT is not set
+# CONFIG_INCLUDE_SUSv2 is not set
+# CONFIG_USE_PORTABLE_CODE is not set
+CONFIG_PLATFORM_LINUX=y
+CONFIG_FEATURE_BUFFERS_USE_MALLOC=y
+# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
+# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
+CONFIG_SHOW_USAGE=y
+CONFIG_FEATURE_VERBOSE_USAGE=y
+CONFIG_FEATURE_COMPRESS_USAGE=y
+# CONFIG_FEATURE_INSTALLER is not set
+# CONFIG_INSTALL_NO_USR is not set
+CONFIG_LOCALE_SUPPORT=y
+CONFIG_UNICODE_SUPPORT=y
+# CONFIG_UNICODE_USING_LOCALE is not set
+# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set
+CONFIG_SUBST_WCHAR=63
+CONFIG_LAST_SUPPORTED_WCHAR=767
+# CONFIG_UNICODE_COMBINING_WCHARS is not set
+# CONFIG_UNICODE_WIDE_WCHARS is not set
+# CONFIG_UNICODE_BIDI_SUPPORT is not set
+# CONFIG_UNICODE_NEUTRAL_TABLE is not set
+# CONFIG_UNICODE_PRESERVE_BROKEN is not set
+CONFIG_LONG_OPTS=y
+CONFIG_FEATURE_DEVPTS=y
+# CONFIG_FEATURE_CLEAN_UP is not set
+CONFIG_FEATURE_WTMP=y
+CONFIG_FEATURE_UTMP=y
+CONFIG_FEATURE_PIDFILE=y
+CONFIG_FEATURE_SUID=y
+CONFIG_FEATURE_SUID_CONFIG=y
+CONFIG_FEATURE_SUID_CONFIG_QUIET=y
+# CONFIG_SELINUX is not set
+# CONFIG_FEATURE_PREFER_APPLETS is not set
+CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
+CONFIG_FEATURE_SYSLOG=y
+# CONFIG_FEATURE_HAVE_RPC is not set
+
+#
+# Build Options
+#
+# CONFIG_STATIC is not set
+# CONFIG_PIE is not set
+# CONFIG_NOMMU is not set
+# CONFIG_BUILD_LIBBUSYBOX is not set
+# CONFIG_FEATURE_INDIVIDUAL is not set
+# CONFIG_FEATURE_SHARED_BUSYBOX is not set
+CONFIG_LFS=y
+CONFIG_CROSS_COMPILER_PREFIX=""
+CONFIG_EXTRA_CFLAGS=""
+
+#
+# Debugging Options
+#
+# CONFIG_DEBUG is not set
+# CONFIG_DEBUG_PESSIMIZE is not set
+# CONFIG_WERROR is not set
+CONFIG_NO_DEBUG_LIB=y
+# CONFIG_DMALLOC is not set
+# CONFIG_EFENCE is not set
+
+#
+# Installation Options ("make install" behavior)
+#
+CONFIG_INSTALL_APPLET_SYMLINKS=y
+# CONFIG_INSTALL_APPLET_HARDLINKS is not set
+# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set
+# CONFIG_INSTALL_APPLET_DONT is not set
+# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set
+# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set
+# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set
+CONFIG_PREFIX="./_install"
+
+#
+# Busybox Library Tuning
+#
+CONFIG_PASSWORD_MINLEN=6
+CONFIG_MD5_SIZE_VS_SPEED=2
+CONFIG_FEATURE_FAST_TOP=y
+# CONFIG_FEATURE_ETC_NETWORKS is not set
+CONFIG_FEATURE_USE_TERMIOS=y
+CONFIG_FEATURE_EDITING=y
+CONFIG_FEATURE_EDITING_MAX_LEN=1024
+# CONFIG_FEATURE_EDITING_VI is not set
+CONFIG_FEATURE_EDITING_HISTORY=64
+CONFIG_FEATURE_EDITING_SAVEHISTORY=y
+CONFIG_FEATURE_TAB_COMPLETION=y
+CONFIG_FEATURE_USERNAME_COMPLETION=y
+CONFIG_FEATURE_EDITING_FANCY_PROMPT=y
+# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set
+CONFIG_FEATURE_NON_POSIX_CP=y
+CONFIG_FEATURE_VERBOSE_CP_MESSAGE=y
+CONFIG_FEATURE_COPYBUF_KB=4
+CONFIG_MONOTONIC_SYSCALL=y
+CONFIG_IOCTL_HEX2STR_ERROR=y
+CONFIG_FEATURE_HWIB=y
+
+#
+# Applets
+#
+
+#
+# Archival Utilities
+#
+CONFIG_FEATURE_SEAMLESS_XZ=y
+# CONFIG_FEATURE_SEAMLESS_LZMA is not set
+CONFIG_FEATURE_SEAMLESS_BZ2=y
+CONFIG_FEATURE_SEAMLESS_GZ=y
+CONFIG_FEATURE_SEAMLESS_Z=y
+CONFIG_AR=y
+# CONFIG_FEATURE_AR_LONG_FILENAMES is not set
+CONFIG_FEATURE_AR_CREATE=y
+CONFIG_BUNZIP2=y
+# CONFIG_BZIP2 is not set
+CONFIG_CPIO=y
+# CONFIG_FEATURE_CPIO_O is not set
+# CONFIG_FEATURE_CPIO_P is not set
+# CONFIG_DPKG is not set
+# CONFIG_DPKG_DEB is not set
+# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set
+CONFIG_GUNZIP=y
+CONFIG_GZIP=y
+CONFIG_FEATURE_GZIP_LONG_OPTIONS=y
+CONFIG_LZOP=y
+# CONFIG_LZOP_COMPR_HIGH is not set
+# CONFIG_RPM2CPIO is not set
+# CONFIG_RPM is not set
+CONFIG_TAR=y
+CONFIG_FEATURE_TAR_CREATE=y
+CONFIG_FEATURE_TAR_AUTODETECT=y
+CONFIG_FEATURE_TAR_FROM=y
+CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y
+# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set
+CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y
+CONFIG_FEATURE_TAR_LONG_OPTIONS=y
+CONFIG_FEATURE_TAR_TO_COMMAND=y
+CONFIG_FEATURE_TAR_UNAME_GNAME=y
+CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y
+# CONFIG_FEATURE_TAR_SELINUX is not set
+# CONFIG_UNCOMPRESS is not set
+# CONFIG_UNLZMA is not set
+# CONFIG_FEATURE_LZMA_FAST is not set
+# CONFIG_LZMA is not set
+CONFIG_UNXZ=y
+CONFIG_XZ=y
+CONFIG_UNZIP=y
+
+#
+# Coreutils
+#
+CONFIG_BASENAME=y
+CONFIG_CAT=y
+CONFIG_DATE=y
+CONFIG_FEATURE_DATE_ISOFMT=y
+# CONFIG_FEATURE_DATE_NANO is not set
+CONFIG_FEATURE_DATE_COMPAT=y
+CONFIG_TEST=y
+# CONFIG_FEATURE_TEST_64 is not set
+CONFIG_TR=y
+CONFIG_FEATURE_TR_CLASSES=y
+# CONFIG_FEATURE_TR_EQUIV is not set
+# CONFIG_BASE64=y
+# CONFIG_CAL is not set
+# CONFIG_CATV is not set
+CONFIG_CHGRP=y
+CONFIG_CHMOD=y
+CONFIG_CHOWN=y
+CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y
+CONFIG_CHROOT=y
+# CONFIG_CKSUM is not set
+# CONFIG_COMM is not set
+CONFIG_CP=y
+CONFIG_FEATURE_CP_LONG_OPTIONS=y
+CONFIG_CUT=y
+CONFIG_DD=y
+CONFIG_FEATURE_DD_SIGNAL_HANDLING=y
+CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y
+# CONFIG_FEATURE_DD_IBS_OBS is not set
+CONFIG_DF=y
+CONFIG_FEATURE_DF_FANCY=y
+CONFIG_DIRNAME=y
+# CONFIG_DOS2UNIX is not set
+# CONFIG_UNIX2DOS is not set
+CONFIG_DU=y
+CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y
+CONFIG_ECHO=y
+CONFIG_FEATURE_FANCY_ECHO=y
+CONFIG_ENV=y
+CONFIG_FEATURE_ENV_LONG_OPTIONS=y
+# CONFIG_EXPAND is not set
+# CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set
+CONFIG_EXPR=y
+# CONFIG_EXPR_MATH_SUPPORT_64 is not set
+CONFIG_FALSE=y
+# CONFIG_FOLD is not set
+CONFIG_FSYNC=y
+CONFIG_HEAD=y
+CONFIG_FEATURE_FANCY_HEAD=y
+# CONFIG_HOSTID is not set
+CONFIG_ID=y
+# CONFIG_INSTALL is not set
+# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set
+# CONFIG_LENGTH is not set
+CONFIG_LN=y
+CONFIG_LOGNAME=y
+CONFIG_LS=y
+CONFIG_FEATURE_LS_FILETYPES=y
+CONFIG_FEATURE_LS_FOLLOWLINKS=y
+CONFIG_FEATURE_LS_RECURSIVE=y
+CONFIG_FEATURE_LS_SORTFILES=y
+CONFIG_FEATURE_LS_TIMESTAMPS=y
+CONFIG_FEATURE_LS_USERNAME=y
+CONFIG_FEATURE_LS_COLOR=y
+# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set
+CONFIG_MD5SUM=y
+CONFIG_MKDIR=y
+CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y
+CONFIG_MKFIFO=y
+CONFIG_MKNOD=y
+CONFIG_MV=y
+CONFIG_FEATURE_MV_LONG_OPTIONS=y
+CONFIG_NICE=y
+CONFIG_NOHUP=y
+CONFIG_OD=y
+# CONFIG_PRINTENV is not set
+CONFIG_PRINTF=y
+CONFIG_PWD=y
+CONFIG_READLINK=y
+CONFIG_FEATURE_READLINK_FOLLOW=y
+CONFIG_REALPATH=y
+CONFIG_RM=y
+CONFIG_RMDIR=y
+CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y
+CONFIG_SEQ=y
+# CONFIG_SHA1SUM is not set
+CONFIG_SHA256SUM=y
+CONFIG_SHA512SUM=y
+CONFIG_SLEEP=y
+CONFIG_FEATURE_FANCY_SLEEP=y
+CONFIG_FEATURE_FLOAT_SLEEP=y
+CONFIG_SORT=y
+CONFIG_FEATURE_SORT_BIG=y
+# CONFIG_SPLIT is not set
+# CONFIG_FEATURE_SPLIT_FANCY is not set
+# CONFIG_STAT is not set
+# CONFIG_FEATURE_STAT_FORMAT is not set
+CONFIG_STTY=y
+# CONFIG_SUM is not set
+CONFIG_SYNC=y
+# CONFIG_TAC is not set
+CONFIG_TAIL=y
+CONFIG_FEATURE_FANCY_TAIL=y
+CONFIG_TEE=y
+CONFIG_FEATURE_TEE_USE_BLOCK_IO=y
+CONFIG_TOUCH=y
+CONFIG_TRUE=y
+CONFIG_TTY=y
+CONFIG_UNAME=y
+# CONFIG_UNEXPAND is not set
+# CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set
+CONFIG_UNIQ=y
+CONFIG_USLEEP=y
+CONFIG_UUDECODE=y
+CONFIG_UUENCODE=y
+CONFIG_WC=y
+# CONFIG_FEATURE_WC_LARGE is not set
+CONFIG_WHO=y
+CONFIG_WHOAMI=y
+CONFIG_YES=y
+
+#
+# Common options for cp and mv
+#
+# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set
+
+#
+# Common options for ls, more and telnet
+#
+CONFIG_FEATURE_AUTOWIDTH=y
+
+#
+# Common options for df, du, ls
+#
+CONFIG_FEATURE_HUMAN_READABLE=y
+
+#
+# Common options for md5sum, sha1sum, sha256sum, sha512sum
+#
+CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y
+
+#
+# Console Utilities
+#
+CONFIG_CHVT=y
+CONFIG_FGCONSOLE=y
+CONFIG_CLEAR=y
+CONFIG_DEALLOCVT=y
+CONFIG_DUMPKMAP=y
+# CONFIG_KBD_MODE is not set
+CONFIG_LOADFONT=y
+CONFIG_LOADKMAP=y
+CONFIG_OPENVT=y
+CONFIG_RESET=y
+# CONFIG_RESIZE is not set
+# CONFIG_FEATURE_RESIZE_PRINT is not set
+CONFIG_SETCONSOLE=y
+# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set
+CONFIG_SETFONT=y
+CONFIG_FEATURE_SETFONT_TEXTUAL_MAP=y
+CONFIG_DEFAULT_SETFONT_DIR=""
+# CONFIG_SETKEYCODES is not set
+# CONFIG_SETLOGCONS is not set
+CONFIG_SHOWKEY=y
+
+#
+# Common options for loadfont and setfont
+#
+CONFIG_FEATURE_LOADFONT_PSF2=y
+CONFIG_FEATURE_LOADFONT_RAW=y
+
+#
+# Debian Utilities
+#
+# CONFIG_MKTEMP is not set
+# CONFIG_PIPE_PROGRESS is not set
+# CONFIG_RUN_PARTS is not set
+# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set
+# CONFIG_FEATURE_RUN_PARTS_FANCY is not set
+# CONFIG_START_STOP_DAEMON is not set
+# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set
+# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set
+# CONFIG_WHICH is not set
+
+#
+# Editors
+#
+# CONFIG_PATCH is not set
+# CONFIG_AWK is not set
+# CONFIG_FEATURE_AWK_LIBM is not set
+CONFIG_CMP=y
+# CONFIG_DIFF is not set
+# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set
+# CONFIG_FEATURE_DIFF_DIR is not set
+# CONFIG_ED is not set
+CONFIG_SED=y
+# CONFIG_VI is not set
+CONFIG_FEATURE_VI_MAX_LEN=0
+# CONFIG_FEATURE_VI_8BIT is not set
+# CONFIG_FEATURE_VI_COLON is not set
+# CONFIG_FEATURE_VI_YANKMARK is not set
+# CONFIG_FEATURE_VI_SEARCH is not set
+# CONFIG_FEATURE_VI_USE_SIGNALS is not set
+# CONFIG_FEATURE_VI_DOT_CMD is not set
+# CONFIG_FEATURE_VI_READONLY is not set
+# CONFIG_FEATURE_VI_SETOPTS is not set
+# CONFIG_FEATURE_VI_SET is not set
+# CONFIG_FEATURE_VI_WIN_RESIZE is not set
+# CONFIG_FEATURE_VI_ASK_TERMINAL is not set
+# CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set
+# CONFIG_FEATURE_ALLOW_EXEC is not set
+
+#
+# Finding Utilities
+#
+CONFIG_FIND=y
+CONFIG_FEATURE_FIND_PRINT0=y
+CONFIG_FEATURE_FIND_MTIME=y
+CONFIG_FEATURE_FIND_MMIN=y
+CONFIG_FEATURE_FIND_PERM=y
+CONFIG_FEATURE_FIND_TYPE=y
+CONFIG_FEATURE_FIND_XDEV=y
+CONFIG_FEATURE_FIND_MAXDEPTH=y
+CONFIG_FEATURE_FIND_NEWER=y
+CONFIG_FEATURE_FIND_INUM=y
+CONFIG_FEATURE_FIND_EXEC=y
+CONFIG_FEATURE_FIND_USER=y
+CONFIG_FEATURE_FIND_GROUP=y
+CONFIG_FEATURE_FIND_NOT=y
+CONFIG_FEATURE_FIND_DEPTH=y
+CONFIG_FEATURE_FIND_PAREN=y
+CONFIG_FEATURE_FIND_SIZE=y
+CONFIG_FEATURE_FIND_PRUNE=y
+CONFIG_FEATURE_FIND_DELETE=y
+CONFIG_FEATURE_FIND_PATH=y
+CONFIG_FEATURE_FIND_REGEX=y
+# CONFIG_FEATURE_FIND_CONTEXT is not set
+CONFIG_FEATURE_FIND_LINKS=y
+CONFIG_GREP=y
+CONFIG_FEATURE_GREP_EGREP_ALIAS=y
+CONFIG_FEATURE_GREP_FGREP_ALIAS=y
+CONFIG_FEATURE_GREP_CONTEXT=y
+CONFIG_XARGS=y
+# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set
+CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y
+CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y
+CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y
+
+#
+# Init Utilities
+#
+# CONFIG_BOOTCHARTD is not set
+# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set
+# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set
+# CONFIG_HALT is not set
+# CONFIG_FEATURE_CALL_TELINIT is not set
+CONFIG_TELINIT_PATH=""
+# CONFIG_INIT is not set
+# CONFIG_FEATURE_USE_INITTAB is not set
+# CONFIG_FEATURE_KILL_REMOVED is not set
+CONFIG_FEATURE_KILL_DELAY=0
+# CONFIG_FEATURE_INIT_SCTTY is not set
+# CONFIG_FEATURE_INIT_SYSLOG is not set
+# CONFIG_FEATURE_EXTRA_QUIET is not set
+# CONFIG_FEATURE_INIT_COREDUMPS is not set
+# CONFIG_FEATURE_INITRD is not set
+CONFIG_INIT_TERMINAL_TYPE=""
+# CONFIG_MESG is not set
+
+#
+# Login/Password Management Utilities
+#
+# CONFIG_ADD_SHELL is not set
+# CONFIG_REMOVE_SHELL is not set
+# CONFIG_FEATURE_SHADOWPASSWDS is not set
+# CONFIG_USE_BB_PWD_GRP is not set
+# CONFIG_USE_BB_SHADOW is not set
+# CONFIG_USE_BB_CRYPT is not set
+# CONFIG_USE_BB_CRYPT_SHA is not set
+# CONFIG_ADDUSER is not set
+# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set
+# CONFIG_FEATURE_CHECK_NAMES is not set
+CONFIG_FIRST_SYSTEM_ID=0
+CONFIG_LAST_SYSTEM_ID=0
+# CONFIG_ADDGROUP is not set
+# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set
+# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set
+# CONFIG_DELUSER is not set
+# CONFIG_DELGROUP is not set
+# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set
+CONFIG_GETTY=y
+CONFIG_LOGIN=y
+# CONFIG_PAM is not set
+CONFIG_LOGIN_SCRIPTS=y
+CONFIG_FEATURE_NOLOGIN=y
+CONFIG_FEATURE_SECURETTY=y
+# CONFIG_PASSWD is not set
+# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set
+# CONFIG_CRYPTPW is not set
+# CONFIG_CHPASSWD is not set
+# CONFIG_SU is not set
+# CONFIG_FEATURE_SU_SYSLOG is not set
+# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set
+# CONFIG_SULOGIN is not set
+# CONFIG_VLOCK is not set
+
+#
+# Linux Ext2 FS Progs
+#
+CONFIG_CHATTR=y
+CONFIG_FSCK=y
+# CONFIG_LSATTR is not set
+# CONFIG_TUNE2FS is not set
+
+#
+# Linux Module Utilities
+#
+CONFIG_MODINFO=y
+# CONFIG_MODPROBE_SMALL is not set
+# CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE is not set
+# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set
+CONFIG_INSMOD=y
+CONFIG_RMMOD=y
+CONFIG_LSMOD=y
+CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y
+CONFIG_MODPROBE=y
+CONFIG_FEATURE_MODPROBE_BLACKLIST=y
+# CONFIG_DEPMOD is not set
+
+#
+# Options common to multiple modutils
+#
+# CONFIG_FEATURE_2_4_MODULES is not set
+# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set
+# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set
+# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set
+# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set
+CONFIG_FEATURE_CHECK_TAINTED_MODULE=y
+CONFIG_FEATURE_MODUTILS_ALIAS=y
+CONFIG_FEATURE_MODUTILS_SYMBOLS=y
+CONFIG_DEFAULT_MODULES_DIR="/lib/modules"
+CONFIG_DEFAULT_DEPMOD_FILE="modules.dep"
+
+#
+# Linux System Utilities
+#
+# CONFIG_BLOCKDEV is not set
+# CONFIG_REV is not set
+# CONFIG_ACPID is not set
+# CONFIG_FEATURE_ACPID_COMPAT is not set
+# CONFIG_BLKID is not set
+CONFIG_DMESG=y
+CONFIG_FEATURE_DMESG_PRETTY=y
+# CONFIG_FBSET is not set
+# CONFIG_FEATURE_FBSET_FANCY is not set
+# CONFIG_FEATURE_FBSET_READMODE is not set
+# CONFIG_FDFLUSH is not set
+# CONFIG_FDFORMAT is not set
+CONFIG_FDISK=y
+CONFIG_FDISK_SUPPORT_LARGE_DISKS=y
+CONFIG_FEATURE_FDISK_WRITABLE=y
+# CONFIG_FEATURE_AIX_LABEL is not set
+# CONFIG_FEATURE_SGI_LABEL is not set
+# CONFIG_FEATURE_SUN_LABEL is not set
+CONFIG_FEATURE_OSF_LABEL=y
+# CONFIG_FEATURE_GPT_LABEL is not set
+CONFIG_FEATURE_FDISK_ADVANCED=y
+# CONFIG_FINDFS is not set
+# CONFIG_FLOCK is not set
+CONFIG_FREERAMDISK=y
+# CONFIG_FSCK_MINIX is not set
+CONFIG_MKFS_EXT2=y
+# CONFIG_MKFS_MINIX is not set
+# CONFIG_FEATURE_MINIX2 is not set
+# CONFIG_MKFS_REISER is not set
+CONFIG_MKFS_VFAT=y
+CONFIG_GETOPT=y
+CONFIG_FEATURE_GETOPT_LONG=y
+# CONFIG_HEXDUMP is not set
+# CONFIG_FEATURE_HEXDUMP_REVERSE is not set
+# CONFIG_HD is not set
+# CONFIG_HWCLOCK is not set
+# CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set
+# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set
+# CONFIG_IPCRM is not set
+# CONFIG_IPCS is not set
+# CONFIG_LOSETUP is not set
+# CONFIG_LSPCI is not set
+# CONFIG_LSUSB is not set
+CONFIG_MDEV=y
+CONFIG_FEATURE_MDEV_CONF=y
+CONFIG_FEATURE_MDEV_RENAME=y
+CONFIG_FEATURE_MDEV_RENAME_REGEXP=y
+CONFIG_FEATURE_MDEV_EXEC=y
+CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y
+# CONFIG_MKSWAP is not set
+# CONFIG_FEATURE_MKSWAP_UUID is not set
+CONFIG_MORE=y
+CONFIG_MOUNT=y
+# CONFIG_FEATURE_MOUNT_FAKE is not set
+CONFIG_FEATURE_MOUNT_VERBOSE=y
+CONFIG_FEATURE_MOUNT_HELPERS=y
+# CONFIG_FEATURE_MOUNT_LABEL is not set
+# CONFIG_FEATURE_MOUNT_NFS is not set
+# CONFIG_FEATURE_MOUNT_CIFS is not set
+CONFIG_FEATURE_MOUNT_FLAGS=y
+CONFIG_FEATURE_MOUNT_FSTAB=y
+CONFIG_PIVOT_ROOT=y
+# CONFIG_RDATE is not set
+# CONFIG_RDEV is not set
+# CONFIG_READPROFILE is not set
+# CONFIG_RTCWAKE is not set
+# CONFIG_SCRIPT is not set
+# CONFIG_SCRIPTREPLAY is not set
+# CONFIG_SETARCH is not set
+# CONFIG_SWAPONOFF is not set
+# CONFIG_FEATURE_SWAPON_PRI is not set
+CONFIG_SWITCH_ROOT=y
+CONFIG_UMOUNT=y
+CONFIG_FEATURE_UMOUNT_ALL=y
+
+#
+# Common options for mount/umount
+#
+CONFIG_FEATURE_MOUNT_LOOP=y
+CONFIG_FEATURE_MOUNT_LOOP_CREATE=y
+# CONFIG_FEATURE_MTAB_SUPPORT is not set
+# CONFIG_VOLUMEID is not set
+# CONFIG_FEATURE_VOLUMEID_EXT is not set
+# CONFIG_FEATURE_VOLUMEID_BTRFS is not set
+# CONFIG_FEATURE_VOLUMEID_REISERFS is not set
+# CONFIG_FEATURE_VOLUMEID_FAT is not set
+# CONFIG_FEATURE_VOLUMEID_HFS is not set
+# CONFIG_FEATURE_VOLUMEID_JFS is not set
+# CONFIG_FEATURE_VOLUMEID_XFS is not set
+# CONFIG_FEATURE_VOLUMEID_NTFS is not set
+# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set
+# CONFIG_FEATURE_VOLUMEID_UDF is not set
+# CONFIG_FEATURE_VOLUMEID_LUKS is not set
+# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set
+# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set
+# CONFIG_FEATURE_VOLUMEID_ROMFS is not set
+# CONFIG_FEATURE_VOLUMEID_SYSV is not set
+# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set
+# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set
+
+#
+# Miscellaneous Utilities
+#
+# CONFIG_CONSPY is not set
+# CONFIG_NANDWRITE is not set
+# CONFIG_NANDDUMP is not set
+# CONFIG_UBIATTACH is not set
+# CONFIG_UBIDETACH is not set
+# CONFIG_ADJTIMEX is not set
+# CONFIG_BBCONFIG is not set
+# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set
+# CONFIG_BEEP is not set
+CONFIG_FEATURE_BEEP_FREQ=0
+CONFIG_FEATURE_BEEP_LENGTH_MS=0
+# CONFIG_CHAT is not set
+# CONFIG_FEATURE_CHAT_NOFAIL is not set
+# CONFIG_FEATURE_CHAT_TTY_HIFI is not set
+# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set
+# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set
+# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set
+# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set
+# CONFIG_FEATURE_CHAT_CLR_ABORT is not set
+# CONFIG_CHRT is not set
+# CONFIG_CROND is not set
+# CONFIG_FEATURE_CROND_D is not set
+# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set
+CONFIG_FEATURE_CROND_DIR=""
+# CONFIG_CRONTAB is not set
+# CONFIG_DC is not set
+# CONFIG_FEATURE_DC_LIBM is not set
+# CONFIG_DEVFSD is not set
+# CONFIG_DEVFSD_MODLOAD is not set
+# CONFIG_DEVFSD_FG_NP is not set
+# CONFIG_DEVFSD_VERBOSE is not set
+# CONFIG_FEATURE_DEVFS is not set
+CONFIG_DEVMEM=y
+# CONFIG_EJECT is not set
+# CONFIG_FEATURE_EJECT_SCSI is not set
+# CONFIG_FBSPLASH is not set
+# CONFIG_FLASHCP is not set
+# CONFIG_FLASH_LOCK is not set
+# CONFIG_FLASH_UNLOCK is not set
+# CONFIG_FLASH_ERASEALL is not set
+# CONFIG_IONICE is not set
+# CONFIG_INOTIFYD is not set
+# CONFIG_LAST is not set
+# CONFIG_FEATURE_LAST_SMALL is not set
+# CONFIG_FEATURE_LAST_FANCY is not set
+# CONFIG_LESS is not set
+CONFIG_FEATURE_LESS_MAXLINES=0
+# CONFIG_FEATURE_LESS_BRACKETS is not set
+# CONFIG_FEATURE_LESS_FLAGS is not set
+# CONFIG_FEATURE_LESS_MARKS is not set
+# CONFIG_FEATURE_LESS_REGEXP is not set
+# CONFIG_FEATURE_LESS_WINCH is not set
+# CONFIG_FEATURE_LESS_DASHCMD is not set
+# CONFIG_FEATURE_LESS_LINENUMS is not set
+# CONFIG_HDPARM is not set
+# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set
+# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set
+# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set
+# CONFIG_MAKEDEVS is not set
+# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
+# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
+# CONFIG_MAN is not set
+# CONFIG_MICROCOM is not set
+# CONFIG_MOUNTPOINT is not set
+# CONFIG_MT is not set
+# CONFIG_RAIDAUTORUN is not set
+CONFIG_READAHEAD=y
+# CONFIG_RFKILL is not set
+# CONFIG_RUNLEVEL is not set
+# CONFIG_RX is not set
+CONFIG_SETSID=y
+# CONFIG_STRINGS is not set
+# CONFIG_TASKSET is not set
+# CONFIG_FEATURE_TASKSET_FANCY is not set
+# CONFIG_TIME is not set
+# CONFIG_TIMEOUT is not set
+# CONFIG_TTYSIZE is not set
+# CONFIG_VOLNAME is not set
+# CONFIG_WALL is not set
+CONFIG_WATCHDOG=y
+
+#
+# Networking Utilities
+#
+CONFIG_NBDCLIENT=y
+# CONFIG_NC=y
+# CONFIG_NC_SERVER=y
+# CONFIG_NC_EXTRA=y
+# CONFIG_NC_110_COMPAT is not set
+CONFIG_FEATURE_IPV6=y
+# CONFIG_FEATURE_UNIX_LOCAL is not set
+CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y
+# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set
+# CONFIG_ARP is not set
+# CONFIG_ARPING is not set
+# CONFIG_BRCTL is not set
+# CONFIG_FEATURE_BRCTL_FANCY is not set
+# CONFIG_FEATURE_BRCTL_SHOW is not set
+# CONFIG_DNSD is not set
+# CONFIG_ETHER_WAKE is not set
+# CONFIG_FAKEIDENTD is not set
+# CONFIG_FTPD=y
+# CONFIG_FEATURE_FTP_WRITE=y
+# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y
+# CONFIG_FTPGET is not set
+# CONFIG_FTPPUT is not set
+# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
+CONFIG_HOSTNAME=y
+# CONFIG_HTTPD=y
+# CONFIG_FEATURE_HTTPD_RANGES=y
+# CONFIG_FEATURE_HTTPD_USE_SENDFILE=y
+# CONFIG_FEATURE_HTTPD_SETUID=y
+# CONFIG_FEATURE_HTTPD_BASIC_AUTH=y
+# CONFIG_FEATURE_HTTPD_AUTH_MD5=y
+# CONFIG_FEATURE_HTTPD_CGI=y
+# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y
+# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y
+# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y
+# CONFIG_FEATURE_HTTPD_ERROR_PAGES=y
+# CONFIG_FEATURE_HTTPD_PROXY=y
+# CONFIG_FEATURE_HTTPD_GZIP=y
+CONFIG_IFCONFIG=y
+CONFIG_FEATURE_IFCONFIG_STATUS=y
+# CONFIG_FEATURE_IFCONFIG_SLIP is not set
+# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set
+CONFIG_FEATURE_IFCONFIG_HW=y
+CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y
+# CONFIG_IFENSLAVE is not set
+CONFIG_IFPLUGD=y
+CONFIG_IFUPDOWN=y
+CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate"
+# CONFIG_FEATURE_IFUPDOWN_IP is not set
+# CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN is not set
+CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN=y
+CONFIG_FEATURE_IFUPDOWN_IPV4=y
+CONFIG_FEATURE_IFUPDOWN_IPV6=y
+CONFIG_FEATURE_IFUPDOWN_MAPPING=y
+# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set
+# CONFIG_INETD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set
+# CONFIG_FEATURE_INETD_RPC is not set
+CONFIG_IP=y
+CONFIG_FEATURE_IP_ADDRESS=y
+CONFIG_FEATURE_IP_LINK=y
+CONFIG_FEATURE_IP_ROUTE=y
+CONFIG_FEATURE_IP_TUNNEL=y
+# CONFIG_FEATURE_IP_RULE is not set
+# CONFIG_FEATURE_IP_SHORT_FORMS is not set
+# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set
+# CONFIG_IPADDR is not set
+# CONFIG_IPLINK is not set
+# CONFIG_IPROUTE is not set
+# CONFIG_IPTUNNEL is not set
+# CONFIG_IPRULE is not set
+# CONFIG_IPCALC is not set
+# CONFIG_FEATURE_IPCALC_FANCY is not set
+# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set
+# CONFIG_NAMEIF is not set
+# CONFIG_FEATURE_NAMEIF_EXTENDED is not set
+CONFIG_NETSTAT=y
+CONFIG_FEATURE_NETSTAT_WIDE=y
+CONFIG_FEATURE_NETSTAT_PRG=y
+CONFIG_NSLOOKUP=y
+CONFIG_NTPD=y
+CONFIG_FEATURE_NTPD_SERVER=y
+CONFIG_PING=y
+CONFIG_PING6=y
+CONFIG_FEATURE_FANCY_PING=y
+# CONFIG_PSCAN is not set
+CONFIG_ROUTE=y
+# CONFIG_SLATTACH is not set
+# CONFIG_TCPSVD is not set
+CONFIG_TELNET=y
+# CONFIG_FEATURE_TELNET_TTYPE is not set
+CONFIG_FEATURE_TELNET_AUTOLOGIN=y
+CONFIG_TELNETD=y
+# CONFIG_FEATURE_TELNETD_STANDALONE is not set
+# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set
+# CONFIG_TFTP=y
+# CONFIG_TFTPD is not set
+
+#
+# Common options for tftp/tftpd
+#
+# CONFIG_FEATURE_TFTP_GET=y
+# CONFIG_FEATURE_TFTP_PUT=y
+# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
+# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set
+# CONFIG_TFTP_DEBUG is not set
+# CONFIG_TRACEROUTE=y
+# CONFIG_TRACEROUTE6=y
+# CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
+# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y
+# CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y
+# CONFIG_TUNCTL=y
+CONFIG_FEATURE_TUNCTL_UG=y
+CONFIG_UDHCPD=y
+CONFIG_DHCPRELAY=y
+CONFIG_DUMPLEASES=y
+# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set
+CONFIG_DHCPD_LEASES_FILE="/var/lib/misc/udhcpd.leases"
+CONFIG_UDHCPC=y
+CONFIG_FEATURE_UDHCPC_ARPING=y
+# CONFIG_FEATURE_UDHCP_PORT is not set
+CONFIG_UDHCP_DEBUG=9
+# CONFIG_FEATURE_UDHCP_RFC3397 is not set
+CONFIG_UDHCPC_DEFAULT_SCRIPT="@DATADIR@/udhcpc/default.script"
+CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80
+CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n"
+# CONFIG_UDPSVD is not set
+# CONFIG_VCONFIG is not set
+CONFIG_WGET=y
+CONFIG_FEATURE_WGET_STATUSBAR=y
+CONFIG_FEATURE_WGET_AUTHENTICATION=y
+CONFIG_FEATURE_WGET_LONG_OPTIONS=y
+CONFIG_FEATURE_WGET_TIMEOUT=y
+# CONFIG_ZCIP is not set
+
+#
+# Print Utilities
+#
+# CONFIG_LPD is not set
+# CONFIG_LPR is not set
+# CONFIG_LPQ is not set
+
+#
+# Mail Utilities
+#
+# CONFIG_MAKEMIME is not set
+CONFIG_FEATURE_MIME_CHARSET=""
+# CONFIG_POPMAILDIR is not set
+# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set
+# CONFIG_REFORMIME is not set
+# CONFIG_FEATURE_REFORMIME_COMPAT is not set
+# CONFIG_SENDMAIL is not set
+
+#
+# Process Utilities
+#
+# CONFIG_IOSTAT is not set
+# CONFIG_MPSTAT is not set
+# CONFIG_PMAP is not set
+# CONFIG_POWERTOP is not set
+# CONFIG_SMEMCAP is not set
+# CONFIG_FREE is not set
+# CONFIG_FUSER is not set
+CONFIG_KILL=y
+CONFIG_KILLALL=y
+# CONFIG_KILLALL5 is not set
+# CONFIG_NMETER is not set
+# CONFIG_PGREP is not set
+CONFIG_PIDOF=y
+CONFIG_FEATURE_PIDOF_SINGLE=y
+CONFIG_FEATURE_PIDOF_OMIT=y
+# CONFIG_PKILL is not set
+CONFIG_PS=y
+CONFIG_FEATURE_PS_WIDE=y
+# CONFIG_FEATURE_PS_TIME is not set
+# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set
+# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set
+# CONFIG_RENICE is not set
+# CONFIG_BB_SYSCTL is not set
+# CONFIG_TOP is not set
+# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set
+# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set
+# CONFIG_FEATURE_TOP_SMP_CPU is not set
+# CONFIG_FEATURE_TOP_DECIMALS is not set
+# CONFIG_FEATURE_TOP_SMP_PROCESS is not set
+# CONFIG_FEATURE_TOPMEM is not set
+# CONFIG_FEATURE_SHOW_THREADS is not set
+# CONFIG_UPTIME is not set
+# CONFIG_WATCH is not set
+
+#
+# Runit Utilities
+#
+# CONFIG_RUNSV is not set
+# CONFIG_RUNSVDIR is not set
+# CONFIG_FEATURE_RUNSVDIR_LOG is not set
+# CONFIG_SV is not set
+CONFIG_SV_DEFAULT_SERVICE_DIR=""
+# CONFIG_SVLOGD is not set
+# CONFIG_CHPST is not set
+# CONFIG_SETUIDGID is not set
+# CONFIG_ENVUIDGID is not set
+# CONFIG_ENVDIR is not set
+# CONFIG_SOFTLIMIT is not set
+# CONFIG_CHCON is not set
+# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set
+# CONFIG_GETENFORCE is not set
+# CONFIG_GETSEBOOL is not set
+# CONFIG_LOAD_POLICY is not set
+# CONFIG_MATCHPATHCON is not set
+# CONFIG_RESTORECON is not set
+# CONFIG_RUNCON is not set
+# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set
+# CONFIG_SELINUXENABLED is not set
+# CONFIG_SETENFORCE is not set
+# CONFIG_SETFILES is not set
+# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set
+# CONFIG_SETSEBOOL is not set
+# CONFIG_SESTATUS is not set
+
+#
+# Shells
+#
+CONFIG_ASH=y
+CONFIG_ASH_BASH_COMPAT=y
+CONFIG_ASH_JOB_CONTROL=y
+CONFIG_ASH_ALIAS=y
+CONFIG_ASH_GETOPTS=y
+CONFIG_ASH_BUILTIN_ECHO=y
+CONFIG_ASH_BUILTIN_PRINTF=y
+CONFIG_ASH_BUILTIN_TEST=y
+# CONFIG_ASH_CMDCMD is not set
+# CONFIG_ASH_MAIL is not set
+# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_ASH_RANDOM_SUPPORT is not set
+CONFIG_ASH_EXPAND_PRMT=y
+CONFIG_CTTYHACK=y
+# CONFIG_HUSH is not set
+# CONFIG_HUSH_BASH_COMPAT is not set
+# CONFIG_HUSH_BRACE_EXPANSION is not set
+# CONFIG_HUSH_HELP is not set
+# CONFIG_HUSH_INTERACTIVE is not set
+# CONFIG_HUSH_SAVEHISTORY is not set
+# CONFIG_HUSH_JOB is not set
+# CONFIG_HUSH_TICK is not set
+# CONFIG_HUSH_IF is not set
+# CONFIG_HUSH_LOOPS is not set
+# CONFIG_HUSH_CASE is not set
+# CONFIG_HUSH_FUNCTIONS is not set
+# CONFIG_HUSH_LOCAL is not set
+# CONFIG_HUSH_RANDOM_SUPPORT is not set
+# CONFIG_HUSH_EXPORT_N is not set
+# CONFIG_HUSH_MODE_X is not set
+# CONFIG_MSH is not set
+CONFIG_FEATURE_SH_IS_ASH=y
+# CONFIG_FEATURE_SH_IS_HUSH is not set
+# CONFIG_FEATURE_SH_IS_NONE is not set
+# CONFIG_FEATURE_BASH_IS_ASH is not set
+# CONFIG_FEATURE_BASH_IS_HUSH is not set
+CONFIG_FEATURE_BASH_IS_NONE=y
+CONFIG_SH_MATH_SUPPORT=y
+CONFIG_SH_MATH_SUPPORT_64=y
+CONFIG_FEATURE_SH_EXTRA_QUIET=y
+# CONFIG_FEATURE_SH_STANDALONE is not set
+# CONFIG_FEATURE_SH_NOFORK is not set
+
+#
+# System Logging Utilities
+#
+CONFIG_SYSLOGD=y
+CONFIG_FEATURE_ROTATE_LOGFILE=y
+CONFIG_FEATURE_REMOTE_LOG=y
+CONFIG_FEATURE_SYSLOGD_DUP=y
+CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256
+CONFIG_FEATURE_IPC_SYSLOG=y
+CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16
+CONFIG_LOGREAD=y
+CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING=y
+CONFIG_KLOGD=y
+CONFIG_FEATURE_KLOGD_KLOGCTL=y
+CONFIG_LOGGER=y
-- 
1.7.3.4




^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 5/6] Added images for the TS7500 ARM SBCs
  2011-03-30 14:07 ` [PATCH 5/6] Added images for the TS7500 ARM SBCs UDel V2G Team
@ 2011-03-30 14:33   ` Marcin Juszkiewicz
  0 siblings, 0 replies; 20+ messages in thread
From: Marcin Juszkiewicz @ 2011-03-30 14:33 UTC (permalink / raw)
  To: openembedded-devel

Dnia 2011-03-30, śro o godzinie 10:07 -0400, UDel V2G Team pisze:
> * This commit includes two images - one for building the initrd image and the other for
>   building the rootfs image.
> 
> Signed-off-by: UDel V2G Team <v2g.udel@gmail.com>

Please use real "name surname" instead.

> diff --git a/recipes/images/ts75xx-initrd-image.bb b/recipes/images/ts75xx-initrd-image.bb
> new file mode 100644
> index 0000000..306bf3a
> --- /dev/null
> +++ b/recipes/images/ts75xx-initrd-image.bb

> +# Use a newer version of busybox since it includes the nbd-client applet.
> +# We no longer need to build the nbd-client program since we enable this.
> +DEPENDS = "busybox-1.18.3"

This is ugly - please provide patch which will enable nbd-client in
default busybox instead.

> +IMAGE_INSTALL = "busybox 

> canctl dioctl dmxctl spictl ts-utils ts-initrd \

I suggest creating task-ts75xx for it. Will be easier to add them into
images.

> +# This should build all the correct device tables.
> +IMAGE_DEVICE_TABLES = "files/device_table-ts75xx.txt"

This should probably be set in machine config. What if I will build this
image for c7x0?

> +fix_image () {

s/fix_image/remove_any_files_we_do_not_want_in_initrd/

Some will be done by setting package management variable to "none".


> +++ b/recipes/images/ts75xx-rootfs-image.bb

> +IMAGE_PREPROCESS_COMMAND = "create_etc_timestamp ; "

> +IMAGE_INIT_MANAGER = "sysvinit"

> +DISTRO_SSH_DAEMON = "openssh"

Do not override this - this is *distro* decision does it want openssh or
dropbear.

> +DEPENDS = "\
> +	task-proper-tools \
> +	${DISTRO_SSH_DAEMON} \
> +	${@base_contains('MACHINE_FEATURES', 'ext2', 'task-base-ext2', '', d)} \
> +	${@base_contains('MACHINE_FEATURES', 'usbhost', 'task-base-usbhost', '', d)} \
> +	canctl dioctl dmxctl spictl ts-utils ts-initrd \

> +	coreutils \
> +	findutils \
> +	bash \

Those are part of task-proper-tools iirc.

> +	python \

without extra modules?

> +KERNEL_MODULES = "\

why not install "kernel-modules" meta package instead?




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/6] Add recipes for building TS75xx userspace utilities
  2011-03-30 14:07 ` [PATCH 4/6] Add recipes for building TS75xx userspace utilities UDel V2G Team
@ 2011-03-30 14:40   ` Marcin Juszkiewicz
  2011-03-30 16:55     ` Sachin Kamboj
  0 siblings, 1 reply; 20+ messages in thread
From: Marcin Juszkiewicz @ 2011-03-30 14:40 UTC (permalink / raw)
  To: openembedded-devel

Dnia 2011-03-30, śro o godzinie 10:07 -0400, UDel V2G Team pisze:

Few notes:

1. use real name surname for commits
2. drop any PR=r0 or DEPENDS="" lines
3. I would prefer patching Makefile then own do_compile/do_install
4. tarballs are not versioned - discuss it with upstream

> +++ b/recipes/ts7500/ts7500_0.0.1.bb

rename to task-ts7500 

> @@ -0,0 +1,7 @@
> +DESCRIPTION = "TS 7500 Utility Scripts"
> +MAINTAINER = "Sachin Kamboj"

E-mail please. And add this to /MAINTAINERS instead.

> +PR = "r0"

"r0" is default - drop

> +# ALLOW_EMPTY = 1

"1" is preferred version

> +DEPENDS = "canctl ts-utils  dioctl  dmxctl  spictl nbd"

DEPENDS will be generated from RDEPENDS - drop

> +RDEPENDS = "canctl ts-utils  dioctl  dmxctl  spictl nbd-client"

> +PROVIDES = "ts7500"

useless - drop





^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs
  2011-03-30 14:07 [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
                   ` (4 preceding siblings ...)
  2011-03-30 14:07 ` [PATCH 6/6] Adds custom defconfigs for Technologic Systems " UDel V2G Team
@ 2011-03-30 14:43 ` Marcin Juszkiewicz
  2011-03-31 20:48 ` Khem Raj
  6 siblings, 0 replies; 20+ messages in thread
From: Marcin Juszkiewicz @ 2011-03-30 14:43 UTC (permalink / raw)
  To: openembedded-devel

Dnia 2011-03-30, śro o godzinie 10:07 -0400, UDel V2G Team pisze:
> +++ b/conf/machine/include/tune-fa526.inc

> +# This core basically resembles a ARM920T but has NO thumb
> interworking support
> +# which makes it not fully EABI compliant 

This is not arm920t core. Vendor says "The cores are based on the ARMv4™
instruction set and AMBA™ 2.0 AHB bus architecture." There is no
information on which core they based.




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/6] Add kernel support for the Technologic Systems TS7500 ARM SBCs
  2011-03-30 14:07 ` [PATCH 3/6] Add kernel support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
@ 2011-03-30 14:45   ` Marcin Juszkiewicz
  2011-04-02  8:53   ` Petr Štetiar
  1 sibling, 0 replies; 20+ messages in thread
From: Marcin Juszkiewicz @ 2011-03-30 14:45 UTC (permalink / raw)
  To: openembedded-devel

Dnia 2011-03-30, śro o godzinie 10:07 -0400, UDel V2G Team pisze:
> * Adds a custom kernel with all the patches for the Cavium FA 526 core

> +++ b/recipes/linux/linux-ts75xx_2.6.35.bb

Each year we are repeating the same message - most of board does not
require own kernel recipes. But people still invent them. Please merge
your board into recipes/linux/linux_2.6.35.bb instead of providing own
one.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/6] Allows the use of the angstrom distribution with ARM cores that do not support THUMB_INTERWORK instructions
  2011-03-30 14:07 ` [PATCH 2/6] Allows the use of the angstrom distribution with ARM cores that do not support THUMB_INTERWORK instructions UDel V2G Team
@ 2011-03-30 15:04   ` Koen Kooi
  2011-03-31 20:57   ` Khem Raj
  1 sibling, 0 replies; 20+ messages in thread
From: Koen Kooi @ 2011-03-30 15:04 UTC (permalink / raw)
  To: openembedded-devel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 30-03-11 16:07, UDel V2G Team wrote:
> * Setting THUMB_INTERWORK = "yes" precludes the building of
>   any angstrom distribution for cores that do not support
>   thumb and thumb_interwork since the distro definitions
>   take precedence over any local settings.
> 
> Signed-off-by: UDel V2G Team <v2g.udel@gmail.com>

That needs to be a real name, but the change looks OK otherwise

Khem, Thomas, how did you produce working collie image before this changes?

regards,

Koen

> ---
>  conf/distro/include/angstrom.inc |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/conf/distro/include/angstrom.inc b/conf/distro/include/angstrom.inc
> index 5a02723..9ec1dc7 100644
> --- a/conf/distro/include/angstrom.inc
> +++ b/conf/distro/include/angstrom.inc
> @@ -54,7 +54,7 @@ ARM_INSTRUCTION_SET = "${ANGSTROM_ARM_INSTRUCTION_SET}"
>  #    but requires more instructions (140% for 70% smaller code) so may be
>  #    slower.
>  
> -THUMB_INTERWORK = "yes"
> +THUMB_INTERWORK ?= "yes"
>  # "yes" "no"
>  #    Whether to compile with code to allow interworking between the two
>  #    instruction sets.  This allows thumb code to be executed on a primarily

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Darwin)

iD8DBQFNk0aaMkyGM64RGpERAgM1AKCT29EFboKvc144BRY9nll1oVEX2ACgjeDm
DmldbpGH/jHxj7n/ZbAyNww=
=oPTu
-----END PGP SIGNATURE-----




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs
@ 2011-03-30 16:40 R.T. McGee
  2011-03-30 17:42 ` Koen Kooi
  0 siblings, 1 reply; 20+ messages in thread
From: R.T. McGee @ 2011-03-30 16:40 UTC (permalink / raw)
  To: openembedded-devel

Its true, the FA526 is not a ARM920T but it's a bit different from other
standard ARMv4 types.

Comments about the FA526 and ARM920T similarity are based on work like this:
http://openocd.sourcearchive.com/lines/0.3.1/fa526_8c-source.html
This are not from the perspective of the instruction set, but it more or
less talking about hardware features.

In the upcoming versions of GCC there will be a mtune option for the FA526,
because it is different enough
from a old standard armv4 and there and some code optimizations for the
pipeline, cache  etc.
http://gcc.gnu.org/ml/gcc-patches/2010-11/msg02208/gcc-4.6-svn-20101116-faraday-cpu.patch

Just to recap for others, the TS-7500 has a Cavium CNS2132 (aka Star Semi
STR8132) SoC which contains a FA526 core.

Thanks,
RT


> From: Marcin Juszkiewicz <marcin <at> juszkiewicz.com.pl>
> Subject: Re: [oe] [PATCH 1/6] Add support for the Technologic Systems
> TS7500 ARM SBCs
> Date: 2011-03-30 14:43:36 GMT
>
> Dnia 2011-03-30, śro o godzinie 10:07 -0400, UDel V2G Team pisze:
> > +++ b/conf/machine/include/tune-fa526.inc
>
> > +# This core basically resembles a ARM920T but has NO thumb
> > interworking support
> > +# which makes it not fully EABI compliant
>
> This is not arm920t core. Vendor says "The cores are based on the ARMv4(tm)
> instruction set and AMBA(tm) 2.0 AHB bus architecture." There is no
> information on which core they based.
>
> _______________________________________________
> Openembedded-devel mailing list
> Openembedded-devel <at> lists.openembedded.org
> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-devel
>


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/6] Add recipes for building TS75xx userspace utilities
  2011-03-30 14:40   ` Marcin Juszkiewicz
@ 2011-03-30 16:55     ` Sachin Kamboj
  2011-04-02  8:40       ` Petr Štetiar
  0 siblings, 1 reply; 20+ messages in thread
From: Sachin Kamboj @ 2011-03-30 16:55 UTC (permalink / raw)
  To: openembedded-devel

Thanks for suggesting these changes. I'll submit a new version of the patch soon...

On Mar 30, 2011, at 10:40 AM, Marcin Juszkiewicz wrote:

> Dnia 2011-03-30, śro o godzinie 10:07 -0400, UDel V2G Team pisze:
> 3. I would prefer patching Makefile then own do_compile/do_install

The original makefiles (if they exist at all - only a few of these utilities have actual makefiles) are rather esoteric - for example they contain support for building these utilities simultaneously for different platforms and need links to separate cross-compilers for all these platforms. It is way simpler to include the compilation instructions here. 

> 4. tarballs are not versioned - discuss it with upstream

We'll discuss this with the vendor - however, can we include these tarballs in the interim?

/Thanks,
Sachin.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs
  2011-03-30 16:40 R.T. McGee
@ 2011-03-30 17:42 ` Koen Kooi
  2011-03-31  9:19   ` Phil Blundell
  0 siblings, 1 reply; 20+ messages in thread
From: Koen Kooi @ 2011-03-30 17:42 UTC (permalink / raw)
  To: openembedded-devel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 30-03-11 18:40, R.T. McGee wrote:
> Its true, the FA526 is not a ARM920T but it's a bit different from other
> standard ARMv4 types.
> 
> Comments about the FA526 and ARM920T similarity are based on work like this:
> http://openocd.sourcearchive.com/lines/0.3.1/fa526_8c-source.html
> This are not from the perspective of the instruction set, but it more or
> less talking about hardware features.

So it's more like a ARM920?

> 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Darwin)

iD8DBQFNk2twMkyGM64RGpERAu6YAKC02zPo1mZcM8MOiys2fNrxdFPu3gCgoNay
H6ZSLNVdA4kadZYqvWAqoeA=
=b62T
-----END PGP SIGNATURE-----




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs
  2011-03-30 17:42 ` Koen Kooi
@ 2011-03-31  9:19   ` Phil Blundell
  0 siblings, 0 replies; 20+ messages in thread
From: Phil Blundell @ 2011-03-31  9:19 UTC (permalink / raw)
  To: openembedded-devel

On Wed, 2011-03-30 at 19:42 +0200, Koen Kooi wrote:
> On 30-03-11 18:40, R.T. McGee wrote:
> > Its true, the FA526 is not a ARM920T but it's a bit different from other
> > standard ARMv4 types.
> > 
> > Comments about the FA526 and ARM920T similarity are based on work like this:
> > http://openocd.sourcearchive.com/lines/0.3.1/fa526_8c-source.html
> > This are not from the perspective of the instruction set, but it more or
> > less talking about hardware features.
> 
> So it's more like a ARM920?

It's sort of like an ARM920 might perhaps be if such a thing existed,
yeah, but even then it probably wouldn't be an exact equivalent.  The
original description of "resembles ARM920T without Thumb" sounds like
it's about as good as it's going to get in terms of drawing an analogy
between the ARM cores and the Faraday ones.

p.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs
  2011-03-30 14:07 [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
                   ` (5 preceding siblings ...)
  2011-03-30 14:43 ` [PATCH 1/6] Add support for the " Marcin Juszkiewicz
@ 2011-03-31 20:48 ` Khem Raj
  6 siblings, 0 replies; 20+ messages in thread
From: Khem Raj @ 2011-03-31 20:48 UTC (permalink / raw)
  To: openembedded-devel

On Wed, Mar 30, 2011 at 7:07 AM, UDel V2G Team <v2g.udel@gmail.com> wrote:
> * Includes conf/machine/ts75xx.conf and conf/machine/include/tune-fa526.inc
>  files needed for building OE packages w/ EABI and *NO* thumb support
>
> Signed-off-by: UDel V2G Team <v2g.udel@gmail.com>
> ---
>  conf/machine/include/tune-fa526.inc |   22 ++++++++++++++++++++++
>  conf/machine/ts75xx.conf            |   22 ++++++++++++++++++++++
>  2 files changed, 44 insertions(+), 0 deletions(-)
>  create mode 100755 conf/machine/include/tune-fa526.inc
>  create mode 100755 conf/machine/ts75xx.conf
>
> diff --git a/conf/machine/include/tune-fa526.inc b/conf/machine/include/tune-fa526.inc
> new file mode 100755
> index 0000000..a5c5008
> --- /dev/null
> +++ b/conf/machine/include/tune-fa526.inc
> @@ -0,0 +1,22 @@
> +# This tune file is for the Faraday FA526 core is used in
> +# ARM processors like the Semi STR8132/ Cavium CNS2132, which is
> +# in the Technologic Systems TS-7500 board in addition to some
> +# NAS boxes out there.
> +#
> +# This core basically resembles a ARM920T but has NO thumb interworking support
> +# which makes it not fully EABI compliant
> +#
> +# Hence, we need to diable all thumb instructions here
> +# Also be sure to disable all thumb flags/features/includes in the distros
> +
> +FEED_ARCH = "armv4"
> +BASE_PACKAGE_ARCH = "armv4"
> +
> +# Ideally we want the following CFLAGS for our architecture.
> +# Angstorm will automtically add the thumb flags, so don't include them here
> +# TARGET_CC_ARCH += "-march=armv4 -mno-thumb-interwork -mno-thumb -mfloat-abi=soft"

-mfloat-abi=soft is probably not needed since thats the toolchain default.

> +TARGET_CC_ARCH += "-march=armv4 -mfloat-abi=soft"
> +
> +PACKAGE_EXTRA_ARCHS += "armv4"
> +LDFLAGS += "-Xlinker --fix-v4bx -Xassembler --fix-v4bx"

those should also be default when toolchain is build for armv4
where do u need to specify that in LDFLAGS

> +THUMB_INTERWORK = "no"
> diff --git a/conf/machine/ts75xx.conf b/conf/machine/ts75xx.conf
> new file mode 100755
> index 0000000..d76548d
> --- /dev/null
> +++ b/conf/machine/ts75xx.conf
> @@ -0,0 +1,22 @@
> +#@TYPE: Machine
> +#@Name: Technologic Systems TS-75xx SBC
> +#@DESCRIPTION: Machine configuration for Technologic Systems TS-75xx SBC
> +
> +TARGET_ARCH = "arm"
> +
> +MACHINE_FEATURES = "kernel26 ext2 usbhost"
> +
> +# This requires cavium fa526 patch set to function
> +# See the linux-ts75xx directory for the patches
> +PREFERRED_PROVIDER_virtual/kernel = "linux-ts75xx"
> +PREFERRED_VERSION_linux = "2.6.35"
> +
> +SERIAL_CONSOLE = "115200 ttyS0"
> +USE_VT = "0"
> +
> +# Uses the traditional TS-7500 bootloader process
> +# See the ts75xx-initrd-image.bb recipe for building
> +# an initrd script that only uses EABI userspace utilities
> +CMDLINE = "root=/dev/ram0 init=/linuxrc console=/dev/ttyS0,115200 lpj=958464"
> +
> +require conf/machine/include/tune-fa526.inc
> --
> 1.7.3.4
>
>
> _______________________________________________
> Openembedded-devel mailing list
> Openembedded-devel@lists.openembedded.org
> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-devel
>



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/6] Allows the use of the angstrom distribution with ARM cores that do not support THUMB_INTERWORK instructions
  2011-03-30 14:07 ` [PATCH 2/6] Allows the use of the angstrom distribution with ARM cores that do not support THUMB_INTERWORK instructions UDel V2G Team
  2011-03-30 15:04   ` Koen Kooi
@ 2011-03-31 20:57   ` Khem Raj
  1 sibling, 0 replies; 20+ messages in thread
From: Khem Raj @ 2011-03-31 20:57 UTC (permalink / raw)
  To: openembedded-devel

On Wed, Mar 30, 2011 at 7:07 AM, UDel V2G Team <v2g.udel@gmail.com> wrote:
> * Setting THUMB_INTERWORK = "yes" precludes the building of
>  any angstrom distribution for cores that do not support
>  thumb and thumb_interwork since the distro definitions
>  take precedence over any local settings.
>
> Signed-off-by: UDel V2G Team <v2g.udel@gmail.com>
> ---
>  conf/distro/include/angstrom.inc |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/conf/distro/include/angstrom.inc b/conf/distro/include/angstrom.inc
> index 5a02723..9ec1dc7 100644
> --- a/conf/distro/include/angstrom.inc
> +++ b/conf/distro/include/angstrom.inc
> @@ -54,7 +54,7 @@ ARM_INSTRUCTION_SET = "${ANGSTROM_ARM_INSTRUCTION_SET}"
>  #    but requires more instructions (140% for 70% smaller code) so may be
>  #    slower.
>
> -THUMB_INTERWORK = "yes"
> +THUMB_INTERWORK ?= "yes"

This change should not be needed since EABI mandates interworking and
gcc in OE generates a sequence which works on armv4
and it interworking safe on armv4t+

>  # "yes" "no"
>  #    Whether to compile with code to allow interworking between the two
>  #    instruction sets.  This allows thumb code to be executed on a primarily
> --
> 1.7.3.4
>
>
> _______________________________________________
> Openembedded-devel mailing list
> Openembedded-devel@lists.openembedded.org
> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-devel
>



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 6/6] Adds custom defconfigs for Technologic Systems TS7500 ARM SBCs
  2011-03-30 14:07 ` [PATCH 6/6] Adds custom defconfigs for Technologic Systems " UDel V2G Team
@ 2011-03-31 21:00   ` Khem Raj
  0 siblings, 0 replies; 20+ messages in thread
From: Khem Raj @ 2011-03-31 21:00 UTC (permalink / raw)
  To: openembedded-devel

On Wed, Mar 30, 2011 at 7:07 AM, UDel V2G Team <v2g.udel@gmail.com> wrote:
> * Added a busybox defconfig for building a version of busybox that will be
>  very similar to the original shipped version
>

what changes do you have on top of default config.

> Signed-off-by: UDel V2G Team <v2g.udel@gmail.com>
> ---
>  recipes/busybox/busybox-1.13.2/ts75xx/defconfig |  986 +++++++++++++++++++++++
>  recipes/busybox/busybox-1.18.3/ts75xx/defconfig |  986 +++++++++++++++++++++++
>  2 files changed, 1972 insertions(+), 0 deletions(-)
>  create mode 100644 recipes/busybox/busybox-1.13.2/ts75xx/defconfig
>  create mode 100644 recipes/busybox/busybox-1.18.3/ts75xx/defconfig
>
> diff --git a/recipes/busybox/busybox-1.13.2/ts75xx/defconfig b/recipes/busybox/busybox-1.13.2/ts75xx/defconfig
> new file mode 100644
> index 0000000..4b6658e
> --- /dev/null
> +++ b/recipes/busybox/busybox-1.13.2/ts75xx/defconfig
> @@ -0,0 +1,986 @@
> +#
> +# Automatically generated make config: don't edit
> +# Busybox version: 1.18.3
> +# Thu Mar 24 13:42:39 2011
> +#
> +CONFIG_HAVE_DOT_CONFIG=y
> +
> +#
> +# Busybox Settings
> +#
> +
> +#
> +# General Configuration
> +#
> +# CONFIG_DESKTOP is not set
> +# CONFIG_EXTRA_COMPAT is not set
> +# CONFIG_INCLUDE_SUSv2 is not set
> +# CONFIG_USE_PORTABLE_CODE is not set
> +CONFIG_PLATFORM_LINUX=y
> +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y
> +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
> +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
> +CONFIG_SHOW_USAGE=y
> +CONFIG_FEATURE_VERBOSE_USAGE=y
> +CONFIG_FEATURE_COMPRESS_USAGE=y
> +# CONFIG_FEATURE_INSTALLER is not set
> +# CONFIG_INSTALL_NO_USR is not set
> +CONFIG_LOCALE_SUPPORT=y
> +CONFIG_UNICODE_SUPPORT=y
> +# CONFIG_UNICODE_USING_LOCALE is not set
> +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set
> +CONFIG_SUBST_WCHAR=63
> +CONFIG_LAST_SUPPORTED_WCHAR=767
> +# CONFIG_UNICODE_COMBINING_WCHARS is not set
> +# CONFIG_UNICODE_WIDE_WCHARS is not set
> +# CONFIG_UNICODE_BIDI_SUPPORT is not set
> +# CONFIG_UNICODE_NEUTRAL_TABLE is not set
> +# CONFIG_UNICODE_PRESERVE_BROKEN is not set
> +CONFIG_LONG_OPTS=y
> +CONFIG_FEATURE_DEVPTS=y
> +# CONFIG_FEATURE_CLEAN_UP is not set
> +CONFIG_FEATURE_WTMP=y
> +CONFIG_FEATURE_UTMP=y
> +CONFIG_FEATURE_PIDFILE=y
> +CONFIG_FEATURE_SUID=y
> +CONFIG_FEATURE_SUID_CONFIG=y
> +CONFIG_FEATURE_SUID_CONFIG_QUIET=y
> +# CONFIG_SELINUX is not set
> +# CONFIG_FEATURE_PREFER_APPLETS is not set
> +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
> +CONFIG_FEATURE_SYSLOG=y
> +# CONFIG_FEATURE_HAVE_RPC is not set
> +
> +#
> +# Build Options
> +#
> +# CONFIG_STATIC is not set
> +# CONFIG_PIE is not set
> +# CONFIG_NOMMU is not set
> +# CONFIG_BUILD_LIBBUSYBOX is not set
> +# CONFIG_FEATURE_INDIVIDUAL is not set
> +# CONFIG_FEATURE_SHARED_BUSYBOX is not set
> +CONFIG_LFS=y
> +CONFIG_CROSS_COMPILER_PREFIX=""
> +CONFIG_EXTRA_CFLAGS=""
> +
> +#
> +# Debugging Options
> +#
> +# CONFIG_DEBUG is not set
> +# CONFIG_DEBUG_PESSIMIZE is not set
> +# CONFIG_WERROR is not set
> +CONFIG_NO_DEBUG_LIB=y
> +# CONFIG_DMALLOC is not set
> +# CONFIG_EFENCE is not set
> +
> +#
> +# Installation Options ("make install" behavior)
> +#
> +CONFIG_INSTALL_APPLET_SYMLINKS=y
> +# CONFIG_INSTALL_APPLET_HARDLINKS is not set
> +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set
> +# CONFIG_INSTALL_APPLET_DONT is not set
> +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set
> +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set
> +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set
> +CONFIG_PREFIX="./_install"
> +
> +#
> +# Busybox Library Tuning
> +#
> +CONFIG_PASSWORD_MINLEN=6
> +CONFIG_MD5_SIZE_VS_SPEED=2
> +CONFIG_FEATURE_FAST_TOP=y
> +# CONFIG_FEATURE_ETC_NETWORKS is not set
> +CONFIG_FEATURE_USE_TERMIOS=y
> +CONFIG_FEATURE_EDITING=y
> +CONFIG_FEATURE_EDITING_MAX_LEN=1024
> +# CONFIG_FEATURE_EDITING_VI is not set
> +CONFIG_FEATURE_EDITING_HISTORY=64
> +CONFIG_FEATURE_EDITING_SAVEHISTORY=y
> +CONFIG_FEATURE_TAB_COMPLETION=y
> +CONFIG_FEATURE_USERNAME_COMPLETION=y
> +CONFIG_FEATURE_EDITING_FANCY_PROMPT=y
> +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set
> +CONFIG_FEATURE_NON_POSIX_CP=y
> +CONFIG_FEATURE_VERBOSE_CP_MESSAGE=y
> +CONFIG_FEATURE_COPYBUF_KB=4
> +CONFIG_MONOTONIC_SYSCALL=y
> +CONFIG_IOCTL_HEX2STR_ERROR=y
> +CONFIG_FEATURE_HWIB=y
> +
> +#
> +# Applets
> +#
> +
> +#
> +# Archival Utilities
> +#
> +CONFIG_FEATURE_SEAMLESS_XZ=y
> +# CONFIG_FEATURE_SEAMLESS_LZMA is not set
> +CONFIG_FEATURE_SEAMLESS_BZ2=y
> +CONFIG_FEATURE_SEAMLESS_GZ=y
> +CONFIG_FEATURE_SEAMLESS_Z=y
> +CONFIG_AR=y
> +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set
> +CONFIG_FEATURE_AR_CREATE=y
> +CONFIG_BUNZIP2=y
> +# CONFIG_BZIP2 is not set
> +CONFIG_CPIO=y
> +# CONFIG_FEATURE_CPIO_O is not set
> +# CONFIG_FEATURE_CPIO_P is not set
> +# CONFIG_DPKG is not set
> +# CONFIG_DPKG_DEB is not set
> +# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set
> +CONFIG_GUNZIP=y
> +CONFIG_GZIP=y
> +CONFIG_FEATURE_GZIP_LONG_OPTIONS=y
> +CONFIG_LZOP=y
> +# CONFIG_LZOP_COMPR_HIGH is not set
> +# CONFIG_RPM2CPIO is not set
> +# CONFIG_RPM is not set
> +CONFIG_TAR=y
> +CONFIG_FEATURE_TAR_CREATE=y
> +CONFIG_FEATURE_TAR_AUTODETECT=y
> +CONFIG_FEATURE_TAR_FROM=y
> +CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y
> +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set
> +CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y
> +CONFIG_FEATURE_TAR_LONG_OPTIONS=y
> +CONFIG_FEATURE_TAR_TO_COMMAND=y
> +CONFIG_FEATURE_TAR_UNAME_GNAME=y
> +CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y
> +# CONFIG_FEATURE_TAR_SELINUX is not set
> +# CONFIG_UNCOMPRESS is not set
> +# CONFIG_UNLZMA is not set
> +# CONFIG_FEATURE_LZMA_FAST is not set
> +# CONFIG_LZMA is not set
> +CONFIG_UNXZ=y
> +CONFIG_XZ=y
> +CONFIG_UNZIP=y
> +
> +#
> +# Coreutils
> +#
> +CONFIG_BASENAME=y
> +CONFIG_CAT=y
> +CONFIG_DATE=y
> +CONFIG_FEATURE_DATE_ISOFMT=y
> +# CONFIG_FEATURE_DATE_NANO is not set
> +CONFIG_FEATURE_DATE_COMPAT=y
> +CONFIG_TEST=y
> +# CONFIG_FEATURE_TEST_64 is not set
> +CONFIG_TR=y
> +CONFIG_FEATURE_TR_CLASSES=y
> +# CONFIG_FEATURE_TR_EQUIV is not set
> +# CONFIG_BASE64=y
> +# CONFIG_CAL is not set
> +# CONFIG_CATV is not set
> +CONFIG_CHGRP=y
> +CONFIG_CHMOD=y
> +CONFIG_CHOWN=y
> +CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y
> +CONFIG_CHROOT=y
> +# CONFIG_CKSUM is not set
> +# CONFIG_COMM is not set
> +CONFIG_CP=y
> +CONFIG_FEATURE_CP_LONG_OPTIONS=y
> +CONFIG_CUT=y
> +CONFIG_DD=y
> +CONFIG_FEATURE_DD_SIGNAL_HANDLING=y
> +CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y
> +# CONFIG_FEATURE_DD_IBS_OBS is not set
> +CONFIG_DF=y
> +CONFIG_FEATURE_DF_FANCY=y
> +CONFIG_DIRNAME=y
> +# CONFIG_DOS2UNIX is not set
> +# CONFIG_UNIX2DOS is not set
> +CONFIG_DU=y
> +CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y
> +CONFIG_ECHO=y
> +CONFIG_FEATURE_FANCY_ECHO=y
> +CONFIG_ENV=y
> +CONFIG_FEATURE_ENV_LONG_OPTIONS=y
> +# CONFIG_EXPAND is not set
> +# CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set
> +CONFIG_EXPR=y
> +# CONFIG_EXPR_MATH_SUPPORT_64 is not set
> +CONFIG_FALSE=y
> +# CONFIG_FOLD is not set
> +CONFIG_FSYNC=y
> +CONFIG_HEAD=y
> +CONFIG_FEATURE_FANCY_HEAD=y
> +# CONFIG_HOSTID is not set
> +CONFIG_ID=y
> +# CONFIG_INSTALL is not set
> +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set
> +# CONFIG_LENGTH is not set
> +CONFIG_LN=y
> +CONFIG_LOGNAME=y
> +CONFIG_LS=y
> +CONFIG_FEATURE_LS_FILETYPES=y
> +CONFIG_FEATURE_LS_FOLLOWLINKS=y
> +CONFIG_FEATURE_LS_RECURSIVE=y
> +CONFIG_FEATURE_LS_SORTFILES=y
> +CONFIG_FEATURE_LS_TIMESTAMPS=y
> +CONFIG_FEATURE_LS_USERNAME=y
> +CONFIG_FEATURE_LS_COLOR=y
> +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set
> +CONFIG_MD5SUM=y
> +CONFIG_MKDIR=y
> +CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y
> +CONFIG_MKFIFO=y
> +CONFIG_MKNOD=y
> +CONFIG_MV=y
> +CONFIG_FEATURE_MV_LONG_OPTIONS=y
> +CONFIG_NICE=y
> +CONFIG_NOHUP=y
> +CONFIG_OD=y
> +# CONFIG_PRINTENV is not set
> +CONFIG_PRINTF=y
> +CONFIG_PWD=y
> +CONFIG_READLINK=y
> +CONFIG_FEATURE_READLINK_FOLLOW=y
> +CONFIG_REALPATH=y
> +CONFIG_RM=y
> +CONFIG_RMDIR=y
> +CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y
> +CONFIG_SEQ=y
> +# CONFIG_SHA1SUM is not set
> +CONFIG_SHA256SUM=y
> +CONFIG_SHA512SUM=y
> +CONFIG_SLEEP=y
> +CONFIG_FEATURE_FANCY_SLEEP=y
> +CONFIG_FEATURE_FLOAT_SLEEP=y
> +CONFIG_SORT=y
> +CONFIG_FEATURE_SORT_BIG=y
> +# CONFIG_SPLIT is not set
> +# CONFIG_FEATURE_SPLIT_FANCY is not set
> +# CONFIG_STAT is not set
> +# CONFIG_FEATURE_STAT_FORMAT is not set
> +CONFIG_STTY=y
> +# CONFIG_SUM is not set
> +CONFIG_SYNC=y
> +# CONFIG_TAC is not set
> +CONFIG_TAIL=y
> +CONFIG_FEATURE_FANCY_TAIL=y
> +CONFIG_TEE=y
> +CONFIG_FEATURE_TEE_USE_BLOCK_IO=y
> +CONFIG_TOUCH=y
> +CONFIG_TRUE=y
> +CONFIG_TTY=y
> +CONFIG_UNAME=y
> +# CONFIG_UNEXPAND is not set
> +# CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set
> +CONFIG_UNIQ=y
> +CONFIG_USLEEP=y
> +CONFIG_UUDECODE=y
> +CONFIG_UUENCODE=y
> +CONFIG_WC=y
> +# CONFIG_FEATURE_WC_LARGE is not set
> +CONFIG_WHO=y
> +CONFIG_WHOAMI=y
> +CONFIG_YES=y
> +
> +#
> +# Common options for cp and mv
> +#
> +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set
> +
> +#
> +# Common options for ls, more and telnet
> +#
> +CONFIG_FEATURE_AUTOWIDTH=y
> +
> +#
> +# Common options for df, du, ls
> +#
> +CONFIG_FEATURE_HUMAN_READABLE=y
> +
> +#
> +# Common options for md5sum, sha1sum, sha256sum, sha512sum
> +#
> +CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y
> +
> +#
> +# Console Utilities
> +#
> +CONFIG_CHVT=y
> +CONFIG_FGCONSOLE=y
> +CONFIG_CLEAR=y
> +CONFIG_DEALLOCVT=y
> +CONFIG_DUMPKMAP=y
> +# CONFIG_KBD_MODE is not set
> +CONFIG_LOADFONT=y
> +CONFIG_LOADKMAP=y
> +CONFIG_OPENVT=y
> +CONFIG_RESET=y
> +# CONFIG_RESIZE is not set
> +# CONFIG_FEATURE_RESIZE_PRINT is not set
> +CONFIG_SETCONSOLE=y
> +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set
> +CONFIG_SETFONT=y
> +CONFIG_FEATURE_SETFONT_TEXTUAL_MAP=y
> +CONFIG_DEFAULT_SETFONT_DIR=""
> +# CONFIG_SETKEYCODES is not set
> +# CONFIG_SETLOGCONS is not set
> +CONFIG_SHOWKEY=y
> +
> +#
> +# Common options for loadfont and setfont
> +#
> +CONFIG_FEATURE_LOADFONT_PSF2=y
> +CONFIG_FEATURE_LOADFONT_RAW=y
> +
> +#
> +# Debian Utilities
> +#
> +# CONFIG_MKTEMP is not set
> +# CONFIG_PIPE_PROGRESS is not set
> +# CONFIG_RUN_PARTS is not set
> +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set
> +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set
> +# CONFIG_START_STOP_DAEMON is not set
> +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set
> +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set
> +# CONFIG_WHICH is not set
> +
> +#
> +# Editors
> +#
> +# CONFIG_PATCH is not set
> +# CONFIG_AWK is not set
> +# CONFIG_FEATURE_AWK_LIBM is not set
> +CONFIG_CMP=y
> +# CONFIG_DIFF is not set
> +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set
> +# CONFIG_FEATURE_DIFF_DIR is not set
> +# CONFIG_ED is not set
> +CONFIG_SED=y
> +# CONFIG_VI is not set
> +CONFIG_FEATURE_VI_MAX_LEN=0
> +# CONFIG_FEATURE_VI_8BIT is not set
> +# CONFIG_FEATURE_VI_COLON is not set
> +# CONFIG_FEATURE_VI_YANKMARK is not set
> +# CONFIG_FEATURE_VI_SEARCH is not set
> +# CONFIG_FEATURE_VI_USE_SIGNALS is not set
> +# CONFIG_FEATURE_VI_DOT_CMD is not set
> +# CONFIG_FEATURE_VI_READONLY is not set
> +# CONFIG_FEATURE_VI_SETOPTS is not set
> +# CONFIG_FEATURE_VI_SET is not set
> +# CONFIG_FEATURE_VI_WIN_RESIZE is not set
> +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set
> +# CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set
> +# CONFIG_FEATURE_ALLOW_EXEC is not set
> +
> +#
> +# Finding Utilities
> +#
> +CONFIG_FIND=y
> +CONFIG_FEATURE_FIND_PRINT0=y
> +CONFIG_FEATURE_FIND_MTIME=y
> +CONFIG_FEATURE_FIND_MMIN=y
> +CONFIG_FEATURE_FIND_PERM=y
> +CONFIG_FEATURE_FIND_TYPE=y
> +CONFIG_FEATURE_FIND_XDEV=y
> +CONFIG_FEATURE_FIND_MAXDEPTH=y
> +CONFIG_FEATURE_FIND_NEWER=y
> +CONFIG_FEATURE_FIND_INUM=y
> +CONFIG_FEATURE_FIND_EXEC=y
> +CONFIG_FEATURE_FIND_USER=y
> +CONFIG_FEATURE_FIND_GROUP=y
> +CONFIG_FEATURE_FIND_NOT=y
> +CONFIG_FEATURE_FIND_DEPTH=y
> +CONFIG_FEATURE_FIND_PAREN=y
> +CONFIG_FEATURE_FIND_SIZE=y
> +CONFIG_FEATURE_FIND_PRUNE=y
> +CONFIG_FEATURE_FIND_DELETE=y
> +CONFIG_FEATURE_FIND_PATH=y
> +CONFIG_FEATURE_FIND_REGEX=y
> +# CONFIG_FEATURE_FIND_CONTEXT is not set
> +CONFIG_FEATURE_FIND_LINKS=y
> +CONFIG_GREP=y
> +CONFIG_FEATURE_GREP_EGREP_ALIAS=y
> +CONFIG_FEATURE_GREP_FGREP_ALIAS=y
> +CONFIG_FEATURE_GREP_CONTEXT=y
> +CONFIG_XARGS=y
> +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set
> +CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y
> +CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y
> +CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y
> +
> +#
> +# Init Utilities
> +#
> +# CONFIG_BOOTCHARTD is not set
> +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set
> +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set
> +# CONFIG_HALT is not set
> +# CONFIG_FEATURE_CALL_TELINIT is not set
> +CONFIG_TELINIT_PATH=""
> +# CONFIG_INIT is not set
> +# CONFIG_FEATURE_USE_INITTAB is not set
> +# CONFIG_FEATURE_KILL_REMOVED is not set
> +CONFIG_FEATURE_KILL_DELAY=0
> +# CONFIG_FEATURE_INIT_SCTTY is not set
> +# CONFIG_FEATURE_INIT_SYSLOG is not set
> +# CONFIG_FEATURE_EXTRA_QUIET is not set
> +# CONFIG_FEATURE_INIT_COREDUMPS is not set
> +# CONFIG_FEATURE_INITRD is not set
> +CONFIG_INIT_TERMINAL_TYPE=""
> +# CONFIG_MESG is not set
> +
> +#
> +# Login/Password Management Utilities
> +#
> +# CONFIG_ADD_SHELL is not set
> +# CONFIG_REMOVE_SHELL is not set
> +# CONFIG_FEATURE_SHADOWPASSWDS is not set
> +# CONFIG_USE_BB_PWD_GRP is not set
> +# CONFIG_USE_BB_SHADOW is not set
> +# CONFIG_USE_BB_CRYPT is not set
> +# CONFIG_USE_BB_CRYPT_SHA is not set
> +# CONFIG_ADDUSER is not set
> +# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set
> +# CONFIG_FEATURE_CHECK_NAMES is not set
> +CONFIG_FIRST_SYSTEM_ID=0
> +CONFIG_LAST_SYSTEM_ID=0
> +# CONFIG_ADDGROUP is not set
> +# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set
> +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set
> +# CONFIG_DELUSER is not set
> +# CONFIG_DELGROUP is not set
> +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set
> +CONFIG_GETTY=y
> +CONFIG_LOGIN=y
> +# CONFIG_PAM is not set
> +CONFIG_LOGIN_SCRIPTS=y
> +CONFIG_FEATURE_NOLOGIN=y
> +CONFIG_FEATURE_SECURETTY=y
> +# CONFIG_PASSWD is not set
> +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set
> +# CONFIG_CRYPTPW is not set
> +# CONFIG_CHPASSWD is not set
> +# CONFIG_SU is not set
> +# CONFIG_FEATURE_SU_SYSLOG is not set
> +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set
> +# CONFIG_SULOGIN is not set
> +# CONFIG_VLOCK is not set
> +
> +#
> +# Linux Ext2 FS Progs
> +#
> +CONFIG_CHATTR=y
> +CONFIG_FSCK=y
> +# CONFIG_LSATTR is not set
> +# CONFIG_TUNE2FS is not set
> +
> +#
> +# Linux Module Utilities
> +#
> +CONFIG_MODINFO=y
> +# CONFIG_MODPROBE_SMALL is not set
> +# CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE is not set
> +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set
> +CONFIG_INSMOD=y
> +CONFIG_RMMOD=y
> +CONFIG_LSMOD=y
> +CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y
> +CONFIG_MODPROBE=y
> +CONFIG_FEATURE_MODPROBE_BLACKLIST=y
> +# CONFIG_DEPMOD is not set
> +
> +#
> +# Options common to multiple modutils
> +#
> +# CONFIG_FEATURE_2_4_MODULES is not set
> +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set
> +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set
> +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set
> +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set
> +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set
> +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set
> +CONFIG_FEATURE_CHECK_TAINTED_MODULE=y
> +CONFIG_FEATURE_MODUTILS_ALIAS=y
> +CONFIG_FEATURE_MODUTILS_SYMBOLS=y
> +CONFIG_DEFAULT_MODULES_DIR="/lib/modules"
> +CONFIG_DEFAULT_DEPMOD_FILE="modules.dep"
> +
> +#
> +# Linux System Utilities
> +#
> +# CONFIG_BLOCKDEV is not set
> +# CONFIG_REV is not set
> +# CONFIG_ACPID is not set
> +# CONFIG_FEATURE_ACPID_COMPAT is not set
> +# CONFIG_BLKID is not set
> +CONFIG_DMESG=y
> +CONFIG_FEATURE_DMESG_PRETTY=y
> +# CONFIG_FBSET is not set
> +# CONFIG_FEATURE_FBSET_FANCY is not set
> +# CONFIG_FEATURE_FBSET_READMODE is not set
> +# CONFIG_FDFLUSH is not set
> +# CONFIG_FDFORMAT is not set
> +CONFIG_FDISK=y
> +CONFIG_FDISK_SUPPORT_LARGE_DISKS=y
> +CONFIG_FEATURE_FDISK_WRITABLE=y
> +# CONFIG_FEATURE_AIX_LABEL is not set
> +# CONFIG_FEATURE_SGI_LABEL is not set
> +# CONFIG_FEATURE_SUN_LABEL is not set
> +CONFIG_FEATURE_OSF_LABEL=y
> +# CONFIG_FEATURE_GPT_LABEL is not set
> +CONFIG_FEATURE_FDISK_ADVANCED=y
> +# CONFIG_FINDFS is not set
> +# CONFIG_FLOCK is not set
> +CONFIG_FREERAMDISK=y
> +# CONFIG_FSCK_MINIX is not set
> +CONFIG_MKFS_EXT2=y
> +# CONFIG_MKFS_MINIX is not set
> +# CONFIG_FEATURE_MINIX2 is not set
> +# CONFIG_MKFS_REISER is not set
> +CONFIG_MKFS_VFAT=y
> +CONFIG_GETOPT=y
> +CONFIG_FEATURE_GETOPT_LONG=y
> +# CONFIG_HEXDUMP is not set
> +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set
> +# CONFIG_HD is not set
> +# CONFIG_HWCLOCK is not set
> +# CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set
> +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set
> +# CONFIG_IPCRM is not set
> +# CONFIG_IPCS is not set
> +# CONFIG_LOSETUP is not set
> +# CONFIG_LSPCI is not set
> +# CONFIG_LSUSB is not set
> +CONFIG_MDEV=y
> +CONFIG_FEATURE_MDEV_CONF=y
> +CONFIG_FEATURE_MDEV_RENAME=y
> +CONFIG_FEATURE_MDEV_RENAME_REGEXP=y
> +CONFIG_FEATURE_MDEV_EXEC=y
> +CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y
> +# CONFIG_MKSWAP is not set
> +# CONFIG_FEATURE_MKSWAP_UUID is not set
> +CONFIG_MORE=y
> +CONFIG_MOUNT=y
> +# CONFIG_FEATURE_MOUNT_FAKE is not set
> +CONFIG_FEATURE_MOUNT_VERBOSE=y
> +CONFIG_FEATURE_MOUNT_HELPERS=y
> +# CONFIG_FEATURE_MOUNT_LABEL is not set
> +# CONFIG_FEATURE_MOUNT_NFS is not set
> +# CONFIG_FEATURE_MOUNT_CIFS is not set
> +CONFIG_FEATURE_MOUNT_FLAGS=y
> +CONFIG_FEATURE_MOUNT_FSTAB=y
> +CONFIG_PIVOT_ROOT=y
> +# CONFIG_RDATE is not set
> +# CONFIG_RDEV is not set
> +# CONFIG_READPROFILE is not set
> +# CONFIG_RTCWAKE is not set
> +# CONFIG_SCRIPT is not set
> +# CONFIG_SCRIPTREPLAY is not set
> +# CONFIG_SETARCH is not set
> +# CONFIG_SWAPONOFF is not set
> +# CONFIG_FEATURE_SWAPON_PRI is not set
> +CONFIG_SWITCH_ROOT=y
> +CONFIG_UMOUNT=y
> +CONFIG_FEATURE_UMOUNT_ALL=y
> +
> +#
> +# Common options for mount/umount
> +#
> +CONFIG_FEATURE_MOUNT_LOOP=y
> +CONFIG_FEATURE_MOUNT_LOOP_CREATE=y
> +# CONFIG_FEATURE_MTAB_SUPPORT is not set
> +# CONFIG_VOLUMEID is not set
> +# CONFIG_FEATURE_VOLUMEID_EXT is not set
> +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set
> +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set
> +# CONFIG_FEATURE_VOLUMEID_FAT is not set
> +# CONFIG_FEATURE_VOLUMEID_HFS is not set
> +# CONFIG_FEATURE_VOLUMEID_JFS is not set
> +# CONFIG_FEATURE_VOLUMEID_XFS is not set
> +# CONFIG_FEATURE_VOLUMEID_NTFS is not set
> +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set
> +# CONFIG_FEATURE_VOLUMEID_UDF is not set
> +# CONFIG_FEATURE_VOLUMEID_LUKS is not set
> +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set
> +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set
> +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set
> +# CONFIG_FEATURE_VOLUMEID_SYSV is not set
> +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set
> +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set
> +
> +#
> +# Miscellaneous Utilities
> +#
> +# CONFIG_CONSPY is not set
> +# CONFIG_NANDWRITE is not set
> +# CONFIG_NANDDUMP is not set
> +# CONFIG_UBIATTACH is not set
> +# CONFIG_UBIDETACH is not set
> +# CONFIG_ADJTIMEX is not set
> +# CONFIG_BBCONFIG is not set
> +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set
> +# CONFIG_BEEP is not set
> +CONFIG_FEATURE_BEEP_FREQ=0
> +CONFIG_FEATURE_BEEP_LENGTH_MS=0
> +# CONFIG_CHAT is not set
> +# CONFIG_FEATURE_CHAT_NOFAIL is not set
> +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set
> +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set
> +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set
> +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set
> +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set
> +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set
> +# CONFIG_CHRT is not set
> +# CONFIG_CROND is not set
> +# CONFIG_FEATURE_CROND_D is not set
> +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set
> +CONFIG_FEATURE_CROND_DIR=""
> +# CONFIG_CRONTAB is not set
> +# CONFIG_DC is not set
> +# CONFIG_FEATURE_DC_LIBM is not set
> +# CONFIG_DEVFSD is not set
> +# CONFIG_DEVFSD_MODLOAD is not set
> +# CONFIG_DEVFSD_FG_NP is not set
> +# CONFIG_DEVFSD_VERBOSE is not set
> +# CONFIG_FEATURE_DEVFS is not set
> +CONFIG_DEVMEM=y
> +# CONFIG_EJECT is not set
> +# CONFIG_FEATURE_EJECT_SCSI is not set
> +# CONFIG_FBSPLASH is not set
> +# CONFIG_FLASHCP is not set
> +# CONFIG_FLASH_LOCK is not set
> +# CONFIG_FLASH_UNLOCK is not set
> +# CONFIG_FLASH_ERASEALL is not set
> +# CONFIG_IONICE is not set
> +# CONFIG_INOTIFYD is not set
> +# CONFIG_LAST is not set
> +# CONFIG_FEATURE_LAST_SMALL is not set
> +# CONFIG_FEATURE_LAST_FANCY is not set
> +# CONFIG_LESS is not set
> +CONFIG_FEATURE_LESS_MAXLINES=0
> +# CONFIG_FEATURE_LESS_BRACKETS is not set
> +# CONFIG_FEATURE_LESS_FLAGS is not set
> +# CONFIG_FEATURE_LESS_MARKS is not set
> +# CONFIG_FEATURE_LESS_REGEXP is not set
> +# CONFIG_FEATURE_LESS_WINCH is not set
> +# CONFIG_FEATURE_LESS_DASHCMD is not set
> +# CONFIG_FEATURE_LESS_LINENUMS is not set
> +# CONFIG_HDPARM is not set
> +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set
> +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set
> +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set
> +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set
> +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set
> +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set
> +# CONFIG_MAKEDEVS is not set
> +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
> +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
> +# CONFIG_MAN is not set
> +# CONFIG_MICROCOM is not set
> +# CONFIG_MOUNTPOINT is not set
> +# CONFIG_MT is not set
> +# CONFIG_RAIDAUTORUN is not set
> +CONFIG_READAHEAD=y
> +# CONFIG_RFKILL is not set
> +# CONFIG_RUNLEVEL is not set
> +# CONFIG_RX is not set
> +CONFIG_SETSID=y
> +# CONFIG_STRINGS is not set
> +# CONFIG_TASKSET is not set
> +# CONFIG_FEATURE_TASKSET_FANCY is not set
> +# CONFIG_TIME is not set
> +# CONFIG_TIMEOUT is not set
> +# CONFIG_TTYSIZE is not set
> +# CONFIG_VOLNAME is not set
> +# CONFIG_WALL is not set
> +CONFIG_WATCHDOG=y
> +
> +#
> +# Networking Utilities
> +#
> +CONFIG_NBDCLIENT=y
> +# CONFIG_NC=y
> +# CONFIG_NC_SERVER=y
> +# CONFIG_NC_EXTRA=y
> +# CONFIG_NC_110_COMPAT is not set
> +CONFIG_FEATURE_IPV6=y
> +# CONFIG_FEATURE_UNIX_LOCAL is not set
> +CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y
> +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set
> +# CONFIG_ARP is not set
> +# CONFIG_ARPING is not set
> +# CONFIG_BRCTL is not set
> +# CONFIG_FEATURE_BRCTL_FANCY is not set
> +# CONFIG_FEATURE_BRCTL_SHOW is not set
> +# CONFIG_DNSD is not set
> +# CONFIG_ETHER_WAKE is not set
> +# CONFIG_FAKEIDENTD is not set
> +# CONFIG_FTPD=y
> +# CONFIG_FEATURE_FTP_WRITE=y
> +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y
> +# CONFIG_FTPGET is not set
> +# CONFIG_FTPPUT is not set
> +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
> +CONFIG_HOSTNAME=y
> +# CONFIG_HTTPD=y
> +# CONFIG_FEATURE_HTTPD_RANGES=y
> +# CONFIG_FEATURE_HTTPD_USE_SENDFILE=y
> +# CONFIG_FEATURE_HTTPD_SETUID=y
> +# CONFIG_FEATURE_HTTPD_BASIC_AUTH=y
> +# CONFIG_FEATURE_HTTPD_AUTH_MD5=y
> +# CONFIG_FEATURE_HTTPD_CGI=y
> +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y
> +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y
> +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y
> +# CONFIG_FEATURE_HTTPD_ERROR_PAGES=y
> +# CONFIG_FEATURE_HTTPD_PROXY=y
> +# CONFIG_FEATURE_HTTPD_GZIP=y
> +CONFIG_IFCONFIG=y
> +CONFIG_FEATURE_IFCONFIG_STATUS=y
> +# CONFIG_FEATURE_IFCONFIG_SLIP is not set
> +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set
> +CONFIG_FEATURE_IFCONFIG_HW=y
> +CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y
> +# CONFIG_IFENSLAVE is not set
> +CONFIG_IFPLUGD=y
> +CONFIG_IFUPDOWN=y
> +CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate"
> +# CONFIG_FEATURE_IFUPDOWN_IP is not set
> +# CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN is not set
> +CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN=y
> +CONFIG_FEATURE_IFUPDOWN_IPV4=y
> +CONFIG_FEATURE_IFUPDOWN_IPV6=y
> +CONFIG_FEATURE_IFUPDOWN_MAPPING=y
> +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set
> +# CONFIG_INETD is not set
> +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set
> +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set
> +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set
> +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set
> +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set
> +# CONFIG_FEATURE_INETD_RPC is not set
> +CONFIG_IP=y
> +CONFIG_FEATURE_IP_ADDRESS=y
> +CONFIG_FEATURE_IP_LINK=y
> +CONFIG_FEATURE_IP_ROUTE=y
> +CONFIG_FEATURE_IP_TUNNEL=y
> +# CONFIG_FEATURE_IP_RULE is not set
> +# CONFIG_FEATURE_IP_SHORT_FORMS is not set
> +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set
> +# CONFIG_IPADDR is not set
> +# CONFIG_IPLINK is not set
> +# CONFIG_IPROUTE is not set
> +# CONFIG_IPTUNNEL is not set
> +# CONFIG_IPRULE is not set
> +# CONFIG_IPCALC is not set
> +# CONFIG_FEATURE_IPCALC_FANCY is not set
> +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set
> +# CONFIG_NAMEIF is not set
> +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set
> +CONFIG_NETSTAT=y
> +CONFIG_FEATURE_NETSTAT_WIDE=y
> +CONFIG_FEATURE_NETSTAT_PRG=y
> +CONFIG_NSLOOKUP=y
> +CONFIG_NTPD=y
> +CONFIG_FEATURE_NTPD_SERVER=y
> +CONFIG_PING=y
> +CONFIG_PING6=y
> +CONFIG_FEATURE_FANCY_PING=y
> +# CONFIG_PSCAN is not set
> +CONFIG_ROUTE=y
> +# CONFIG_SLATTACH is not set
> +# CONFIG_TCPSVD is not set
> +CONFIG_TELNET=y
> +# CONFIG_FEATURE_TELNET_TTYPE is not set
> +CONFIG_FEATURE_TELNET_AUTOLOGIN=y
> +CONFIG_TELNETD=y
> +# CONFIG_FEATURE_TELNETD_STANDALONE is not set
> +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set
> +# CONFIG_TFTP=y
> +# CONFIG_TFTPD is not set
> +
> +#
> +# Common options for tftp/tftpd
> +#
> +# CONFIG_FEATURE_TFTP_GET=y
> +# CONFIG_FEATURE_TFTP_PUT=y
> +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
> +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set
> +# CONFIG_TFTP_DEBUG is not set
> +# CONFIG_TRACEROUTE=y
> +# CONFIG_TRACEROUTE6=y
> +# CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
> +# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y
> +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y
> +# CONFIG_TUNCTL=y
> +CONFIG_FEATURE_TUNCTL_UG=y
> +CONFIG_UDHCPD=y
> +CONFIG_DHCPRELAY=y
> +CONFIG_DUMPLEASES=y
> +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set
> +CONFIG_DHCPD_LEASES_FILE="/var/lib/misc/udhcpd.leases"
> +CONFIG_UDHCPC=y
> +CONFIG_FEATURE_UDHCPC_ARPING=y
> +# CONFIG_FEATURE_UDHCP_PORT is not set
> +CONFIG_UDHCP_DEBUG=9
> +# CONFIG_FEATURE_UDHCP_RFC3397 is not set
> +CONFIG_UDHCPC_DEFAULT_SCRIPT="@DATADIR@/udhcpc/default.script"
> +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80
> +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n"
> +# CONFIG_UDPSVD is not set
> +# CONFIG_VCONFIG is not set
> +CONFIG_WGET=y
> +CONFIG_FEATURE_WGET_STATUSBAR=y
> +CONFIG_FEATURE_WGET_AUTHENTICATION=y
> +CONFIG_FEATURE_WGET_LONG_OPTIONS=y
> +CONFIG_FEATURE_WGET_TIMEOUT=y
> +# CONFIG_ZCIP is not set
> +
> +#
> +# Print Utilities
> +#
> +# CONFIG_LPD is not set
> +# CONFIG_LPR is not set
> +# CONFIG_LPQ is not set
> +
> +#
> +# Mail Utilities
> +#
> +# CONFIG_MAKEMIME is not set
> +CONFIG_FEATURE_MIME_CHARSET=""
> +# CONFIG_POPMAILDIR is not set
> +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set
> +# CONFIG_REFORMIME is not set
> +# CONFIG_FEATURE_REFORMIME_COMPAT is not set
> +# CONFIG_SENDMAIL is not set
> +
> +#
> +# Process Utilities
> +#
> +# CONFIG_IOSTAT is not set
> +# CONFIG_MPSTAT is not set
> +# CONFIG_PMAP is not set
> +# CONFIG_POWERTOP is not set
> +# CONFIG_SMEMCAP is not set
> +# CONFIG_FREE is not set
> +# CONFIG_FUSER is not set
> +CONFIG_KILL=y
> +CONFIG_KILLALL=y
> +# CONFIG_KILLALL5 is not set
> +# CONFIG_NMETER is not set
> +# CONFIG_PGREP is not set
> +CONFIG_PIDOF=y
> +CONFIG_FEATURE_PIDOF_SINGLE=y
> +CONFIG_FEATURE_PIDOF_OMIT=y
> +# CONFIG_PKILL is not set
> +CONFIG_PS=y
> +CONFIG_FEATURE_PS_WIDE=y
> +# CONFIG_FEATURE_PS_TIME is not set
> +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set
> +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set
> +# CONFIG_RENICE is not set
> +# CONFIG_BB_SYSCTL is not set
> +# CONFIG_TOP is not set
> +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set
> +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set
> +# CONFIG_FEATURE_TOP_SMP_CPU is not set
> +# CONFIG_FEATURE_TOP_DECIMALS is not set
> +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set
> +# CONFIG_FEATURE_TOPMEM is not set
> +# CONFIG_FEATURE_SHOW_THREADS is not set
> +# CONFIG_UPTIME is not set
> +# CONFIG_WATCH is not set
> +
> +#
> +# Runit Utilities
> +#
> +# CONFIG_RUNSV is not set
> +# CONFIG_RUNSVDIR is not set
> +# CONFIG_FEATURE_RUNSVDIR_LOG is not set
> +# CONFIG_SV is not set
> +CONFIG_SV_DEFAULT_SERVICE_DIR=""
> +# CONFIG_SVLOGD is not set
> +# CONFIG_CHPST is not set
> +# CONFIG_SETUIDGID is not set
> +# CONFIG_ENVUIDGID is not set
> +# CONFIG_ENVDIR is not set
> +# CONFIG_SOFTLIMIT is not set
> +# CONFIG_CHCON is not set
> +# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set
> +# CONFIG_GETENFORCE is not set
> +# CONFIG_GETSEBOOL is not set
> +# CONFIG_LOAD_POLICY is not set
> +# CONFIG_MATCHPATHCON is not set
> +# CONFIG_RESTORECON is not set
> +# CONFIG_RUNCON is not set
> +# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set
> +# CONFIG_SELINUXENABLED is not set
> +# CONFIG_SETENFORCE is not set
> +# CONFIG_SETFILES is not set
> +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set
> +# CONFIG_SETSEBOOL is not set
> +# CONFIG_SESTATUS is not set
> +
> +#
> +# Shells
> +#
> +CONFIG_ASH=y
> +CONFIG_ASH_BASH_COMPAT=y
> +CONFIG_ASH_JOB_CONTROL=y
> +CONFIG_ASH_ALIAS=y
> +CONFIG_ASH_GETOPTS=y
> +CONFIG_ASH_BUILTIN_ECHO=y
> +CONFIG_ASH_BUILTIN_PRINTF=y
> +CONFIG_ASH_BUILTIN_TEST=y
> +# CONFIG_ASH_CMDCMD is not set
> +# CONFIG_ASH_MAIL is not set
> +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set
> +# CONFIG_ASH_RANDOM_SUPPORT is not set
> +CONFIG_ASH_EXPAND_PRMT=y
> +CONFIG_CTTYHACK=y
> +# CONFIG_HUSH is not set
> +# CONFIG_HUSH_BASH_COMPAT is not set
> +# CONFIG_HUSH_BRACE_EXPANSION is not set
> +# CONFIG_HUSH_HELP is not set
> +# CONFIG_HUSH_INTERACTIVE is not set
> +# CONFIG_HUSH_SAVEHISTORY is not set
> +# CONFIG_HUSH_JOB is not set
> +# CONFIG_HUSH_TICK is not set
> +# CONFIG_HUSH_IF is not set
> +# CONFIG_HUSH_LOOPS is not set
> +# CONFIG_HUSH_CASE is not set
> +# CONFIG_HUSH_FUNCTIONS is not set
> +# CONFIG_HUSH_LOCAL is not set
> +# CONFIG_HUSH_RANDOM_SUPPORT is not set
> +# CONFIG_HUSH_EXPORT_N is not set
> +# CONFIG_HUSH_MODE_X is not set
> +# CONFIG_MSH is not set
> +CONFIG_FEATURE_SH_IS_ASH=y
> +# CONFIG_FEATURE_SH_IS_HUSH is not set
> +# CONFIG_FEATURE_SH_IS_NONE is not set
> +# CONFIG_FEATURE_BASH_IS_ASH is not set
> +# CONFIG_FEATURE_BASH_IS_HUSH is not set
> +CONFIG_FEATURE_BASH_IS_NONE=y
> +CONFIG_SH_MATH_SUPPORT=y
> +CONFIG_SH_MATH_SUPPORT_64=y
> +CONFIG_FEATURE_SH_EXTRA_QUIET=y
> +# CONFIG_FEATURE_SH_STANDALONE is not set
> +# CONFIG_FEATURE_SH_NOFORK is not set
> +
> +#
> +# System Logging Utilities
> +#
> +CONFIG_SYSLOGD=y
> +CONFIG_FEATURE_ROTATE_LOGFILE=y
> +CONFIG_FEATURE_REMOTE_LOG=y
> +CONFIG_FEATURE_SYSLOGD_DUP=y
> +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256
> +CONFIG_FEATURE_IPC_SYSLOG=y
> +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16
> +CONFIG_LOGREAD=y
> +CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING=y
> +CONFIG_KLOGD=y
> +CONFIG_FEATURE_KLOGD_KLOGCTL=y
> +CONFIG_LOGGER=y
> diff --git a/recipes/busybox/busybox-1.18.3/ts75xx/defconfig b/recipes/busybox/busybox-1.18.3/ts75xx/defconfig
> new file mode 100644
> index 0000000..4b6658e
> --- /dev/null
> +++ b/recipes/busybox/busybox-1.18.3/ts75xx/defconfig
> @@ -0,0 +1,986 @@
> +#
> +# Automatically generated make config: don't edit
> +# Busybox version: 1.18.3
> +# Thu Mar 24 13:42:39 2011
> +#
> +CONFIG_HAVE_DOT_CONFIG=y
> +
> +#
> +# Busybox Settings
> +#
> +
> +#
> +# General Configuration
> +#
> +# CONFIG_DESKTOP is not set
> +# CONFIG_EXTRA_COMPAT is not set
> +# CONFIG_INCLUDE_SUSv2 is not set
> +# CONFIG_USE_PORTABLE_CODE is not set
> +CONFIG_PLATFORM_LINUX=y
> +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y
> +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
> +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
> +CONFIG_SHOW_USAGE=y
> +CONFIG_FEATURE_VERBOSE_USAGE=y
> +CONFIG_FEATURE_COMPRESS_USAGE=y
> +# CONFIG_FEATURE_INSTALLER is not set
> +# CONFIG_INSTALL_NO_USR is not set
> +CONFIG_LOCALE_SUPPORT=y
> +CONFIG_UNICODE_SUPPORT=y
> +# CONFIG_UNICODE_USING_LOCALE is not set
> +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set
> +CONFIG_SUBST_WCHAR=63
> +CONFIG_LAST_SUPPORTED_WCHAR=767
> +# CONFIG_UNICODE_COMBINING_WCHARS is not set
> +# CONFIG_UNICODE_WIDE_WCHARS is not set
> +# CONFIG_UNICODE_BIDI_SUPPORT is not set
> +# CONFIG_UNICODE_NEUTRAL_TABLE is not set
> +# CONFIG_UNICODE_PRESERVE_BROKEN is not set
> +CONFIG_LONG_OPTS=y
> +CONFIG_FEATURE_DEVPTS=y
> +# CONFIG_FEATURE_CLEAN_UP is not set
> +CONFIG_FEATURE_WTMP=y
> +CONFIG_FEATURE_UTMP=y
> +CONFIG_FEATURE_PIDFILE=y
> +CONFIG_FEATURE_SUID=y
> +CONFIG_FEATURE_SUID_CONFIG=y
> +CONFIG_FEATURE_SUID_CONFIG_QUIET=y
> +# CONFIG_SELINUX is not set
> +# CONFIG_FEATURE_PREFER_APPLETS is not set
> +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
> +CONFIG_FEATURE_SYSLOG=y
> +# CONFIG_FEATURE_HAVE_RPC is not set
> +
> +#
> +# Build Options
> +#
> +# CONFIG_STATIC is not set
> +# CONFIG_PIE is not set
> +# CONFIG_NOMMU is not set
> +# CONFIG_BUILD_LIBBUSYBOX is not set
> +# CONFIG_FEATURE_INDIVIDUAL is not set
> +# CONFIG_FEATURE_SHARED_BUSYBOX is not set
> +CONFIG_LFS=y
> +CONFIG_CROSS_COMPILER_PREFIX=""
> +CONFIG_EXTRA_CFLAGS=""
> +
> +#
> +# Debugging Options
> +#
> +# CONFIG_DEBUG is not set
> +# CONFIG_DEBUG_PESSIMIZE is not set
> +# CONFIG_WERROR is not set
> +CONFIG_NO_DEBUG_LIB=y
> +# CONFIG_DMALLOC is not set
> +# CONFIG_EFENCE is not set
> +
> +#
> +# Installation Options ("make install" behavior)
> +#
> +CONFIG_INSTALL_APPLET_SYMLINKS=y
> +# CONFIG_INSTALL_APPLET_HARDLINKS is not set
> +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set
> +# CONFIG_INSTALL_APPLET_DONT is not set
> +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set
> +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set
> +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set
> +CONFIG_PREFIX="./_install"
> +
> +#
> +# Busybox Library Tuning
> +#
> +CONFIG_PASSWORD_MINLEN=6
> +CONFIG_MD5_SIZE_VS_SPEED=2
> +CONFIG_FEATURE_FAST_TOP=y
> +# CONFIG_FEATURE_ETC_NETWORKS is not set
> +CONFIG_FEATURE_USE_TERMIOS=y
> +CONFIG_FEATURE_EDITING=y
> +CONFIG_FEATURE_EDITING_MAX_LEN=1024
> +# CONFIG_FEATURE_EDITING_VI is not set
> +CONFIG_FEATURE_EDITING_HISTORY=64
> +CONFIG_FEATURE_EDITING_SAVEHISTORY=y
> +CONFIG_FEATURE_TAB_COMPLETION=y
> +CONFIG_FEATURE_USERNAME_COMPLETION=y
> +CONFIG_FEATURE_EDITING_FANCY_PROMPT=y
> +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set
> +CONFIG_FEATURE_NON_POSIX_CP=y
> +CONFIG_FEATURE_VERBOSE_CP_MESSAGE=y
> +CONFIG_FEATURE_COPYBUF_KB=4
> +CONFIG_MONOTONIC_SYSCALL=y
> +CONFIG_IOCTL_HEX2STR_ERROR=y
> +CONFIG_FEATURE_HWIB=y
> +
> +#
> +# Applets
> +#
> +
> +#
> +# Archival Utilities
> +#
> +CONFIG_FEATURE_SEAMLESS_XZ=y
> +# CONFIG_FEATURE_SEAMLESS_LZMA is not set
> +CONFIG_FEATURE_SEAMLESS_BZ2=y
> +CONFIG_FEATURE_SEAMLESS_GZ=y
> +CONFIG_FEATURE_SEAMLESS_Z=y
> +CONFIG_AR=y
> +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set
> +CONFIG_FEATURE_AR_CREATE=y
> +CONFIG_BUNZIP2=y
> +# CONFIG_BZIP2 is not set
> +CONFIG_CPIO=y
> +# CONFIG_FEATURE_CPIO_O is not set
> +# CONFIG_FEATURE_CPIO_P is not set
> +# CONFIG_DPKG is not set
> +# CONFIG_DPKG_DEB is not set
> +# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set
> +CONFIG_GUNZIP=y
> +CONFIG_GZIP=y
> +CONFIG_FEATURE_GZIP_LONG_OPTIONS=y
> +CONFIG_LZOP=y
> +# CONFIG_LZOP_COMPR_HIGH is not set
> +# CONFIG_RPM2CPIO is not set
> +# CONFIG_RPM is not set
> +CONFIG_TAR=y
> +CONFIG_FEATURE_TAR_CREATE=y
> +CONFIG_FEATURE_TAR_AUTODETECT=y
> +CONFIG_FEATURE_TAR_FROM=y
> +CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y
> +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set
> +CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y
> +CONFIG_FEATURE_TAR_LONG_OPTIONS=y
> +CONFIG_FEATURE_TAR_TO_COMMAND=y
> +CONFIG_FEATURE_TAR_UNAME_GNAME=y
> +CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y
> +# CONFIG_FEATURE_TAR_SELINUX is not set
> +# CONFIG_UNCOMPRESS is not set
> +# CONFIG_UNLZMA is not set
> +# CONFIG_FEATURE_LZMA_FAST is not set
> +# CONFIG_LZMA is not set
> +CONFIG_UNXZ=y
> +CONFIG_XZ=y
> +CONFIG_UNZIP=y
> +
> +#
> +# Coreutils
> +#
> +CONFIG_BASENAME=y
> +CONFIG_CAT=y
> +CONFIG_DATE=y
> +CONFIG_FEATURE_DATE_ISOFMT=y
> +# CONFIG_FEATURE_DATE_NANO is not set
> +CONFIG_FEATURE_DATE_COMPAT=y
> +CONFIG_TEST=y
> +# CONFIG_FEATURE_TEST_64 is not set
> +CONFIG_TR=y
> +CONFIG_FEATURE_TR_CLASSES=y
> +# CONFIG_FEATURE_TR_EQUIV is not set
> +# CONFIG_BASE64=y
> +# CONFIG_CAL is not set
> +# CONFIG_CATV is not set
> +CONFIG_CHGRP=y
> +CONFIG_CHMOD=y
> +CONFIG_CHOWN=y
> +CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y
> +CONFIG_CHROOT=y
> +# CONFIG_CKSUM is not set
> +# CONFIG_COMM is not set
> +CONFIG_CP=y
> +CONFIG_FEATURE_CP_LONG_OPTIONS=y
> +CONFIG_CUT=y
> +CONFIG_DD=y
> +CONFIG_FEATURE_DD_SIGNAL_HANDLING=y
> +CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y
> +# CONFIG_FEATURE_DD_IBS_OBS is not set
> +CONFIG_DF=y
> +CONFIG_FEATURE_DF_FANCY=y
> +CONFIG_DIRNAME=y
> +# CONFIG_DOS2UNIX is not set
> +# CONFIG_UNIX2DOS is not set
> +CONFIG_DU=y
> +CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y
> +CONFIG_ECHO=y
> +CONFIG_FEATURE_FANCY_ECHO=y
> +CONFIG_ENV=y
> +CONFIG_FEATURE_ENV_LONG_OPTIONS=y
> +# CONFIG_EXPAND is not set
> +# CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set
> +CONFIG_EXPR=y
> +# CONFIG_EXPR_MATH_SUPPORT_64 is not set
> +CONFIG_FALSE=y
> +# CONFIG_FOLD is not set
> +CONFIG_FSYNC=y
> +CONFIG_HEAD=y
> +CONFIG_FEATURE_FANCY_HEAD=y
> +# CONFIG_HOSTID is not set
> +CONFIG_ID=y
> +# CONFIG_INSTALL is not set
> +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set
> +# CONFIG_LENGTH is not set
> +CONFIG_LN=y
> +CONFIG_LOGNAME=y
> +CONFIG_LS=y
> +CONFIG_FEATURE_LS_FILETYPES=y
> +CONFIG_FEATURE_LS_FOLLOWLINKS=y
> +CONFIG_FEATURE_LS_RECURSIVE=y
> +CONFIG_FEATURE_LS_SORTFILES=y
> +CONFIG_FEATURE_LS_TIMESTAMPS=y
> +CONFIG_FEATURE_LS_USERNAME=y
> +CONFIG_FEATURE_LS_COLOR=y
> +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set
> +CONFIG_MD5SUM=y
> +CONFIG_MKDIR=y
> +CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y
> +CONFIG_MKFIFO=y
> +CONFIG_MKNOD=y
> +CONFIG_MV=y
> +CONFIG_FEATURE_MV_LONG_OPTIONS=y
> +CONFIG_NICE=y
> +CONFIG_NOHUP=y
> +CONFIG_OD=y
> +# CONFIG_PRINTENV is not set
> +CONFIG_PRINTF=y
> +CONFIG_PWD=y
> +CONFIG_READLINK=y
> +CONFIG_FEATURE_READLINK_FOLLOW=y
> +CONFIG_REALPATH=y
> +CONFIG_RM=y
> +CONFIG_RMDIR=y
> +CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y
> +CONFIG_SEQ=y
> +# CONFIG_SHA1SUM is not set
> +CONFIG_SHA256SUM=y
> +CONFIG_SHA512SUM=y
> +CONFIG_SLEEP=y
> +CONFIG_FEATURE_FANCY_SLEEP=y
> +CONFIG_FEATURE_FLOAT_SLEEP=y
> +CONFIG_SORT=y
> +CONFIG_FEATURE_SORT_BIG=y
> +# CONFIG_SPLIT is not set
> +# CONFIG_FEATURE_SPLIT_FANCY is not set
> +# CONFIG_STAT is not set
> +# CONFIG_FEATURE_STAT_FORMAT is not set
> +CONFIG_STTY=y
> +# CONFIG_SUM is not set
> +CONFIG_SYNC=y
> +# CONFIG_TAC is not set
> +CONFIG_TAIL=y
> +CONFIG_FEATURE_FANCY_TAIL=y
> +CONFIG_TEE=y
> +CONFIG_FEATURE_TEE_USE_BLOCK_IO=y
> +CONFIG_TOUCH=y
> +CONFIG_TRUE=y
> +CONFIG_TTY=y
> +CONFIG_UNAME=y
> +# CONFIG_UNEXPAND is not set
> +# CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set
> +CONFIG_UNIQ=y
> +CONFIG_USLEEP=y
> +CONFIG_UUDECODE=y
> +CONFIG_UUENCODE=y
> +CONFIG_WC=y
> +# CONFIG_FEATURE_WC_LARGE is not set
> +CONFIG_WHO=y
> +CONFIG_WHOAMI=y
> +CONFIG_YES=y
> +
> +#
> +# Common options for cp and mv
> +#
> +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set
> +
> +#
> +# Common options for ls, more and telnet
> +#
> +CONFIG_FEATURE_AUTOWIDTH=y
> +
> +#
> +# Common options for df, du, ls
> +#
> +CONFIG_FEATURE_HUMAN_READABLE=y
> +
> +#
> +# Common options for md5sum, sha1sum, sha256sum, sha512sum
> +#
> +CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y
> +
> +#
> +# Console Utilities
> +#
> +CONFIG_CHVT=y
> +CONFIG_FGCONSOLE=y
> +CONFIG_CLEAR=y
> +CONFIG_DEALLOCVT=y
> +CONFIG_DUMPKMAP=y
> +# CONFIG_KBD_MODE is not set
> +CONFIG_LOADFONT=y
> +CONFIG_LOADKMAP=y
> +CONFIG_OPENVT=y
> +CONFIG_RESET=y
> +# CONFIG_RESIZE is not set
> +# CONFIG_FEATURE_RESIZE_PRINT is not set
> +CONFIG_SETCONSOLE=y
> +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set
> +CONFIG_SETFONT=y
> +CONFIG_FEATURE_SETFONT_TEXTUAL_MAP=y
> +CONFIG_DEFAULT_SETFONT_DIR=""
> +# CONFIG_SETKEYCODES is not set
> +# CONFIG_SETLOGCONS is not set
> +CONFIG_SHOWKEY=y
> +
> +#
> +# Common options for loadfont and setfont
> +#
> +CONFIG_FEATURE_LOADFONT_PSF2=y
> +CONFIG_FEATURE_LOADFONT_RAW=y
> +
> +#
> +# Debian Utilities
> +#
> +# CONFIG_MKTEMP is not set
> +# CONFIG_PIPE_PROGRESS is not set
> +# CONFIG_RUN_PARTS is not set
> +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set
> +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set
> +# CONFIG_START_STOP_DAEMON is not set
> +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set
> +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set
> +# CONFIG_WHICH is not set
> +
> +#
> +# Editors
> +#
> +# CONFIG_PATCH is not set
> +# CONFIG_AWK is not set
> +# CONFIG_FEATURE_AWK_LIBM is not set
> +CONFIG_CMP=y
> +# CONFIG_DIFF is not set
> +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set
> +# CONFIG_FEATURE_DIFF_DIR is not set
> +# CONFIG_ED is not set
> +CONFIG_SED=y
> +# CONFIG_VI is not set
> +CONFIG_FEATURE_VI_MAX_LEN=0
> +# CONFIG_FEATURE_VI_8BIT is not set
> +# CONFIG_FEATURE_VI_COLON is not set
> +# CONFIG_FEATURE_VI_YANKMARK is not set
> +# CONFIG_FEATURE_VI_SEARCH is not set
> +# CONFIG_FEATURE_VI_USE_SIGNALS is not set
> +# CONFIG_FEATURE_VI_DOT_CMD is not set
> +# CONFIG_FEATURE_VI_READONLY is not set
> +# CONFIG_FEATURE_VI_SETOPTS is not set
> +# CONFIG_FEATURE_VI_SET is not set
> +# CONFIG_FEATURE_VI_WIN_RESIZE is not set
> +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set
> +# CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set
> +# CONFIG_FEATURE_ALLOW_EXEC is not set
> +
> +#
> +# Finding Utilities
> +#
> +CONFIG_FIND=y
> +CONFIG_FEATURE_FIND_PRINT0=y
> +CONFIG_FEATURE_FIND_MTIME=y
> +CONFIG_FEATURE_FIND_MMIN=y
> +CONFIG_FEATURE_FIND_PERM=y
> +CONFIG_FEATURE_FIND_TYPE=y
> +CONFIG_FEATURE_FIND_XDEV=y
> +CONFIG_FEATURE_FIND_MAXDEPTH=y
> +CONFIG_FEATURE_FIND_NEWER=y
> +CONFIG_FEATURE_FIND_INUM=y
> +CONFIG_FEATURE_FIND_EXEC=y
> +CONFIG_FEATURE_FIND_USER=y
> +CONFIG_FEATURE_FIND_GROUP=y
> +CONFIG_FEATURE_FIND_NOT=y
> +CONFIG_FEATURE_FIND_DEPTH=y
> +CONFIG_FEATURE_FIND_PAREN=y
> +CONFIG_FEATURE_FIND_SIZE=y
> +CONFIG_FEATURE_FIND_PRUNE=y
> +CONFIG_FEATURE_FIND_DELETE=y
> +CONFIG_FEATURE_FIND_PATH=y
> +CONFIG_FEATURE_FIND_REGEX=y
> +# CONFIG_FEATURE_FIND_CONTEXT is not set
> +CONFIG_FEATURE_FIND_LINKS=y
> +CONFIG_GREP=y
> +CONFIG_FEATURE_GREP_EGREP_ALIAS=y
> +CONFIG_FEATURE_GREP_FGREP_ALIAS=y
> +CONFIG_FEATURE_GREP_CONTEXT=y
> +CONFIG_XARGS=y
> +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set
> +CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y
> +CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y
> +CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y
> +
> +#
> +# Init Utilities
> +#
> +# CONFIG_BOOTCHARTD is not set
> +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set
> +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set
> +# CONFIG_HALT is not set
> +# CONFIG_FEATURE_CALL_TELINIT is not set
> +CONFIG_TELINIT_PATH=""
> +# CONFIG_INIT is not set
> +# CONFIG_FEATURE_USE_INITTAB is not set
> +# CONFIG_FEATURE_KILL_REMOVED is not set
> +CONFIG_FEATURE_KILL_DELAY=0
> +# CONFIG_FEATURE_INIT_SCTTY is not set
> +# CONFIG_FEATURE_INIT_SYSLOG is not set
> +# CONFIG_FEATURE_EXTRA_QUIET is not set
> +# CONFIG_FEATURE_INIT_COREDUMPS is not set
> +# CONFIG_FEATURE_INITRD is not set
> +CONFIG_INIT_TERMINAL_TYPE=""
> +# CONFIG_MESG is not set
> +
> +#
> +# Login/Password Management Utilities
> +#
> +# CONFIG_ADD_SHELL is not set
> +# CONFIG_REMOVE_SHELL is not set
> +# CONFIG_FEATURE_SHADOWPASSWDS is not set
> +# CONFIG_USE_BB_PWD_GRP is not set
> +# CONFIG_USE_BB_SHADOW is not set
> +# CONFIG_USE_BB_CRYPT is not set
> +# CONFIG_USE_BB_CRYPT_SHA is not set
> +# CONFIG_ADDUSER is not set
> +# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set
> +# CONFIG_FEATURE_CHECK_NAMES is not set
> +CONFIG_FIRST_SYSTEM_ID=0
> +CONFIG_LAST_SYSTEM_ID=0
> +# CONFIG_ADDGROUP is not set
> +# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set
> +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set
> +# CONFIG_DELUSER is not set
> +# CONFIG_DELGROUP is not set
> +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set
> +CONFIG_GETTY=y
> +CONFIG_LOGIN=y
> +# CONFIG_PAM is not set
> +CONFIG_LOGIN_SCRIPTS=y
> +CONFIG_FEATURE_NOLOGIN=y
> +CONFIG_FEATURE_SECURETTY=y
> +# CONFIG_PASSWD is not set
> +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set
> +# CONFIG_CRYPTPW is not set
> +# CONFIG_CHPASSWD is not set
> +# CONFIG_SU is not set
> +# CONFIG_FEATURE_SU_SYSLOG is not set
> +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set
> +# CONFIG_SULOGIN is not set
> +# CONFIG_VLOCK is not set
> +
> +#
> +# Linux Ext2 FS Progs
> +#
> +CONFIG_CHATTR=y
> +CONFIG_FSCK=y
> +# CONFIG_LSATTR is not set
> +# CONFIG_TUNE2FS is not set
> +
> +#
> +# Linux Module Utilities
> +#
> +CONFIG_MODINFO=y
> +# CONFIG_MODPROBE_SMALL is not set
> +# CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE is not set
> +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set
> +CONFIG_INSMOD=y
> +CONFIG_RMMOD=y
> +CONFIG_LSMOD=y
> +CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y
> +CONFIG_MODPROBE=y
> +CONFIG_FEATURE_MODPROBE_BLACKLIST=y
> +# CONFIG_DEPMOD is not set
> +
> +#
> +# Options common to multiple modutils
> +#
> +# CONFIG_FEATURE_2_4_MODULES is not set
> +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set
> +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set
> +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set
> +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set
> +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set
> +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set
> +CONFIG_FEATURE_CHECK_TAINTED_MODULE=y
> +CONFIG_FEATURE_MODUTILS_ALIAS=y
> +CONFIG_FEATURE_MODUTILS_SYMBOLS=y
> +CONFIG_DEFAULT_MODULES_DIR="/lib/modules"
> +CONFIG_DEFAULT_DEPMOD_FILE="modules.dep"
> +
> +#
> +# Linux System Utilities
> +#
> +# CONFIG_BLOCKDEV is not set
> +# CONFIG_REV is not set
> +# CONFIG_ACPID is not set
> +# CONFIG_FEATURE_ACPID_COMPAT is not set
> +# CONFIG_BLKID is not set
> +CONFIG_DMESG=y
> +CONFIG_FEATURE_DMESG_PRETTY=y
> +# CONFIG_FBSET is not set
> +# CONFIG_FEATURE_FBSET_FANCY is not set
> +# CONFIG_FEATURE_FBSET_READMODE is not set
> +# CONFIG_FDFLUSH is not set
> +# CONFIG_FDFORMAT is not set
> +CONFIG_FDISK=y
> +CONFIG_FDISK_SUPPORT_LARGE_DISKS=y
> +CONFIG_FEATURE_FDISK_WRITABLE=y
> +# CONFIG_FEATURE_AIX_LABEL is not set
> +# CONFIG_FEATURE_SGI_LABEL is not set
> +# CONFIG_FEATURE_SUN_LABEL is not set
> +CONFIG_FEATURE_OSF_LABEL=y
> +# CONFIG_FEATURE_GPT_LABEL is not set
> +CONFIG_FEATURE_FDISK_ADVANCED=y
> +# CONFIG_FINDFS is not set
> +# CONFIG_FLOCK is not set
> +CONFIG_FREERAMDISK=y
> +# CONFIG_FSCK_MINIX is not set
> +CONFIG_MKFS_EXT2=y
> +# CONFIG_MKFS_MINIX is not set
> +# CONFIG_FEATURE_MINIX2 is not set
> +# CONFIG_MKFS_REISER is not set
> +CONFIG_MKFS_VFAT=y
> +CONFIG_GETOPT=y
> +CONFIG_FEATURE_GETOPT_LONG=y
> +# CONFIG_HEXDUMP is not set
> +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set
> +# CONFIG_HD is not set
> +# CONFIG_HWCLOCK is not set
> +# CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set
> +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set
> +# CONFIG_IPCRM is not set
> +# CONFIG_IPCS is not set
> +# CONFIG_LOSETUP is not set
> +# CONFIG_LSPCI is not set
> +# CONFIG_LSUSB is not set
> +CONFIG_MDEV=y
> +CONFIG_FEATURE_MDEV_CONF=y
> +CONFIG_FEATURE_MDEV_RENAME=y
> +CONFIG_FEATURE_MDEV_RENAME_REGEXP=y
> +CONFIG_FEATURE_MDEV_EXEC=y
> +CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y
> +# CONFIG_MKSWAP is not set
> +# CONFIG_FEATURE_MKSWAP_UUID is not set
> +CONFIG_MORE=y
> +CONFIG_MOUNT=y
> +# CONFIG_FEATURE_MOUNT_FAKE is not set
> +CONFIG_FEATURE_MOUNT_VERBOSE=y
> +CONFIG_FEATURE_MOUNT_HELPERS=y
> +# CONFIG_FEATURE_MOUNT_LABEL is not set
> +# CONFIG_FEATURE_MOUNT_NFS is not set
> +# CONFIG_FEATURE_MOUNT_CIFS is not set
> +CONFIG_FEATURE_MOUNT_FLAGS=y
> +CONFIG_FEATURE_MOUNT_FSTAB=y
> +CONFIG_PIVOT_ROOT=y
> +# CONFIG_RDATE is not set
> +# CONFIG_RDEV is not set
> +# CONFIG_READPROFILE is not set
> +# CONFIG_RTCWAKE is not set
> +# CONFIG_SCRIPT is not set
> +# CONFIG_SCRIPTREPLAY is not set
> +# CONFIG_SETARCH is not set
> +# CONFIG_SWAPONOFF is not set
> +# CONFIG_FEATURE_SWAPON_PRI is not set
> +CONFIG_SWITCH_ROOT=y
> +CONFIG_UMOUNT=y
> +CONFIG_FEATURE_UMOUNT_ALL=y
> +
> +#
> +# Common options for mount/umount
> +#
> +CONFIG_FEATURE_MOUNT_LOOP=y
> +CONFIG_FEATURE_MOUNT_LOOP_CREATE=y
> +# CONFIG_FEATURE_MTAB_SUPPORT is not set
> +# CONFIG_VOLUMEID is not set
> +# CONFIG_FEATURE_VOLUMEID_EXT is not set
> +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set
> +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set
> +# CONFIG_FEATURE_VOLUMEID_FAT is not set
> +# CONFIG_FEATURE_VOLUMEID_HFS is not set
> +# CONFIG_FEATURE_VOLUMEID_JFS is not set
> +# CONFIG_FEATURE_VOLUMEID_XFS is not set
> +# CONFIG_FEATURE_VOLUMEID_NTFS is not set
> +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set
> +# CONFIG_FEATURE_VOLUMEID_UDF is not set
> +# CONFIG_FEATURE_VOLUMEID_LUKS is not set
> +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set
> +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set
> +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set
> +# CONFIG_FEATURE_VOLUMEID_SYSV is not set
> +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set
> +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set
> +
> +#
> +# Miscellaneous Utilities
> +#
> +# CONFIG_CONSPY is not set
> +# CONFIG_NANDWRITE is not set
> +# CONFIG_NANDDUMP is not set
> +# CONFIG_UBIATTACH is not set
> +# CONFIG_UBIDETACH is not set
> +# CONFIG_ADJTIMEX is not set
> +# CONFIG_BBCONFIG is not set
> +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set
> +# CONFIG_BEEP is not set
> +CONFIG_FEATURE_BEEP_FREQ=0
> +CONFIG_FEATURE_BEEP_LENGTH_MS=0
> +# CONFIG_CHAT is not set
> +# CONFIG_FEATURE_CHAT_NOFAIL is not set
> +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set
> +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set
> +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set
> +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set
> +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set
> +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set
> +# CONFIG_CHRT is not set
> +# CONFIG_CROND is not set
> +# CONFIG_FEATURE_CROND_D is not set
> +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set
> +CONFIG_FEATURE_CROND_DIR=""
> +# CONFIG_CRONTAB is not set
> +# CONFIG_DC is not set
> +# CONFIG_FEATURE_DC_LIBM is not set
> +# CONFIG_DEVFSD is not set
> +# CONFIG_DEVFSD_MODLOAD is not set
> +# CONFIG_DEVFSD_FG_NP is not set
> +# CONFIG_DEVFSD_VERBOSE is not set
> +# CONFIG_FEATURE_DEVFS is not set
> +CONFIG_DEVMEM=y
> +# CONFIG_EJECT is not set
> +# CONFIG_FEATURE_EJECT_SCSI is not set
> +# CONFIG_FBSPLASH is not set
> +# CONFIG_FLASHCP is not set
> +# CONFIG_FLASH_LOCK is not set
> +# CONFIG_FLASH_UNLOCK is not set
> +# CONFIG_FLASH_ERASEALL is not set
> +# CONFIG_IONICE is not set
> +# CONFIG_INOTIFYD is not set
> +# CONFIG_LAST is not set
> +# CONFIG_FEATURE_LAST_SMALL is not set
> +# CONFIG_FEATURE_LAST_FANCY is not set
> +# CONFIG_LESS is not set
> +CONFIG_FEATURE_LESS_MAXLINES=0
> +# CONFIG_FEATURE_LESS_BRACKETS is not set
> +# CONFIG_FEATURE_LESS_FLAGS is not set
> +# CONFIG_FEATURE_LESS_MARKS is not set
> +# CONFIG_FEATURE_LESS_REGEXP is not set
> +# CONFIG_FEATURE_LESS_WINCH is not set
> +# CONFIG_FEATURE_LESS_DASHCMD is not set
> +# CONFIG_FEATURE_LESS_LINENUMS is not set
> +# CONFIG_HDPARM is not set
> +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set
> +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set
> +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set
> +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set
> +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set
> +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set
> +# CONFIG_MAKEDEVS is not set
> +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
> +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
> +# CONFIG_MAN is not set
> +# CONFIG_MICROCOM is not set
> +# CONFIG_MOUNTPOINT is not set
> +# CONFIG_MT is not set
> +# CONFIG_RAIDAUTORUN is not set
> +CONFIG_READAHEAD=y
> +# CONFIG_RFKILL is not set
> +# CONFIG_RUNLEVEL is not set
> +# CONFIG_RX is not set
> +CONFIG_SETSID=y
> +# CONFIG_STRINGS is not set
> +# CONFIG_TASKSET is not set
> +# CONFIG_FEATURE_TASKSET_FANCY is not set
> +# CONFIG_TIME is not set
> +# CONFIG_TIMEOUT is not set
> +# CONFIG_TTYSIZE is not set
> +# CONFIG_VOLNAME is not set
> +# CONFIG_WALL is not set
> +CONFIG_WATCHDOG=y
> +
> +#
> +# Networking Utilities
> +#
> +CONFIG_NBDCLIENT=y
> +# CONFIG_NC=y
> +# CONFIG_NC_SERVER=y
> +# CONFIG_NC_EXTRA=y
> +# CONFIG_NC_110_COMPAT is not set
> +CONFIG_FEATURE_IPV6=y
> +# CONFIG_FEATURE_UNIX_LOCAL is not set
> +CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y
> +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set
> +# CONFIG_ARP is not set
> +# CONFIG_ARPING is not set
> +# CONFIG_BRCTL is not set
> +# CONFIG_FEATURE_BRCTL_FANCY is not set
> +# CONFIG_FEATURE_BRCTL_SHOW is not set
> +# CONFIG_DNSD is not set
> +# CONFIG_ETHER_WAKE is not set
> +# CONFIG_FAKEIDENTD is not set
> +# CONFIG_FTPD=y
> +# CONFIG_FEATURE_FTP_WRITE=y
> +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y
> +# CONFIG_FTPGET is not set
> +# CONFIG_FTPPUT is not set
> +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
> +CONFIG_HOSTNAME=y
> +# CONFIG_HTTPD=y
> +# CONFIG_FEATURE_HTTPD_RANGES=y
> +# CONFIG_FEATURE_HTTPD_USE_SENDFILE=y
> +# CONFIG_FEATURE_HTTPD_SETUID=y
> +# CONFIG_FEATURE_HTTPD_BASIC_AUTH=y
> +# CONFIG_FEATURE_HTTPD_AUTH_MD5=y
> +# CONFIG_FEATURE_HTTPD_CGI=y
> +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y
> +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y
> +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y
> +# CONFIG_FEATURE_HTTPD_ERROR_PAGES=y
> +# CONFIG_FEATURE_HTTPD_PROXY=y
> +# CONFIG_FEATURE_HTTPD_GZIP=y
> +CONFIG_IFCONFIG=y
> +CONFIG_FEATURE_IFCONFIG_STATUS=y
> +# CONFIG_FEATURE_IFCONFIG_SLIP is not set
> +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set
> +CONFIG_FEATURE_IFCONFIG_HW=y
> +CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y
> +# CONFIG_IFENSLAVE is not set
> +CONFIG_IFPLUGD=y
> +CONFIG_IFUPDOWN=y
> +CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate"
> +# CONFIG_FEATURE_IFUPDOWN_IP is not set
> +# CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN is not set
> +CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN=y
> +CONFIG_FEATURE_IFUPDOWN_IPV4=y
> +CONFIG_FEATURE_IFUPDOWN_IPV6=y
> +CONFIG_FEATURE_IFUPDOWN_MAPPING=y
> +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set
> +# CONFIG_INETD is not set
> +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set
> +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set
> +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set
> +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set
> +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set
> +# CONFIG_FEATURE_INETD_RPC is not set
> +CONFIG_IP=y
> +CONFIG_FEATURE_IP_ADDRESS=y
> +CONFIG_FEATURE_IP_LINK=y
> +CONFIG_FEATURE_IP_ROUTE=y
> +CONFIG_FEATURE_IP_TUNNEL=y
> +# CONFIG_FEATURE_IP_RULE is not set
> +# CONFIG_FEATURE_IP_SHORT_FORMS is not set
> +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set
> +# CONFIG_IPADDR is not set
> +# CONFIG_IPLINK is not set
> +# CONFIG_IPROUTE is not set
> +# CONFIG_IPTUNNEL is not set
> +# CONFIG_IPRULE is not set
> +# CONFIG_IPCALC is not set
> +# CONFIG_FEATURE_IPCALC_FANCY is not set
> +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set
> +# CONFIG_NAMEIF is not set
> +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set
> +CONFIG_NETSTAT=y
> +CONFIG_FEATURE_NETSTAT_WIDE=y
> +CONFIG_FEATURE_NETSTAT_PRG=y
> +CONFIG_NSLOOKUP=y
> +CONFIG_NTPD=y
> +CONFIG_FEATURE_NTPD_SERVER=y
> +CONFIG_PING=y
> +CONFIG_PING6=y
> +CONFIG_FEATURE_FANCY_PING=y
> +# CONFIG_PSCAN is not set
> +CONFIG_ROUTE=y
> +# CONFIG_SLATTACH is not set
> +# CONFIG_TCPSVD is not set
> +CONFIG_TELNET=y
> +# CONFIG_FEATURE_TELNET_TTYPE is not set
> +CONFIG_FEATURE_TELNET_AUTOLOGIN=y
> +CONFIG_TELNETD=y
> +# CONFIG_FEATURE_TELNETD_STANDALONE is not set
> +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set
> +# CONFIG_TFTP=y
> +# CONFIG_TFTPD is not set
> +
> +#
> +# Common options for tftp/tftpd
> +#
> +# CONFIG_FEATURE_TFTP_GET=y
> +# CONFIG_FEATURE_TFTP_PUT=y
> +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
> +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set
> +# CONFIG_TFTP_DEBUG is not set
> +# CONFIG_TRACEROUTE=y
> +# CONFIG_TRACEROUTE6=y
> +# CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
> +# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y
> +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y
> +# CONFIG_TUNCTL=y
> +CONFIG_FEATURE_TUNCTL_UG=y
> +CONFIG_UDHCPD=y
> +CONFIG_DHCPRELAY=y
> +CONFIG_DUMPLEASES=y
> +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set
> +CONFIG_DHCPD_LEASES_FILE="/var/lib/misc/udhcpd.leases"
> +CONFIG_UDHCPC=y
> +CONFIG_FEATURE_UDHCPC_ARPING=y
> +# CONFIG_FEATURE_UDHCP_PORT is not set
> +CONFIG_UDHCP_DEBUG=9
> +# CONFIG_FEATURE_UDHCP_RFC3397 is not set
> +CONFIG_UDHCPC_DEFAULT_SCRIPT="@DATADIR@/udhcpc/default.script"
> +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80
> +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n"
> +# CONFIG_UDPSVD is not set
> +# CONFIG_VCONFIG is not set
> +CONFIG_WGET=y
> +CONFIG_FEATURE_WGET_STATUSBAR=y
> +CONFIG_FEATURE_WGET_AUTHENTICATION=y
> +CONFIG_FEATURE_WGET_LONG_OPTIONS=y
> +CONFIG_FEATURE_WGET_TIMEOUT=y
> +# CONFIG_ZCIP is not set
> +
> +#
> +# Print Utilities
> +#
> +# CONFIG_LPD is not set
> +# CONFIG_LPR is not set
> +# CONFIG_LPQ is not set
> +
> +#
> +# Mail Utilities
> +#
> +# CONFIG_MAKEMIME is not set
> +CONFIG_FEATURE_MIME_CHARSET=""
> +# CONFIG_POPMAILDIR is not set
> +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set
> +# CONFIG_REFORMIME is not set
> +# CONFIG_FEATURE_REFORMIME_COMPAT is not set
> +# CONFIG_SENDMAIL is not set
> +
> +#
> +# Process Utilities
> +#
> +# CONFIG_IOSTAT is not set
> +# CONFIG_MPSTAT is not set
> +# CONFIG_PMAP is not set
> +# CONFIG_POWERTOP is not set
> +# CONFIG_SMEMCAP is not set
> +# CONFIG_FREE is not set
> +# CONFIG_FUSER is not set
> +CONFIG_KILL=y
> +CONFIG_KILLALL=y
> +# CONFIG_KILLALL5 is not set
> +# CONFIG_NMETER is not set
> +# CONFIG_PGREP is not set
> +CONFIG_PIDOF=y
> +CONFIG_FEATURE_PIDOF_SINGLE=y
> +CONFIG_FEATURE_PIDOF_OMIT=y
> +# CONFIG_PKILL is not set
> +CONFIG_PS=y
> +CONFIG_FEATURE_PS_WIDE=y
> +# CONFIG_FEATURE_PS_TIME is not set
> +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set
> +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set
> +# CONFIG_RENICE is not set
> +# CONFIG_BB_SYSCTL is not set
> +# CONFIG_TOP is not set
> +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set
> +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set
> +# CONFIG_FEATURE_TOP_SMP_CPU is not set
> +# CONFIG_FEATURE_TOP_DECIMALS is not set
> +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set
> +# CONFIG_FEATURE_TOPMEM is not set
> +# CONFIG_FEATURE_SHOW_THREADS is not set
> +# CONFIG_UPTIME is not set
> +# CONFIG_WATCH is not set
> +
> +#
> +# Runit Utilities
> +#
> +# CONFIG_RUNSV is not set
> +# CONFIG_RUNSVDIR is not set
> +# CONFIG_FEATURE_RUNSVDIR_LOG is not set
> +# CONFIG_SV is not set
> +CONFIG_SV_DEFAULT_SERVICE_DIR=""
> +# CONFIG_SVLOGD is not set
> +# CONFIG_CHPST is not set
> +# CONFIG_SETUIDGID is not set
> +# CONFIG_ENVUIDGID is not set
> +# CONFIG_ENVDIR is not set
> +# CONFIG_SOFTLIMIT is not set
> +# CONFIG_CHCON is not set
> +# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set
> +# CONFIG_GETENFORCE is not set
> +# CONFIG_GETSEBOOL is not set
> +# CONFIG_LOAD_POLICY is not set
> +# CONFIG_MATCHPATHCON is not set
> +# CONFIG_RESTORECON is not set
> +# CONFIG_RUNCON is not set
> +# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set
> +# CONFIG_SELINUXENABLED is not set
> +# CONFIG_SETENFORCE is not set
> +# CONFIG_SETFILES is not set
> +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set
> +# CONFIG_SETSEBOOL is not set
> +# CONFIG_SESTATUS is not set
> +
> +#
> +# Shells
> +#
> +CONFIG_ASH=y
> +CONFIG_ASH_BASH_COMPAT=y
> +CONFIG_ASH_JOB_CONTROL=y
> +CONFIG_ASH_ALIAS=y
> +CONFIG_ASH_GETOPTS=y
> +CONFIG_ASH_BUILTIN_ECHO=y
> +CONFIG_ASH_BUILTIN_PRINTF=y
> +CONFIG_ASH_BUILTIN_TEST=y
> +# CONFIG_ASH_CMDCMD is not set
> +# CONFIG_ASH_MAIL is not set
> +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set
> +# CONFIG_ASH_RANDOM_SUPPORT is not set
> +CONFIG_ASH_EXPAND_PRMT=y
> +CONFIG_CTTYHACK=y
> +# CONFIG_HUSH is not set
> +# CONFIG_HUSH_BASH_COMPAT is not set
> +# CONFIG_HUSH_BRACE_EXPANSION is not set
> +# CONFIG_HUSH_HELP is not set
> +# CONFIG_HUSH_INTERACTIVE is not set
> +# CONFIG_HUSH_SAVEHISTORY is not set
> +# CONFIG_HUSH_JOB is not set
> +# CONFIG_HUSH_TICK is not set
> +# CONFIG_HUSH_IF is not set
> +# CONFIG_HUSH_LOOPS is not set
> +# CONFIG_HUSH_CASE is not set
> +# CONFIG_HUSH_FUNCTIONS is not set
> +# CONFIG_HUSH_LOCAL is not set
> +# CONFIG_HUSH_RANDOM_SUPPORT is not set
> +# CONFIG_HUSH_EXPORT_N is not set
> +# CONFIG_HUSH_MODE_X is not set
> +# CONFIG_MSH is not set
> +CONFIG_FEATURE_SH_IS_ASH=y
> +# CONFIG_FEATURE_SH_IS_HUSH is not set
> +# CONFIG_FEATURE_SH_IS_NONE is not set
> +# CONFIG_FEATURE_BASH_IS_ASH is not set
> +# CONFIG_FEATURE_BASH_IS_HUSH is not set
> +CONFIG_FEATURE_BASH_IS_NONE=y
> +CONFIG_SH_MATH_SUPPORT=y
> +CONFIG_SH_MATH_SUPPORT_64=y
> +CONFIG_FEATURE_SH_EXTRA_QUIET=y
> +# CONFIG_FEATURE_SH_STANDALONE is not set
> +# CONFIG_FEATURE_SH_NOFORK is not set
> +
> +#
> +# System Logging Utilities
> +#
> +CONFIG_SYSLOGD=y
> +CONFIG_FEATURE_ROTATE_LOGFILE=y
> +CONFIG_FEATURE_REMOTE_LOG=y
> +CONFIG_FEATURE_SYSLOGD_DUP=y
> +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256
> +CONFIG_FEATURE_IPC_SYSLOG=y
> +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16
> +CONFIG_LOGREAD=y
> +CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING=y
> +CONFIG_KLOGD=y
> +CONFIG_FEATURE_KLOGD_KLOGCTL=y
> +CONFIG_LOGGER=y
> --
> 1.7.3.4
>
>
> _______________________________________________
> Openembedded-devel mailing list
> Openembedded-devel@lists.openembedded.org
> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-devel
>



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/6] Add recipes for building TS75xx userspace utilities
  2011-03-30 16:55     ` Sachin Kamboj
@ 2011-04-02  8:40       ` Petr Štetiar
  0 siblings, 0 replies; 20+ messages in thread
From: Petr Štetiar @ 2011-04-02  8:40 UTC (permalink / raw)
  To: openembedded-devel

Sachin Kamboj <v2g.udel@gmail.com> [2011-03-30 12:55:35]:

> We'll discuss this with the vendor - however, can we include these tarballs
> in the interim?

Maybe, that you can skip the vendor part, make GitHub account, add all the
files in one project and make ts75xx-utils versioned package and recipe. I
don't see any point why it should be in separate recipe. It's possible to make
different packages from one recipe.

-- ynezz



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/6] Add kernel support for the Technologic Systems TS7500 ARM SBCs
  2011-03-30 14:07 ` [PATCH 3/6] Add kernel support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
  2011-03-30 14:45   ` Marcin Juszkiewicz
@ 2011-04-02  8:53   ` Petr Štetiar
  1 sibling, 0 replies; 20+ messages in thread
From: Petr Štetiar @ 2011-04-02  8:53 UTC (permalink / raw)
  To: openembedded-devel

UDel V2G Team <v2g.udel@gmail.com> [2011-03-30 10:07:07]:

>  .../linux/linux-ts75xx-2.6.35/ts75xx/defconfig.bak | 1521 +

You can drop that .bak file.

-- ynezz



^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2011-04-02  8:55 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-30 14:07 [PATCH 1/6] Add support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
2011-03-30 14:07 ` [PATCH 2/6] Allows the use of the angstrom distribution with ARM cores that do not support THUMB_INTERWORK instructions UDel V2G Team
2011-03-30 15:04   ` Koen Kooi
2011-03-31 20:57   ` Khem Raj
2011-03-30 14:07 ` [PATCH 3/6] Add kernel support for the Technologic Systems TS7500 ARM SBCs UDel V2G Team
2011-03-30 14:45   ` Marcin Juszkiewicz
2011-04-02  8:53   ` Petr Štetiar
2011-03-30 14:07 ` [PATCH 4/6] Add recipes for building TS75xx userspace utilities UDel V2G Team
2011-03-30 14:40   ` Marcin Juszkiewicz
2011-03-30 16:55     ` Sachin Kamboj
2011-04-02  8:40       ` Petr Štetiar
2011-03-30 14:07 ` [PATCH 5/6] Added images for the TS7500 ARM SBCs UDel V2G Team
2011-03-30 14:33   ` Marcin Juszkiewicz
2011-03-30 14:07 ` [PATCH 6/6] Adds custom defconfigs for Technologic Systems " UDel V2G Team
2011-03-31 21:00   ` Khem Raj
2011-03-30 14:43 ` [PATCH 1/6] Add support for the " Marcin Juszkiewicz
2011-03-31 20:48 ` Khem Raj
  -- strict thread matches above, loose matches on Subject: below --
2011-03-30 16:40 R.T. McGee
2011-03-30 17:42 ` Koen Kooi
2011-03-31  9:19   ` Phil Blundell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.