* [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(®s, 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, ®s, 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(®);
++ bret = (reg & (1 << pin)) != 0;
++ }
++ else
++ {
++ /* GPIOB */
++ str8100_gpio_b_datain(®);
++ 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 &= 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 &= ~(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, ®);
++ /* if error exists, set Bypass Filter enable */
++ if ((reg & 0xfffc)) {
++ star_nic_read_phy(port, 15, ®);
++ star_nic_read_phy(port, 27, ®2);
++ 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, ®2);
++
++ 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, ®);
++ 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, ®);
++ star_nic_read_phy(port, 28, ®2);
++ /* 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, ®);
++ 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, ®);
++ PDEBUG("[0,%d,%x]\n", 2, reg);
++ star_gsw_read_phy(29, 31, ®);
++ 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 |= (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 |= (0x1 << 10);
++ star_gsw_write_phy(29, 18, reg);
++
++
++ // P4_FORCE 100 Mbps
++ star_gsw_read_phy(29, 22, ®);
++ reg |= (0x1 << 10);
++ star_gsw_write_phy(29, 22, reg);
++
++
++ // P4_FORCE_FULL duplex
++ star_gsw_read_phy(29, 22, ®);
++ 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 |= (0x1 < 13);
++ star_gsw_write_phy(29, 18, reg);
++ star_gsw_read_phy(29, 18, ®);
++ printk("[29,%d,%x]\n", 18, reg);
++ #endif
++#if 0
++ //star_gsw_read_phy(29, 23, ®);
++ //reg = reg & 0xF800;
++ //reg = reg | 0x7C2;
++
++
++ star_gsw_write_phy(29, 24, 0x1);
++
++ star_gsw_read_phy(29, 24, ®);
++ PDEBUG("[ 29, 24, %x]\n", reg);
++
++ star_gsw_write_phy(29, 25, 0x2);
++ udelay(1000);
++
++ star_gsw_read_phy(29, 25, ®);
++ 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, ®);
++ PDEBUG("[29,%d,%x]\n", II, reg);
++ }
++
++ for(II=1;II<=10;II++)
++ {
++ star_gsw_read_phy(30, II, ®);
++ 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 = ¤t_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.